Как использовать SwingWorker?

Друзья, я разрабатываю java-приложение. Это для мониторинга производительности. на этом я получаю значения в одном классе и рисую график в другом классе. я хочу использовать swingworker для альтернативного выполнения этих двух классов.

        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();

Над классом для сбора состояния сервера и сохранения его в хэш-карте. этот класс называется «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();

Выше приведен код для рисования Graph в одном классе под названием «Graph». Как я могу использовать Swing Worker для альтернативного выполнения этого и рисования графика на каждой итерации. если вы знаете, помогите мне, пожалуйста.


person A.Mohamed Bilal    schedule 06.01.2014    source источник
comment
Взгляните на Параллелизм с Swing. Есть раздел об использовании SwingWorker   -  person Paul Samsotha    schedule 06.01.2014
comment
Несвязанный: пожалуйста, изучите соглашения об именах Java и придерживайтесь их.   -  person kleopatra    schedule 06.01.2014
comment
возможный дубликат JFreeChart не показывает график в каждую итерацию в потоке?   -  person trashgod    schedule 06.01.2014


Ответы (2)


SwingWorker может показаться, что их намного проще использовать.

По сути, вам нужно принять несколько основных решений о том, чего вы хотите достичь.

  • Вы хотите периодически возвращать обновления во время выполнения процесса или
  • Вы хотите вернуть результат процесса... или и то, и другое?
  • Вы хотите предоставлять обновления прогресса?

В зависимости от того, что вы хотите сделать, изменится способ объявления SwingWorker.

Например...

public class HardWorker extends SwingWorker<ReturnValueType, PeriodicalType> {

Где ReturnValueType — это окончательный результат, который будет сгенерирован обработчиком, а PeriodicalType — это тип объекта, который может быть отправлен обратно в поток пользовательского интерфейса, если вы хотите выполнять периодические обновления (это значения, которые вы можете указать самостоятельно).

Вы можете указать Void или Object для любого из этих значений, если вам все равно.

При выполнении SwingWorker вызовет doInBackground, этот метод будет вызываться в своем собственном потоке, что позволит выполнять вашу длительную задачу вне потока диспетчеризации событий.

Если вы хотите отправить значение обратно в пользовательский интерфейс до завершения работы метода doInBackground, вы можете вызвать publish(instanceOfPeriodicalType). Значения, переданные этому методу, в конечном итоге будут переданы методу process.

Поскольку в метод publish можно отправить несколько элементов, метод process предоставляет аргумент List<PeriodicalType>. При вызове этот метод будет выполняться в контексте EDT, что позволит вам обновить пользовательский интерфейс.

После завершения doInBackground будет возвращено return значение типа ReturnValueType (или null, если вам все равно).

Если вас интересует этот результат, вы должны использовать SwingWorker#get, но вы должны помнить, что этот метод будет блокироваться до тех пор, пока не вернется doInBackground, то есть вы не должны вызывать этот метод в EDT, пока не узнаете, что метод doInBackground вернулся. Вы можете проверить состояние воркера, используя его методы isDone или isCancelled, или...

Вы можете использовать PropertyChangeListener и отслеживать свойство state или переопределить метод done для SwingWorker.

Если вы хотите предоставлять обновления хода выполнения, находясь в методе doInBackground, вы можете вызвать setProgress для обновления хода выполнения работника. Это вызовет PropertyChangeEvent с именем progress, за которым вы можете следить с помощью PropertyChangeListener. Вызовы этому прослушивателю будут выполняться в контексте EDT.

Взгляни на:

Больше подробностей.

Как правило, для того, чтобы использовать SwingWorker, нужно разделить свой дизайн на две группы. Все, что можно сделать в фоновом режиме, и все, что нужно сделать в EDT.

Вы можете начать строить базовую концепцию вашего воркера.

Базовый пример...

Это предполагает многое. По сути, предполагается, что пользовательский интерфейс уже настроен, и он будет использоваться для выбора новых результатов и передачи их обратно в определенную серию.

В принципе, как и требовалось, рабочий обезумел, и серия перешла к нему...

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

Затем работа будет выполнять запрос и передавать результаты обратно в метод process.

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();
            }

        }            
    }

}
person MadProgrammer    schedule 06.01.2014
comment
может ли кто-нибудь сказать мне, как поочередно вызывать эти два набора кодировок в Swingworker. любой образец формата для моей проблемы также очень ценится. пожалуйста.,.... - person A.Mohamed Bilal; 06.01.2014
comment
@A.MohamedBilal: полный пример рассматривается здесь. - person trashgod; 06.01.2014
comment
ой ну спасибо. но это для генерации кодирования графа. Я хочу знать, как заставить эти два класса работать попеременно, используя Swing Worker, и я хочу генерировать график на каждой итерации. Можете ли вы просто дать этот код. Если я получу это, мой проект будет завершен. пожалуйста. @trashgod - person A.Mohamed Bilal; 06.01.2014
comment
Приведенный пример добавляет точку на график с каждой итерацией. - person trashgod; 06.01.2014
comment
На каждой итерации передавать результат взаимодействия в publish - person MadProgrammer; 06.01.2014
comment
MySQLClass MySQL = новый MySQLClass(); MySQL.execute(); Это моя кодировка. и я просто пишу запрос в функции doinBackground, сохраняю эти данные в хэш-карте и публикую хэш-карту. В функции процесса я просто пишу сгенерированное графом кодирование. При этом я также получаю вывод, а не альтернативную форму. вывод, например, MySql Occur MySql Occur Connection Close Connection Close Graph Occur 71547 Chart Added Sleep=1000 Graph Occur 71547 Chart Added Sleep=1000 Что я должен сделать, чтобы выполнить это в альтернативной форме. - person A.Mohamed Bilal; 07.01.2014
comment
В принципе. Я добавил очень простой пример, и вам придется настроить его, чтобы заставить его работать... - person MadProgrammer; 07.01.2014

Сначала я просто вызываю функцию doInBackground() из MySQL.execute();, используя это. А затем в функции doInBackground() я просто собираю эти значения счетчика и использую функцию publish(); для передачи определенного значения. здесь я просто передаю флаг, чтобы обозначить, что данные были успешно собраны. опубликовать(GraphLock);

После вызова Publish(); вызывается метод Process(List chunks). При этом я просто проверяю условие и вызываю класс Graph для создания графика.

    if(GraphLock==true)
        SwingUtilities.invokeLater(new Graph());

Работает исправно...

person A.Mohamed Bilal    schedule 29.01.2014