不幸的是,我已经成为持续更新标签问题的牺牲品。在搜索解决方案时,我找到了许多upvotes的答案,建议将我的标签绑定到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();
}
}
}
}
答案 0 :(得分: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
答案 1 :(得分:0)
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);
}
}
答案 2 :(得分:0)
您可以通过时间轴或任务类更改标签本身的值。
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++);
}
}