Java Reference
In-Depth Information
// Bad code, this will cause the UI to be unresponsive
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
// TODO properly handle interruption
}
}
The Thread.sleep(Long.MAX_VALUE) simulates code that takes a long time to execute. In real-life applications,
this might be a database call, a web service call, or a piece of complicated code. As a result, if you click the “Change
Fill” button, the color change is not seen in the rectangle. What is worse, the whole UI appears to be locked up: The
“Change Fill” and “Change Stroke” buttons stop working; the close window button that is provided by the operating
system will not have the desired effect. The operating system might also mark the program as “Not Responding,” and
the only way to stop the program is to use the operating system's forced kill functionality.
To fix problems like this, we need to offload long-running code to worker threads and communicate the result
of the long computation back to the JavaFX application thread to update the states of the UI so that the user can see
the result. Depending on when you learned your Java, your answer to the first question of offloading code to worker
threads might be different. If you are a longtime Java programmer your instinctive reaction might be to instantiate a
Runnable , wrap it in a Thread , and call start() on it. If you started with Java after Java 5 and learned the java.util.
concurrent hierarchy of classes, your reaction might be to stand up a java.util.concurrent.ExecutorService and
submit java.util.concurrent.FutureTask s to it. JavaFX includes a worker threading framework based on the latter
approach in the javafx.concurrent package.
We examine the interfaces and classes in this framework in the next few sections, but before we do that we use
the Runnable and Thread approach to offload computation to a worker thread. Our intention here is to highlight the
answer to the second question of how to cause code to be run on the JavaFX application thread from a worker thread.
The complete corrected program can be found in ResponsiveUIExample.java . Here is the new code for the event
handler of the “Change Fill” button:
view.changeFillButton.setOnAction(actionEvent -> {
final Paint fillPaint = model.getFillPaint();
if (fillPaint.equals(Color.LIGHTGRAY)) {
model.setFillPaint(Color.GRAY);
} else {
model.setFillPaint(Color.LIGHTGRAY);
}
Runnable task = () -> {
try {
Thread.sleep(3000);
Platform.runLater(() -> {
final Rectangle rect = view.rectangle;
double newArcSize =
rect.getArcHeight() < 20 ? 30 : 0;
rect.setArcWidth(newArcSize);
rect.setArcHeight(newArcSize);
});
} catch (InterruptedException e) {
// TODO properly handle interruption
}
};
new Thread(task).start();
});
 
Search WWH ::




Custom Search