Холст внутри JLayeredPane не работает в JavaFX (с использованием SwingNode)

#java #swing #javafx

Вопрос:

Я пытаюсь добавить в свой холст JLayeredPane , который находится внутри SwingNode ( SwingNode он встроен в мое приложение JavaFX), но он не отображается. С другой стороны, он отображается в a JFrame .

Код приложения

 public class SwingNodeSample_2 extends Application {

    public static void main(String[] args) {
        // Create the top-level container frame
        final JFrame frame = new JFrame(); // Swing's JFrame or AWT's Frame
        JLayeredPane lPane = getjLayeredPane();
        frame.add(lPane);
        //panel.setBounds(x, y, width, height);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                // Use a dedicate thread to run the stop() to ensure that the
                // animator stops before program exits.
                new Thread() {
                    @Override
                    public void run() {
                        System.exit(0);
                    }
                }.start();
            }
        });

        frame.setTitle("Canvas is displayed in JFrame");
        frame.pack();
        frame.setVisible(true);
        launch(args);
    }

    private static JLayeredPane getjLayeredPane() {
        JLayeredPane lPane = new JLayeredPane();
        lPane.setPreferredSize(new Dimension(500, 500));
        final Canvas canvas = new Canvas() {
            {
                setBackground(Color.GRAY);
                setBounds(0,0,300, 200);
            }

            public void paint(Graphics g) {
                g.setColor(Color.red);
                g.fillOval(75, 75, 150, 75);
            }
        };

        lPane.add(canvas,0);
        lPane.add(new JPanel() {
            {
                setBackground(Color.BLUE);
                setBounds(300,200,50,50);
            }
        }, 1);

        return lPane;
    }

    @Override
    public void start(Stage stage) {
        // Create a animator that drives canvas' display() at the specified FPS.
        final SwingNode swingNode = new SwingNode();
        SwingUtilities.invokeLater(() -> {
            swingNode.setContent(getjLayeredPane());
        });

        StackPane pane = new StackPane();
        pane.getChildren().add(swingNode);
        Scene scene = new Scene(pane, 500, 500);
        stage.setScene(scene);
        stage.setTitle("Canvas Embedded in JavaFX doesn't work !!");
        stage.show();
    }
}
 

Вывод пользовательского интерфейса

синий прямоугольник отображается в обоих, а холст отображается только в JFrame

У вас есть идея, почему JPanel это хорошо работает для обоих, но нет Canvas ?

Комментарии:

1.Смотрите документацию. «Иерархия компонентов, содержащихся в JComponent экземпляре, не должна содержать каких-либо тяжеловесных компонентов, в противном SwingNode случае может не получиться ее раскрасить.» Canvas является тяжеловесным компонентом (т. Е. Не подклассом JComponent ).

2. Вместо холста, подкласс JPanel и переопределите компонент Paint, а не paint. Первая строка в вашем компоненте краски должна быть вызовом super.paintComponent. Видишь docs.oracle.com/javase/tutorial/uiswing/painting . Конечно, вы всегда можете использовать холст JavaFX вместо того, чтобы иметь дело с головной болью от смешивания JavaFX и Swing.

3. Также, если у вас есть существующий код, написанный на качели холст и не хочу тратить силы, чтобы перенести его в JavaFX (или он использует некоторые сторонние библиотеки, такие как jfreechart, который участков качели холст), вы можете воспользоваться fxgraphics2d , чтобы ваши качели холст команды построены в JavaFX с холста. Конечно, в большинстве случаев предпочтительнее было бы рисовать непосредственно на холсте JavaFX.