2013-05-16 150 views
8

我試圖在Swing應用程序中使用OpenDyslexic作爲字體選項。但令人驚訝的是,OpenDyslexic看起來比同尺寸的其他任何字體都大得多,即使它在其他應用程序中看起來正常。我嘗試了一些其他OpenType字體,並且它們看起來並不特別大或小。爲什麼OpenDyslexic在Java中如此之大,以及我如何讓Java正常地調整它的大小,所以我不必特殊說明OpenDyslexic的大小?爲什麼這個字體在Java中如此之大?

對於所有操作系統上的Oracle JRE(我試過1.7.0_11,1.7.0_15和最新的1.7.0_21),當Java使用Font.createFont加載字體文件時,字體太大。然而,當我安裝字體到操作系統中,該行爲是在所有3個平臺上的不同:

  • 在Linux中,安裝的字體~/.fonts沒有什麼好處。截圖在安裝字體和安裝之後看起來是一樣的。
  • 在Windows中,安裝字體修復了字體字形,但字體的間距仍然太大!見下面的截圖。
  • 在OS X中,安裝字體修復了它!它看起來像在OS X上一個正常大小的字體

更新:有趣的是,OpenJDK的(無論是7u21 Ubuntu的軟件包在Linux和OS X的obuildfactory編譯)不表現出錯誤。在OpenJDK上,15pt OpenDyslexic'm'的寬度爲15px,因爲它應該是當從文件創建字體和操作系統處理字體時。該錯誤位於最新的Oracle JRE中,但不在最新的OpenJDK中。

這是我的示例程序。請注意,要嘗試它,您需要將OpenDyslexic文件放入資源/中。或者,將OpenDyslexic安裝到您的系統中並取出registerFonts()呼叫。

SansSerif is normal sizeOpenDyslexic is huge at the same point sizeAfter installing OpenDyslexic on Windows, it looks stupidAfter installing font on OS X: perfect!

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Font; 
import java.awt.FontFormatException; 
import java.awt.GraphicsEnvironment; 
import java.io.IOException; 
import java.io.InputStream; 
import java.lang.reflect.InvocationTargetException; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Locale; 

import javax.swing.DefaultComboBoxModel; 
import javax.swing.DefaultListCellRenderer; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.WindowConstants; 
import javax.swing.event.ListDataEvent; 
import javax.swing.event.ListDataListener; 

public class FontFrame { 
    /** 
    * Register extra fonts from resources. If you already have it installed on 
    * the computer, you can skip this. 
    */ 
    private static void registerFonts() { 
     String[] resources = { 
      "OpenDyslexic-Regular.otf", 
      "OpenDyslexic-Italic.otf", 
      "OpenDyslexic-Bold.otf", 
      "OpenDyslexic-BoldItalic.otf" 
     }; 
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     for (String filename: resources) { 
      InputStream stream = FontFrame.class.getResourceAsStream("resources/" + filename); 
      try { 
       Font font = Font.createFont(Font.TRUETYPE_FONT, stream); 
       ge.registerFont(font); 
      } catch (FontFormatException | IOException e) { 
       throw new IllegalStateException(e); 
      } 
     } 
    } 
    private static void createUI(boolean allFonts) { 
     final JTextArea textArea = new JTextArea(
       "Font created to help dyslexic readers. " + 
       "Bottom heavy and unique character shapes help " + 
       "prevent letters and numbers from being confused."); 
     textArea.setWrapStyleWord(true); 
     textArea.setLineWrap(true); 
     final DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(); 
     if (allFonts) { 
      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
      HashSet<Object> seenFamilies = new HashSet<>(); 
      Font[] fonts = ge.getAllFonts(); 
      for (Font font: fonts) { 
       String familyName = font.getFamily(Locale.ENGLISH); 
       if (seenFamilies.contains(familyName)) 
        continue; 
       seenFamilies.add(familyName); 
       model.addElement(familyName); 
      } 
     } else { 
      model.addElement("SansSerif"); 
      model.addElement("OpenDyslexic"); 
     } 

     final int fontSize = 15; 
     textArea.setFont(new Font("SansSerif", Font.PLAIN, fontSize)); 
     model.addListDataListener(new ListDataListener() { 
      @Override public void intervalRemoved(ListDataEvent e) {} 
      @Override public void intervalAdded(ListDataEvent e) {} 
      @Override public void contentsChanged(ListDataEvent e) { 
       if (e.getIndex0() == -1 && e.getIndex1() == -1) { 
        SwingUtilities.invokeLater(new Runnable() { @Override public void run() { 
         String selectedFamily = (String) model.getSelectedItem(); 
         Font font = new Font(selectedFamily, Font.PLAIN, fontSize); 
         textArea.setFont(font); 
        }}); 
       } 
      } 
     }); 
     JComboBox<String> familyChooser = new JComboBox<>(model); 
     familyChooser.setMaximumRowCount(50); 
     familyChooser.setRenderer(new DefaultListCellRenderer() { 
      private static final long serialVersionUID = 1L; 
      public Component getListCellRendererComponent(JList<?> list, 
        Object value, int index, boolean isSelected, 
        boolean cellHasFocus) { 
       Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
       String familyName = (String) value; 
       Font font = new Font(familyName, Font.PLAIN, fontSize); 
       comp.setFont(font); 
       return comp; 
      } 
     }); 

     JPanel jpanel = new JPanel(); 
     jpanel.setLayout(new BorderLayout()); 
     jpanel.add(familyChooser, BorderLayout.NORTH); 
     jpanel.add(textArea, BorderLayout.CENTER); 
     JFrame jframe = new JFrame(); 
     jframe.getContentPane().add(jpanel); 
     jframe.setSize(300, 300); 
     jframe.invalidate(); 
     jframe.setVisible(true); 
     jframe.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
    } 
    public static void main(String[] args) throws InvocationTargetException, InterruptedException { 
     registerFonts(); 
     final boolean allFonts = Arrays.asList(args).contains("--all"); 
     SwingUtilities.invokeAndWait(new Runnable() { 
      @Override public void run() { 
       createUI(allFonts); 
      } 
     }); 
    } 
} 
+0

[你可以測試](http://tips4java.wordpress.com/2008/11/30/visual-font-designer/)如果屬實,由Darryl Burke – mKorbel

+0

@mKorbel製作,字體看起來一樣在可視化字體設計器演示中,就像在查看已安裝的字體時一樣。在OS X上看起來不錯,但在其他平臺上看起來很糟糕。 (請注意,我已經更新了這個問題來描述在不同平臺上安裝字體。) – yonran

回答

1

並不是每一個Java版本支持的OpenType(參見this overview)。如果你可以沒有一些OpenType功能,最簡單的解決方案就是將字體文件轉換爲TTF。似乎有幾個free online options來幫助你,如果這解決了你的問題,你仍然可以投資專業軟件來獲得更好的結果。

+0

但是,您鏈接的網頁聲稱Windows上的Java支持OpenType(TrueType和PostScript變體),而Windows實際上看起來最糟糕。 – yonran

+0

由於這不是官方聲明,因此OTF可能會導致問題。這些問題的具體化可能還取決於其他因素,如操作系統版本。 //另一方面,我個人只有PS字體的問題,並且轉換它們就是解決方案。是否有其他原因阻止你嘗試?例如,我沒有閱讀OpenDyslexic許可證...... – Tilo

+0

感謝Tilo。將字體從otf轉換爲ttf後,它在所有平臺上都具有正確的大小,無論是在安裝時還是從字體文件加載時。 – yonran

相關問題