javajavafxswingutilities

Adding swingNode to javaFx


i wrote an app with javaFx and wanna add a JButton to a Pane in SwingNode this is my controller of fxml

public class Controller implements Initializable {

    @FXML
    private Pane pane;

    private static final SwingNode swingNode = new SwingNode();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        createSwingContent(swingNode);
        pane.getChildren().add(swingNode);
    }

    @FXML
    private void handleButtonAction(ActionEvent event) {

    }

    private void createSwingContent(final SwingNode swingNode) {
        SwingUtilities.invokeLater(() -> {
            JButton jButton = new JButton("Click me!");
            jButton.setBounds(0,0,80,50);

            JPanel panel = new JPanel();
            panel.setLayout(null);
            panel.add(jButton);

            swingNode.setContent(panel);

        });
    }
}

but it doesn't work, so what's wrong whit it ? BTW, when i added a non-swingNode to my Pane it works and shows the Button but in swingNode manner it doesn't work !


Solution

  • Since you are managing all the layout "by hand", by calling setLayout(null) and setBounds(...); on the button, you need to size the panel by hand too:

    private void createSwingContent(final SwingNode swingNode) {
        SwingUtilities.invokeLater(() -> {
            JButton jButton = new JButton("Click me!");
            jButton.setBounds(0,0,80,50);
    
            JPanel panel = new JPanel();
            panel.setLayout(null);
            panel.add(jButton);
    
            panel.setSize(90, 60);
    
            swingNode.setContent(panel);
    
        });
    }
    

    Alternatively, use a layout manager (e.g., just the default one, as shown here):

    private void createSwingContent(final SwingNode swingNode) {
        SwingUtilities.invokeLater(() -> {
            JButton jButton = new JButton("Click me!");
            // jButton.setBounds(0,0,80,50);
    
            jButton.setPreferredSize(new Dimension(80, 50));
    
            JPanel panel = new JPanel();
            // panel.setLayout(null);
            panel.add(jButton);
    
            swingNode.setContent(panel);
    
        });
    }
    

    With your current code, the button is added to the JPanel, but since the JPanel has zero width and height, so does the SwingNode, and so you can't see the button.

    As an aside, it is a mistake to make the swingNode static. If you were to load the FXML more than once in the application, you would have the same node at two different places in the scene graph, which is not allowed.