JavaFX 8 摆动兼容性

2022-09-04 04:25:27

我目前正在评估使用SwingNode将我当前的Swing应用程序转换为JavaFX 8是否可行,然后慢慢地将所有内容更改为JavaFX组件。我偶然发现了两个问题,这可能是JavaFX 8中挥之不去的错误,但我不能确定。

  1. 将内容添加到 SwingNode 后,Javafx 菜单未正确绘制(大多数情况下),导致出现黑条
  2. 使 JScrollBars 变得不透明似乎不起作用

    import java.awt.Color;
    import java.awt.GridLayout;
    
    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.layout.StackPane;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    
    
    public class Test extends Application {    
    
        @Override
        public void start(Stage stage) throws Exception {
            stage.setMaximized(true);
    
            VBox vbox = new VBox();
            MenuBar menuBar = new MenuBar();
            menuBar.getMenus().add(new Menu("bla"));
            vbox.getChildren().add(menuBar);
    
            StackPane mainPane = new StackPane();        
            mainPane.setPrefSize(9999, 9999); //Better way to ensure all space used?
            vbox.getChildren().add(mainPane);
            vbox.setVisible(true);
    
            Scene scene = new Scene(vbox, 9999, 9999); //Better way to ensure all space used?
            stage.setScene(scene);
    
            SwingNode swingNode = new SwingNode();
            mainPane.getChildren().add(swingNode);
    
            JPanel jPanel = new JPanel();
            swingNode.setContent(jPanel); //Seems to interfere with painting of menu
    
            jPanel.setBackground(Color.WHITE);
            jPanel.setLayout(new GridLayout(2, 1));
            jPanel.add(new JPanel());
    
            JPanel nonOpaquePanel = new JPanel();
            nonOpaquePanel.setOpaque(false);
            JScrollPane scrollPane = new JScrollPane(nonOpaquePanel);
            scrollPane.setOpaque(false);
            scrollPane.getViewport().setOpaque(false); //Black background -> Bug?
            jPanel.add(scrollPane);
    
            stage.show();
        }
    
        /**
         * Main method launching the application.
         */
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    可执行罐

编辑:我编辑了我的示例,以使用 EDT 创建 Swing 组件。这并没有改变任何事情。还是我做错了什么?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;


public class Test extends Application {
    private JPanel jPanel = null;

    @Override
    public void start(Stage stage) throws Exception {
        if (Platform.isFxApplicationThread()) { // all of this happens on the fx application thread
            stage.setMaximized(true);

            VBox vbox = new VBox();
            MenuBar menuBar = new MenuBar();
            menuBar.getMenus().add(new Menu("bla"));
            vbox.getChildren().add(menuBar);

            StackPane mainPane = new StackPane();        
            mainPane.setPrefSize(9999, 9999); //Better way to ensure all space used?
            vbox.getChildren().add(mainPane);
            vbox.setVisible(true);

            Scene scene = new Scene(vbox, 9999, 9999); //Better way to ensure all space used?
            stage.setScene(scene);

            SwingNode swingNode = new SwingNode();
            mainPane.getChildren().add(swingNode);                    

            SwingUtilities.invokeLater(new Runnable() { //Use EDT to build swing components              
                @Override
                public void run() {
                    jPanel = new JPanel();

                    jPanel.setBackground(Color.WHITE);
                    jPanel.setLayout(new GridLayout(2, 1));
                    jPanel.add(new JPanel());

                    JLabel nonOpaquePanel = new JLabel("Bla");
                    nonOpaquePanel.setPreferredSize(new Dimension(5000, 5000));
                    nonOpaquePanel.setOpaque(false);
                    JScrollPane scrollPane = new JScrollPane(nonOpaquePanel);
                    scrollPane.setOpaque(false);
                    scrollPane.getViewport().setOpaque(false); //Black background -> Bug?
                    jPanel.add(scrollPane);
                }
            });

            Thread.sleep(1000); //terrible way to wait for the EDT, I know
            swingNode.setContent(jPanel); //Seems to interfere with painting of menu            
            stage.show();

            SwingUtilities.invokeLater(new Runnable() { //I am pretty sure this isn't necessary, but whatever                       
                @Override
                public void run() {
                    jPanel.repaint();    
                }
            });
        }
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {
        launch(args);
    }
}

答案 1

尝试在进行更新调用时将更新代码包装在此内容中。这段代码以前在其他项目上帮助过我。

Platform.runLater(new Runnable() {
            @Override
            public void run() {
                // Update the text node with calculated results
            }
       });


答案 2

您可以使用 ,因此您不必自己调度事件。-Djavafx.embed.singleThread=true

JavaFx APIDesign


推荐