【问题标题】:CSS Padding not Rendered in JTextPaneJTextPane 中未呈现 CSS 填充
【发布时间】:2016-09-05 15:52:52
【问题描述】:

我正在使用JTextPane 来呈现一些 HTML。我正在使用HTMLEditorKitStyleSheetcode 属性添加规则,因此它看起来与StackOverflow 上的代码完全一样。问题是 JTextPane 不会在代码上呈现填充(顶部/底部 1 像素,左侧/右侧 5 像素),即使 padding 属性被列为 的属性之一 渲染引擎支持in the documentation

这是我希望看到的(如this CSSDeck Lab 所示):
↑-↑                   ↑-↑
编辑:
我已经从在我的 HTML 中使用 <code> 标签切换到 @Sharcoux 的建议下切换到 <span>。这使得 used-to-be-code 的字体大小与<pre> 标签中的文本相同,使得红色背景与绿色边框具有相同的高度,但是仍然没有产生预期的结果。 Here是原图,有兴趣的话。

这是实际出现的:

我也尝试过将 CSS 与文本内联,但无济于事。

MCVE(也已编辑):

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;

public class CodePaddingMCVE {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new JFrame("Code Padding Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JTextPane tp = new JTextPane();
            tp.setContentType("text/html");

            HTMLEditorKit kit = new HTMLEditorKit();
            tp.setEditorKit(kit);
            StyleSheet sheet = kit.getStyleSheet();
            sheet.addRule("span {padding: 1px 5px; background-color: red}"); //Using span here
            sheet.addRule("pre {padding: 0px; background-color: green}");
            tp.setDocument(kit.createDefaultDocument());
            tp.setText("<html><pre>NotCode<span>Code</span>NotCode</pre></html>"); //Using <span> here too

            JScrollPane sp = new JScrollPane(tp) {
                private static final long serialVersionUID = 1L;

                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(250, 50);
                }

            };

            frame.getContentPane().add(sp);
            frame.pack();
            frame.setVisible(true);
        });
    }

}

我正在使用 OS X Yosemite 10.10.15、Eclipse Mars.2 4.5.2 和 Java 8 [1.8.0_66]。

【问题讨论】:

  • 您应该使用 span 元素而不是代码。而且我不确定 pre 标签是否被识别,但我不记得了,现在正在我的手机上。

标签: java html css swing jtextpane


【解决方案1】:

你是对的,边距和填充似乎不适用于内联元素。您有 3 个选项。

1) 放弃 JTextPane 并改用 JavaFX WebView。

2) 放弃 HTMLDocument 并使用另一个实现。

3) 尝试在 HTMLEditorKit 中扩展 HTMLFactory,并扩展 InlineView。它会给你类似的东西:

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.InlineView;
import javax.swing.text.html.StyleSheet;

public class CodePaddingMCVE {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Code Padding Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JTextPane tp = new JTextPane();
                tp.setContentType("text/html");

                HTMLEditorKit kit = new HTMLEditorKit() {
                    public ViewFactory getViewFactory() {
                        return new HTMLFactory() {
                            public View create(Element elem) {
                                AttributeSet attrs = elem.getAttributes();
                                Object elementName =
                                    attrs.getAttribute(AbstractDocument.ElementNameAttribute);
                                Object o = (elementName != null) ?
                                    null : attrs.getAttribute(StyleConstants.NameAttribute);
                                if (o instanceof HTML.Tag) {
                                    HTML.Tag kind = (HTML.Tag) o;
                                    if (kind == HTML.Tag.CONTENT) {
                                        return new InlineView(elem) {
                                            private short left;
                                            private short right;
                                            private short top;
                                            private short bottom;
                                            protected void setPropertiesFromAttributes() {
                                                AttributeSet attr = getAttributes();
                                                if (attr != null) {
                                                    top = (short) StyleConstants.getSpaceAbove(attr);
                                                    left = (short) StyleConstants.getLeftIndent(attr);
                                                    bottom = (short) StyleConstants.getSpaceBelow(attr);
                                                    right = (short) StyleConstants.getRightIndent(attr);
                                                }
                                                super.setPropertiesFromAttributes();
                                            }
                                            //TODO : use the top, left, bottom and right properties to draw the margin/padding
                                        };
                                    }
                                }
                                return super.create(elem);
                            }
                        };
                    }
                };
                tp.setEditorKit(kit);
                StyleSheet sheet = kit.getStyleSheet();
                sheet.addRule("span {padding: 5px 5px 5px 5px; background-color: red}"); //Using span here
                sheet.addRule("pre {padding: 0px; background-color: green}");
                tp.setDocument(kit.createDefaultDocument());
                tp.setText("<html><pre>NotCode<span>Code</span>NotCode</pre></html>"); //Using <span> here too

                JScrollPane sp = new JScrollPane(tp) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(250, 50);
                    }

                };

                frame.getContentPane().add(sp);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

如果您想走这条路,您需要深入了解 LabelView 和 GlyphView 以了解如何实现填充或边距。也许其他人可以帮助完成这项工作。

祝你好运。

【讨论】:

  • 感谢您的回答!我选择了 JavaFX WebView,因为这似乎是最简单的方法。
猜你喜欢
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多