我正在开发一个使用 JFreeChart 来呈现图表的 Web 应用程序。但是,当服务器没有安装任何中文字体时,即使我设置了字体,JFreeChart也不会显示中文字符。
然后我写了一个小测试代码,发现在绘制图表之前添加这行代码可以解决问题。
GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
所以我的问题是 -
-
即使我从文件创建字体,为什么也必须将字体注册到 JVM 中?这是否意味着 JFreeChart 不使用我直接设置的字体?
-
当我将程序部署到服务器时,即使我添加这行代码,它也不会显示汉字。如何让它始终使用我设置的字体,以便在所有环境下都能正确显示字符?
我知道我可以做一个fallback
目录在$JAVA_HOME/jre/lib
并将我的字体放入其中。但这并不能解释为什么 JFreeChart 无法以我设置的字体显示。
UPDATE
我很确定字体已正确加载,也是如此registerFont()
当我将程序部署到 Tomcat 中时返回 true。
UPDATE 2
根据JAVA 2D 常见问题解答,现在我意识到我必须打电话registerFont()
为了使我自己的字体“安装”到 JVM 中,并且我的字体将通过Font
构造函数。
从 Java SE 6 开始,有一种方法:
GraphicsEnvironment.registerFont() 使您能够
可供字体构造函数使用的“创建”字体,并通过以下方式列出
字体枚举 API。 Font.createFont() 和此方法结合起来
提供一种将字体“安装”到正在运行的 JRE 中的方法,因此它是
就像操作系统安装的字体一样可用。然而这个字体不
在 JRE 调用中保持不变。
但是,既然我已经有了Font
创建/派生自的实例createFont()
,为什么我的程序不需要创建其他的Font
?
以下是我使用的代码,它只是输出 PNG 格式的图表。如果您想运行代码,您应该更改输出位置和字体以满足您的需要,并且这是 SourceForge 链接对于我在代码中使用的中文字体。
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.io.File;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
public class Problem {
public static void main(String[] args) throws Exception {
setJFreeChartTheme();
PieDataset dataset = createDataSet();
JFreeChart chart = ChartFactory.createPieChart(
"Chinese Testing", dataset, true, true, false);
ChartUtilities.saveChartAsJPEG(new File("/tmp/output.png"),
chart, 800, 600);
System.out.println("Done");
}
private static void setJFreeChartTheme() throws Exception {
Font font = loadFont();
//==================================================================
GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
//==================================================================
StandardChartTheme theme = new StandardChartTheme("Chinese font", true);
theme.setExtraLargeFont(font.deriveFont(Font.BOLD, 20));
theme.setLargeFont(font.deriveFont(Font.BOLD, 16));
theme.setRegularFont(font.deriveFont(Font.PLAIN, 14));
theme.setSmallFont(font.deriveFont(Font.PLAIN, 12));
ChartFactory.setChartTheme(theme);
}
private static Font loadFont() throws Exception {
File file = new File("/tmp/wqy-zenhei.ttc");
return Font.createFont(Font.TRUETYPE_FONT, file);
}
private static PieDataset createDataSet() {
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("種類1", Integer.valueOf(1));
dataset.setValue("種類2", Integer.valueOf(2));
dataset.setValue("種類3", Integer.valueOf(3));
return dataset;
}
}