Search code examples
javaswingjavafxnetbeans-pluginsjdk1.7

JavaFX and Swing performance issues


We have been having perpetual performance issues when running JavaFX inside a JFXPanel in Swing based applications.

This seems to only be a problem when running on JDK1.7, because whenever it is possible to run JDK1.8 this works perfectly without changing any code.

The symptoms are that the application seems to render fonts in a fuzzy way and also the performance is terrible (multiple seconds to respond to keypress when typing in a TextField).

We are observing the correct rules about EDT, AWT and Platform threads, so I doubt that this can be the issue.

We are stuck having to support JDK1.7 because this is a plug-in for NetBeans which some users will be running on JDK1.7 for various good reasons and we cannot force them to upgrade.

EDIT: Here is a MCVE which recreates the problem

package javaapplication3;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

    private static void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Swing and JavaFX");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFX(fxPanel);
            }
       });
    }

    private static void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        Scene scene = createScene();
        fxPanel.setScene(scene);
    }

    private static Scene createScene() {
        Group  root  =  new  Group();
        Scene  scene  =  new  Scene(root, Color.ALICEBLUE);
        TextField  text  =  new  TextField();
        Label label = new Label();
        VBox box = new VBox();

        label.setText("This is a test label");


        box.getChildren().add(label);
        box.getChildren().add(text);

        root.getChildren().add(box);

        return (scene);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                initAndShowGUI();
            }
        });
    }
}

The tests we are performing have very simple javafx with e.g. only an AnchorPane with a TextField on it and absolutely no code behind it, and just typing in the TextField is painfully slow.

Behavior looks very much like lock contention between the Swing and JavaFX threads, but it does not seem like we can find any explanation or solution.


Solution

  • This is not the answer that you are looking for, but since we have the same problem with Java 7 support, the answer is that Java 7 has reached its end of life:

    July 2015: Updates for Java 7 are no longer available to the public. Oracle offers updates to Java 7 only for customers who have purchased Java support or have Oracle products that require Java 7.

    https://www.java.com/en/download/faq/java_7.xml

    There are no "good reasons" if problem solving is as easy as using a different java version. You don't break things by upgrading to Java 8.