在Java中显示繁体中文和简体中文

在Java中显示繁体中文和简体中文,java,unicode,internationalization,Java,Unicode,Internationalization,是否可以在同一个Java应用程序中使用“SansSerif”等逻辑字体同时绘制繁体和简体汉字?我只得到带有CJK代码点的传统品种 在创建字体之前,我已尝试设置Locale.setDefault()和GraphicsEnvironment.preferLocaleFonts()。在启动java.exe时,我尝试在命令行上使用-Duser.language和-Duser.country。还尝试创建设置了AttributedCharacterIterator.Attribute.LANGUAGE的字体

是否可以在同一个Java应用程序中使用“SansSerif”等逻辑字体同时绘制繁体和简体汉字?我只得到带有CJK代码点的传统品种

在创建字体之前,我已尝试设置Locale.setDefault()和GraphicsEnvironment.preferLocaleFonts()。在启动java.exe时,我尝试在命令行上使用-Duser.language和-Duser.country。还尝试创建设置了AttributedCharacterIterator.Attribute.LANGUAGE的字体。没有效果

我没有使用Swing或AWT。只是想画一个屏幕外的缓冲区图像。我在Windows7上,我验证了我安装的字体支持繁体和简体中文(明柳和SimSun)。我还检查了Java的字体配置文件,我看到上面列出了这两种字体


我还应该做什么?

是的,您可以用Java显示简体和繁体中文文本,只要您的字体同时包含两组字符

我写这个简短的程序是为了证明:

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

public class ChineseFonts {

    public static final int GAP = 35;
    public static final int FONTS_PER_LINE = 2;

    public ChineseFonts(String s) {

        Rectangle rect = new Rectangle(0, 0, 1024, 768);
        BufferedImage bufferedImage = new BufferedImage((int) Math.ceil(rect.getWidth()), (int) Math.ceil(rect.getHeight()), BufferedImage.TYPE_4BYTE_ABGR);
        Graphics graphics = bufferedImage.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(rect.x, rect.y, rect.width, rect.height);
        graphics.setColor(Color.BLUE);

        String title = "Chinese Fonts on " + System.getProperty("os.name") + ", version " + System.getProperty("os.version");
        int fontY = 30;
        printString(title, graphics, 0, fontY, new Font(Font.SERIF, Font.BOLD | Font.ITALIC, 28), false);
        fontY += GAP + 10;
        int counter = 0;
        for (String fontName : new String[]{Font.MONOSPACED, Font.SANS_SERIF, Font.SERIF}) {
            Font font = new Font(fontName, Font.PLAIN, 24);
            printString(s, graphics, counter++, fontY, font, true);
            if (counter % FONTS_PER_LINE == 0)
                fontY += GAP;
        }
        Font[] localFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
        List<Font> chineseFonts = new ArrayList<Font>();
        String simplifiedAndTraditionalChinese = "????";
        for (int j = 0; j < localFonts.length; j++) {
            if (localFonts[j].canDisplayUpTo(simplifiedAndTraditionalChinese) == -1) {
                chineseFonts.add(localFonts[j].deriveFont(24F));
            }
        }
        for (Font font : chineseFonts) {
            printString(s, graphics, counter++, fontY, font, true);
            if (counter % FONTS_PER_LINE == 0)
                fontY += GAP;
        }
        graphics.dispose();
        try {
            ImageIO.write(bufferedImage, "png", new File("chineseFonts.png"));
        } catch (Exception e) {
            // ignored
        }
    }

    private void printString(String s, Graphics graphics, int counter, int y, Font font, boolean showFontDetails) {
        graphics.setFont(font);
        if (showFontDetails)
            s = font.getFamily() + " " + s;
        graphics.drawString(s, 20 + (counter % FONTS_PER_LINE) * 510, y);
        if (showFontDetails)
            System.out.println("Printing " + s + " using " + font.getName() + ", which is " + font.getFontName() + " in family " + font.getFamily());
    }

    public static void main(String args[]) {
        new ChineseFonts("S: 漢字 T: 汉字");
    }
}
import java.awt.*;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.util.ArrayList;
导入java.util.List;
导入javax.imageio.imageio;
公共类中文字体{
公共静态最终积分差距=35;
公共静态最终整型字体每行=2;
公共中文字体(字符串s){
矩形rect=新矩形(0,0,1024,768);
buffereImage buffereImage=new buffereImage((int)Math.ceil(rect.getWidth()),(int)Math.ceil(rect.getHeight()),buffereImage.TYPE_4BYTE_ABGR);
Graphics Graphics=buffereImage.getGraphics();
图形.设置颜色(颜色.白色);
图形.fillRect(rect.x,rect.y,rect.width,rect.height);
图形。设置颜色(颜色。蓝色);
String title=“中文字体在”+System.getProperty(“os.name”)+”,version“+System.getProperty(“os.version”);
int-fontY=30;
打印字符串(标题、图形、0、字体、新字体(Font.SERIF、Font.BOLD | Font.ITALIC、28)、假);
fontY+=间隙+10;
int计数器=0;
对于(String fontName:新字符串[]{Font.MONOSPACED,Font.SANS_SERIF,Font.SERIF}){
Font Font=新字体(fontName,Font.PLAIN,24);
打印字符串(s、图形、计数器++、字体、字体、真);
如果(计数器%FONTS\u每行==0)
fontY+=间隙;
}
Font[]localFonts=GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
List chineseFonts=new ArrayList();
字符串SimpledAndTraditionalChinese=“?”;
对于(int j=0;j
使用的2个简体和2个繁体汉字来自维基百科的汉字页面。当您运行它时,所有使用的字体都会打印到标准输出,并输出带有字体名称和汉字的图像

以下是3种逻辑字体和第一种有效的物理字体:

  • 等距
  • 桑塞里夫
  • 衬线
  • Arial Unicode MS S

是否有需要在同一组件上显示繁体和简体中文文本的用例?我想让用户在不重新启动应用程序的情况下动态切换语言。此外,列表中可用语言的名称都是用其本机脚本编写的,因此我希望这些语言也能正确显示。在您的情况下,我建议您设置字体和文本以呈现文本。首先使用一种字体呈现,然后使用另一种字体呈现。是否可行?如果我按物理名称选择字体,它可能会起作用,但我必须提前知道所有支持平台的字体名称。我希望Java能通过它的问题是Java字符串由16位Unicode字符组成,汉字的呈现取决于字体,因为繁体中文和简体中文没有区别。在许多情况下,相同的Unicode代码点在繁体中文和简体中文中有不同的字形()。有一些方法可以存储在OpenType字体中特定于语言的字形,但您必须能够告诉呈现的字体“使用繁体中文字形”",而Java不能这样做。这不是问题所在。问题是是否可以在Java中使用逻辑字体来显示简体和繁体汉字。如果用户不接受代码点的统一字形,而代码点在不同语言中有不同的别名字形,则用户可以将Java的font.properties配置为为他们喜欢的语言选择一种更好的物理字体。有几种很好的免费中文字体可供选择。对科尔姆:我的评论是针对这个答案,而不是问题。特别是“你有一个字体。”