JavaFX-并发和更新标签

JavaFX-并发和更新标签,java,concurrency,javafx,label,togglebutton,Java,Concurrency,Javafx,Label,Togglebutton,我对这段代码有问题。我想制作一个应用程序,只要按下切换按钮,它就会在标签中连续显示随机值。这就是我创造的,它可以工作,但几秒钟后的窗口是可怕的。我做错了什么 下面是类的代码,它生成随机值: public class ValueMaker{ private StringPropterty x, y, z; private Random generator; private boolean isStarted = false; private int randomiz

我对这段代码有问题。我想制作一个应用程序,只要按下切换按钮,它就会在标签中连续显示随机值。这就是我创造的,它可以工作,但几秒钟后的窗口是可怕的。我做错了什么

下面是类的代码,它生成随机值:

public class ValueMaker{
    private StringPropterty x, y, z;
    private Random generator;
    private boolean isStarted = false;
    private int randomizedX(){ return generator.nextInt(10); }
    private int randomizedY(){ return generator.nextInt(10); }
    private int randomizedZ(){ return generator.nextInt(10); }

    public StringProperty xProperty(){ return x; }
    public StringProperty yProperty(){ return y; }
    public StringProperty zProperty() { return z; }

    public ValueMaker(){
        x = new SimpleStringProperty("0");
        y = new SimpleStringProperty("0");
        z = new SimpleStringProperty("0");
        generator = new Random();
    }



    private void setValues(){
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                x.set(String.valueOf(randomizedX()));
                y.set(String.valueOf(randomizedY()));
                z.set(String.valueOf(randomizedZ()));
            }
        });
    }

    public startRandomize(){
        isStarted = true;
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (isStarted){
                    setValues();
                }
            }
        });
        t.start();
    }

    public stopRandomize(){
        isStarted = false;
    }
}
下面是一段控制器代码,它调用以下方法:

   @FXML
   private void initialize(){
            labelX.textProperty().bind(ValueMaker.xProperty());
            labelY.textProperty().bind(ValueMaker.yProperty());
            labelZ.textProperty().bind(ValueMaker.zProperty());
            startRandomizeButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
                    @Override
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                        if (newValue==true){
                            ValueMaker.startRandomize();
                        }
                        else{
                            ValueMaker.stopRandomize();
                        }

                    }
                });
            }

我认为当你开始你的线程-它使用所有可用的资源。它在无限循环中工作,不间断地生成随机数。 尝试将睡眠添加到线程的循环中,使其暂停几毫秒并稍微释放CPU。
无论如何,您可能需要添加睡眠,否则随机标签将更改得太快。

我认为当您启动线程时,它会使用所有可用资源。它在无限循环中工作,不间断地生成随机数。 尝试将睡眠添加到线程的循环中,使其暂停几毫秒并稍微释放CPU。
您可能仍然需要添加睡眠,否则随机标签将更改得太快。

连续调用Platform.runLater会阻塞JavaFX应用程序线程。实现这一点的最佳方法是使用在每个帧中都将在其处于活动状态时调用的

AnimationTimer timer = new AnimationTimer() {    

    @Override
    public void handle(long now) {
        x.set(String.valueOf(randomizedX()));
        y.set(String.valueOf(randomizedY()));
        z.set(String.valueOf(randomizedZ()));
    }
};
然后调用示例中的计时器:

startRandomizeButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
       @Override
       public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
               // newValue==true is not required
               if (newValue){
                   timer.start();
               }
               else{
                   timer.stop();
               }
       });
}

连续调用Platform.runLater会阻塞JavaFX应用程序线程。实现这一点的最佳方法是使用在每个帧中都将在其处于活动状态时调用的

AnimationTimer timer = new AnimationTimer() {    

    @Override
    public void handle(long now) {
        x.set(String.valueOf(randomizedX()));
        y.set(String.valueOf(randomizedY()));
        z.set(String.valueOf(randomizedZ()));
    }
};
然后调用示例中的计时器:

startRandomizeButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
       @Override
       public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
               // newValue==true is not required
               if (newValue){
                   timer.start();
               }
               else{
                   timer.stop();
               }
       });
}

你的线程有无限循环吗?是的,有。当用户按下untoggle按钮时,我通过布尔变量isStarted来打破这个循环。你的线程有一个无限循环吗?是的,它有。当用户按下untoggle按钮时,我通过布尔变量isStarted打破了这个循环。当我使用Swing在Java中实现同样的事情,但没有绑定数据时,我用myslef更新label,它工作得非常好。没错,标签变化太快了,但窗口并没有冻结。当我使用Swing在Java中实现同样的东西,但没有绑定数据时,我用myslef更新标签,它工作得非常好。没错,标签变化太快了,但窗口并没有冻结。