Java AttributedString,粗体和上标

我试图渲染一个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("test bold, super and both"), BorderLayout.SOUTH); frame.pack(); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setVisible(true); } } 

关于完整示例的一些注意事项:

  • 使用TextAttribute.WEIGHT指定粗体

  • 使用TextAttribute.SIZE指定字体大小。

  • 使用TextLayout计算首选大小,如此处所示。

  • 应该在事件派发线程上构造和操作Swing GUI对象。

  • “Swing程序应该覆盖paintComponent()而不是覆盖paint() 。” – 在AWT和Swing中绘画:绘制方法

图片

 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 https://stackoverflow.com/a/31360762/230513 */ 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( "test bold, super and both", JLabel .CENTER), BorderLayout.SOUTH); frame.pack(); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setVisible(true); } }