2015-07-11 250 views
1

我想呈现一个java.text.AttributedString,它既是粗体又是上标。虽然它可以使一些范围加粗或上标,但渲染似乎无法处理加粗和上标的范围。Java 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); 
    } 
} 

回答

2

您完整的例子一些注意事项:

image

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(
      "<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); 
    } 
} 
+0

谢谢,trashgod ...我忽略了'WEIGHT'属性。当然,你也提到了你提到的一般Swing指导方针。但是,新的AttributedStringTest():: display'语法对我来说看起来像C++还是它的一些功能性的Java 8的东西? –

+0

@FranzD .:正确;请参阅[*方法参考*](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)。 – trashgod

+0

我喜欢这个......感谢您以多种方式启发我:) –