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

我有一个为JFreeChart扩展JPanel的类。 在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()); } 

请参阅相关来源以检查事件接线。 添加到JSpinner ChangeListener可能比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 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); } }