簡體   English   中英

JavaFx Platform.runLater應用程序不響應

[英]JavaFx Platform.runLater Application Not Responsive

在下面的簡化JavaFx程序中,它總是說Application Not Responsive。 當我注釋掉Platform.runLater(new Runnable(){...}時,它不會崩潰。有什么主意是什么問題,我該如何解決?

package apptest;

import java.awt.BorderLayout;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class apptest {


    public static JFXPanel jfxPanel = new JFXPanel();          


    public static void main(String[] args){

        final JFrame frame = new JFrame(); 


        Platform.runLater(new Runnable() {

        @Override 
        public void run() { 

        JPanel login = new JPanel();
        login.setLayout(new BorderLayout());
        login.setBounds(0, 0, 415, 180);     


        WebView webView = new WebView();
        WebEngine engine = webView.getEngine();
        engine.load("http://www.google.com");

        VBox root = new VBox(webView);
        root.setStyle( "-fx-focus-color: transparent;");
        Scene scene = new Scene(root,414,179);    

        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setContent(webView);                              

        root.getChildren().addAll(scrollPane);
        jfxPanel.setScene(scene); 
        frame.add(login, BorderLayout.NORTH);
        login.add(jfxPanel, BorderLayout.NORTH);

        }

      }); 


        frame.setLayout(null);
        frame.setSize(415,180);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setResizable(false);
        frame.setAlwaysOnTop(true);
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
        Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
        int x = 10;
        int y = (int) rect.getMaxY() - (frame.getHeight() + 50);        
        frame.setLocation(x, y);
        frame.setVisible(true); 


    }

    }

在回答之前,我想問一下您是否真的需要將JavaFX嵌入到Swing應用程序中。 這是兩個不同的工具包,將兩者一起使用會使事情變得非常困難,特別是因為您必須管理兩個不同的執行線程(必須在其中執行所有Swing工作的AWT事件分發線程,以及在其中必須執行所有操作的FX Application線程)。 JavaFX工作必須進行)。

假設您確實確實需要將JavaFX嵌入到Swing框架而不是JavaFX Stage中,則需要使用SwingUtilities.invokeLater(...)在AWT事件分發線程上創建Swing組件。 需要使用Platform.runLater()在FX Application線程上創建JavaFX控件。 在您的代碼中,您在主線程(而不是AWT線程)上創建和配置JFrame ,並在FX Application線程(同樣,不是AWT線程)上創建JPanel 我相信這會導致應用程序死鎖。

JFXPanelJavadocs中顯示了如何正確地對此進行線程化的基本概述。

另一個注意事項是您的布局結構錯誤。 您將webView直接添加到VBox

VBox root = new VBox(webView);

但隨后您將相同的webView放在ScrollPane

scrollPane.setContent(webView);                              

這會將相同的組件兩次添加到場景圖,這是不允許的(無論如何也沒有任何意義)。 由於WebView實現了自己的滾動,因此您可以完全省略ScrollPane

再次假設您需要混合使用Swing和JavaFX,您的應用程序代碼應類似於

import java.awt.BorderLayout;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class apptest {


    public static void main(String[] args) {

        // Create swing components on AWT thread:

        SwingUtilities.invokeLater(()  -> {
            final JFrame frame = new JFrame();
            JPanel login = new JPanel();
            login.setLayout(new BorderLayout());
            login.setBounds(0, 0, 415, 180);
            JFXPanel jfxPanel = new JFXPanel();
            frame.add(login, BorderLayout.NORTH);
            login.add(jfxPanel, BorderLayout.NORTH);

            // Create JavaFX content on FX Application Thread:

            Platform.runLater(new Runnable() {

                @Override
                public void run() {


                    WebView webView = new WebView();
                    WebEngine engine = webView.getEngine();
                    engine.load("http://www.google.com");

                    VBox root = new VBox(webView);
                    root.setStyle("-fx-focus-color: transparent;");
                    Scene scene = new Scene(root, 414, 179);

                    jfxPanel.setScene(scene);

                }

            });

            frame.setLayout(null);
            frame.setSize(415, 180);
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            frame.setResizable(false);
            frame.setAlwaysOnTop(true);
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
            Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
            int x = 10;
            int y = (int) rect.getMaxY() - (frame.getHeight() + 50);
            frame.setLocation(x, y);
            frame.setVisible(true);


        });

    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM