当前位置: 首页 > 知识库问答 >
问题:

JavaFX标签不会持续更新

祝锐
2023-03-14

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

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

任何帮助将不胜感激!

程序描述:以下程序的理想功能是在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();
        }
    }
  }
}

共有3个答案

章茂
2023-03-14

您可以通过时间线或任务类更改标签本身的值。

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++);
    }

}
濮阳耀
2023-03-14

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);
    }
}
蒋畅
2023-03-14

就个人而言,在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
 类似资料:
  • > System.out正确显示标签上的id; 第二个控制器与嵌入在第一个控制器中的FXML文件绑定。如代码所示,第二个FXML文件/控制器是动态加载的:。 当从第二个控制器中的initialize方法设置id时,id会按预期显示在标签中: public void initialize(){this.setid(“12”);} 编辑: 此窗格声明为属性 第二个:

  • 我正在尝试为用Java编写的应用程序制作GUI。 我用Scene Builder制作了fxml文档,正确设置了fx: id,现在我正在尝试对表单进行简单的更改。 我的DocumentController: 我的外汇主文件: 我现在想要的一切,都是将LabelData设置为实际时间戳,但当我运行FX主文件时,什么都不会发生。有人能帮我吗? 谢谢你保罗 更新时间: 我的整个FXML文档: 我想要的一切

  • 主要内容:创建标签,标签内容,标签字体,包装文本,应用效果,标签鼠标事件,更新标签JavaFX API的包中的类可用于显示一个文本元素。 我们可以包装文本元素以适应特定空间,添加图形图像或使用JavaFX 控件应用视觉效果。 以下代码显示如何使用显示文本。 创建标签 JavaFX API提供了类的三个构造函数来创建标签。 标签内容 创建标签后,我们可以使用类中的以下方法添加文本和图形内容。 - 设置标签的文本标题 - 设置图形图标 方法设置文本和图标之间的间距。方法设置标签文本

  • 我需要更改JavaFX中标签的锚点。我将锚点描述为选择来翻译底层节点的点。默认情况下,锚点似乎是左上角。 我试图通过如下描述的附加翻译来解决这个问题: 代码应转换标签,使其像右下角的锚点一样工作。这不起作用,因为在我执行代码时,标签的边界框是[minX:0.0,minY:0.0,minZ:0.0,宽度:-1.0,高度:-1.0,深度:0.0,maxX:-1.0,maxY:-1.0,maxZ:0.0

  • 问题内容: 如何建立持续集成标签而不是分支的实践? 我具有标签存储库目录的以下结构: 我想配置我的持续集成工具(可以是CruiseControl,Hudson和Jenkins到TeamCity的任何工具),以在两个文件夹中的任何一个中创建了最新标记。 例如,如果结构已更改并且标签已出现在目录中,我想触发标签下的源代码构建: 是否可以使用任何现有的持续集成工具在标签下构建源代码,或者为此目的我应该编

  • 我无法从其他类更改标签的文本。我需要不断更新主屏幕上的日期和时间,而我也可以同时执行其他功能。我使用了一个TimeSetting类,它扩展了Thread,在它的run()方法中,我使用setText()在无限循环中调用了updation命令,然后让该方法Hibernate一秒钟。但是在运行这个时,什么也没有发生,在关闭输出窗口时,我得到一个错误,说NullPointerExcpetion 下面是两