2015-07-11 45 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

我喜歡這個......感謝您以多種方式啓發我:) –