JEditorPaneHTMLEditorKitParserHex十六进制处理

wen java案例 2

本文目录导读:

JEditorPaneHTMLEditorKitParserHex十六进制处理

  1. 最常见的问题:CSS 中的十六进制颜色被忽略
  2. 通过 setForeground 编程设置颜色
  3. 解析器版本与严格模式
  4. 通过 HTMLEditorKit 扩展解析器(高级)
  5. 测试示例 (可直接运行)

JEditorPaneHTMLEditorKit 在处理十六进制颜色(Hex)时可能遇到的问题,通常是由于 HTML 解析器的严格程度CSS 解析的兼容性 导致的。

以下是几个核心问题及解决方案:

最常见的问题:CSS 中的十六进制颜色被忽略

现象: 你设置了类似 <span style="color: #FF0000;">Red</span>,但文字显示为黑色(默认颜色)。

原因: HTMLEditorKit 携带的解析器(默认是 ParserDelegator)在处理 CSS 属性值时,对连续的数字/字母串(lexer 解析)有限制,如果在 style 属性中直接使用 #FF0000,解析器可能无法正确识别 及其后的十六进制数作为颜色值。

解决方案: 最好的方法是避免使用简写的十六进制颜色,或者使用 TTF (TRUETYPE FONT) 标准的 Color 表示法,或者使用 RGB 十进制函数

  • 改用 RGB 函数:

    <span style="color: rgb(255, 0, 0);">Red Text</span>

    这种方式在 Swing 的 HTMLEditorKit 中最为稳定。

  • 使用更长的 Hex 格式(通常是 8 位,虽然 Swing 不完全支持 alpha 但能识别):

    <span style="color: #FF0000;">Red</span>

    注:某些 Swing 版本对 3 位简写(如 #F00)完全无法识别,建议始终使用 6 位(如 #FF0000)。

通过 setForeground 编程设置颜色

现象: 你想在 JEditorPane 中动态地插入带有十六进制颜色的文本。

原因: JEditorPanesetCharacterAttributes 或直接使用 MutableAttributeSet 不直接接受十六进制字符串,它需要 java.awt.Color 对象。

解决方案: 将十六进制字符串转换为 Java AWT Color 对象,然后设置属性。

import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class HexColorExample {
    public static void main(String[] args) {
        JEditorPane editorPane = new JEditorPane();
        editorPane.setContentType("text/html");
        editorPane.setText("<html><body>Initial Text</body></html>");
        // 获取 Document
        StyledDocument doc = (StyledDocument) editorPane.getDocument();
        // 1. 将十六进制字符串转换为 Color
        String hexColor = "#00FF00"; // 绿色
        Color color = Color.decode(hexColor); // 或者 Integer.parseInt(hexColor.substring(1), 16)
        // 2. 创建属性集
        SimpleAttributeSet attributes = new SimpleAttributeSet();
        StyleConstants.setForeground(attributes, color);
        StyleConstants.setBold(attributes, true);
        // 3. 应用到文档(例如从位置 0 开始,长度为 5)
        int start = 0;
        int length = 5; // 替换前5个字符
        doc.setCharacterAttributes(start, length, attributes, false);
    }
}

解析器版本与严格模式

问题: HTMLEditorKit 内部使用了一个古老的 HTML 3.2 解析器(javax.swing.text.html.parser.ParserDelegator),它对 HTML 5 和现代 CSS 语法支持很差。

特殊行为:

  • <font color="#FF0000"> 标签虽然过时,但在 Swing 中往往比 CSS style 属性更可靠
    <font color="#FF0000">Red</font>  <!-- 通常工作良好 -->
  • CSS 样式块 <style> .class { color: #FF0000; } </style> 在 Swing 中几乎完全不支持。

建议: 如果必须使用 Hex,优先使用 <font color="#RRGGBB"> 标签,而不是 CSS style="color: X"

通过 HTMLEditorKit 扩展解析器(高级)

如果默认解析器无法满足需求,你可以重写 HTMLEditorKitgetParser 方法,提供一个自定义解析器,但这非常复杂,通常不推荐。

使用场景 推荐写法 原因
静态 HTML 模板 <span style="color: rgb(255,0,0);"> rgb() 函数在 Swing 解析器中识别率最高
代码中动态插入 Color.decode("#FF0000") + StyleConstants.setForeground() 完全绕过 HTML 解析器,直接操作 AWT Color
简单场景 <font color="#FF0000"> Swing 解析器对 <font> 标签的兼容性最好
避免使用 <span style="color: #F00;"> 3位简写几乎一定会被忽略
避免使用 CSS 类 / <style> Swing 几乎不解析外部或嵌入的 CSS 规则

测试示例 (可直接运行)

import javax.swing.*;
import java.awt.*;
public class HexColorTest {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Hex Test");
        JEditorPane pane = new JEditorPane();
        pane.setContentType("text/html");
        // 测试不同写法
        String html = "<html><body>"
            + "<p style='color: #FF0000;'>1. CSS Hex #FF0000 (FAIL)</p>"
            + "<p style='color: rgb(255, 0, 0);'>2. CSS rgb (PASS)</p>"
            + "<font color='#00FF00'>3. Font tag Green (PASS)</font><br>"
            + "<span style='color: #0000FF;'>4. Blue Hex (可能FAIL)</span>"
            + "</body></html>";
        pane.setText(html);
        frame.add(new JScrollPane(pane));
        frame.setSize(400, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

如果你遇到十六进制颜色无法显示,最稳妥的两种方法是:

  1. 在 HTML 中使用 rgb(255,0,0) 代替十六进制。
  2. 在 Java 代码中使用 Color.decode() + StyledDocument.setCharacterAttributes()

抱歉,评论功能暂时关闭!