JavaFX - 控制和并发 [英] JavaFX - Control and Concurrency
问题描述
我有一个示例Hello World JavaFx。我正在使用Eclipse和eFxclipse插件。我的Eclipse是kepler,它是Eclipse 4.3.2版本,Java servion是Jdk1.7-045。
I have a sample Hello World JavaFx. I am using Eclipse and eFxclipse plugin. My Eclipse is kepler which is Eclipse 4.3.2 version and Java servion is Jdk1.7-045.
我尝试添加的是很少的并发代码,我只想更新示例中的按钮文本。这个后端任务是否可以与前期UI控件交互,例如按钮,场景?如果没有,我如何制作定制的后端任务,然后与UI控件进行交互?
What I try to add is very little concurrency codes, I just want to update button text in the example. Could this backend task interact with upfront UI control, for example button, scene? If not, how could I make tailored backend task, then interact with UI control?
提前致谢
package com.juhani.fx.exer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application{
private static final short COREPOOLSIZE=2;
private static final short MAXIMUMPOOLSIZE=2;
private static final int WORKQUEUECAPACITY=100;
private static Logger log = LogManager.getLogger(
HelloWorld.class.getName());
private ExecutorService executors = new ThreadPoolExecutor(COREPOOLSIZE,MAXIMUMPOOLSIZE,20,TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(WORKQUEUECAPACITY));
public static void main(String[] args) {
LogMessage logMessage = new LogMessage("BEGIN",1.0,1,"HELLOWORLD");
log.trace(logMessage.toString());
launch(args);
}
@Override
public void start(final Stage primaryStage) throws InterruptedException {
primaryStage.setTitle("Hello World!");
final Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
final StackPane root = new StackPane();
root.getChildren().add(btn);
final Scene scene= new Scene(root,300,250);
primaryStage.setScene(scene);
primaryStage.show();
Task<Boolean> task = new Task<Boolean>() {
@Override
public Boolean call() {
for(int i=0;i<20;i++){
btn.setText("First row\nSecond row "+i);
primaryStage.show();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error(new LogMessage("entering interruption",1.0,2,"exception").toString());
}
}
return new Boolean(true);
}
};
executors.submit(task);
}
}
推荐答案
这个答案专门讨论了Platform.runLater的使用。如果您正在使用Task,最好使用它提供的方法更新UI,如
kleopatra的回答。
要更新UI,您必须使用Javafx线程。
For updating the UI, you have to be on the Javafx thread.
进入任何其他线程后,请使用 Platform.runLater()
将这些数据更新回Javafx UI。一个工作示例可以在下面找到
Once you are on any other thread, use Platform.runLater()
to update those data back to Javafx UI. A working example can be found below
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
private static final short COREPOOLSIZE = 2;
private static final short MAXIMUMPOOLSIZE = 2;
private static final int WORKQUEUECAPACITY = 100;
private ExecutorService executors = new
ThreadPoolExecutor(COREPOOLSIZE, MAXIMUMPOOLSIZE, 20, TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(WORKQUEUECAPACITY));
public static void main(String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws InterruptedException {
primaryStage.setTitle("Hello World!");
final Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
final StackPane root = new StackPane();
root.getChildren().add(btn);
final Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
Task<Boolean> task = new Task<Boolean>() {
@Override
public Boolean call() {
final AtomicInteger i = new AtomicInteger(0);
for( ; i.get() < 20; i.incrementAndGet()) {
Platform.runLater(new Runnable() {
@Override
public void run() {
btn.setText("First row\nSecond row " + i);
}
});
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {}
}
return Boolean.valueOf(true);
}
};
executors.submit(task);
}
}
有关详细信息,您可以浏览提供的链接< a href =https://stackoverflow.com/a/23920527/1759128>这里
For more information you can go through the links provided here
这篇关于JavaFX - 控制和并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!