Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use SwingWorker?

Friends, i am developing a java application. Thats for performance monitoring. on that i am getting values in one class and drawing a graph in another class. i want to use swingworker to perform those two class alternatively.

        ResultSet rs;
        Connection conn = null;

        conn = (Connection)getMySqlConnection();

        Statement st = conn.createStatement();
        rs = st.executeQuery("SHOW GLOBAL STATUS");
        while(rs.next())
        {
            Map_MySql.put(rs.getString(1), rs.getString(2));
        }
        conn.close();

Above class for collecting server status and store it in hash map. this class called as "MySQLClass".

        System.out.println("Graph Occur");
        XYDataset Dataset;
        TimeSeries Series = new TimeSeries("Random Data");
        Second sec = new Second();
        ChartPanel CPanel;
        if(Operation_Combo.getSelectedItem().toString() == "MySQL")
        {
         if(MySQLClass.Map_MySql.get(""+MainWindow.SelectedNode+"") == null)
         {
             Value = 0;
         }
         else
         {
             Value = Integer.parseInt(MySQLClass.Map_MySql.get(""+MainWindow.SelectedNode+""));
         }
         System.out.println(Value);
        }
        if(Operation_Combo.getSelectedItem().toString() == "SQL Server")
        {
         if(SqlServerClass.Map_SQLServer.get(""+MainWindow.SelectedNode+"") == null)
         {
             Value = 0;
         }
         else
         {
             Value = Integer.parseInt(SqlServerClass.Map_SQLServer.get(""+MainWindow.SelectedNode+""));
         }
         System.out.println(Value);
        }
        String CounterName = MainWindow.SelectedNode.toString();
        Series.add(sec, Value);
        Dataset = new TimeSeriesCollection(Series);
        Chart = ChartFactory.createTimeSeriesChart(CounterName, "Time", "Range", Dataset, true, false, false);
        XYPlot Plot = (XYPlot)Chart.getPlot();
        Plot.setBackgroundPaint(Color.LIGHT_GRAY);
        Plot.setDomainGridlinePaint(Color.WHITE);
        Plot.setRangeGridlinePaint(Color.RED);
        CPanel = new ChartPanel(Chart);
        Panel1.revalidate();
        Panel1.add(CPanel);
        System.out.println("Chart Added");
        Panel1.validate();
        Panel1.repaint();
        Thread.sleep((int)MainWindow.Interval_Combo.getSelectedItem() * 1000);
        System.out.println("Sleep="+((int)MainWindow.Interval_Combo.getSelectedItem() * 1000));
        System.gc();

Above is the code for drawing Graph in one class called "Graph". How can i use swing worker to perform this alternatively and draw graph in every iteration. if you know help me please.

like image 331
A.Mohamed Bilal Avatar asked Mar 21 '23 02:03

A.Mohamed Bilal


1 Answers

SwingWorker is a lot simpler to use them it might seem.

Basically, you need to make a few basic decisions about what you want to achieve.

  • Do you want to return periodically updates while the process is running or
  • Do you want to return a result of the process...or both?
  • Do you want to provide progression updates?

Depending on what you want to do, will change the way you declare the SwingWorker.

For example...

public class HardWorker extends SwingWorker<ReturnValueType, PeriodicalType> {

Where ReturnValueType is the final result that will be generated by the worker and PeriodicalType is the type of object that could be sent back to the UI thread should you want to perform periodical updates (these are values you can specify yourself).

You can specify Void or Object for either of these values should you not care

When executed, the SwingWorker will call doInBackground, this method will be called within its own thread, allowing to perform your long running task outside of the Event Dispatching Thread.

If you want to send a value back to the UI before the doInBackground method has finished, you can call publish(instanceOfPeriodicalType). The values passed to this method will, eventually, be passed to the process method.

Because it's possible for multiple items to sent to the publish method, the process method provides a List<PeriodicalType> argument. When called, this method will be executed within the context of the EDT, allowing you to up date the UI.

Once doInBackground completes, it will return a return value of type ReturnValueType (or null if you don't care).

If you're interested in this result, you should use SwingWorker#get, but you should beware that this method will block until doInBackground returns, meaning you shouldn't call this method within the EDT until you know the doInBackground method has returned. You can check the state of worker using it's isDone or isCancelled methods, or...

You could use a PropertyChangeListener and monitor the state property or override the done method of the SwingWorker.

If you want to provide progress updates, while in the doInBackground method, you can call setProgress to update the progress of the worker. This will trigger a PropertyChangeEvent named progress, which you can monitor through the use of a PropertyChangeListener. Calls to this listener will be made within the context of the EDT.

Take a look at:

  • SwingWorker
  • Worker Threads and SwingWorker

For more details.

Generally, in order to use a SwingWorker, what you want to do, is separate your design into two groups. Every thing that can be done in the background and everything that needs to be done within the EDT.

You can start building the basic concept of your worker.

Basic Example...

This assumes a lot. Basically, it assumes that UI is already setup and this would be used to pick out new results and pass them back to a specific series.

Basically, as required, the worker would be insansiated, and the series passed to it...

GraphWorker worker = new GraphWorker(series);
worker.execute();

The work would then execute the query and pass the results back to the process method

public class GraphWorker extends SwingWorker<Void, String[]> {

    private TimeSeries series;
    private Second sec;

    public GraphWorker(TimeSeries series) {
        this.series = series;
        sec = new Second();
    }

    @Override
    protected Void doInBackground() throws Exception {
        ResultSet rs;
        Connection conn = null;
        try {

            conn = (Connection) getMySqlConnection();

            Statement st = conn.createStatement();
            rs = st.executeQuery("SHOW GLOBAL STATUS");
            while (rs.next()) {
                publish(new String[]{rs.getString(1), rs.getString(2)});
            }
        } finally {
            conn.close();
        }
        return null;
    }

    @Override
    protected void process(List<String[]> chunks) {
        for (String[] value : chunks) {

            try {
                int iValue = Integer.parseInt(value[1]);
                series.add(sec, Value);
            } catch (NumberFormatException exp) {
                exp.printStackTrace();
            }

        }            
    }

}
like image 151
MadProgrammer Avatar answered Mar 23 '23 16:03

MadProgrammer