2013-10-18 166 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(); 
          } 
         }); 
        } 
    }