如何在JavaFX中每2秒更新一次标签框?
我试图在应用程序GUI中模拟一个基本的恒温器 我想用新的温度值每隔2秒更新一个标签框值 例如,我的初始温度将显示为68度,并每2秒更新到69度、70度等,直到75度 这是我用JavaFX编写的一段代码。控制面板是标签框所在的te表单对象。它仅将最终值更新为75。它不会每2秒更新一次。我已经编写了一个方法暂停,导致2秒延迟。所有标签都会使用其最终值进行更新,但不会每2秒更新一次。调试时,我可以看到值每2秒增加一个。此代码是在ButtonOnClick事件中编写的如何在JavaFX中每2秒更新一次标签框?,java,swing,javafx-2,javafx,Java,Swing,Javafx 2,Javafx,我试图在应用程序GUI中模拟一个基本的恒温器 我想用新的温度值每隔2秒更新一个标签框值 例如,我的初始温度将显示为68度,并每2秒更新到69度、70度等,直到75度 这是我用JavaFX编写的一段代码。控制面板是标签框所在的te表单对象。它仅将最终值更新为75。它不会每2秒更新一次。我已经编写了一个方法暂停,导致2秒延迟。所有标签都会使用其最终值进行更新,但不会每2秒更新一次。调试时,我可以看到值每2秒增加一个。此代码是在ButtonOnClick事件中编写的 private void jBut
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int i=0;
Timer asd = new Timer(1000,null);
asd.setDelay(1000);
while(i < 10)
{
jTextField1.setText(Integer.toString(i));
i++;
asd.start();
}
}
要使用计时器解决任务,您需要用代码实现TimerTask,并使用TimerscheduleAtFixedRate方法重复运行该代码:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.print("I would be called every 2 seconds");
}
}, 0, 2000);
还请注意,如果您使用JavaFX,则必须在Swing UI线程或FX UI线程上调用任何UI操作:
private int i = 0;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jTextField1.setText(Integer.toString(i++));
}
});
}
}, 0, 2000);
}
对于JavaFX,您需要更新FXUI线程上的FX控件,而不是Swing线程上的FX控件。要实现这一点,请使用javafx.application.PlatformrunLater方法而不是SwingUtilities这里有一个替代解决方案,它使用javafx动画时间线而不是计时器 我喜欢这个解决方案,因为动画框架确保一切都发生在JavaFX应用程序线程上,所以您不需要担心线程问题
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.Random;
public class ThermostatApp extends Application {
@Override public void start(final Stage stage) throws Exception {
final Thermostat thermostat = new Thermostat();
final TemperatureLabel temperatureLabel = new TemperatureLabel(thermostat);
VBox layout = new VBox(10);
layout.getChildren().addAll(temperatureLabel);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 20; -fx-font-size: 20;");
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) throws Exception {
launch(args);
}
}
class TemperatureLabel extends Label {
public TemperatureLabel(final Thermostat thermostat) {
textProperty().bind(
Bindings.format(
"%3d \u00B0F",
thermostat.temperatureProperty()
)
);
}
}
class Thermostat {
private static final Duration PROBE_FREQUENCY = Duration.seconds(2);
private final ReadOnlyIntegerWrapper temperature;
private final TemperatureProbe probe;
private final Timeline timeline;
public ReadOnlyIntegerProperty temperatureProperty() {
return temperature.getReadOnlyProperty();
}
public Thermostat() {
probe = new TemperatureProbe();
temperature = new ReadOnlyIntegerWrapper(probe.readTemperature());
timeline = new Timeline(
new KeyFrame(
Duration.ZERO,
new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
temperature.set(probe.readTemperature());
}
}
),
new KeyFrame(
PROBE_FREQUENCY
)
);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
}
class TemperatureProbe {
private static final Random random = new Random();
public int readTemperature() {
return 72 + random.nextInt(6);
}
}
该解决方案基于以下的倒计时计时器解决方案:调用平台。runLater为我工作:
Platform.runLater(new Runnable() {
@Override
public void run() {
}
});
这与什么有关?JavaFX和Swing是不同的GUI工具包。您通常会使用一个或另一个。如果swing框架中有此问题的解决方案,将帮助我在swing中的JavaFX中实现它,您将使用javax.swing.Timer。@user1364861它最后只更新,在这种情况下没有任何帮助,这是一篇简短、可编译的文章的原因,否则这个问题根本无法回答。我对计时器没有问题。显然,你确实对计时器有问题,因为你不知道如何使用它阅读api文档。。。提示:你的计时器不工作。你知道如何停止这个计时器吗?使用动画计时器怎么样?这也在javafx应用程序线程上运行吗?是的,动画计时器在javafx应用程序上运行,是的,它可以用某种方式回答这个问题。使用时间轴更直接,因为它是一个更高级别的构造,完全满足问题的要求,每2秒调用一次UI更新,以时间轴使用的关键帧结构设置直观的方式。如果你想做一个游戏循环或一个物理模型,更新的时间间隔可能会不断变化,那么AnimationTimer是合适的。感谢你的解释,是的,我刚刚尝试了Timeline,它比AnimationTimer更容易使用