'How to update chart after selecting item from JComboBox?

I'm trying to change the values of bar chart depending on the selected item from the combobox list. The code below is a short example. The method for creating/updating the chart works well with button MouseListener or ActionPerformed, but it does not instantly change when I select an item from the combobox list.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
 
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.category.DefaultCategoryDataset;
 
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
 
public class MainTest extends JFrame {
     
    private JPanel contentPane;
    private JPanel panel;
    private JComboBox<String> comboBox;
    private static JPanel chartMainPanel;
     
    static String selectedItem = "Select";
     
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainTest frame = new MainTest();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
     
    public MainTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 474, 409);
        contentPane = new JPanel();
        contentPane.setBackground(Color.WHITE);
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
         
        panel = new JPanel();
        panel.setBounds(0, 0, 458, 370);
        contentPane.add(panel);
        panel.setLayout(null);
         
        comboBox = new JComboBox<String>();
        comboBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (!comboBox.getSelectedItem().equals("Select")) {
                    selectedItem = comboBox.getSelectedItem().toString();
                }
                else {
                    selectedItem = "Select";
                }
                chart();
            }
        });
        comboBox.setFocusable(false);
        comboBox.setModel(new DefaultComboBoxModel<String>(new String[] {"Select", "First", "Second", "Third"}));
        comboBox.setBounds(10, 11, 146, 28);
        panel.add(comboBox);
         
        chartMainPanel = new JPanel();
        chartMainPanel.setBounds(10, 105, 438, 176);
        panel.add(chartMainPanel);
        chartMainPanel.setLayout(new BorderLayout(0, 0));
         
        JButton btnNewButton = new JButton("Refresh");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                chart();
            }
        });
        btnNewButton.setBounds(166, 11, 103, 28);
        panel.add(btnNewButton);
         
        chart();
    }
    public static void chart() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        int a1 = 0;
        int a2 = 0;
        int a3 = 0;
         
        int b1 = 0;
        int b2 = 0;
        int b3 = 0;
         
        int c1 = 0;
        int c2 = 0;
        int c3 = 0;
         
        if (selectedItem.equals("First")) {
            a1 = 1;
            a2 = 1;
            a3 = 1;
             
            b1 = 1;
            b2 = 1;
            b3 = 1;
             
            c1 = 1;
            c2 = 1;
            c3 = 1;
        }
        else if (selectedItem.equals("Second")) {
            a1 = 2;
            a2 = 2;
            a3 = 2;
             
            b1 = 2;
            b2 = 2;
            b3 = 2;
             
            c1 = 2;
            c2 = 2;
            c3 = 2;
        }
        else if (selectedItem.equals("Third")) {
            a1 = 3;
            a2 = 3;
            a3 = 3;
             
            b1 = 3;
            b2 = 3;
            b3 = 3;
             
            c1 = 3;
            c2 = 3;
            c3 = 3;
        }
        else {
            a1 = 0;
            a2 = 0;
            a3 = 0;
             
            b1 = 0;
            b2 = 0;
            b3 = 0;
             
            c1 = 0;
            c2 = 0;
            c3 = 0;
        }
         
        dataset.setValue(a1, "part 1", "Q1");
        dataset.setValue(a2, "part 1", "Q2");
        dataset.setValue(a3, "part 1", "Q3");
         
        dataset.setValue(b1, "part 2", "Q1");
        dataset.setValue(b2, "part 2", "Q2");
        dataset.setValue(b3, "part 2", "Q3");
         
        dataset.setValue(c1, "part 3", "Q1");
        dataset.setValue(c2, "part 3", "Q2");
        dataset.setValue(c3, "part 3", "Q3");
         
        Font font = new Font("Tahoma", Font.PLAIN, 12);
        Font font2 = new Font("Tahoma", Font.PLAIN, 13);
         
        JFreeChart chart = ChartFactory.createBarChart("", "", "Rating", dataset, PlotOrientation.VERTICAL, false, false, false);
        CategoryPlot categoryPlot = chart.getCategoryPlot();
        categoryPlot.setBackgroundPaint(Color.WHITE);
        categoryPlot.setRangeGridlinePaint(Color.GRAY);
        categoryPlot.setOutlinePaint(Color.WHITE);
         
        categoryPlot.getDomainAxis().setLabelFont(font);
        categoryPlot.getDomainAxis().setTickLabelFont(font);
        categoryPlot.getDomainAxis().setTickLabelPaint(new Color(160, 163, 165));
         
        categoryPlot.getRangeAxis().setLabelFont(font2);
        categoryPlot.getRangeAxis().setTickLabelFont(font2);
        categoryPlot.getRangeAxis().setTickLabelPaint(new Color(160, 163, 165));
        categoryPlot.getRangeAxis().setRange(0, 3);
         
        ((BarRenderer) categoryPlot.getRenderer()).setBarPainter(new StandardBarPainter());
        BarRenderer renderer = (BarRenderer)chart.getCategoryPlot().getRenderer();
        renderer.setMaximumBarWidth(0.04);
        renderer.setSeriesPaint(0, new Color(102, 204, 255));
        renderer.setSeriesPaint(1, new Color(102, 204, 153));
         
        ChartPanel chartPanel = new ChartPanel(chart);
        chartMainPanel.add(chartPanel, BorderLayout.CENTER);
        chartPanel.setPopupMenu(null);
        chartPanel.removeAll();
        chartPanel.setMouseZoomable(false, false);
        chartPanel.revalidate();    
    }
}


Solution 1:[1]

You don't need to replace the ChartPanel each time you want to see a new CategoryDataset; just the set the plot's new dataset like here. This example has a JComboBox<String> for selection and a Map<String, CategoryDataset> from which to choose:

combo.addItemListener((ItemEvent e) -> {
    var key = (String) e.getItem();
    plot.setDataset(map.get(key));
});

Bar Chart

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.util.HashMap;
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.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

public class ComboTest {

    private DefaultCategoryDataset createDataset(int i) {
        var set = new DefaultCategoryDataset();
        for (int j = 1; j < 4; j++) {
            set.addValue(i * 1, "Series 1", "Category " + j);
            set.addValue(i * 2, "Series 2", "Category " + j);
            set.addValue(i * 3, "Series 3", "Category " + j);
        }
        return set;
    }

    private void display() {
        var keys = new String[]{"Zero", "One", "Two", "Three", "Four"};
        var barChart = ChartFactory.createBarChart("", "Category", "Score",
            null, PlotOrientation.VERTICAL, true, true, false);
        var plot = (CategoryPlot) barChart.getPlot();
        var map = new HashMap<String, CategoryDataset>();
        var combo = new JComboBox<String>();
        for (int i = 0; i < keys.length; i++) {
            map.put(keys[i], createDataset(i));
            combo.addItem(keys[i]);
        }
        combo.addItemListener((ItemEvent e) -> {
            var key = (String) e.getItem();
            plot.setDataset(map.get(key));
        });
        combo.setSelectedIndex(keys.length / 2);
        var controlPanel = new JPanel();
        controlPanel.add(combo);
        var f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(controlPanel, BorderLayout.NORTH);
        f.add(new ChartPanel(barChart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(567, 345);
            }
        });
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Catalina Island