5

JTextPane / JTextField(またはそれらの下のフォントレンダリングのどこか)に奇妙なバグを発見しました。他の誰かが同じことに遭遇し、これに対する解決策を持っているのではないかと思います。

JTextPaneに「特殊な」またはまれな文字を表示しようとしていますが、JTextFieldのフォント(JTextPaneとはまったく関係ありません!)を変更するとすぐに、JTextPaneが「分割」され、これらが表示されなくなります。文字。

これは私が何を意味するかを説明するより良い仕事をするはずです:

public class Scrap {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200, 200);
    frame.setLayout(new BorderLayout());

    JTextField field = new JTextField();

    // Uncomment this line... and the JTextPane nor the JTextField
    // no longer display the characters
    // field.setFont(new Font("Arial", Font.PLAIN, 14));

    frame.add(field, BorderLayout.SOUTH);

    JTextPane textPane = new JTextPane();
    textPane.setFont(new Font("Arial", Font.PLAIN, 14));

    JScrollPane scroll = new JScrollPane(textPane);
    frame.add(scroll, BorderLayout.CENTER);

    StyledDocument doc = (StyledDocument) textPane.getDocument();

    try {
        String str = "◕ ◡◡ ◕";

        doc.insertString(doc.getLength(), str, null);

    } catch (BadLocationException e) {
        e.printStackTrace();
    }

    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
}
}

編集:これが問題のより良い例です。フォントのサイズに関連しているようです。スライダーを動かすと、サイズ14でグリフがレンダリングされず、14がJTextFieldのフォントのサイズであることがわかります。

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.*;
import java.awt.*;

public class Scrap {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(600, 200);
    frame.setLayout(new BorderLayout());

    final JTextField field = new JTextField(10);

    final JTextPane textPane = new JTextPane();

    StyledDocument doc = (StyledDocument) textPane.getDocument();

    JPanel panel = new JPanel();
    frame.add(panel, BorderLayout.SOUTH);

    // Set the Font of the JTextField, and the JTextPane
    // no longer displays the text of that size correctly...

    int changeMe = 14;

    field.setFont(new Font("Tahoma", Font.PLAIN, changeMe));

    // If we change the Font Family, the problem goes away...
    // field.setFont(new Font("Dialog", Font.PLAIN, 14));

    panel.add(field);

    final JLabel label = new JLabel();

    final JSlider slider = new JSlider(6, 32);
    slider.addChangeListener(new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            textPane.setFont(new Font("Tahoma", Font.PLAIN, slider.getValue()));

            textPane.selectAll();

            SimpleAttributeSet attr = new SimpleAttributeSet();
            StyleConstants.setFontSize(attr, slider.getValue());
            textPane.setCharacterAttributes(attr, true);

            label.setText("" + slider.getValue());
        }
    });

    slider.setValue(14);

    panel.add(slider);

    panel.add(label);

    JScrollPane scroll = new JScrollPane(textPane);
    frame.add(scroll, BorderLayout.CENTER);

    Style s = doc.addStyle("test", null);

    try {
        String str = "◕ ◡◡ ◕";

        doc.insertString(doc.getLength(), str, doc.getStyle("test"));

    } catch (BadLocationException e) {
        e.printStackTrace();
    }

    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
}
}
4

3 に答える 3

2

何が起こったのか、そしてその理由はわかりませんが、設定する必要があります

textPane.setContentType("text/html");

ここに画像の説明を入力してください

import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;

public class Scrap {


    public  Scrap() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200, 200);
        frame.setLayout(new BorderLayout());
        JTextField field = new JTextField();
        // Uncomment this line... and the JTextPane nor the JTextField
        // no longer display the characters
        field.setFont(new Font("Arial", Font.PLAIN, 14));
        frame.add(field, BorderLayout.SOUTH);
        JTextPane textPane = new JTextPane();
        textPane.setFont(new Font("Arial", Font.PLAIN, 14));
        textPane.setContentType("text/html");
        JScrollPane scroll = new JScrollPane(textPane);
        frame.add(scroll, BorderLayout.CENTER);
        StyledDocument doc = (StyledDocument) textPane.getDocument();
        try {
            String str = "\uD0180, \u2460, \u2760, \u2380, \u2C60, \u5000, \u03E0";
            doc.insertString(doc.getLength(), str, null);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Scrap fs = new Scrap();
            }
        });
    }
}
于 2012-10-15T20:48:36.197 に答える
2

複数の言語 (中国語などの「非標準」文字を含む言語を含む) をサポートする必要があるアプリケーションを作成しようとしたときに、同様の問題が発生しました。以前はウィジェットのフォントを に設定しArialていましたが、問題がありました。次の解決策で私の問題は解決しましたが、あなたの問題は解決しない可能性があります。

