【问题标题】:Swing HTML drawStringSwing HTML drawString
【发布时间】:2011-12-08 03:58:24
【问题描述】:

我正在尝试为特定目的创建一些特殊组件,在该组件上我需要绘制一个 HTML 字符串,这是一个示例代码:

 public class MyComponent extends JComponent{
     public MyComponent(){
        super();
     }

     protected void paintComponent(Graphics g){
        //some drawing operations...
        g.drawString("<html><u>text to render</u></html>",10,10);
     }
 }

不幸的是,drawString 方法似乎无法识别 HTML 格式,它愚蠢地按原样绘制字符串。

有什么办法可以做到吗?

【问题讨论】:

  • 为什么不使用 JLabel?它支持 HTML 标签。
  • 我的组件不只是绘制一个 html 字符串,还有很多其他的绘制操作我不想在示例代码中展示,只是为了关注真正的问题。
  • '特别'怎么样? “具体”什么?这个问题的答案表明,包含更多而不是更少的细节是个好主意。

标签: java html swing graphics2d jcomponent


【解决方案1】:

如果是 Java2D 的粉丝;但是为了在 Swing 组件和布局中充分利用 HTML,我鼓励您使用 @camickr 建议的组件方法。如有必要,您可以使用在JTable中看到的享元renderer approach,其中重复使用单个组件进行绘图。下面的例子是一个非常简化的技术大纲,只改变了颜色和位置。

附录:更新示例;另见CellRendererPaneMake your apps fly: Implement Flyweight to improve performance

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.CellRendererPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/7774960 */
public class PaintComponentTest extends JPanel {

    private static final int N = 8;
    private static final String s = "<html><big><u>Hello</u></html>";
    private JLabel renderer = new JLabel(s);
    private CellRendererPane crp = new CellRendererPane();
    private Dimension dim;

    public PaintComponentTest() {
        this.setBackground(Color.black);
        dim = renderer.getPreferredSize();
        this.add(crp);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < N; i++) {
            renderer.setForeground(Color.getHSBColor((float) i / N, 1, 1));
            crp.paintComponent(g, renderer, this,
                i * dim.width, i * dim.height, dim.width, dim.height);
        }
    }

    private void display() {
        JFrame f = new JFrame("PaintComponentTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setSize(dim.width * N, dim.height * (N + 1));
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new PaintComponentTest().display();
            }
        });
    }
}

【讨论】:

  • 非常感谢您的帮助。我发现了另一种不需要 CellRendererPane 的方法。 (看看我的回答帖子)。
  • 不客气。 CellRendererPane 为缓冲和验证提供了一些方便的优化,这些优化在未来可能会被证明是有用的。
【解决方案2】:

正如其他人评论的那样,Swing 组件支持 HTML 3.2 和基本样式。

有关如何在paintComponent(Graphics) 方法中利用该功能的详细信息,请参阅this thread 上的LabelRenderTest.java 源代码。

方法是将标签渲染到图像,然后将图像渲染到Graphics对象。

【讨论】:

  • 我找到了一种使用 JLabel 绘制 htmlString 的方法,但无需渲染图像(查看我的帖子)。非常感谢您的帮助。
【解决方案3】:

您的问题的答案是不支持 HTML。

简单的解决方案是使用 Swing 组件并正确布局。

如果你想自己做,那么你需要操作你用于 drawString() 方法的字体。您可以使用带有斜体、粗体等的字体。

【讨论】:

  • 非常感谢您的回答,它帮助我思考正确的方式。
【解决方案4】:

我找到了一种简短而简洁的方法来模拟paintHtmlString;这是代码:

public class MyComponent extends JComponent {

    private JLabel label = null;

    public MyComponent() {
        super();
    }

    private JLabel getLabel() {
        if (label == null) {
            label = new JLabel();
        }
        return label;
    }

    /**
     * x and y stand for the upper left corner of the label
     * and not for the baseline coordinates ...
     */
    private void paintHtmlString(Graphics g, String html, int x, int y) {
        g.translate(x, y);
        getLabel().setText(html);
        //the fontMetrics stringWidth and height can be replaced by
        //getLabel().getPreferredSize() if needed
        getLabel().paint(g);
        g.translate(-x, -y);
    }

    protected void paintComponent(Graphics g) {
        //some drawing operations...
        paintHtmlString(g, "<html><u>some text</u></html>", 10, 10);
    }
}

感谢大家的帮助,非常感谢。

【讨论】:

  • here 所述,如果 JLabel 从未添加到 pack()ed(或等效项)的框架下,则可能需要 getLabel().setSize(getLabel().getPreferredSize())
【解决方案5】:

这不是实现的方式。

drawString(String str, int x, int y) 仅绘制指定字符串给出的文本,使用此图形上下文的当前字体和颜色。

你可以从这里获得更多关于你的问题的信息,How to Use HTML in Swing Components

【讨论】:

  • 谢谢你的回答,它帮助我走对了路。
【解决方案6】:

使用JLabel 作为您的基类。 Graphics.drawString() 只能……画一个字符串。

【讨论】:

  • 我的组件不只是绘制一个 html 字符串,还有很多其他的绘制操作,我不想在示例代码中展示,只是为了关注真正的问题。我知道 JLabel 和所有其他保存文本的 Swing 组件都支持 html 格式。
    我只是想知道是否有任何方法可以通过 Graphics 实例呈现 html 文本。
  • 感谢您的帮助。
【解决方案7】:

没有一种简单的方法来渲染 HTML 以使用 Graphics 进行绘制,请使用 JLabel。

但是,有一种有趣的方法可以通过使用 HTML 创建 JLabel 并将其图形绘制到组件来完成此操作:

private JLabel label;

public MyComponent() {
    label = new JLabel("Before Red");
    label.setText("<html><u>test</u></html>");
    this.add(label);
}

public void repaint(Graphics g){
    g = label.getGraphics();
}

完成此操作的最简单方法是为您的图形设置字体,例如:

public void repaint(Graphics g){    
    Font f = new Font("Courier", Font.BOLD, 12);
    g.setFont(f);
    g.drawString("Bolded Courier", 5, 15);
}

【讨论】:

    猜你喜欢
    • 2012-03-17
    • 1970-01-01
    • 2017-04-27
    • 2021-10-14
    • 1970-01-01
    • 2020-01-29
    • 2013-10-16
    • 1970-01-01
    • 2010-09-30
    相关资源
    最近更新 更多