【问题标题】:JavaFX label will not continuously updateJavaFX 标签不会持续更新
【发布时间】:2017-05-19 01:50:36
【问题描述】:

不幸的是,我已经成为不断更新标签问题的牺牲品。在寻找解决方案时,我找到了一个答案,其中有很多人建议将我的标签绑定到 StringProperty,然后每当更改 StringProperty 时,标签的文本就会随之更改。但是,我终其一生都无法让它发挥作用。

我知道这是某种线程问题。有没有办法使用 DataBinding 解决方案等解决问题,或者线程是唯一的选择?如果线程是唯一的选择,你能指出我正确的方向吗?我也没有找到使用线程的好解决方案...

任何帮助将不胜感激!

程序说明:下面程序的预期功能是让标签在for循环中从0-10计数时不断更新。

public class First extends Application {
Stage mainStage;
Scene mainScene;

Button mainButton;
Label mainLabel;

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage stage) throws Exception {

    mainStage = stage;
    mainButton = new Button("Begin!");
    mainLabel = new Label("Ready");

    VBox box = new VBox(50);
    box.getChildren().addAll(mainLabel, mainButton);

    mainScene = new Scene(box, 200, 200);
    mainStage.setScene(mainScene);
    mainStage.setTitle("Test Program");
    mainStage.show();

    //Handles Button Press
    mainButton.setOnAction(e -> {
        Second s = new Second();
        mainLabel.textProperty().bind(s.getProperty());
        s.count();
    });
  }
}

这是第二课:

public class Second {

private StringProperty strP = new SimpleStringProperty(this, "strProperty", "");

//Get Property
public StringProperty getProperty() {
    return strP;
}

//Get String
public String getString() {
    return strP.get();
}

//Changes StringProperty every 0.25s
public void count() {

    for (int i = 0; i <= 10; i++) {

        this.strP.set(Integer.toString(i));

        try {
            Thread.sleep(250);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
    }
  }
}

【问题讨论】:

    标签: java multithreading javafx label


    【解决方案1】:

    个人在JavaFX中,我通常会这样创建一个计数器(你可以把这个想法应用到你的项目中):

    Label timerLabel = new Label();
    Timer timer = new Timer();
    int count = 0;
    timer.schedule(new TimerTask() { // timer task to update the seconds
        @Override
        public void run() {
            // use Platform.runLater(Runnable runnable) If you need to update a GUI component from a non-GUI thread.
            Platform.runLater(new Runnable() { 
                public void run() {
                    timerLabel.setText("Second : " + count);
                    count++;
                    if (count >= 10){timer.cancel();}
    }});}}, 1000, 1000); //Every 1 second
    

    【讨论】:

      【解决方案2】:

      Java8 和 JavaFx 具有使线程更容易的新类。您可以使用 AnimationTimer 或 Timeline。此示例使用时间轴。

      import javafx.animation.*;
      import javafx.application.*;
      import javafx.event.*;
      import javafx.scene.*;
      import javafx.scene.control.*;
      import javafx.scene.layout.*;
      import javafx.stage.*;
      import javafx.util.*;
      
      /**
       *
       * @author Sedrick
       */
      public class First  extends Application {
      
          Stage mainStage;
          Scene mainScene;
      
          Button mainButton;
          Label mainLabel;
      
          public static void main(String[] args)
          {
              launch(args);
          }
      
          @Override
          public void start(Stage stage) throws Exception
          {
      
              mainStage = stage;
              mainButton = new Button("Begin!");
              mainLabel = new Label("Ready");
      
              VBox box = new VBox(50);
              box.getChildren().addAll(mainLabel, mainButton);
      
              mainScene = new Scene(box, 200, 200);
              mainStage.setScene(mainScene);
              mainStage.setTitle("Test Program");
              mainStage.show();
      
              //Handles Button Press
              mainButton.setOnAction(e -> {
                  Second s = new Second();
                  mainLabel.textProperty().bind(s.getProperty());
                  Timeline timeline = new Timeline(
                          new KeyFrame(Duration.seconds(0),
                                  new EventHandler<ActionEvent>() {
                              @Override
                              public void handle(ActionEvent actionEvent)
                              {
                                  s.setStrP(Integer.toString(Integer.parseInt(s.getStrP()) + 1));//I think you should have used an Integer here.
                              }
                          }
                          ),
                          new KeyFrame(Duration.seconds(1))//Do something every second. In this case we are going to increment setStrP.
                  );
                  timeline.setCycleCount(10);//Repeat this 10 times
                  timeline.play();
              });
          }
      }
      
      
      
