Implementing JavaFX Stage in C ++ Windows Application

A Java Swing window can be easily integrated into a C ++ application (on Windows) using the WEmbeddedFrame class:

// (1)
SwingUtilities.invokeLater(() -> {
  try {
    WEmbeddedFrame meinJFrame = new WEmbeddedFrame(hwndParentFromCppApplication);
    meinJFrame.add(... panel ...);
    ...
    meinJFrame.setVisible(true);
  }
  catch (...) {}
});

      

It seems to run smoothly even though the parent HWND comes from a different process. (This is because the Java engineers can manipulate chainsaws: http://blogs.msdn.com/b/oldnewthing/archive/2013/04/12/10410454.aspx : -)

As far as I can research, to put a JavaFX Stage in a parent window with parents is only an indirect path with a JFXPanel object wrapped in a Swing WEmbeddedFrame.

// (2)
Platform.runLater(() -> {
    try {
        WEmbeddedFrame frame = new WEmbeddedFrame(hwndParentFromCppApplication);
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setVisible(true);

        Scene scene = ...
        fxPanel.setScene(scene);
        frame.show();
    } catch (...) {}
});

      

But this solution has two major drawbacks:

  • The scene flickers when you move the mouse over it.

  • List items and menu items are placed in the wrong position after moving the parent window.

I also tried to put Stage on AppletWindow:

// (3)
Stage fxstage = new Stage();
fxstage.initStyle(StageStyle.UNDECORATED);
fxstage.setScene(scene);

AppletWindow appw = tk.createAppletWindow(hwndParentFromCppApplication, "");
appw.setStageOnTop(fxstage);
appw.setPosition(0, 0);
appw.setSize(100, 100);
appw.setVisible(true);

// fxstage.show();

      

It only shows a black rectangle. If I uncomment fxstage.show (), the stage opens as a top-level window - not inside an applet.

In the JavaFX sources, I found the com.sun.javafx.stage.EmbeddedWindow class. This sounds promising, but how do you use it? Accordingly, how do I build the required HostInterface implementation?

Do you know how to put a JavaFX stage in a Windows C ++ window?

Thank you very much in advance!

Wolfgang relationship

+3


source to share


1 answer


Based on (2) I found a solution after spending days with debugging inside the JavaFX source.

  • Wrap the JXPanel in a JPanel. It stops flickering.
  • Overwrite JXPanel.setCursor () and call WEmbeddedFrame.setCursor (). Otherwise, changing the cursor in JavaFX controls has no effect.
  • Set scene.getWindow (). setX (), Y, Width, Heigth in GetClientRect () in native container window. This shows dropdowns and menu items in the correct position.

But I still have two problems:

(4) I cannot get the javafx.stage.Window object from the JXPanel that can be used as the owner window for example. for FileChooser. The following code returns an internally used Stage object. But when used as owner, it doesn't block child windows.



public Window getWindow() {
    try {
        Class<?> clazz = fxPanel.getClass().getSuperclass();
        Field field = clazz.getDeclaredField("stage");
        field.setAccessible(true);
        Window w = (Window) field.get(fxPanel);
        return w;
    } catch (Throwable e) {
        throw new IllegalStateException("Cannot obtain JavaFX window.");
    }

      

(5) On opening FileChooser (owner = null), an exception is thrown on the UI thread. I am currently ignoring the exception because it doesn't harm anything.

    Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: null source
    at java.util.EventObject.<init>(EventObject.java:56)
    at java.awt.AWTEvent.<init>(AWTEvent.java:337)
    at sun.awt.UngrabEvent.<init>(UngrabEvent.java:48)
    ...
    at com.sun.javafx.stage.WindowPeerListener.focusUngrab(WindowPeerListener.java:105)
    ...
    at com.sun.javafx.tk.quantum.EmbeddedStage.focusUngrab(EmbeddedStage.java:252)
    ...
    at com.sun.javafx.tk.quantum.QuantumToolkit.showFileChooser(QuantumToolkit.java:1421)
    at javafx.stage.FileChooser.showDialog(FileChooser.java:416)
    at javafx.stage.FileChooser.showOpenMultipleDialog(FileChooser.java:373)

      

+1


source







All Articles