Java Swing CSS样式属性“class”在HTMLEditorKit / HTMLDocument中使用

时间:2013-07-22 16:55:59

标签: java swing htmleditorkit

我的问题如下:

我正在尝试向已实现的HTML编辑器添加功能 在Java Swing中使用HTMLEditorKit和HTMLDocument类。这个想法 是为了提供在不同风格之间切换的可能性 在HTML编辑器中编辑文本。不同的风格定义 背景/前景色,字体等。

我已经设法以编程方式加载样式表文件。代码 对于这看起来如下:

class HtmlEditor extends JFrame implements Keylistener, MouseListener {

private HTMLDocument  m_doc;

private HTMLEditorKit m_kit;

[...]


public HtmlEditor(...) {

    [...]
    final URL formats = HtmlEditor.class.getResource("/formats.css");
predefStyles = new StyleSheet();
predefStyles.importStyleSheet(formats);
m_kit.getStyleSheet().addStyleSheet(predefStyles);

    [...]
}

样式表文件如下所示:

.style1 { background-color:silver }
.style2 { background-color:aqua }
.style3 { background-color:teal }

将该样式表添加到HTMLEditorKit实例的StyleSheet中 在将内容插入HTML时,我已经可以使用这些样式 编辑器使用其源编辑器(在源编辑器中可以插入 直接使用HTML代码,例如“< span class =”style1“>样式文字< / span>”)。 为了允许在WYSIWYG部分中使用样式,我添加了一个 JComboBox进入编辑器的工具栏,显示其名称 来自“formats.css”的样式(样式名称中的前导“。”) 去除)。在JComboBox的ActionListener中,我现在正试图设置 “class”属性。我的代码如下:

    cbStyles = new JComboBox<String>(getStyleNames());
    cbStyles.setToolTipText("Select Style");
    cbStyles.setMaximumSize(null);
    cbStyles.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            currStyle = cbStyles.getSelectedItem().toString();

            final SimpleAttributeSet attr = new SimpleAttributeSet();
            attr.addAttribute(HTML.Attribute.CLASS, currStyle);
            m_kit.getInputAttributes().addAttributes(attr);
            m_editor.requestFocusInWindow();
        }
    });
    m_toolBar.add(cbStyles);

不幸的是,这似乎不起作用。至少,改变之后 这种风格我没有把它应用到我之后进入的文本中 在源视图中,“class”属性不会出现在包含HTML组件中。我检查了管理设置的HtmlEditor类中的代码 另一种字体,看看我是否可以使用相同的技术 为我的目的chaning字体。各自的动作监听器 附加到JComboBox,提供字体选择外观 如下:

        cbFonts.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            m_fontName = m_cbFonts.getSelectedItem().toString();
            final MutableAttributeSet attr = new SimpleAttributeSet();
            StyleConstants.setFontFamily(attr, m_fontName);
            m_kit.getInputAttributes().addAttributes(attr);
            m_editor.requestFocusInWindow();
        }
    });

正如我们在这里看到的,StyleConstants类用于设置 属性为新字体。令我困惑的是那个 StyleConstants类似乎没有提供设置方法 “class”属性。从它的Javadoc可以看出,有很多 设置对齐,字体系列,粗体等属性的方法, 等等 可能我的方法以一种非常简单的方式是不正确的。也许我做到了 尚未正确理解在CSS中使用CSS的概念 HTMLDocument的。 任何帮助将不胜感激!

根据我对HTML的理解,CSS可以使用如下:

A&lt; style&gt; &lt; head&gt;内的元素part定义了样式类。例如:

<style type="text/css">;
.style1 { background-color:silver }
.style2 { background-color:aqua }
.style3 { background-color:teal }
</style>

然后在HTML中可以引用这些类 HTML元素中的通用属性“class”。例如:

&lt; span class =“style1”&gt; style1&lt; / span&gt;

中的文字

所以应该可以以某种方式插入“class”属性 预定义样式作为HTMLDocument中元素的值 由HTMLEditorKit管理。我的小HTML编辑器是 提供在当前插入位置激活样式的功能 在文件里面。所以我们假设插入符号位于a内 像这样的段落:

&lt; p&gt;某些没有样式的文字&lt; / p&gt;

在结束段落标记之前的“样式”一词之后。

现在我想激活,比方说,style1。这应该导致 如下结构:

&lt; p&gt;某些没有样式的文字&lt; span class =“style1”&gt; &LT; /跨度&GT;&LT; / p为H.

现在,插入位置应位于新的&lt; span&gt;内。元件。

或者如果插入符号位于空段落的开头:

&LT p为H.;&LT; / p为H.

应用样式后,结构应如下所示:

&lt; p class =“style1”&gt; &LT; / p为H.

我认为这应该没什么大不了的,但不知道如何获得 这样做了。

在中间我尝试了另一种方法来解决我的问题,但没有成功。这里有完整的示例代码(希望不要太多; - ):

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.StringWriter;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;

