Method of updating UI with javafx
- 2021-10-24 23:08:01
- OfStack
Update UI with javafx
JavaFx If UI is updated in a child thread, either task or runable will report an error
java.lang.IllegalStateException: Not on FX application thread; currentThread =
In this case, you can use the following methods
1. Platform. runLater ()
This method can be called directly in threads whose current thread is not javafx, such as runnable and thread. runLater () is not thread blocking, and it will only be executed when the main thread of javafx is completely empty or idle.
Platform.runLater(new Runnable() {
@Override
public void run() {
// Update JavaFX The code of the main thread of is placed here
p.cancelProgressBar();
}
});
But what if you have to execute this code first, there are ways
1. future is a worker thread
It allows you to block the current thread, execute the code in the thread, and execute it sequentially after getting the return value
// Definition 1 A FutureTask , and then Plateform.runLater() This futuretask
final FutureTask<String> query = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
// New 1 Windows ( Method creates the stage)
VcodeController vc = new VcodeController();
return vc.show(url4vcode);
}
});
Platform.runLater(query); // Focus
String vcode = query.get(); // So you can get the return value
System.out.println(vcode);
2. Using CountDownLatch, directly block the current main thread and execute relevant code business
/**
* Runs the specified {@link Runnable} on the
* JavaFX application thread and waits for completion.
*
* @param action the {@link Runnable} to run
* @throws NullPointerException if {@code action} is {@code null}
*/
public static void runAndWait(Runnable action) {
if (action == null)
throw new NullPointerException("action");
// run synchronously on JavaFX thread
if (Platform.isFxApplicationThread()) {
action.run();
return;
}
// queue on JavaFX thread and wait for completion
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(() -> {
try {
action.run();
} finally {
doneLatch.countDown();
}
});
try {
doneLatch.await();
} catch (InterruptedException e) {
// ignore exception
}
}
3. Use the return value of the task thread
task is an ui thread implemented by javafx, and it implements futureTask and worlker threads, so it can be used as a normal thread, and it can also rewrite the return value method to refresh the interface of ui
However, it should be noted that the call method of task is still a common thread method. If you want to refresh the ui interface in task, you should
scheduled (), succeeded (), running () any one of the methods, it is OK, so that the thread of task, refresh the interface function
package com.yz.readismqtest1;
import javafx.concurrent.Task;
public class deda {
public static void main(String[] args) {
Task task = new Task() {
@Override
protected Object call() throws Exception {
// Execute common methods
return null;
}
@Override
protected void scheduled() {
// Update JavaFX The code of the main thread of is placed here
super.scheduled();
}
@Override
protected void succeeded() {
// Update JavaFX The code of the main thread of is placed here
super.succeeded();
}
@Override
protected void running() {
// Update JavaFX The code of the main thread of is placed here
super.running();
}
};
}
}
Concurrent Programming of JavaFX and Updating of UI
JavaFX Concurrent Programming and UI Update
Project requirements
According to the needs of the project, the concurrent test of the equipment should be carried out, and the test results should be displayed in real time on the interface
Technologies involved
1. Using Observer to realize communication between multiple objects (observer mode)
2. Because there is only one UI, which needs to receive and display a large amount of data in a short time, javafx. concurrent is used
3. Thread pool pool to reduce the resource occupation of objects
The use of the above technology refers to a large number of network resources and books, and will not be listed again. Thank you for your authors.
Core code
// 1 Getting objects from the thread pool
ObjectPoolDrawUIService objPool = ObjectPoolDrawUIService.getInstance();
DrawUIService obj = (DrawUIService)objPool.getObject();
// 2 The initialization of an object produceCaseResult Is the data content that needs to be updated ,i It's line number information, which is placed in Object[] Transfer in
obj.init(new Object[]{produceCaseResult,i}, new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
Object[] objArray = (Object[])t.getSource().getValue();
testDetailList.set((int) objArray[1], (ProduceCaseResult)objArray[0]);
// 4 Because it is executed in a thread, the returnObject Code cannot follow obj.restart Later, it will lead to being quickly restart
objPool.returnObject(obj);
}
});
// 3 , execution
obj.restart(); // Because it is from pool Gets from, may have finished executing, so restart
Special attention should be paid to the above code, and the code 4 The following code is the location of javafx.concurrent Core code of
public class DrawUIService extends Service<Object[]>{
Object[] showData = {null,null};
public void init(Object[] showData, EventHandler<WorkerStateEvent> eventHandler) {
this.showData = showData;
setOnSucceeded(eventHandler);
}
@Override
protected Task<Object[]> createTask() {
return new Task<Object[]>() {
@Override
protected Object[] call() throws Exception {
return showData;
}
};
}
}