使用JFree Chart3D绘制饼状图中文乱码问题

19 阅读2分钟

最近想用swing写一个简单的桌面端程序,其中仪表盘需要用到饼状图,于是参考JFree的官方示例代码自己整了一个(其实就是cv大法),最终代码如下:

@ItemView(value = "仪表盘", order = 101, category = GroupConstants.DASHBOARD, description = "仪表盘")
@Component
@Lazy
public class DashboardView extends AbstractMigView {
    @Override
    protected MigLayout defineMigLayout() {
        return new MigLayout("wrap 1", "[grow]", "[grow]");
    }
    @Override
    protected void render() {
        Base3DPanel content = new Base3DPanel(new BorderLayout());
        PieDataset3D<String> dataset = createDataset();
        final Chart3D chart = createChart(dataset);
        Chart3DPanel chartPanel = new Chart3DPanel(chart);
        chartPanel.setMargin(0.15);
        content.setChartPanel(chartPanel);
        content.add(new DisplayPanel3D(chartPanel));
        JButton button = new JButton("Change the Data");
        button.addActionListener(e -> {
            PieDataset3D<String> dataset1 = createDataset();
            PiePlot3D plot = (PiePlot3D) chart.getPlot();
            plot.setDataset(dataset1);
        });
        content.add(button, BorderLayout.SOUTH);
        view.add(content, "grow");
    }
    private static PieDataset3D<String> createDataset() {
        StandardPieDataset3D<String> dataset = new StandardPieDataset3D<>();
        dataset.add("United States", Math.random() * 30);
        dataset.add("France", Math.random() * 20);
        dataset.add("New Zealand", Math.random() * 12);
        dataset.add("United Kingdom", Math.random() * 43);
        dataset.add("Australia", Math.random() * 43);
        dataset.add("Canada", Math.random() * 43);
        return dataset;
    }
    private static Chart3D createChart(PieDataset3D<String> dataset) {
        final Chart3D chart = Chart3DFactory.createPieChart("Orson Charts 3D",
                "For more info see: https://github.com/jfree/orson-charts/",
                dataset);
        chart.setTitleAnchor(TitleAnchor.TOP_LEFT);
        PiePlot3D plot = (PiePlot3D) chart.getPlot();
        plot.setLegendLabelGenerator(new StandardPieLabelGenerator(StandardPieLabelGenerator.PERCENT_TEMPLATE));
        plot.setSectionLabelGenerator(new StandardPieLabelGenerator(StandardPieLabelGenerator.PERCENT_TEMPLATE));
        plot.setSectionColors(Colors.createFancyLightColors());
        return chart;
    }
}

运行效果: image.png 看起来还是肥肠补错的哈,但随之而来我就发现一个严重的问题,这不是一个普通的饼状图,用一般的手段没法让它渲染中文,不管我咋折腾运行出来都是乱码。在用AI辅佐建了好几个工具类,自定义了好几个panel后,最终还是以无可奈何告终。无奈只能自己翻翻源码看看能不能找到出路了,于是我点开这个饼状图的实现一顿检索,终于在我一通王八拳后还是让我找到了一点蛛丝马迹,在Chart3D中提供了一个方法setStyle方法,这个方法需要一个ChartStyle参数,刚好在这个ChartStyle中就定义了一众设置各个地方字体的方法,那就试试吧,于是将上述createChart方法修改成这样:

private static Chart3D createChart(PieDataset3D<String> dataset) {
    // 宋体
    Font simSun = new Font("SimSun", 10, 12);
    final Chart3D chart = Chart3DFactory.createPieChart(
            "系统资源使用情况(实时监控)",
            "数据更新时间: " + java.time.LocalTime.now().format(java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss")),
            dataset
    );
    StandardChartStyle standardChartStyle = new StandardChartStyle();
    standardChartStyle.setTitleFont(simSun);
    standardChartStyle.setSubtitleFont(simSun);
    standardChartStyle.setSectionLabelFont(simSun);
    standardChartStyle.setAxisLabelFont(simSun);
    standardChartStyle.setAxisTickLabelFont(simSun);
    standardChartStyle.setLegendHeaderFont(simSun);
    standardChartStyle.setLegendItemFont(simSun);
    standardChartStyle.setLegendFooterFont(simSun);
    standardChartStyle.setMarkerLabelFont(simSun);
    chart.setStyle(standardChartStyle);
    chart.setTitleAnchor(TitleAnchor.TOP_LEFT);
    PiePlot3D plot = (PiePlot3D) chart.getPlot();
    plot.setLegendLabelGenerator(new StandardPieLabelGenerator(StandardPieLabelGenerator.PERCENT_TEMPLATE));
    plot.setSectionLabelGenerator(new StandardPieLabelGenerator(StandardPieLabelGenerator.PERCENT_TEMPLATE));
    plot.setSectionColors(Colors.createFancyLightColors());
    return chart;
}

最终运行效果如下: image.png 完美解决,撒花ヾ(≧▽≦*)o