public class HTMLEditor extends JFrame {

private static final long serialVersionUID = 1L;
private final JEditorPane jep;
private final HTMLEditorKit edtKit;
private final HTMLDocument doc;

public static void main(String[] args) {
    final HTMLEditor editor = new HTMLEditor();
    editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    editor.setVisible(true);
}

public HTMLEditor() {
    super("Simple HTML Editor");
    jep = new JEditorPane();
    edtKit = new HTMLEditorKit();
    jep.setEditorKit(edtKit);
    addMyStyles();

    doc = (HTMLDocument) edtKit.createDefaultDocument();
    jep.setDocument(doc);
    jep.setText("<html><head></head>" +
            "<body><div class=\"style1\">STYLE1</div>" +
            "</body>");

    final Container content = getContentPane();
    content.add(jep, BorderLayout.CENTER);
    content.add(createToolBar(), BorderLayout.NORTH);
    setJMenuBar(createMenuBar());
    setSize(320, 240);
}

/**
 * Adds three simple style definitions to the HTMLEditorKit's style sheet.
 */
void addMyStyles() {
    final StyleSheet styles = edtKit.getStyleSheet();
    styles.addRule(".style1 { background-color:silver; }");
    styles.addRule(".style2 { background-color:aqua; }");
    styles.addRule(".style3 { background-color:teal; }");
}

/**
 * Creates the toolbar with two buttons:
 * <li>Button to switch between bold and normal text
 * <li>Button for activating a style class
 * @return The toolbar
 */
protected JToolBar createToolBar() {
    final JToolBar bar = new JToolBar();
    final Action boldAct = jep.getActionMap().get("font-bold");
    boldAct.putValue(Action.NAME, "Bold");
    bar.add(boldAct);
    bar.addSeparator();
    final Action styleAct = new StyleAction();
    jep.getActionMap().put("activate-style", styleAct);
    bar.add(styleAct);

    return bar;
}

/**
 * Creates the menu bar. It only offers and action to display the HTML source
 * in a popup window.
 * @return The menu bar
 */
protected JMenuBar createMenuBar() {
    final JMenuBar menubar = new JMenuBar();
    final JMenu view = new JMenu("View");
    menubar.add(view);
    final JMenuItem preview = new JMenuItem("Preview");
    view.add(preview);
    preview.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            final HTMLPreview previewer =
                    new HTMLPreview(HTMLEditor.this, getDocSource());
            previewer.setVisible(true);
        }
    });

    return menubar;
}

/**
 * Helper method to extract the HTML source code from the HTML document
 * @return The HTML source code
 */
private String getDocSource() {
    final StringWriter sw = new StringWriter();
    try {
        edtKit.write(sw, doc, 0, doc.getLength());
    } catch (IOException | BadLocationException e1) {
        e1.printStackTrace();
    }
    try {
        sw.close();
    } catch (final IOException e1) {
        e1.printStackTrace();
    }
    return sw.toString();
}

/**
 * Implements the action for insertion of a user supplied style (should be
 * "style1", "style2" or "style3").
 *
 */
public class StyleAction extends StyledEditorKit.StyledTextAction {

    private static final long serialVersionUID = 1L;

    public StyleAction() {
        super("Activate a Style");
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        final JEditorPane editor = getEditor(ae);
        if (editor == null)
            return;
        final String value = JOptionPane.showInputDialog(HTMLEditor.this,
                                                         "Style Name:");
        try {
            final String text = "<span class=\"" + value + "\"></span>";
            edtKit.insertHTML(doc, editor.getCaretPosition(),
                              text, 0, 0, HTML.Tag.SPAN);
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}
}

/**
 * Popup window for display of the current contents of the editor as HTML
 * source code.
 */
class HTMLPreview extends JDialog {

private static final long serialVersionUID = 1L;

public HTMLPreview(JFrame parent, String source) {
    super(parent, "HTML Source", true);

    final JPanel pp = new JPanel(new BorderLayout());
    pp.setBorder(new EmptyBorder(10, 10, 5, 10));

    final JTextArea srcTxtArea = new JTextArea(source, 20, 60);
    srcTxtArea.setFont(new Font("Courier", Font.PLAIN, 12));
    final JScrollPane sp = new JScrollPane(srcTxtArea);
    pp.add(sp, BorderLayout.CENTER);

    final JPanel p = new JPanel(new FlowLayout());
    final JPanel p1 = new JPanel(new GridLayout(1, 2, 10, 0));

    final JButton closeBtn = new JButton("Close");
    closeBtn.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            dispose();
        }
    });
    p1.add(closeBtn);
    p.add(p1);
    pp.add(p, BorderLayout.SOUTH);
    getContentPane().add(pp, BorderLayout.CENTER);
    pack();
    setResizable(true);
    setLocationRelativeTo(parent);
}
}

从ctor中可以看出。 HTMLEditor类我首先添加了三个用户定义的样式(样式[1-3]),然后通过插入使用style1进行格式化的文本来检查它们是否有效。 我希望在用户定义的文本格式化之间切换应该以与在粗体和普通字体显示之间切换文本类似的方式完成。 所以我的问题是:如何将用户定义的CSS样式应用于HTMLDocument中的元素? 非常感谢任何提示。

0 个答案:

没有答案