JavaFx: ImageView.setRotate let menubar freeze

1 day ago 2
ARTICLE AD BOX

I try to program an application, which simulates and demonstrates a compass based on JavaFx25 / Java25 and Maven 3.9.12.

This application has a menubar with some menu items, a compass image (compass.png) set in an ImageView, a slider for setting the rotation speed and a label for showing the current rotation angle.

In the background I have a "calculation thread", which takes the sliders value, calculates the new heading and updates the label value and let the imageview rotate.

Actually, this works fine so far, but the effect is, after a couple of seconds, you can not use the menubar/items anymore. It seems that all menu buttons or submenues are completely freezed.

Based on commenting out some lines, I am sure, that the command imageView.setRotate() makes the trouble.

Here is my code so far (based on a reduced, minimal, but reproducable example):

My Main.java:

public class Main { static void main(String[] args) { GUI.launch(GUI.class, args); } }

GUI.java

public class GUI extends Application { public static double HEADING = 0.0; private Thread calculationThread; public static Scene scene; @Override public void init() { calculationThread = new Thread(new CalculationThread()); calculationThread.setDaemon(true); } @Override public void start(Stage primaryStage) { VBox mainWindow = CompassWindow.createCompassWindow(); calculationThread.start(); scene = new Scene(mainWindow, 620, 780); primaryStage.setScene(scene); primaryStage.show(); } }

CalculationThread.java

public class CalculationThread implements Runnable { private static final long UPDATE_RATE_COMPASS = 50; // in [ms] @Override public void run() { while (true) { try { double step = (sliderSimulator.getValue() / 10) / (1000.0 / UPDATE_RATE_COMPASS); HEADING = HEADING + step; if (HEADING >= 360.0) HEADING = HEADING - 360.0; if (HEADING < 0.0) HEADING = HEADING + 360.0; Platform.runLater(() -> labelHeadingValue.setText(String.valueOf(HEADING))); Platform.runLater(() -> { //ATTENTION: If this line is commented in, the problem occurs! if (imageCompass != null) imageCompass.setRotate(-HEADING); }); Thread.sleep(UPDATE_RATE_COMPASS); } catch (Exception e) { System.err.println(e); } } } }

and CompassWindow.java

public class CompassWindow { private static GridPane gridPaneBottomMenue; private static VBox vBoxSimulator; public static ImageView imageCompass; public static Slider sliderSimulator; public static Label labelHeadingValue; public static VBox createCompassWindow() { MenuBar menuBar = new MenuBar(); Menu menuFile = new Menu("File"); Menu menueHelp = new Menu("Help"); MenuItem itemClose = new MenuItem("Close"); itemClose.setOnAction((e) -> System.exit(0)); MenuItem itemInfo = new MenuItem("Info"); menuFile.getItems().addAll(itemClose); menueHelp.getItems().addAll(itemInfo); menuBar.getMenus().addAll(menuFile, menueHelp); imageCompass = new ImageView(new Image("compass.png", 600, 600, false, false)); imageCompass.setTranslateX(50); gridPaneBottomMenue = new GridPane(); labelHeadingValue = new Label("---"); gridPaneBottomMenue.add(labelHeadingValue,2,0); sliderSimulator = new Slider(-20, 20, 0); sliderSimulator.setSnapToTicks(true); sliderSimulator.setBlockIncrement(1); sliderSimulator.setMajorTickUnit(1); sliderSimulator.setMinorTickCount(0); sliderSimulator.valueProperty().addListener((obs, oldval, newVal) -> sliderSimulator.setValue(newVal.intValue())); vBoxSimulator = new VBox(10, sliderSimulator); gridPaneBottomMenue.add(vBoxSimulator,1,0); GridPane gridPaneGlobal = new GridPane(); gridPaneGlobal.add(imageCompass, 0, 0); gridPaneGlobal.add(gridPaneBottomMenue, 0, 1); return new VBox(menuBar, gridPaneGlobal); } }

My pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>ImageViewExample</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>25</java.version> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>25.0.2</version> </dependency> </dependencies> <build> <finalName>javafx</finalName> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> <resource> <directory>src/main/config</directory> <targetPath>${project.build.directory}</targetPath> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>org.example.Main</mainClass> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.6.1</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <finalName>${project.artifactId}</finalName> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.5.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>org.example.Main</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project>

Add any picture compass.png in resources-dir, build it with mvn clean package -U and start it with java -jar ImageViewExample.jar.

Could somebody give me any hint, why menubar/items freezes and how I can avoid this? Maybe there is another possibility to listen on a change of the slider and let the imageView rotate?

Read Entire Article