【问题标题】:Bad display for JavaFX WebView under macOSmacOS 下 JavaFX WebView 显示不好
【发布时间】:2021-05-03 23:13:43
【问题描述】:

我们使用 JavaFX WebView 作为我们的应用内浏览器。它在 Windows 10 下运行良好。

但是,当我们在 macOS Catalina 10.15.7 下运行时,所有显示的毛线都消失了。该应用在 Java 8 上运行。


这是我们简单的应用内浏览器的代码。

SimpleSwingBrowser.java

public class SimpleSwingBrowser extends JDialog {
 
    private final JFXPanel jfxPanel = new JFXPanel();
    private WebEngine engine;
    private String loadedURL = null;
    private final JPanel panel = new JPanel(new BorderLayout());
 
    public SimpleSwingBrowser() {
        super(JStock.instance(), JDialog.ModalityType.APPLICATION_MODAL);
        initComponents();
    }

    
    private void initComponents() {
        createScene();
  
        // http://stackoverflow.com/questions/11269632/javafx-hmtleditor-doesnt-react-on-return-key
        jfxPanel.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                if (e.getKeyChar() == 10) {
                    e.setKeyChar((char) 13);
                    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
                }
            }
        });

        panel.add(jfxPanel, BorderLayout.CENTER);
        
        getContentPane().add(panel);
        
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-460)/2, (screenSize.height-680)/2, 460, 680);
    }
    
    private void createScene() {
 
        Platform.runLater(new Runnable() {
            @Override 
            public void run() {
                final WebView view = new WebView();
                engine = view.getEngine();
                
                engine.titleProperty().addListener(new ChangeListener<String>() {
                    @Override
                    public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override 
                            public void run() {
                                SimpleSwingBrowser.this.setTitle(newValue);
                            }
                        });
                    }
                });
 
                engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {

                    @Override
                    public void changed(ObservableValue<? extends State> observable, State oldValue, final State newValue) {
                        if (newValue == FAILED) {
                            final int result = JOptionPane.showConfirmDialog(
                                panel,
                                MessagesBundle.getString("error_message_unable_connect_to_internet"),
                                MessagesBundle.getString("error_title_unable_connect_to_internet"),
                                JOptionPane.YES_NO_OPTION);
                            
                            if (result == JOptionPane.YES_OPTION) {
                                if (loadedURL != null) {
                                    engine.load(loadedURL);
                                }
                            }
                        }
                    }
                });
                
                // http://stackoverflow.com/questions/11206942/how-to-hide-scrollbars-in-the-javafx-webview
                // hide webview scrollbars whenever they appear.
                view.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() {
                    @Override 
                    public void onChanged(Change<? extends Node> change) {
                        Set<Node> deadSeaScrolls = view.lookupAll(".scroll-bar");
                        for (Node scroll : deadSeaScrolls) {
                            scroll.setVisible(false);
                        }
                    }
                });
                
                jfxPanel.setScene(new Scene(view));
            }
        });
    }
 
    public void loadURL(final String url) {
        Platform.runLater(new Runnable() {
            @Override 
            public void run() {
                String tmp = toURL(url);
                
                if (tmp == null) {
                    tmp = toURL("http://" + url);
                }
 
                loadedURL = tmp;
                engine.load(tmp);
            }
        });
    }

    private static String toURL(String str) {
        try {
            return new URL(str).toExternalForm();
        } catch (MalformedURLException exception) {
            return null;
        }
    }
}

知道为什么会这样吗?有什么我可以解决的吗?谢谢。

【问题讨论】:

标签: java macos swing javafx


【解决方案1】:

正如this answer 中所述,您可以尝试使用另一个用户代理。前段时间,当我在 Java 1.8.0_66 上遇到类似问题时,我使用了以下用户代理(在 macOS 上模拟 Firefox):

webView.getEngine().setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:54.0) Gecko/20100101 Firefox/54.0");

这确实对某些网站有所帮助,但并非对所有网站都有帮助(例如,谷歌地图在上述用户代理中使用了正确的字体,但由于其他问题而无法完全加载)。更新到 Java 9(当时是 9.0.1_11)得到了更好的结果。后来我尝试了以下方法:

String userAgent = this.browser.getEngine().getUserAgent();
if (userAgent != null) {
    String[] parts = userAgent.split(" ");
    String manipulatetUserAgent = "";
    for (int i = 0; i < parts.length; i++) {
        if (i > 0) {
            manipulatetUserAgent += " ";
        }
        
        if (parts[i] != null && parts[i].contains("JavaFX")) {
             manipulatetUserAgent += "Version/13.1.1"; // current safari version
        } else {
            manipulatetUserAgent += parts[i];
        }
    }
    this.browser.getEngine().setUserAgent(manipulatetUserAgent);
}

但实际上几个月前我从尝试修复 JavaFX WebView 到学习如何使用 Java Chromium Embedded Framework (JCEF) 这是

一个简单的框架,用于将基于 Chromium 的浏览器嵌入到使用 Java 编程语言的其他应用程序中。

在集成过程中肯定会产生更多开销,但看起来很有希望。

一开始我对 WebView 非常感兴趣,但随着时间的推移遇到了许多错误。首先,我等待修复错误,但随后出现了更多错误。最后一件让我沮丧的事情是登录在某些网站上无法可靠地工作(可能是因为他们使用的是Google's reCAPTCHA)。 因此请注意,如果用户代理修复完全有效,它可能只是暂时的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    相关资源
    最近更新 更多