Java には、表示できない特定の文字セットの文字が検出されるたびに、フォールバック メカニズムがあります。これは、JRE で提供される fontconfig.properties ファイルを使用して構成できます (ファイルは元々「fontconfig.properties.src」として提供されているため、手動で名前を変更する必要があります)。

DialogSerifSansSerifMonospacedまたはの間にないフォントを強制するとDialogInput、現在の文字セット (この場合は Arial) が画面に描画しようとしている文字 (またはグリフ) を表すことができない場合、Java は別の文字セットを使用する方法がありません。

fontconfig.properties.src ファイルを見ると、さまざまな種類のフォント ( 、 など) の多くのエントリが含まれていることがわかりDialog.plainますSerif.bold。これらは、上記のフォントが特定のグリフを表示できない場合に使用する実際の代替フォントです。したがって、たとえば、ウィジェットのフォントを に設定するFont.DIALOGと、Java がフォントのリストを試して文字を表示できるようになります。

詳細については、Oracle の Web サイト ( Java 7 についてはこちら) を参照してください。fontconfig.properties の使用は、Oracle によって正式にサポートされていないことに注意してください。

于 2012-10-15T20:17:07.517 に答える
0

単純なシミュレーション フォントと Glyps、

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class Fonts implements Runnable {

    private String[] fnt;
    private JFrame frm;
    private JScrollPane jsp;
    private JTextPane jta;
    private JTextField field;
    private int width = 450;
    private int height = 300;
    private GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    private StyledDocument doc;
    private MutableAttributeSet mas;
    private int cp = 0;
    private Highlighter.HighlightPainter cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.cyan);
    private Highlighter.HighlightPainter redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.red);
    private Highlighter.HighlightPainter whitePainter = new DefaultHighlighter.DefaultHighlightPainter(Color.white);
    private int _count = 0;
    private int _lenght = 0;

    public Fonts() {
        jta = new JTextPane();
        doc = jta.getStyledDocument();
        jsp = new JScrollPane(jta);
        jsp.setPreferredSize(new Dimension(height, width));
        frm = new JFrame("awesome");
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setLayout(new BorderLayout());
        frm.add(jsp, BorderLayout.CENTER);
        field = new JTextField();
        field.setText("\u2460, \u2760, \u2380, \u2C60, \u5000, \u03E0");
        frm.add(field, BorderLayout.SOUTH);
        frm.setLocation(100, 100);
        frm.pack();
        frm.setVisible(true);
        jta.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        fnt = ge.getAvailableFontFamilyNames();
        mas = jta.getInputAttributes();
        new Thread(this).start();
    }

    @Override
    public void run() {
        for (int i = 0; i < fnt.length; i++) {
            StyleConstants.setBold(mas, false);
            StyleConstants.setItalic(mas, false);
            StyleConstants.setFontFamily(mas, fnt[i]);
            StyleConstants.setFontSize(mas, 16);
            //dis(fnt[i]);
            dis("\u2460, \u2760, \u2380, \u2C60, \u5000, \u03E0");
            field.setFont(new Font(fnt[i], Font.PLAIN, 14));
            try {
                Thread.sleep(450);
            } catch (Exception e) {
                e.printStackTrace();
            }
            /*StyleConstants.setBold(mas, true);
            dis(fnt[i] + " Bold");
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }
            StyleConstants.setItalic(mas, true);
            dis(fnt[i] + " Bold & Italic");
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }
            StyleConstants.setBold(mas, false);
            dis(fnt[i] + " Italic");
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }*/
        }
        jta.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }

    public void dis(String s) {
        _count++;
        _lenght = jta.getText().length();
        try {
            doc.insertString(cp, s, mas);
            doc.insertString(cp, "\n", mas);
        } catch (Exception bla_bla_bla_bla) {
            bla_bla_bla_bla.printStackTrace();
        }
        if (_count % 2 == 0) {
            try {
                jta.getHighlighter().addHighlight(1, _lenght - 1, cyanPainter);
            } catch (BadLocationException bla_bla_bla_bla) {
            }
        } else if (_count % 3 == 0) {
            try {
                jta.getHighlighter().addHighlight(1, _lenght - 1, redPainter);
            } catch (BadLocationException bla_bla_bla_bla) {
            }
        } else {
            try {
                jta.getHighlighter().addHighlight(1, _lenght - 1, whitePainter);
            } catch (BadLocationException bla_bla_bla_bla) {
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Fonts fs = new Fonts();
            }
        });
    }
}
于 2012-10-15T20:19:22.390 に答える