Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
753 views
in Technique[技术] by (71.8m points)

java - Update normal distribution graph using JTextField in JFreeChart

I have a class that extends JPanel for JFreeChart. Inside of setMean(), I tried updating values of dataset or just the Function2D, but nothing changes on the graph even with 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);
        }
}

And this is executed everytime I change the value in my 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");
        }
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Ordinarily, you could simply update the XYDataset used to create the JFreeChart, and the listening chart would update itself in response. As @Hovercraft notes, repaint() alone is not sufficient to tell the chart's plot that you have replaced the dataset. In the example below, I've refactored the dataset's initialization and passed it to setDataset() as a parameter.

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

See the relevant source to examine the event wiring. A ChangeListener added to a JSpinner may be easier to operate than a JTextField.

image

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 https://stackoverflow.com/a/40167139/230513
 */
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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...