8

Swing アプリケーションのフォント オプションとして OpenDyslexic を使用しようとしています。しかし驚くべきことに、OpenDyslexic は、他のアプリケーションでは通常のサイズに見えますが、同じポイント サイズの他のどのフォントよりもはるかに大きく見えます。他の OpenType フォントをいくつか試してみましたが、特に大きくも小さくも見えません。Java で OpenDyslexic が非常に大きいのはなぜですか? また、OpenDyslexic のサイズを特別に指定する必要がないように、Java を通常のサイズにするにはどうすればよいですか?

すべての OS で 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 (Linux の 7u21 Ubuntu パッケージと OS X の obuildfactory ビルドの両方) にはバグが見られませ。15pt OpenDyslexic 'm' は、フォントがファイルから作成されたときと、オペレーティング システムによってフォントが処理されたときの両方で、OpenJDK では 15px 幅です。このバグは最新の Oracle JRE にはありますが、最新の OpenJDK にはありません。

これが私のサンプルプログラムです。これを試すには、 OpenDyslexicファイルを resources/に配置する必要があることに注意してください。または、システムに OpenDyslexic をインストールしてregisterFonts()電話に出てください。

サンセリフは通常サイズ OpenDyslexic は同じポイント サイズで巨大です WindowsにOpenDyslexicをインストールした後、それはばかげているように見えます OS X にフォントをインストールした後: パーフェクト!

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);
            }
        });
    }
}
4

1 に答える 1

1

すべての Java バージョンが OpenType をサポートしているわけではありません (この概要を参照)。OpenType 機能の一部がなくても生活できる場合、最も簡単な解決策は、フォント ファイルを TTF に変換することです。それを支援する無料のオンラインオプションがいくつかあるようです.これで問題が解決する場合は、プロのソフトウェアに投資して、より良い結果を得ることができます.

于 2013-05-21T17:18:41.897 に答える