简体   繁体   中英

Unicode special characters appearing in Java console, but not in Swing

I'm attempting to add some high-range unicode characters to a JLabel inside of a JFrame, but they only show up as boxes despite using a known supported font. However, when I print these same characters to the Eclipse console, they show up just fine. Here is my code, with "frame" being my JFrame and "textField1" being my JLabel. The Monaco font is the same font that the Eclipse console uses, and is know to support this unicode character:

JFrame frame = new JFrame();
JLabel textField1 = new JLabel();
frame.add(textField1);
frame.setFocusable(true);
frame.setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
frame.setPreferredSize(new Dimension(1000, 500));
frame.requestFocusInWindow();
frame.textField1.setFont(new Font("Monaco", Font.PLAIN, 11 ));
frame.textField1.setText("\uD83C\uDF2D"); 
frame.pack();
frame.setVisible(true);

I've tried setting the JLabel to many different fonts, but all that changes is the relative shape of the "missing character" box. However, if I print this:

System.out.println("\uD83C\uDF2D");

the character prints as expected in the console. Is there some encoding issue that prevents these symbols from working in Swing?

First thing first.

1) \?\? is not supported on Moncaco font.

2) You can check font that supports this character at fileformat

3) Supported font that seems to work for this character, listed there are: LastResport, Symbola and Unifont Upper . See link

Now how do you support it in Java? Download the font , set it to label and use it as shown below.

import java.awt.Dimension;
import java.awt.Font;
import java.io.File;
import java.net.URI;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

public class FrameMain1 {

    public static void main(String[] args) throws Exception {

        File fontFile = new File(new URI("file:///D:/tmp/Symbola.ttf"));
        Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
        font = font.deriveFont(Font.PLAIN, 24f);
        JFrame frame = new JFrame();
        JLabel label1 = new JLabel("\uD83C\uDF2D");
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
        frame.add(label1);
        frame.setFocusable(true);
        //frame.setPreferredSize(new Dimension(1000, 500));
        frame.requestFocusInWindow();
        label1.setFont(font);
        frame.add(label1);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

}

看图片

The Font.canDisplayUpTo(String) method is your friend here. This is how it might be used to create a combo of the fonts that support the text.

        String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().
                getAvailableFontFamilyNames();
        System.out.println(fonts.length + " font families installed");
        Vector<String> supportedFonts = new Vector<>();
        for (String fontName : fonts) {
            Font f = new Font(fontName, Font.PLAIN, 1);
            if (f.canDisplayUpTo(text)<0) {
                System.out.println(fontName);
                supportedFonts.add(fontName);
            }
        }
        fontComboBox = new JComboBox(supportedFonts);

This shows the number of fonts installed on this computer, followed by a listing of the fonts that will display the text (character for a hot-dog).

225 font families installed
Segoe UI Emoji
Segoe UI Symbol

This is the source code that produces the above output, as well as displaying a GUI that allows the user to choose between all the fonts that support the given Unicode character(s):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.Vector;

public class FontCheck {

    private JComponent ui = null;

    private final String text = "\uD83C\uDF2D"; 
    private JComboBox fontComboBox;
    private JTextField outputField = new JTextField(text, 5);

    FontCheck() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout(4,4));
        ui.setBorder(new EmptyBorder(4,4,4,4));

        ui.add(outputField);
        ui.add(getToolBar(), BorderLayout.PAGE_START);

        refreshFont();
    }

    private JToolBar getToolBar() {
        JToolBar tb = new JToolBar();
        tb.setLayout(new FlowLayout());

        String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().
                getAvailableFontFamilyNames();
        System.out.println(fonts.length + " font families installed");
        Vector<String> supportedFonts = new Vector<>();
        for (String fontName : fonts) {
            Font f = new Font(fontName, Font.PLAIN, 1);
            if (f.canDisplayUpTo(text)<0) {
                System.out.println(fontName);
                supportedFonts.add(fontName);
            }
        }
        fontComboBox = new JComboBox(supportedFonts);
        ActionListener refreshListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                refreshFont();
            }
        };
        fontComboBox.addActionListener(refreshListener);

        tb.add(fontComboBox);
        return tb;
    }

    private void refreshFont() {
        String fontName = fontComboBox.getSelectedItem().toString();
        Font f = new Font(fontName, Font.PLAIN, 60);
        outputField.setFont(f);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                FontCheck o = new FontCheck();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM