JavaFX WebView加载页面在后台

时间:2013-09-18 13:16:24

标签: webview javafx-2 javafx

使用JavaFX WebView时遇到问题。我想要实现的是在后台预先获取一个网页,并仅在页面完全加载时对其进行可视化。

我制作了一个简单的exmaple程序来重现问题。页面加载后,我启用一个按钮。 A单击此按钮,然后使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);
            }
        });
    }
}

1 个答案:

答案 0 :(得分: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
}                                            
相关问题