0

I am working on embedding a JavaFX login screen inside a Swing application.

I added a JFXPanel to a JPanel's content frame. Upon loading the application, all is well and smooth until I move my mouse inside the content pane (see link below for a video of this happening). While my mouse is actively moving in the pane, the rendering becomes very laggy:

  • Turns laggy when mouse enters pane enter image description here

Desired behaviour:

  • Use JavaFX designed UI in Swing through means of a JFXPanel without suffering a significant decrease in performance

The code below is a minimal, reproducible example of this problem.


import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.*;

import javax.swing.*;
import java.io.IOException;
import java.net.URL;

public class TestJFXPanel {

    public static void main(String[] args) throws IOException {

        /*
         Create pane with as background an animated image (GIF)
         */
        final Pane pane = new Pane();
        final URL url = new URL("https://i.stack.imgur.com/AvkzQ.gif");
        pane.setBackground(new Background(new BackgroundImage(
                new Image(url.openStream()),
                BackgroundRepeat.NO_REPEAT,
                BackgroundRepeat.NO_REPEAT,
                BackgroundPosition.CENTER,
                BackgroundSize.DEFAULT)));

        /*
         Set the pane as root of a Scene
         */
        final JFXPanel panel = new JFXPanel();
        panel.setScene(new Scene(pane, 500, 500));

        /*
         Invoke JFrame on AWT thread
         */
        SwingUtilities.invokeLater(() -> {

            final JFrame jFrame = new JFrame();

            // Add JFXPanel to content pane of JFrame
            jFrame.getContentPane().add(panel);
            jFrame.pack();

            jFrame.setVisible(true);
        });
    }
}

My thoughts:

  • I suspect this has something to do with the mouse motion being redirected to Swing from JavaFX causing a delay in communication between the FX and Swing threads. I think this is especially costly because I use a GIF as background image of the login screen.
  • I am not sure whether this is caused by a delay in communication of FX and Swing, if it is the case, would handling all my FX UI in Swing resolve this (assuming this is more feasible than porting the entire design to Swing)?

However, if someone is more familiar with integrating JavaFX with Swing and thinks my suspicions are wrong. Some advice on how to proceed are much appreciated!

Update:

  • When I override the processMouseMotionEvent method of the JFXPanel class, so that no MouseMotionEvents get consumed, the problem does not occur. I think this might be a compatibility issue between JavaFX and MacOS.
  • 2
    "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [mre]" – c0der Jun 09 '19 at 05:17
  • 2
    1) `jFrame.setVisible..; jFrame.getContentPane().add..` The order of these statements should be swapped. 2) `jFrame.setSize(765, 503);` This size is no better than a guess for a decorated frame. 3) But post the MRE suggested by @c0der for more advice. 4) *"I use a GIF as background image of the login screen."* One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). E.G. [This answer](https://stackoverflow.com/a/10862262/418556) hot links to an image embedded in [this question](https://stackoverflow.com/q/10861852/418556). – Andrew Thompson Jun 09 '19 at 05:27
  • @c0der thanks for pointing those things out to me, I have updated my post (I hope sufficiently). Any clue :)? – Stan Van Der Bend Jun 09 '19 at 06:29
  • I think your comment was meant for @AndrewThompson – c0der Jun 09 '19 at 06:33
  • @c0der Well thanks to both of you, wasn't able to mention andrew because StackOverflow wouldn't let me (only just now noticed I cannot mention two people in the same post) . – Stan Van Der Bend Jun 09 '19 at 06:35
  • @AndrewThompson Thanks for the help, I tried implementing your suggestions for improving my post :) – Stan Van Der Bend Jun 09 '19 at 06:36
  • 1
    After adding the relevant imports (they should be included in an MRE) and hot-linking to the image, I ran the code. The problem does not manifest here. No matter where the mouse pointer is, or what it's doing, the animation continues without problem. Two questions for you: 1) Shouldn't the Java-FX code be constructed on the Java-FX event thread? (I don't know.) 2) Why is Swing involved at all? I'd almost expect artifacts to disappear in a pure Java-FX code which is properly launched. – Andrew Thompson Jun 09 '19 at 06:50
  • @AndrewThompson If it does not manifest for you than I am starting to think it might be because I am using OS X (unless you're also using OS X). 1: Yes although I wanted to simplify the MRE as much as possible and leaving it out didn't affect the behaviour. 2: I am using Swing because the game I am writing a login screen for, currently uses Swing and has been doing so since 2006, so porting it all over to JavaFX is not a feasible option. Also I am not quite sure what u mean by that last sentence. – Stan Van Der Bend Jun 09 '19 at 06:55
  • 1
    *"I am using Swing because the game I am writing a login screen for, currently uses Swing and has been doing so since 2006"* I don't see that as a good reason for keeping the login as Swing, or (more importantly) for mixing Swing with Java-FX in this screen. *"Also I am not quite sure what u mean by that last sentence."* Please be specific about what you do not understand. I am willing to explain further on details, but I'm not going to try and explain every word in a sentence. – Andrew Thompson Jun 09 '19 at 07:07
  • @AndrewThompson Well, ideally I could use JavaFX till the point of where the player logs in, to then remove the JFXPanel and add a Swing component (in which the 3D world is painted). However when I tried this before I could not get a seamless transformation from JavaFX to Swing (seamless as in add/remove from the ContentPane of a JPanel). Therefore I figured nesting the JavaFX content inside a JPanel would be the ideal solution, as I can then easily switch back and forth between JavaFX and Swing. And I didn't understand what u mean by _artifacts_ disappearing and _properly_ launched. – Stan Van Der Bend Jun 09 '19 at 07:18
  • 1
    OK .. I thought you meant the 'log-in' was using a top level window. By 'artifact' I meant the mouse / frame progression problem. By 'properly' I meant that the Java-FX GUI was launched on the Java-FX event thread (I'm not experienced with Java-FX & don't know if that even applies). – Andrew Thompson Jun 09 '19 at 07:59
  • @AndrewThompson I just did some more debugging and I can confirm this has to do with mouseMotion even handling. If I override the `processMouseMotionEvent` method of the JFXPanel (so that no incoming mouse motion gets processed), then the problem does not occur. Seems like this might be a bug in JavaFX. – Stan Van Der Bend Jun 09 '19 at 08:14

0 Answers0