2013-10-18 86 views
1

看來JTextPane和JTextArea呈現不同的字體。它幾乎不明顯,但我仍然想知道它爲什麼在那裏。JTextArea和JTextPane字體呈現

我已經建立了一個SSCCE,但你不能真正看到它。最好的方法是使用JTextArea運行程序,然後將代碼更改爲JTextPane並再次運行。它們應該以某種方式重疊,即當您從一個窗口切換到另一個窗口時(使用alt +製表符),可以看到差異。你將不得不提供你自己的* .ttf文件。

這是爲什麼?有沒有辦法強制JTextPane以與JTextArea相同的方式呈現文本?

SSCCE:

import java.awt.Font; 
import java.awt.FontFormatException; 
import java.awt.event.FocusEvent; 
import java.awt.event.FocusListener; 
import java.io.IOException; 

import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JTextArea; 
import javax.swing.JTextPane; 
import javax.swing.UIManager; 
import javax.swing.UIManager.LookAndFeelInfo; 
import javax.swing.UnsupportedLookAndFeelException; 


public class Main 
{ 
public static void main(String[] args) 
{ 
    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) 
    { 
     if ("Nimbus".equals(info.getName())) 
     { 
      try 
      { 
       UIManager.setLookAndFeel(info.getClassName()); 
      } 
      catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) 

      { 
       System.out.println("No Nimbus!"); 
      } 

      break; 
     } 
    } 

    JFrame a = new JFrame("Test"); 
    a.setSize(600, 900); 
    a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    a.getContentPane().setLayout(new BoxLayout(a.getContentPane(), BoxLayout.Y_AXIS)); 

    Font d = null; 

    try 
    { 
     d = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("calibri_bold.ttf")); 
     d = d.deriveFont(23f); 
    } 

    catch (FontFormatException | IOException e1) 
    { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 

    final JTextPane b = new JTextPane(); 



    b.setBorder(new JTextArea().getBorder()); 
    b.setFont(d); 

    b.addFocusListener(new FocusListener() { 

     @Override 
     public void focusGained(FocusEvent arg0) { 
      b.repaint(); 
     } 

     @Override 
     public void focusLost(FocusEvent arg0) { 
      b.repaint(); 
     } 

    }); 
    b.setText("It seems that JTextPane and JTextArea are rendering fonts differently. It is barely noticeable, but I still want to know why is it there. I have set up a SSCCE, but you can't really see it. Best method would be to run a program with JTextArea, then change the code to JTextPane and run it again. They should overlap in a way when you change from one window to the other (with alt+ tab) the difference can be seen. Why is that? Is there a way to force the JTextPane to render the text the same way as JTextArea does?"); 
    a.getContentPane().add(b); 

    final JTextArea c = new JTextArea(); 


    c.setFont(d); 
    c.setText("It seems that JTextPane and JTextArea are rendering fonts differently. It is barely noticeable, but I still want to know why is it there. I have set up a SSCCE, but you can't really see it. Best method would be to run a program with JTextArea, then change the code to JTextPane and run it again. They should overlap in a way when you change from one window to the other (with alt+ tab) the difference can be seen. Why is that? Is there a way to force the JTextPane to render the text the same way as JTextArea does?"); 
    c.setLineWrap(true); 
    c.setWrapStyleWord(true); 
    a.getContentPane().add(c); 

    a.setVisible(true); 
} 
} 
+0

'您必須提供自己的* .TTF file.' - 當你使用默認的字體會發生什麼?你的.ttf文件有問題嗎? – camickr

+0

爲什麼會有問題呢?這是一個單一的文件,他們應該顯示它一樣... – Karlovsky120

+0

剛剛離開我的頭頂,有一些字體的RenderingHints。 IE JTextPane可能會將Graphics2D與浮點指標結合使用,JTextArea可能不會。 – Radiodef

回答

4
  • Nimbus L&F有幾個awfull問題,我們可以稱這些問題爲Bugs

  • JTextArea和另一JComponentsUIManager

  • 凍結一些 Keys
  • 你可以去UIManager.getLookAndFeel().uninitialize();大多數按鍵他們是凍結的,但他們中的一些能夠抵抗所有的變化,黑客woodoo,但對於FontJTextArea不是這種情況下

  • 注意你需要重寫所有鍵3次,不如demonstratedin我的代碼,看到main class

enter image description here

