Java AttributedString,粗体和上标
Java AttributedString, both bold and superscript
我正在尝试渲染一个 java.text.AttributedString
,它既是粗体又是上标。虽然它可以使某些范围成为粗体或上标,但渲染似乎无法处理既是粗体又是上标的范围。
以下 SSCCE 显示使用带有 HTML 文本的 JLabel 渲染它工作正常。有没有办法在没有 JLabel 的情况下获得这种行为?
顺便说一句,我查看了创建的 AttributedString 属性,我认为它们没问题,所以这绝对是一个渲染问题。
package funky.chart;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class AttributedStringTest
{
public static void main(String[] args) {
// prevent using the default UI manager who renders in bold by default for the HTML label
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
System.err.println("Could not set look and feel: " + ex);
}
JFrame frame = new JFrame("AttributedString superscript with font");
frame.getContentPane().add(new JPanel() {
@Override
public void paint(Graphics gfx) {
super.paint(gfx);
Font bold = gfx.getFont().deriveFont(Font.BOLD);
// superscript and bold only works fine
AttributedString test1 = new AttributedString("test superscript and bold");
test1.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 16);
test1.addAttribute(TextAttribute.FONT, bold, 21, 25);
// both superscript and bold is only rendered as bold
AttributedString test2 = new AttributedString("test superscript and bold");
test2.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 25);
test2.addAttribute(TextAttribute.FONT, bold, 5, 25);
gfx.drawString(test1.getIterator(), 5, 20);
gfx.drawString(test2.getIterator(), 5, 40);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 70);
}
});
// HTML label works fine
frame.getContentPane().add(
new JLabel("<html>test <b>bold</b>, <sup>super</sup> and <b><sup>both</sup></b>"),
BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
关于您的完整示例的一些注释:
使用TextAttribute.WEIGHT
指定粗体.
使用TextAttribute.SIZE
指定字体大小。
使用TextLayout
to calculate the preferred size, as shown here.
Swing GUI 对象应该在 event dispatch thread.
上 仅 构建和操作
"Swing programs should override paintComponent()
instead of overriding paint()
."—Painting in AWT and Swing: The Paint Methods.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** @see */
public class AttributedStringTest {
public static void main(String[] args) {
EventQueue.invokeLater(new AttributedStringTest()::display);
}
private void display() {
JFrame frame = new JFrame("AttributedString superscript with font");
frame.getContentPane().add(new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// superscript and bold only works fine
AttributedString test1 = new AttributedString("test superscript and bold");
test1.addAttribute(TextAttribute.SIZE, 28, 0, 25);
test1.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 16);
test1.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 21, 25);
// both superscript and bold is only rendered as bold
AttributedString test2 = new AttributedString("test superscript and bold");
test2.addAttribute(TextAttribute.SIZE, 28, 0, 25);
test2.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 25);
test2.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 5, 25);
g.drawString(test1.getIterator(), 5, 35);
g.drawString(test2.getIterator(), 5, 70);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 80);
}
});
// HTML label works fine
frame.getContentPane().add(new JLabel(
"<html>test <b>bold</b>, <sup>super</sup> and <b><sup>both</sup></b>", JLabel .CENTER),
BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
我正在尝试渲染一个 java.text.AttributedString
,它既是粗体又是上标。虽然它可以使某些范围成为粗体或上标,但渲染似乎无法处理既是粗体又是上标的范围。
以下 SSCCE 显示使用带有 HTML 文本的 JLabel 渲染它工作正常。有没有办法在没有 JLabel 的情况下获得这种行为?
顺便说一句,我查看了创建的 AttributedString 属性,我认为它们没问题,所以这绝对是一个渲染问题。
package funky.chart;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class AttributedStringTest
{
public static void main(String[] args) {
// prevent using the default UI manager who renders in bold by default for the HTML label
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
System.err.println("Could not set look and feel: " + ex);
}
JFrame frame = new JFrame("AttributedString superscript with font");
frame.getContentPane().add(new JPanel() {
@Override
public void paint(Graphics gfx) {
super.paint(gfx);
Font bold = gfx.getFont().deriveFont(Font.BOLD);
// superscript and bold only works fine
AttributedString test1 = new AttributedString("test superscript and bold");
test1.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 16);
test1.addAttribute(TextAttribute.FONT, bold, 21, 25);
// both superscript and bold is only rendered as bold
AttributedString test2 = new AttributedString("test superscript and bold");
test2.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 25);
test2.addAttribute(TextAttribute.FONT, bold, 5, 25);
gfx.drawString(test1.getIterator(), 5, 20);
gfx.drawString(test2.getIterator(), 5, 40);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 70);
}
});
// HTML label works fine
frame.getContentPane().add(
new JLabel("<html>test <b>bold</b>, <sup>super</sup> and <b><sup>both</sup></b>"),
BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
关于您的完整示例的一些注释:
使用
TextAttribute.WEIGHT
指定粗体.使用
TextAttribute.SIZE
指定字体大小。使用
TextLayout
to calculate the preferred size, as shown here.Swing GUI 对象应该在 event dispatch thread.
上 仅 构建和操作
"Swing programs should override
paintComponent()
instead of overridingpaint()
."—Painting in AWT and Swing: The Paint Methods.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** @see */
public class AttributedStringTest {
public static void main(String[] args) {
EventQueue.invokeLater(new AttributedStringTest()::display);
}
private void display() {
JFrame frame = new JFrame("AttributedString superscript with font");
frame.getContentPane().add(new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// superscript and bold only works fine
AttributedString test1 = new AttributedString("test superscript and bold");
test1.addAttribute(TextAttribute.SIZE, 28, 0, 25);
test1.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 16);
test1.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 21, 25);
// both superscript and bold is only rendered as bold
AttributedString test2 = new AttributedString("test superscript and bold");
test2.addAttribute(TextAttribute.SIZE, 28, 0, 25);
test2.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 5, 25);
test2.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 5, 25);
g.drawString(test1.getIterator(), 5, 35);
g.drawString(test2.getIterator(), 5, 70);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 80);
}
});
// HTML label works fine
frame.getContentPane().add(new JLabel(
"<html>test <b>bold</b>, <sup>super</sup> and <b><sup>both</sup></b>", JLabel .CENTER),
BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}