支持 Javascript 和 CSS 的 JEditorPane

Posted

技术标签:

【中文标题】支持 Javascript 和 CSS 的 JEditorPane【英文标题】:JEditorPane with Javascript and CSS support 【发布时间】:2012-11-22 22:57:10 【问题描述】:

我正在使用 JEditorPane 开发 Swing,但它不支持 javascript 或一些高级标签,如 <object> 等,并且不支持颜色、字体样式大小等。

是否有任何解决方案使编辑器窗格可以像在普通 html 浏览器中一样显示 HTML 文件?

【问题讨论】:

【参考方案1】:

+1 给 mKorbel。

使用JavaFX WebView,通过与 Swing 集成来支持 HTML5。

这是一个例子:

import java.awt.*;
import java.awt.event.*;
import java.net.MalformedURLException;
import java.net.URL;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import static javafx.concurrent.Worker.State.FAILED;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javax.swing.*;

public class SimpleSwingBrowser implements Runnable 
    private JFXPanel jfxPanel;
    private WebEngine engine;

    private JFrame frame = new JFrame();
    private JPanel panel = new JPanel(new BorderLayout());
    private JLabel lblStatus = new JLabel();

    private JButton btnGo = new JButton("Go");
    private JTextField txtURL = new JTextField();
    private JProgressBar progressBar = new JProgressBar();

    private void initComponents() 
        jfxPanel = new JFXPanel();

        createScene();

        ActionListener al = new ActionListener() 
            @Override public void actionPerformed(ActionEvent e) 
                loadURL(txtURL.getText());
            
        ;

        btnGo.addActionListener(al);
        txtURL.addActionListener(al);

        progressBar.setPreferredSize(new Dimension(150, 18));
        progressBar.setStringPainted(true);

        JPanel topBar = new JPanel(new BorderLayout(5, 0));
        topBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
        topBar.add(txtURL, BorderLayout.CENTER);
        topBar.add(btnGo, BorderLayout.EAST);


        JPanel statusBar = new JPanel(new BorderLayout(5, 0));
        statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
        statusBar.add(lblStatus, BorderLayout.CENTER);
        statusBar.add(progressBar, BorderLayout.EAST);

        panel.add(topBar, BorderLayout.NORTH);
        panel.add(jfxPanel, BorderLayout.CENTER);
        panel.add(statusBar, BorderLayout.SOUTH);

        frame.getContentPane().add(panel);
    

    private void createScene() 

        Platform.runLater(new Runnable() 
            @Override public void run() 

                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() 
                                frame.setTitle(newValue);
                            
                        );
                    
                );

                engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() 
                    @Override public void handle(final WebEvent<String> event) 
                        SwingUtilities.invokeLater(new Runnable() 
                            @Override public void run() 
                                lblStatus.setText(event.getData());
                            
                        );
                    
                );

                engine.locationProperty().addListener(new ChangeListener<String>() 
                    @Override
                    public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) 
                        SwingUtilities.invokeLater(new Runnable() 
                            @Override public void run() 
                                txtURL.setText(newValue);
                            
                        );
                    
                );

                engine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() 
                    @Override
                    public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) 
                        SwingUtilities.invokeLater(new Runnable() 
                            @Override public void run() 
                                progressBar.setValue(newValue.intValue());
                            
                        );
                    
                );

                engine.getLoadWorker()
                        .exceptionProperty()
                        .addListener(new ChangeListener<Throwable>() 

                            public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) 
                                if (engine.getLoadWorker().getState() == FAILED) 
                                    SwingUtilities.invokeLater(new Runnable() 
                                        @Override public void run() 
                                            JOptionPane.showMessageDialog(
                                                    panel,
                                                    (value != null) ?
                                                    engine.getLocation() + "\n" + value.getMessage() :
                                                    engine.getLocation() + "\nUnexpected error.",
                                                    "Loading error...",
                                                    JOptionPane.ERROR_MESSAGE);
                                        
                                    );
                                
                            
                        );

                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);
                

                engine.load(tmp);
            
        );
    

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

    @Override public void run() 

        frame.setPreferredSize(new Dimension(1024, 600));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initComponents();

        loadURL("http://oracle.com");

        frame.pack();
        frame.setVisible(true);
    

    public static void main(String[] args) 
        SwingUtilities.invokeLater(new SimpleSwingBrowser());
    

This link 还提供了一些有用的 WebView 示例,包括演示使用 of JavaScript

参考资料:

Integrating JavaFX into Swing Applications Add Java FX 2.0 to existing Netbeans project

【讨论】:

@MadProgrammer +1 谢谢你,我很想把代码归功于它,但它只是从参考资料中撕下来的:P 是的,但你知道在哪里可以找到它;)【参考方案2】:

当前的 Java6/7 仅支持(最高)Html 3.2,对 css 的支持减少,

对于Html5和相当完整的css support使用JavaFx Components

有自定义 Java 库(完全???)支持 Html4/5、css 和 js,但我建议改用 JavaFX

【讨论】:

先生,当 JFXPanel 被移除时,我必须在摆动窗口上添加和移除 javafx 控件,它不能再次添加到容器窗口中

以上是关于支持 Javascript 和 CSS 的 JEditorPane的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JavaScript 检测 CSS 变量支持?

html Javascript |支持CSS3和响应alo浏览器

JavaScript 检测浏览器是否支持 CSS 变量

[转]JavaScript快速检测浏览器对CSS3特性的支持

JavaScript 使用Javascript Feature Testin确定CSS属性支持

JavaScript 使用JS测试CSS3支持