Today there was a really normal java code like:
setCursor(Waitcursor);
execute something on the server
setCursor(Defaultcursor);
Now the problem… the waitcursor does not appear!
The Code in Swing is still working but not in JavaFX.
There is a (from my point of view) a problem in the current implementation!
Current posts on „stackoverflow“ and other needs a „Task“.
Here is my Implementation with a Testflag „testFlagToUseOnlySetCursor“ to disable my code.
[codesyntax lang=“java“]
import com.sun.javafx.tk.Toolkit; import java.util.logging.Level; import java.util.logging.Logger; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.Event; import javafx.event.EventHandler; import javafx.event.EventType; import javafx.geometry.Orientation; import javafx.scene.Cursor; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.FlowPane; import javafx.stage.Stage; /** * * @author andre */ public class Cursortest extends Application { /** * Testflag to check the difference between the original Oracle * implementation for the cursor. * */ private boolean testFlagToUseOnlySetCursor = false; private Scene scene; private void addWaitcursorHelper() { // The AnimationTimer runs one every Frame AnimationTimer timer = new AnimationTimer() { boolean wasRendered = false; @Override public void handle(long now) { if (Toolkit.getToolkit().isNestedLoopRunning()) { // One rendering must be running once to display the cursor! if (wasRendered) { Toolkit.getToolkit().exitNestedEventLoop(scene, Boolean.FALSE); } // Flag for one Rendering successful wasRendered = true; } else { wasRendered = false; } } }; timer.start(); } /** * Blocking of all! Events when the operation is running */ private EventHandler<Event> blockingHelper = new EventHandler<Event>() { @Override public void handle(Event event) { event.consume(); } }; @Override public void start(Stage primaryStage) { Button btn = new Button(); btn.setText("Perform long action"); btn.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { performAction(); } }); FlowPane root = new FlowPane(Orientation.VERTICAL); root.getChildren().add(btn); scene = new Scene(root, 300, 250); // Helper activation if (!testFlagToUseOnlySetCursor) { addWaitcursorHelper(); } primaryStage.setTitle("Waitcursordemo"); primaryStage.setScene(scene); primaryStage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } private void realCodeExecution() { for (int i = 0; i < 50; i++) { try { System.out.println("Perform: " + i); Thread.sleep(100); } catch (InterruptedException ex) { Logger.getLogger(Cursortest.class.getName()).log(Level.SEVERE, null, ex); } } } private void activateWaitCursor() { if (scene.getCursor() == null || !scene.getCursor().equals(Cursor.WAIT)) { if (!testFlagToUseOnlySetCursor) { //Blocking the events because the user has the chance to click a button in 2 Frames scene.addEventFilter(EventType.ROOT, blockingHelper); } // No multiple activation of the waitcursor and the eventloop scene.setCursor(Cursor.WAIT); if (!testFlagToUseOnlySetCursor) { // Activate a extra eventloop to perform a little hack to draw 2 frames that the cursor is showing Toolkit.getToolkit().enterNestedEventLoop(scene); } } } private void deactiveWaitCursor() { // Remove the cursor on the next paint Platform.runLater(new Runnable() { @Override public void run() { if (scene != null) { scene.setCursor(null); scene.removeEventFilter(EventType.ROOT, blockingHelper); } } }); } private void performAction() { activateWaitCursor(); realCodeExecution(); deactiveWaitCursor(); } }
[/codesyntax]