如何设置“备份"?字形 [英] How to set a "backup" font

查看:71
本文介绍了如何设置“备份"?字形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java 10,并进行摇摆.我使用的是DejaVu Sans Mono字体,因为我认为它看起来不错.但是,它对CJK字符的支持非常差,因此为了最大化支持,我想到了使用Noto Sans CJK作为备份.尽管我也可以将Noto Sans用于拉丁字符,但我不太喜欢它们的拉丁字符.

尽管这似乎是一个琐碎的问题,但我似乎找不到解决方法.即使您无法回答,我也感谢指针.

TL; DR:

我的问题

我无法使用DejaVu Sans Mono显示中文,日文或韩文字符

我的解决方案

使用Noto Sans CJK

我的解决方案出现的问题

诺托·桑斯(Noto Sans)的拉丁语很丑陋,并且不支持阿拉伯语

我的问题

我如何告诉JComponent,如果它无法在Font One(DejaVu)中找到字符,则应该改用Font 2(Noto)?

解决方案

一种方法是检查字体在制作组件(和设置文本)时显示相关字符的能力.

这可以使用

  import java.awt.*;导入javax.swing.*;导入javax.swing.border.EmptyBorder;导入java.util.*;公共类FallbackFont {私有JComponent ui = null;私有最终String [] fontFamilies = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();String [] examplesTexts = {快速的棕色狐狸跳过了那只懒狗.",//英文"\ u6253 \ u5370 \ u8FC7 \ u671F \ u8BC1 \ u4E66 \ u8BB0 \ u5F55",//中文"\ u0627 \ u0644 \ u0633 \ u0644 \ u0627 \ u0645"+"\ u0639 \ u0644 \ u064A \ u0643 \ u0645",//阿拉伯语新的String(Character.toChars(128176))};String [] preferredFonts = {"DejaVu Sans Mono","Microsoft JhengHei","Noto Sans CJK TC Black",//在这里有奇怪的显示问题..};FallbackFont(){initUI();}私有HashMap getCompatibleFonts(String text){HashMap cF =新的HashMap<>();对于(String font:fontFamilies){字体f =新字体(font,Font.PLAIN,1);如果(f.canDisplayUpTo(text)< 0){cF.put(font,f);}}返回cF;}私有字体getPreferredFontForText(String text){HashMapcompatibleFonts = getCompatibleFonts(文本);对于(String preferredFont:preferredFonts){字体=(Font)compatibleFonts.get(preferredFont);if(font!= null){返回字体;}}设置keySet = compatibleFonts.keySet();字符串firstCompatibleFont =(String)keySet.iterator().next();返回(字体)compatibleFonts.get(firstCompatibleFont);}public final void initUI(){如果(ui!= null){返回;}ui = new JPanel(new GridLayout(0,2,4,4));ui.setBorder(newEmptyBorder(4,4,4,4));对于(String text:examplesTexts){字体= getPreferredFontForText(text);JButton b =新的JButton(text);b.setFont(font.deriveFont(b.getFont().getSize2D()));ui.add(b);ui.add(new JLabel(font.getName()));}}公共JComponent getUI(){返回ui;}公共静态void main(String [] args){可运行r =()->{FallbackFont o =新的FallbackFont();JFrame f =新的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);}} 

I'm using Java 10, and swing. I'm using the DejaVu Sans Mono font, because I think it looks nice. However, it has very poor support of CJK characters, so to maximize support, I thought of using Noto Sans CJK as a backup. Although I could use Noto Sans for Latin characters too, I don't quite like their Latin characters too much.

Although this seems like a trivial question, I can't seem to find out how to do it. Even if you can't answer, I appreciate pointers.

TL;DR:

My Problem

I can't display Chinese, Japanese or Korean characters with DejaVu Sans Mono

My Solution

Use Noto Sans CJK

The Problem with my solution

Noto Sans is ugly with Latin, and doesn't support Arabic

My Question

How do I tell a JComponent that if it can't find a character in Font One (DejaVu), it should use Font Two (Noto) instead?

解决方案

One way is to check the font for the ability to display the relevant characters when making the components (and setting the text).

This can be achieved using methods like Font.canDisplayUpTo(String).

E.G.

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

public class FallbackFont {

    private JComponent ui = null;
    private final String[] fontFamilies = GraphicsEnvironment.
            getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
    String[] examplesTexts = {
        "The quick brown fox jumps over the lazy dog.", // English
        "\u6253\u5370\u8FC7\u671F\u8BC1\u4E66\u8BB0\u5F55", // Chinese
        "\u0627\u0644\u0633\u0644\u0627\u0645 "
        + "\u0639\u0644\u064A\u0643\u0645", // Arabic
        new String(Character.toChars(128176))
    };
    String[] preferredFonts = {
        "DejaVu Sans Mono",
        "Microsoft JhengHei",
        "Noto Sans CJK TC Black", // has strange display problem here .. 
    };

    FallbackFont() {
        initUI();
    }

    private HashMap getCompatibleFonts(String text) {
        HashMap cF = new HashMap<>();
        for (String font : fontFamilies) {
            Font f = new Font(font, Font.PLAIN, 1);
            if (f.canDisplayUpTo(text) < 0) {
                cF.put(font, f);
            }
        }
        return cF;
    }

    private Font getPreferredFontForText(String text) {
        HashMap compatibleFonts = getCompatibleFonts(text);
        for (String preferredFont : preferredFonts) {
            Font font = (Font) compatibleFonts.get(preferredFont);
            if (font != null) {
                return font;
            }
        }
        Set keySet = compatibleFonts.keySet();
        String firstCompatibleFont = (String) keySet.iterator().next();
        return (Font) compatibleFonts.get(firstCompatibleFont);
    }

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

        ui = new JPanel(new GridLayout(0, 2, 4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));
        for (String text : examplesTexts) {
            Font font = getPreferredFontForText(text);
            JButton b = new JButton(text);
            b.setFont(font.deriveFont(b.getFont().getSize2D()));
            ui.add(b);
            ui.add(new JLabel(font.getName()));
        }
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            FallbackFont o = new FallbackFont();

            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);
    }
}

这篇关于如何设置“备份"?字形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