Search code examples
javaswingtimerjframejfreechart

How to make Timer class to load a jfreechart every 10 seconds in Java?


I have a JFrame that displays website logons using jfreechart API. It's a bar chart and the dataset comes from SQL database.

The java project loads the chart and the chart shows the current website logons. Since the datasets changes every second, the bar chart should be dynamic.I used Timer class to do that. It runs the loadLogonChart() every 10 seconds. So far I don't have problems. However the problem is though it does update the chart in 10 seconds. However, after 20 seconds, it loads the the values back when I run the forms first.Then this process repeats over and over again. The codes that I use are below. I couldn't figure it what's wrong with it.

public final class MainForm extends javax.swing.JFrame implements ActionListener{


private static int AUTO_UPDATE_CHARTS = 10000;


public MainForm() throws SQLException {
    //Timer for the barchart    
    Timer timerChart = new Timer(AUTO_UPDATE_CHARTS, new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                loadLogonChart();
            } catch (SQLException ex) {
                Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }); 
    timerChart.start();


    //LOAD THE FORM
    loadForm();

}



public void loadForm() throws SQLException{
    initComponents();
    loadLogonChart();

}

public void loadLogonChart() throws SQLException{
     //database class that I need for the barchart datasets
    Database db = new Database();

    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    JFreeChart chart = ChartFactory.createBarChart("Web Site Activity Chart", "Days", "# of visits", dataset, PlotOrientation.VERTICAL, false, true, false);
    CategoryPlot catPlot = chart.getCategoryPlot();

    try {
        dataset.setValue(db.showMonday(), "logon", "Monday");
        dataset.setValue(db.showTuesday(), "logon", "Tuesday");
        dataset.setValue(db.showWednesday(), "logon", "Wednesday");
        dataset.setValue(db.showThursday(), "logon", "Thursday");
        dataset.setValue(db.showFriday(), "logon", "Friday");
        dataset.setValue(db.showSaturday(), "logon", "Saturday");
        dataset.setValue(db.showSunday(), "logon", "Sunday");

        chart = ChartFactory.createBarChart("Web Site Activity Chart", "Days", "# of visits", dataset, PlotOrientation.VERTICAL, false, true, false);
        ChartPanel myChart = new ChartPanel(chart);
        myChart.setMouseWheelEnabled(true);


        BarRenderer renderer = (BarRenderer) catPlot.getRenderer();
        DecimalFormat decimalFormat = new DecimalFormat("##.##");
        renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}",decimalFormat));
        catPlot.setRenderer(renderer);
        renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.TOP_LEFT));
        renderer.setItemLabelsVisible(true);
        chart.getCategoryPlot().setRenderer(renderer);

        //renderer.setBaseItemLabelGenerator(CategoryItemLabelGenerator generator)

        chartPanel.setLayout(new java.awt.BorderLayout());
        chartPanel.add(myChart,BorderLayout.CENTER);
        chartPanel.revalidate();
        chartPanel.validate();

    } catch (SQLException ex) {
        Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
    }

}

Solution

  •     chartPanel.add(myChart,BorderLayout.CENTER);
        chartPanel.revalidate();
        chartPanel.validate();
    

    It looks to me like you attempt to keep adding different components to the chartPanel. Well adding a component does not remove the previous component.

    Swing paints the last component added first so the old panel will display on top of the new panel. Try:

        chartPanel.removeAll();
        chartPanel.add(myChart,BorderLayout.CENTER);
        chartPanel.revalidate();
        chartPanel.validate(); // not needed since you do revalidate
        chartPanel.repaint();