4

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

Dominique
  • 16,450
  • 15
  • 56
  • 112
  • Could you provide an example of your problem ? Meaning a String that fits and one that doesn't. Also, are you sure you are using the correct encoding ? Provide a [mcve] for us to test this please. – AxelH Dec 01 '16 at 09:07
  • I'd like to add an example of a Chinese sentence which is accepted by the JTextField I'm using, but it seems I can only use images as attachment, the RTF file including the sentence is not accepted (and a simple copy/paste of Chinese characters is not working in this comment window, however I'm sure that lots of Chinese characters are accepted, while only the largest are giving problems (like the one in the hyperlink). – Dominique Dec 01 '16 at 09:41
  • Usually the problem is not with JTextField itself, but with the font you are using. You need to find a font that can display the characters you want. I normally use 'Arial Unicode MS' which can display most Unicode characters, but it cannot display the 'four dragon' character – Enwired Dec 01 '16 at 18:23
  • @Dominique That character does not exist in "Arial Unicode MS" font. "MS Word" program does some extra tricks to display characters that don't exist in the font you have specified as long as there is some other font on your system that can support that character, but Java doesn't do those tricks. This link will show some fonts that support this character: http://www.fileformat.info/info/unicode/char/2a6a5/fontsupport.htm – Enwired Dec 02 '16 at 23:44
  • This is a charset or font issue rather than a GUI control issue. – user207421 Dec 03 '16 at 01:21
  • @EJP you are correct, but different GUI components handle fonts differently. Each `JTextField` can use one single font. Each `JTextPane` can use multiple fonts, and at least on Windows it uses font fallbacks for characters not included in the chosen font. – Enwired Dec 05 '16 at 18:10

2 Answers2

1

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

Community
  • 1
  • 1
Enwired
  • 1,563
  • 1
  • 12
  • 26
0

Like @Enwired said, use a font that supports more characters. Fonts are just pictures that contain all of the characters and info on how to display them. So a font with more characters or a font designed for Chinese characters will work much better. This site works very well for finding fonts. It has many that may suit your needs.

Cody Richardson
  • 157
  • 3
  • 16