我正在尝试将一些高范围的unicode字符添加到JFrame内部的JLabel中,但它们只显示为框,尽管使用了已知的支持字体。但是,当我将这些相同的字符打印到Eclipse控制台时,它们显示得很好。这是我的代码,“frame”是我的JFrame,“textField1”是我的JLabel。 Monaco字体与Eclipse控制台使用的字体相同,并且知道支持此unicode字符:
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);
我尝试将JLabel设置为许多不同的字体,但所有更改都是“缺少字符”框的相对形状。但是,如果我打印出来:
System.out.println("\uD83C\uDF2D");
字符在控制台中按预期打印。是否存在一些阻止这些符号在Swing中工作的编码问题?
答案 0 :(得分:3)
首先是第一件事。
1)Moncaco字体不支持\uD83C\uDF2D
。
2)您可以在fileformat
检查支持此字符的字体 3)支持的字体似乎适用于此角色,列出的是:LastResport, Symbola and Unifont Upper
。见link
现在你如何用Java支持它?下载font,将其设置为标签并使用它,如下所示。
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);
}
}
答案 1 :(得分:3)
Font.canDisplayUpTo(String)
方法是你的朋友。这是用于创建支持文本的字体组合的方式。
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);
显示此计算机上安装的字体数量,后面是显示文本的字体列表(热狗字符)。
225 font families installed
Segoe UI Emoji
Segoe UI Symbol
这是产生上述输出的源代码,以及显示允许用户在支持给定Unicode字符的所有字体之间进行选择的GUI:
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);
}
}