【问题标题】:How can I update a JFreeChart's appearance after it's been made visible?如何在 JFreeChart 可见后更新它的外观?
【发布时间】:2026-02-14 01:45:01
【问题描述】:

我如何使用JFreeChart 动态更新图表的外观使其可见?

【问题讨论】:

    标签: java swing dynamic jfreechart


    【解决方案1】:

    ChartPanel 类对此很方便,因为它具有控制图表整体外观的方法,包括属性和缩放状态。此外,还可以访问图表的组件,如下所示。这个相关的example 说明了一个JToolBar 的缩放按钮。

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.NumberFormat;
    import javax.swing.AbstractAction;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.DateAxis;
    import org.jfree.chart.axis.NumberAxis;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.time.TimeSeries;
    import org.jfree.data.time.TimeSeriesCollection;
    import org.jfree.data.time.Year;
    import org.jfree.data.xy.XYDataset;
    
    /** @see http://*.com/questions/5522575 */
    public class ChartPanelDemo {
    
        private static final String title = "Return On Investment";
        private ChartPanel chartPanel = createChart();
    
        public ChartPanelDemo() {
            JFrame f = new JFrame(title);
            f.setTitle(title);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLayout(new BorderLayout(0, 5));
            f.add(chartPanel, BorderLayout.CENTER);
            chartPanel.setMouseWheelEnabled(true);
            chartPanel.setHorizontalAxisTrace(true);
            chartPanel.setVerticalAxisTrace(true);
    
            JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            panel.add(createTrace());
            panel.add(createDate());
            panel.add(createZoom());
            f.add(panel, BorderLayout.SOUTH);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        private JComboBox createTrace() {
            final JComboBox trace = new JComboBox();
            final String[] traceCmds = {"Enable Trace", "Disable Trace"};
            trace.setModel(new DefaultComboBoxModel(traceCmds));
            trace.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (traceCmds[0].equals(trace.getSelectedItem())) {
                        chartPanel.setHorizontalAxisTrace(true);
                        chartPanel.setVerticalAxisTrace(true);
                        chartPanel.repaint();
                    } else {
                        chartPanel.setHorizontalAxisTrace(false);
                        chartPanel.setVerticalAxisTrace(false);
                        chartPanel.repaint();
                    }
                }
            });
            return trace;
        }
    
        private JComboBox createDate() {
            final JComboBox date = new JComboBox();
            final String[] dateCmds = {"Horizontal Dates", "Vertical Dates"};
            date.setModel(new DefaultComboBoxModel(dateCmds));
            date.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    JFreeChart chart = chartPanel.getChart();
                    XYPlot plot = (XYPlot) chart.getPlot();
                    DateAxis domain = (DateAxis) plot.getDomainAxis();
                    if (dateCmds[0].equals(date.getSelectedItem())) {
                        domain.setVerticalTickLabels(false);
                    } else {
                        domain.setVerticalTickLabels(true);
                    }
                }
            });
            return date;
        }
    
        private JButton createZoom() {
            final JButton auto = new JButton(new AbstractAction("Auto Zoom") {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    chartPanel.restoreAutoBounds();
                }
            });
            return auto;
        }
    
        private ChartPanel createChart() {
            XYDataset roiData = createDataset();
            JFreeChart chart = ChartFactory.createTimeSeriesChart(
                title, "Date", "Value", roiData, true, true, false);
            XYPlot plot = chart.getXYPlot();
            XYLineAndShapeRenderer renderer =
                (XYLineAndShapeRenderer) plot.getRenderer();
            renderer.setBaseShapesVisible(true);
            NumberFormat currency = NumberFormat.getCurrencyInstance();
            currency.setMaximumFractionDigits(0);
            NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
            rangeAxis.setNumberFormatOverride(currency);
            return new ChartPanel(chart);
        }
    
        private XYDataset createDataset() {
            TimeSeriesCollection tsc = new TimeSeriesCollection();
            tsc.addSeries(createSeries("Projected", 200));
            tsc.addSeries(createSeries("Actual", 100));
            return tsc;
        }
    
        private TimeSeries createSeries(String name, double scale) {
            TimeSeries series = new TimeSeries(name);
            for (int i = 0; i < 6; i++) {
                series.add(new Year(2005 + i), Math.pow(2, i) * scale);
            }
            return series;
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    ChartPanelDemo cpd = new ChartPanelDemo();
                }
            });
        }
    }
    

    【讨论】:

    • 我喜欢你的回报率。您必须让我们知道您的经纪人是谁 :)
    • @camickr: Euler & Ponzi, LLC! :-)
    • 是否有与 ChartPanel 等效的机制在 Web 应用程序中提供交互式图表?
    • @Hicks:我首先想到的是一个 Java Web Start 应用程序,它从同一台服务器获取 JDBC*Dataset
    • 另见org.jfree.chart.editor,提及here