      import javafx.beans.property.*;
      
      public class Second {
      
          private StringProperty strP = new SimpleStringProperty();
      
          Second()
          {
              setStrP("0");//set to zero
          }
      //Get Property
      
          public StringProperty getProperty()
          {
              return strP;
          }
      
      //Get String
          public String getStrP()
          {
              return strP.get();
          }
      
      //Changes StringProperty every 0.25s
          public void setStrP(String i)
          {
              this.strP.set(i);
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以通过 Timeline 或 Task 类更改 label 本身的值。

        import javafx.animation.KeyFrame;
        import javafx.animation.Timeline;
        import javafx.application.Application;
        import javafx.beans.property.SimpleStringProperty;
        import javafx.beans.property.StringProperty;
        import javafx.concurrent.Task;
        import javafx.event.ActionEvent;
        import javafx.event.EventHandler;
        import javafx.scene.Scene;
        import javafx.scene.control.Button;
        import javafx.scene.control.Label;
        import javafx.scene.layout.VBox;
        import javafx.stage.Stage;
        import javafx.util.Duration;
        
        public class First extends Application {
            Stage mainStage;
            Scene mainScene;
        
            Button mainButton;
            Button mainButton2;
            Label mainLabel;
        
            public static void main(String[] args) {
                launch(args);
        
            }
        
            @Override
            public void start(Stage stage) throws Exception {
        
                mainStage = stage;
                mainButton = new Button("Begin!");
                mainButton2 = new Button("Begin2!");
                mainLabel = new Label("Ready");
        
                VBox box = new VBox(50);
                box.getChildren().addAll(mainLabel, mainButton, mainButton2);
        
                mainScene = new Scene(box, 200, 200);
                mainStage.setScene(mainScene);
                mainStage.setTitle("Test Program");
                mainStage.show();
        
        
                mainButton.setOnAction(e -> {
                    final Second s = new Second();
        
                    mainLabel.textProperty().bind(s.getProperty());
        
                    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0), new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent actionEvent) {
                            s.count();
                        }
                    }), new KeyFrame(Duration.seconds(Second.DURATION)));
        
                    timeline.setCycleCount(11);
                    timeline.play();
        
                });
        
                mainButton2.setOnAction(event -> {
                    final Second s = new Second();
                    s.count2(mainLabel);
        
                });
        
                //
            }
        }
        
        class Second {
        
            private StringProperty strP = new SimpleStringProperty(this, "strProperty", "");
            private int myCount;
            public static float DURATION = 0.25F;
            public static long DURATION_SEC = (long)DURATION * 1000;
        
            Second()
            {
                myCount = 0;
            }
        
            public void count2(final Label mainLabel) {
                Task<Void> task = new Task<Void>() {
                    @Override 
                    public Void call() throws Exception {
                        for (int i=1; i<=10; i++) {
                            updateMessage("Count: "+i);
                            Thread.sleep(DURATION_SEC);
                        }
                        return null ;
                    }
                };
        
                task.messageProperty().addListener((obs, oldMessage, newMessage) -> mainLabel.setText(newMessage));
                new Thread(task).start();
            }
        
            // Get Property
            public StringProperty getProperty() {
                return strP;
            }
        
            // Get String
            public String getString() {
                return strP.get();
            }
        
            public void count()
            {
                this.strP.set("Count: "+myCount++);
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 2020-06-22
          • 2015-06-02
          • 2016-05-10
          • 2021-04-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-08
          • 1970-01-01
          相关资源
          最近更新 更多