在 JFreeChart 中使用 JTextField 更新正态分布图

Update normal distribution graph using JTextField in JFreeChart

我有一个 class 扩展 JPanelJFreeChart。在 setMean() 中,我尝试更新 dataset 的值或仅更新 Function2D 的值,但即使使用 repaint().

,图表上也没有任何变化
    public class JFreeChartPanel extends JPanel {
        Function2D normal = new NormalDistributionFunction2D(0.0, 3.0);
        XYDataset dataset = DatasetUtilities.sampleFunction2D(normal, -5.0, 5.0, 100, "Normal");

        double mean = 0.0, std = 1.0;

        public double getMean() {
            return mean;
        }

        public void setMean(double mean) {
            this.mean = mean;
            normal = new NormalDistributionFunction2D(mean,std);
            dataset = DatasetUtilities.sampleFunction2D(normal, -5.0, 5.0, 100, "Normal");
            repaint();
        }

        public double getStd() {
            return std;
        }

        public void setStd(double std) {
            this.std = std;
        }

        public JFreeChartPanel(){        

            JFreeChart chart = ChartFactory.createXYLineChart(
                "Normal Distribution",
                "X", 
                "Y", 
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false
            );


            final ChartPanel chartPanel = new ChartPanel(chart);
            setLayout(new BorderLayout());
            add(chartPanel);
        }
}

每次我更改 JTextField 中的值时都会执行此操作。

public void updateMean()
    {
        String meanS = mean.getText();
        double mean = 0.0;
        try{
            mean = Double.parseDouble(meanS);
            System.out.println("Mean: "+mean);
            jFreeChartPanel.setMean(mean);
        }catch(Exception e){
            System.out.println("Mean: incorrect input");
        }
    }

通常,您可以简单地更新用于创建 JFreeChartXYDataset,收听图表会自行更新作为响应。由于@Hovercraft ,仅 repaint() 不足以告诉图表您已 替换了 数据集。在下面的示例中,我重构了数据集的初始化并将其作为参数传递给 setDataset()

public void setMean(double mean) {
    this.mean = mean;
    plot.setDataset(initDataset());
}

查看相关内容 source 以检查事件接线。一个ChangeListener加上一个JSpinner可能比一个JTextField更容易操作。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.event.ChangeEvent;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.function.Function2D;
import org.jfree.data.function.NormalDistributionFunction2D;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;

/**
 * @see 
 */
public class TestDistribution {

    private static class JFreeChartPanel extends JPanel {

        private XYPlot plot;
        private double mean = 0.0, sigma = 1.0;
        XYDataset dataset = initDataset();

        private XYDataset initDataset() {
            Function2D normal = new NormalDistributionFunction2D(mean, sigma);
            XYDataset dataset = DatasetUtilities.sampleFunction2D(normal, -5.0, 5.0, 100, "Normal");
            return dataset;
        }

        ;
        public double getMean() {
            return mean;
        }

        public void setMean(double mean) {
            this.mean = mean;
            plot.setDataset(initDataset());
        }

        public double getStd() {
            return sigma;
        }

        public void setStd(double sigma) {
            this.sigma = sigma;
        }

        public JFreeChartPanel() {
            JFreeChart chart = ChartFactory.createXYLineChart(
                "Normal Distribution", "X", "Y", dataset,
                PlotOrientation.VERTICAL, true, true, false
            );
            plot = chart.getXYPlot();
            final ChartPanel chartPanel = new ChartPanel(chart);
            add(chartPanel);
        }
    }

    private void display() {
        JFrame f = new JFrame("TestDistribution");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JFreeChartPanel chartPanel = new JFreeChartPanel();
        f.add(chartPanel);
        JSpinner spinner = new JSpinner();
        spinner.setValue(chartPanel.mean);
        spinner.addChangeListener((ChangeEvent e) -> {
            JSpinner s = (JSpinner) e.getSource();
            Number n = (Number) s.getValue();
            chartPanel.setMean(n.doubleValue());
        });
        f.add(spinner, BorderLayout.PAGE_END);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new TestDistribution()::display);
    }
}