我正在尝试为特定目的创建一些特殊组件,在该组件上我需要绘制一个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格式,它愚蠢地绘制字符串就像它一样。
有没有办法让这项工作?
答案 0 :(得分:10)
正如其他人所评论的那样,Swing组件支持HTML 3.2和基本样式。
有关如何在paintComponent(Graphics)
方法中利用该功能的详细信息,请参阅this thread上的LabelRenderTest.java
来源。
方法是将标签渲染到图像,然后将图像渲染到Graphics
对象。
答案 1 :(得分:10)
如果是Java2D的粉丝;但是为了在Swing组件和布局中获得HTML的最大优势,我建议您使用@camickr建议的组件方法。如有必要,您可以使用JTable
,等中的flyweight renderer approach,其中重复使用单个组件进行绘制。下面的示例是该技术的非常简化轮廓,仅更改颜色和位置。
附录:更新的例子;另请参阅CellRendererPane
和Make 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();
}
});
}
}
答案 2 :(得分:6)
您的问题的答案是不支持HTML。
简单的解决方案是使用Swing组件并正确布局。
如果您想自己动手,那么您需要操作用于drawString()方法的Font。您可以使用带斜体的字体,粗体等。
答案 3 :(得分:6)
我找到了一种模拟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);
}
}
感谢每一位人士的帮助,我非常感谢。
答案 4 :(得分:5)
这不是实施的方式。
drawString(String str, int x, int y)
仅使用此图形上下文的当前字体和颜色绘制指定字符串给出的文本。
您可以从此处获取有关问题的更多信息,How to Use HTML in Swing Components
答案 5 :(得分:4)
使用JLabel
作为基类。 Graphics.drawString()
只能...画一个字符串。
答案 6 :(得分:2)
没有一种简单的方法可以使用Graphics绘制HTML绘图,使用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);
}