Search code examples
javajtextfieldchinese-locale

Any JTextField descendant or replacement who covers more Chinese characters?


I'm working on an application, which uses a JTextfield object as a text input component. During some tests I've seen that not all Chinese characters can be shown using this component. At first this seems normal: some Chinese characters are that large that they are not even covered by Unicode, which (in my humble opinion) explains why they can't be copied to clipboard (only as a bitmap, which means that font modifications can't be tested).

However, there also seem to be characters, like the four dragon character (explained in URL Largest Chinese character in Unicode) which can be copied to clipboard, but which seems not to be accepted by the JTextField object.

Hence my question: is there any descendant of JTextField which covers all Chinese characters, or at least the ones present in Unicode? Or is anybody aware of another, more powerful component?

Thanks in advance


Solution

  • With JTextField you would need to specify a font that can support all the characters that you want to use.

    This may be impossible if you want to support a large number of characters. Example, the font MingLiU-ExtB supports some uncommon Chinese characters like 𪚥, but it does not support common Chinese characters like 漢字.

    Fonts like Arial Unicode MS or MingLiU support common characters, but not uncommon ones.

    So, it may be impossible with JTextField.

    But, JTextPane is more flexible, at least when running on Windows. If it needs some characters that are not in the font you have specified, it will add characters from other fallback fonts. (I have no idea what algorithm it uses to select the other fonts. This behavior might be coming from Windows itself, and not from Java: See discussion of Font Fallback here.)

    This code gives a few examples of JTextField and JTextPane with a few fonts.

    public class ChineseFont {
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
          String text = "test 𪚥 test 漢字.";
    
          JTextField textField1 = new JTextField(text);
          textField1.setFont(new Font("Arial Unicode MS", Font.PLAIN, 24));
          JLabel label1 = new JLabel("JTextField " + textField1.getFont().getFontName());
    
          JTextField textField2 = new JTextField(text);
          textField2.setFont(new Font("MingLiU", Font.PLAIN, 24));
          JLabel label2 = new JLabel("JTextField " + textField2.getFont().getFontName());
    
          JTextField textField3 = new JTextField(text);
          textField3.setFont(new Font("MingLiU-ExtB", Font.PLAIN, 24));
          JLabel label3 = new JLabel("JTextField " + textField3.getFont().getFontName());
    
          JTextPane  textPane4 = new JTextPane();
          textPane4.setFont(new Font("Arial Unicode MS", Font.PLAIN, 24));
          textPane4.setText(text);
          JLabel label4 = new JLabel("JTextPane " + textPane4.getFont().getName());
    
          JTextPane  textPane5 = new JTextPane();
          textPane5.setFont(new Font("MingLiU", Font.PLAIN, 24));
          textPane5.setText(text);
          JLabel label5 = new JLabel("JTextPane " + textPane5.getFont().getName());
    
          JFrame frame = new JFrame();
          Container contentPane = frame.getContentPane();
          contentPane.setLayout(new GridLayout(5, 2, 2, 6));
          contentPane.add(label1);
          contentPane.add(textField1);
          contentPane.add(label2);
          contentPane.add(textField2);
          contentPane.add(label3);
          contentPane.add(textField3);
          contentPane.add(label4);
          contentPane.add(textPane4);
          contentPane.add(label5);
          contentPane.add(textPane5);
    
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setVisible(true);
        });
      }
    }
    

    You can also manually specify fonts for each section of your text using AttributedText. See this answer