UIManager評論 //...Defaults.put("TextPane.font", res);

  • 初步改變

    • UIManager.getLookAndFeel().uninitialize()之後;被稱爲

    enter image description here

    import java.awt.Font; 
    import java.awt.GridLayout; 
    import java.awt.event.ActionEvent; 
    import java.util.logging.Level; 
    import java.util.logging.Logger; 
    import javax.swing.AbstractAction; 
    import javax.swing.Action; 
    import javax.swing.JFrame; 
    import javax.swing.JScrollPane; 
    import javax.swing.JTextArea; 
    import javax.swing.JTextPane; 
    import javax.swing.LookAndFeel; 
    import javax.swing.SwingUtilities; 
    import javax.swing.UIDefaults; 
    import javax.swing.UIManager; 
    import javax.swing.UIManager.LookAndFeelInfo; 
    import javax.swing.UnsupportedLookAndFeelException; 
    import javax.swing.plaf.FontUIResource; 
    
    public class Main { 
    
        private JFrame frame = new JFrame("Test"); 
        private JTextPane textPane = new JTextPane(); 
        private JTextArea textArea = new JTextArea(); 
        private String str = "It seems that JTextPane and JTextArea are rendering fonts differently. " 
          + "It is barely noticeable, but I still want to know why is it there. " 
          + "I have set up a SSCCE, but you can't really see it. Best method would " 
          + "be to run a program with JTextArea, then change the code to JTextPane " 
          + "and run it again. They should overlap in a way when you change from one " 
          + "window to the other (with alt+ tab) the difference can be seen. " 
          + "Why is that? Is there a way to force the JTextPane to render the " 
          + "text the same way as JTextArea does?"; 
        private javax.swing.Timer timer = null; 
        final Font fnt = new Font("Brodway", Font.BOLD, 10); 
    
        public Main() { 
         textPane.setBorder(new JTextArea().getBorder()); 
         textPane.setText(str); 
         textArea.setText(str); 
         textArea.setLineWrap(true); 
         textArea.setWrapStyleWord(true); 
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
         frame.setLayout(new GridLayout(0, 1)); 
         frame.add(new JScrollPane(textPane)); 
         frame.add(new JScrollPane(textArea)); 
         frame.setVisible(true); 
         frame.setSize(400, 400); 
         start(); 
        } 
    
        private void start() { 
         timer = new javax.swing.Timer(2250, updateCol()); 
         timer.setRepeats(false); 
         timer.start(); 
        } 
    
        public Action updateCol() { 
         return new AbstractAction("text load action") { 
          private static final long serialVersionUID = 1L; 
    
          @Override 
          public void actionPerformed(ActionEvent e) { 
    
           try { 
            LookAndFeel lnf = UIManager.getLookAndFeel().getClass().newInstance(); 
            final FontUIResource res = new FontUIResource(fnt); 
            UIDefaults uiDefaults = lnf.getDefaults(); 
            //uiDefaults.put("TextPane.font", res); 
            uiDefaults.put("TextArea.font", res); 
            UIManager.getLookAndFeel().uninitialize(); 
            UIManager.setLookAndFeel(lnf); 
           } catch (InstantiationException ex) { 
            Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex); 
           } catch (IllegalAccessException ex) { 
            Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex); 
           } catch (UnsupportedLookAndFeelException ex) { 
            Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex); 
           } 
           UIDefaults defaults = UIManager.getDefaults(); 
           final FontUIResource res = new FontUIResource(fnt); 
           //defaults.put("TextPane.font", res); 
           defaults.put("TextArea.font", res); 
           SwingUtilities.updateComponentTreeUI(frame); 
          } 
         }; 
        } 
    
        public static void main(String[] args) { 
         final FontUIResource res = new FontUIResource(new Font("Algerian", Font.BOLD, 10)); 
         for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
          if ("Nimbus".equals(info.getName())) { 
           try { 
            UIManager.setLookAndFeel(info.getClassName()); 
            UIDefaults defaults = UIManager.getDefaults(); 
            defaults.put("TextPane.font", res); 
            defaults.put("TextArea.font", res); 
           } catch (ClassNotFoundException | InstantiationException | 
             IllegalAccessException | UnsupportedLookAndFeelException e) { 
            System.out.println("No Nimbus!"); 
           } 
           break; 
          } 
         } 
         java.awt.EventQueue.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           new Main(); 
          } 
         }); 
        } 
    }