java - 我们如何激励 Java 和 Swing 显示来自例如 Comic Sans MS 的所有字形/字符?
问题描述
在每个 Windows 应用程序中,使用和显示任何字体的任何字符都很容易。
例如:在记事本中显示“አማርኛ”并使用 Comic Sans MS:
- 打开记事本
- 更改字体: 格式 » 字体 » Comic Sans MS
- 粘贴文本:አማርኛ
显示“不寻常”字符非常有效——即使在这种网络公式中!
在 Java 和 Swing 中,这是一场噩梦,这只是显示:▯▯▯▯
旁注:
- 我使用 IntelliJ
- 源码文件使用utf8,完美显示测试字符串'አማርኛ'
代码示例:
Font ComicPln32 = new Font("Comic Sans MS", Font.PLAIN, 32);
Font ComicBld32 = new Font(ComicPln32.getName(), Font.BOLD, ComicPln32.getSize());
Border lineBorder = BorderFactory.createLineBorder(new Color(222, 49, 99), 2, true);
Border titleBorder = BorderFactory.createTitledBorder(lineBorder, "አማርኛ",
TitledBorder.LEFT, TitledBorder.TOP, BoldFont, Color.BLUE);
setBorder(titleBorder);
有没有简单的方法可以激励 Java 完成它的工作?
解决方案
在 Java 中加载的显示字符的能力Font
取决于字体本身。在其他软件(尤其是浏览器)中使用了很多技巧来“填充”不支持特定字形的字体,而另一种字体则支持。
但是针对这个具体问题。
[剧透警告:Comic Sans不支持这些角色。]
大多数(包括Comic Sans )都支持字符“abc” ,但不是该系统上的所有字体。
TestFonts
这是在该系统上产生上述输出的代码,使用Font.canDisplayUpTo(..)
. YMMV。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
public class TestFonts {
JList<String> fontFamilyList;
private JPanel gui;
private String[] allFonts;
TestFonts() {
allFonts = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
}
private void updateList(String characters) {
String s = characters;
ListSelectionModel listSelectionModel = fontFamilyList.getSelectionModel();
listSelectionModel.clearSelection();
ListModel listModel = fontFamilyList.getModel();
for (int ii = 0; ii < listModel.getSize(); ii++) {
String fontFamily = listModel.getElementAt(ii).toString();
Font font = new Font(fontFamily, Font.PLAIN, 10);
if (font.canDisplayUpTo(s) < 0) {
listSelectionModel.addSelectionInterval(ii, ii);
}
}
}
public static void main(String[] args) {
Runnable r = () -> {
final JFrame frame = new JFrame("Test Fonts");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
TestFonts tf = new TestFonts();
frame.setContentPane(tf.getGUI());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setLocationByPlatform(true);
frame.setMinimumSize(frame.getSize());
frame.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
public JPanel getGUI() {
if (gui != null) return gui;
gui = new JPanel(new BorderLayout(5, 5));
gui.setBorder(new EmptyBorder(new Insets(4, 4, 4, 4)));
//DefaultListModel allFontModel = new DefaultListModel(allFonts);
fontFamilyList = new JList(allFonts);
fontFamilyList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
fontFamilyList.setVisibleRowCount(40);
gui.add(new JScrollPane(fontFamilyList), BorderLayout.LINE_START);
final JTextField inputField = new JTextField(20);
gui.add(inputField, BorderLayout.PAGE_START);
DocumentListener documentListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updateList(inputField.getText());
}
@Override
public void removeUpdate(DocumentEvent e) {
updateList(inputField.getText());
}
@Override
public void changedUpdate(DocumentEvent e) {
updateList(inputField.getText());
}
};
inputField.getDocument().addDocumentListener(documentListener);
return gui;
}
}
推荐阅读
- c# - 如何在 Asp.Net Core API 启动时将数据加载到 InMemory 数据库中?
- aws-iot - 如何在 AWS IoT greengrass 本地使用 AWS IoT 规则引擎?
- javascript - require('electron') 返回什么?
- perl - 在“perl -n”单线中的下一个文件上重置状态变量
- python - 为什么每次我在 python 中运行代码时我的 PCA 都会发生变化?
- express - 我应该在生产中使用代理中间件吗?
- javascript - WordPress Ajax Uncaught ReferenceError: url is not defined
- azure-devops - 仅在 ARM 模板部署后才知道 ConnectionString 时如何生成 EF Core 迁移脚本?
- javascript - 重要的 npm install @babel/plugin-transform-react-jsx 不起作用
- ansible - 如何将我的文件的包含与ansible进行比较?