1

我在使用 JavaFX WebView 时遇到问题。我想要实现的是在后台预取网页并仅在页面完全加载时将其可视化。

我制作了一个简单的示例程序来重现该问题。加载页面后,我启用了一个按钮。单击此按钮然后使 WebView 可见。

我遇到的问题是,如果我在启用按钮时单击该按钮,则该网页不直接可见。相反,会发生以下情况:起初有一个完全白色的面板,然后在短时间内可以看到网页。我不明白为什么页面不直接可见。我怎样才能实现它,网页是直接可见的?

以下链接指向显示行为的动画 gif: http ://tinypic.com/view.php?pic=oh66bl&s=5#.Ujmv1RddWKk

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class WebViewTest extends javax.swing.JPanel {

    private static JFXPanel browserFxPanel;
    private WebView webView;
    private WebEngine eng;

    /**
     * Creates new form WebViewTest
     */
    public WebViewTest() {
        initComponents();
        Platform.setImplicitExit(false);
        browserFxPanel = new JFXPanel();
        Platform.runLater(new Runnable() {
            public void run() {
                webView = createBrowser();
                Scene scene = new Scene(webView);
                scene.setFill(null);
                browserFxPanel.setScene(
                        scene);
            }
        });
    }

    /**
     * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The
     * content of this method is always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        pnlMain = new javax.swing.JPanel();
        showWebpageButton = new javax.swing.JButton();

        setLayout(new java.awt.GridBagLayout());

        pnlMain.setLayout(new java.awt.BorderLayout());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(pnlMain, gridBagConstraints);

        showWebpageButton.setText("show web page");
        showWebpageButton.setEnabled(false);
        showWebpageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showWebpageButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10);
        add(showWebpageButton, gridBagConstraints);
    }// </editor-fold>                        

    private void showWebpageButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                  
        pnlMain.removeAll();
        pnlMain.add(browserFxPanel, BorderLayout.CENTER);
        WebViewTest.this.invalidate();
        WebViewTest.this.revalidate();
    }                                                 
    // Variables declaration - do not modify                     
    private javax.swing.JPanel pnlMain;
    private javax.swing.JButton showWebpageButton;
    // End of variables declaration                   

    private WebView createBrowser() {
        Double widthDouble = pnlMain.getSize().getWidth();
        Double heightDouble = pnlMain.getSize().getHeight();
        final WebView view = new WebView();
        view.setMinSize(widthDouble, heightDouble);
        view.setPrefSize(widthDouble, heightDouble);
        eng = view.getEngine();
        eng.load("http://todomvc.com/architecture-examples/angularjs/#/");
        eng.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
                final double workDone = eng.getLoadWorker().getWorkDone();
                final double totalWork = eng.getLoadWorker().getTotalWork();
                if (workDone == totalWork) {
                    showWebpageButton.setEnabled(true);
                }
            }
        });
        return view;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JFrame f = new JFrame("Navigator Dummy");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setSize(new Dimension(1024, 800));
                final WebViewTest navDummy = new WebViewTest();
                f.getContentPane().add(navDummy);
                f.setVisible(true);
            }
        });
    }
}
4

1 回答 1

0

JFX需要一个“舞台”来露面。如下修改您的代码,它将完美运行

/**
 * Creates new form WebViewTest
 */
private Stage stage;                // insert this line
public WebViewTest() {
    initComponents();
    Platform.setImplicitExit(false);
    browserFxPanel = new JFXPanel();
    Platform.runLater(new Runnable() {
        public void run() {
            webView = createBrowser();
            Scene scene = new Scene(webView);
            scene.setFill(null);
            stage = new Stage();         // <<<
            stage.setScene(scene);       // <<<
            browserFxPanel.setScene(scene);
        }
    });
}
...
private void showWebpageButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                  
    pnlMain.removeAll();
    pnlMain.add(browserFxPanel, BorderLayout.CENTER);
    WebViewTest.this.invalidate();
    WebViewTest.this.revalidate();
    stage.show();        // <<< afer click Button
}                                            
于 2017-08-03T11:43:04.317 回答