我試圖在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()
呼叫。
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);
}
});
}
}
[你可以測試](http://tips4java.wordpress.com/2008/11/30/visual-font-designer/)如果屬實,由Darryl Burke – mKorbel
@mKorbel製作,字體看起來一樣在可視化字體設計器演示中,就像在查看已安裝的字體時一樣。在OS X上看起來不錯,但在其他平臺上看起來很糟糕。 (請注意,我已經更新了這個問題來描述在不同平臺上安裝字體。) – yonran