Reputation: 119
I have got a JFrame, within this frame there is a JPanel, in a JPanel there is a JFreeChart (chart takes dataset from a method) and this chart is added to ChartPanel created in JPanel, then ChartPanel is added to JPanel. Also I have got JComboBox in JPanel, if I change option in that JComboBox an ActionListener updates value of dataset. Also method which return dataset, takes a string from JComboBox(data of dataset depends on JComboBox output). So if I change option in JComboBox I would want to update JFreeChart with new dataset and display it on screen. I know that I need to add code in that ActionListener but I don't what I should add there, is there any method which updates already created JFreeChart?
private class PanelChart extends JPanel { {
this.setLayout(new BorderLayout());
// Create Dataset
//method GUIImplementation.GetDataForChart takes as an input value of combobox
CategoryDataset dataset = GUIImplementation.GetDataForChart(comboBoxCrimeTypeChart.getSelectedItem().toString());
//Create chart
JFreeChart crimeNumberBarChart = ChartFactory.createBarChart(
"Number of crimes by type", //Chart Title
"Fallen within", // Category axis
"Number of crimes", // Value axis
dataset,
PlotOrientation.VERTICAL,
true,true,false
);
ChartPanel panelCrimeNumberBarChart = new ChartPanel(crimeNumberBarChart);
this.add(panelCrimeNumberBarChart, BorderLayout.CENTER);
PanelChartSouth panelChartSouth = new PanelChartSouth(); //there is a combobox
this.add(panelChartSouth, BorderLayout.SOUTH);
}}
private class ChartButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == backChart) {
SizeAndTitleSetter(0);
SwapPanelChart(0);
} else if(e.getSource() == comboBoxCrimeTypeChart) { //comboBoxCrimeTypeChart is a JComboBox from PanelChartSouth
String crimeType = comboBoxCrimeTypeChart.getSelectedItem().toString();
System.out.println(crimeType);
dataset = GUIImplementation.GetDataForChart(crimeType); // dataset updated
}
}
}
So far I only managed to update somehow that chart by removing PanelChart from JFrame then create new PanelChart and add it to JFrame and use repaint and revalidate. It worked if I changed option in JComboBox once, after second change everything started to brake on screen, old chart didn't want to dissapear and new chart was under it and I could see it if I resized screen.
Upvotes: 1
Views: 2187
Reputation: 205785
You can update an existing chart's dataset, as shown in these examples; when you update the model (dataset), the listening plot (view) will update itself accordingly; concrete implementations of CategoryDataset
typically provide suitable mutators.
DefaultCategoryDataset model = …
…
@Override
public void actionPerformed(ActionEvent e) {
model.setValue(…);
}
You can replace an existing chart's dataset using the relevant plot's setDataset()
method.
CategoryPlot plot = (CategoryPlot) chart.getPlot();
…
@Override
public void actionPerformed(ActionEvent e) {
plot.setDataset(…);
}
While it's technically possible to replace the enclosing view component, as suggested here, it's generally better to update or replace the model, as suggested here.
Upvotes: 2
Reputation: 119
I found out an answer its working but there is a small problem with it. So my ActionListener looks like that now:
private class ChartButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == backChart) {
SizeAndTitleSetter(0);
SwapPanelChart(0);
} else if(e.getSource() == comboBoxCrimeTypeChart) {
SwingUtilities.invokeLater(() -> {
frame.remove(panelChart);
panelChart = new PanelChart();
frame.add(panelChart);
frame.pack();
frame.invalidate();
frame.revalidate();
frame.repaint();
});
}
}
}
After I have added SwingUtilities.invokeLater it started to work well, but now problem is that program slows down after changing JComboBox option few times. Computer's fans are going crazy, now I don't know if this is a problem with this part of code or I made an error somewhere. When I go back to main menu of my program and use other components its work same as before.
I found out why it started to be laggy, in a class PanelChartSouth I was adding actionListener to JComboBox, and after every removing and creating new PanelChart next actionListener was added to JComboBox. So prevent it I have put operation of adding action listeners to if statement
if(ifActionListenerSet == false) {
ifActionListenerSet = true;
ChartButtonListener chartButtonListener = new ChartButtonListener();
backChart.addActionListener(chartButtonListener);
comboBoxCrimeTypeChart.addActionListener(chartButtonListener);
}
Now everything is fine.
Upvotes: 1