You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java Swing JTextPane的HTML元素中绘制带圆角的自定义背景

解决Java Swing HTML渲染器中<code>标签border-radius无效的问题

Swing的HTML渲染器基于老旧的CSS规范,确实不支持border-radius这类CSS3属性。要实现圆角样式的<code>标签,有两种可行方案:

方案一:自定义View绘制圆角背景

通过扩展Swing的View类,手动接管<code>标签的渲染逻辑,自行绘制圆角背景。

1. 自定义CodeView类

重写InlineView的paint方法,先绘制圆角矩形背景,再渲染文本内容:

import javax.swing.text.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;

public class CodeView extends InlineView {
    private static final int CORNER_RADIUS = 6;
    private final Color backgroundColor;

    public CodeView(Element element) {
        super(element);
        // 从元素样式中读取背景色,无样式时使用UI默认色
        Style style = (Style) element.getAttributes().getAttribute(StyleConstants.ResolveAttribute);
        backgroundColor = style != null ? StyleConstants.getBackground(style) 
                                        : UIManager.getColor("InstanceItem.defaultColor");
    }

    @Override
    public void paint(Graphics g, Shape shape) {
        Rectangle bounds = shape.getBounds();
        // 用Graphics2D绘制圆角背景
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(backgroundColor);
        g2d.fill(new RoundRectangle2D.Float(
                bounds.x, bounds.y,
                bounds.width, bounds.height,
                CORNER_RADIUS, CORNER_RADIUS
        ));
        g2d.dispose();

        // 调整文本绘制区域,增加内边距避免内容贴边
        super.paint(g, new Rectangle(
                bounds.x + 2, bounds.y + 1,
                bounds.width - 4, bounds.height - 2
        ));
    }

    @Override
    public float getPreferredSpan(int axis) {
        float span = super.getPreferredSpan(axis);
        // 为内边距预留空间
        if (axis == View.X_AXIS) {
            span += 4; // 左右各2px
        } else {
            span += 2; // 上下各1px
        }
        return span;
    }
}

2. 自定义HTMLEditorKit

创建自定义编辑器工具包,替换默认的ViewFactory,让<code>标签使用我们的CodeView:

import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTML;

public class CustomHtmlKit extends HTMLEditorKit {
    @Override
    public ViewFactory getViewFactory() {
        return new HTMLFactory() {
            @Override
            public View create(Element element) {
                Object tagAttr = element.getAttributes().getAttribute(StyleConstants.NameAttribute);
                if (tagAttr instanceof HTML.Tag && tagAttr == HTML.Tag.CODE) {
                    return new CodeView(element);
                }
                return super.create(element);
            }
        };
    }
}

3. 应用到JEditorPane

将自定义工具包设置给JEditorPane即可生效:

JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(new CustomHtmlKit());
editorPane.setContentType("text/html");
// 加载你的HTML内容
editorPane.setText(fullHtml.toString());

方案二:替换为现代HTML渲染器

如果需要完全支持现代CSS特性,可考虑以下替代方案:

  • JCEF(Java Chromium Embedded Framework):基于Chrome内核,完美兼容所有现代HTML/CSS,渲染效果和浏览器一致。缺点是会增大应用体积,需打包对应平台的原生库。
  • JavaFX WebView:若可迁移到JavaFX,WebView原生支持网页标准,还能通过SwingNode与现有Swing应用集成。

注:CSSBox对CSS3属性的支持确实有限,不推荐用于需要border-radius这类特性的场景。

内容的提问来源于stack exchange,提问作者TheEntropyShard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:43:16