JTextPane/JTextField strange behaviour with rare characters

核能气质少年 提交于 2019-11-29 07:39:56

I had a similar problem when I tried to make an application that would have to support multiple languages (including languages with "non-standard" characters, such as chinese). I used to set the font of my widgets to Arial, and had the problem. The following solution fixed my problem, but it might not fix yours.

Java has a fallback mechanism whenever it encounters characters from specific charsets it can't display. It can be configured using the fontconfig.properties file, which is provided with the JRE (the file is originally provided as "fontconfig.properties.src", you have to manually rename it).

When you force a font that isn't among Dialog, Serif, SansSerif, Monospaced or DialogInput, Java has no way to use a different charset if the current one (in your case Arial) cannot represent the character (or glyph) you are trying to draw on screen.

If you look at the fontconfig.properties.src file, you will see that is has many entries for many types of fonts (e.g. Dialog.plain, Serif.bold, etc). These are the actual fallback fonts to use whenever the fonts above cannot display a specific glyph. So, settings your widgets' font to let's say Font.DIALOG will allow Java to try a list of fonts to display your characters.

More information is available on Oracle's website (here for Java 7). Note that the use of fontconfig.properties isn't officially supported by Oracle.

no deepest idea whats happened, and not why, but have to set

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

simple simulations Fonts and 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();
            }
        });
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!