Hi,

I recently found what seems to be a bug involving SwingNode and new windows on Linux. Essentially, when you have a SwingNode in an FX window, and show a new pure-Swing window, components in the new window will not receive focus even when clicked on, unless you focus away to another application and back again. I've confirmed it on several Ubuntu machines, using Oracle JDKs including 8u77, 8u91 and 9-ea+115. The problem is not present on Windows or Mac.

I have filed this as a bug in the Java bug tracker (JI-9036410), but this will make a big difference to our plans as it prevents us from using SwingNode as part of a plan to slowly transition our application across to FX until the bug gets fixed. So I wondered if anyone here might have an idea for a work-around? No fix too hacky!

I've tried all sorts of requestFocus calls but that doesn't seem to do it. It's not a mouse issue: a mouse listener receives the clicks, but focus is not correctly transferred to the new window. Making the new window an FX window with SwingNode inside can be used to avoid the problem, but that would mean transitioning all our Swing windows to FX or FX/SwingNode, which is a lot to do in one step. So I wondered if anyone here had any better ideas, or had encountered the same bug and already worked around it.

Thanks,

Neil.

P.S. Code to reproduce -- using either the FX menu or Swing button to show the new window has the same issue:
/////////////////////////////////////////

import javax.swing.*;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TestSwingNodeWindow extends Application
{
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        SwingNode swingNode = new SwingNode();
        BorderPane root = new BorderPane(swingNode);
        SwingUtilities.invokeAndWait(() -> {
            JPanel panel = new JPanel();
            JButton button = new JButton("Open window");
            button.addActionListener(e -> {
                showSwingTextFieldWindow();
                // This makes it work (but not a realistic solution):
                //Platform.runLater(() -> root.getChildren().clear());
            });
            panel.add(button);

            swingNode.setContent(panel);
        });
        MenuItem menuItem = new MenuItem("Show window");
menuItem.setOnAction(e -> SwingUtilities.invokeLater(this::showSwingTextFieldWindow));
        root.setTop(new MenuBar(new Menu("Menu", null, menuItem)));
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

    private void showSwingTextFieldWindow()
    {
        JFrame window = new JFrame("The new window");
        window.add(new JTextField("text field"));
        window.pack();
        window.setVisible(true);
    }
}

/////////////////////////////////////////////

Reply via email to