Свинг-обновление компонентов пользовательского интерфейса во время выполнения задания

Я разрабатываю приложение для качелей. В этом у меня есть рабочий процесс работы, которые нужно сделать.

Я запускаю эти задания в цикле for одно за другим. Интересно, что мне нужно обновить строку состояния графического интерфейса с текущим именем задания.

Я не могу использовать SwingUtilities.invokeAndWait, так как он не может работать в потоке отправки, который будет текущим потоком.

Я попытался использовать SwingWorker, так как задания выполняются в цикле, метод SwingWorker doBackGrount() будет выполняться, выйдет и получит следующий индекс для запуска следующего задания. В done() SwingWorker я написал код для обновления графического интерфейса со статусом.

public class TestAction extends SwingWorker<Boolean, Void> {

    boolean executeThread = false;

    public TestAction() {
    }

    @Override
    protected Boolean doInBackground() throws Exception {
        executeThread = ExecuteWebServiceAction.webServiceExecution();
        return executeThread;
    }

    @Override
    protected void done() {
        try {
            boolean isOver = (boolean) get();
            if (isOver) {
                MainApplication.getInstance().getFrame().setStatus(LangUtil.getString("cdsExecuteFinehed")
                        + " " + ((WebServiceTool) DrawingManager.getInstance().getCurrentTool()).getName());
                FrameMain.jPanel6.repaint();
            }
        } catch (Interr`enter code here`uptedException ex) {
            Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ExecutionException ex) {
            Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

И вот здесь я вызываю TestAction:

if (!WorkFlow.isIsWorkflow()) {
    SwingUtilities.invokeLater(
      new Runnable() {
        @Override
        public void run() {
          webServiceExecution();
        }
    });
} else {
     new TestAction().execute();
}

person Nandita    schedule 14.03.2012    source источник
comment
Подход SwingWorker имеет смысл — в чем проблема? Он также имеет метод getProgress(), который поможет вам отслеживать ход выполнения задачи (не уверен, что вам это нужно).   -  person assylias    schedule 14.03.2012
comment
У меня мало времени Так что наймите консультанта и заплатите ему гонорары, соответствующие вашей срочности.   -  person Andrew Thompson    schedule 14.03.2012
comment
пожалуйста, отредактируйте вопрос с вашим SSCCE   -  person mKorbel    schedule 14.03.2012
comment
У меня заканчивается время, извините за это,,, :(   -  person Nandita    schedule 14.03.2012
comment
Проблема заключается в том, что после вызова метода doBackGround()... сразу же выполняется мое следующее задание, а затем вызывается метод done()... Я хочу выполнить метод doBackGround(), а затем метод done(), обновить компонент пользовательского интерфейса, затем перейти к следующему заданию... но этого не происходит   -  person Nandita    schedule 14.03.2012
comment
@user1249469 user1249469 Если вы не публикуете свой код (соответствующие части), вам трудно помочь.   -  person assylias    schedule 14.03.2012
comment
Хорошо, вот он .... класс свингворкеров   -  person Nandita    schedule 14.03.2012
comment
@assylias ... как вставить код в поле для комментариев, так как я новичок в этом   -  person Nandita    schedule 14.03.2012
comment
@user1249469 user1249469 не публикуйте это в комментарии, добавьте его к своему вопросу. Вам нужно вставить 4 пробела в начале каждой строки, чтобы получить правильное форматирование.   -  person assylias    schedule 14.03.2012
comment
@assylias.. Большое спасибо, я только что обновил свой вопрос   -  person Nandita    schedule 14.03.2012


Ответы (3)


вы можете использовать Thread.currentThread().sleep(5000); в методе doInBackground SwingWorker до того, как currentthread завершит свое выполнение и обновит ваш пользовательский интерфейс

person Rahul Borkar    schedule 14.03.2012

работает в цикле один за другим и уведомляет пользовательский интерфейс, когда он сделан

звучит как «большая работа с промежуточными результатами». Промежуточные результаты поддерживаются с помощью методов публикации/обработки:

  • реализовать doInBackground для циклического прохождения заданий и вызова публикации, когда одно из них завершено
  • реализовать процесс обновления пользовательского интерфейса
person kleopatra    schedule 14.03.2012

Вы можете добавить Runnable в свой конструктор, который будет запускаться, когда done() закончится:

public class TestAction extends SwingWorker<Boolean, Void> {

    boolean executeThread = false;
    private final Runnable runWhenDone;

    public TestAction(Runnable runWhenDone) {
        this.runWhenDone = runWhenDone;
    }

    //...

    @Override
    protected void done() {
    try {
        boolean isOver = (boolean) get();
        if (isOver) {
            MainApplication.getInstance().getFrame().setStatus(LangUtil.getString("cdsExecuteFinehed")
                + " " + ((WebServiceTool) DrawingManager.getInstance().getCurrentTool()).getName());

            //Run the Runnable here
            runWhenDone.run();

            //...

И в вашем классе графического интерфейса

Runnable r = new Runnable() {public void run() {updateTheTitle();}};
(new TestAction(r)).execute();
private void updateTheTitle() { yourTitle.setText("I am done");}
person assylias    schedule 14.03.2012
comment
мне нужно создать метод runWhenDone() в TestAction? - person Nandita; 14.03.2012
comment
Является ли ваш класс TestAction внутренним классом для вашего класса GUI или он находится в отдельном файле? - person assylias; 14.03.2012
comment
Если TestAction находится в отдельном файле, вам нужно создать Runnable в своем графическом интерфейсе (см. нижнюю часть моего ответа). Метод updateTheTitle, который вам нужно реализовать в вашем классе GUI для обновления всего, что необходимо обновить, будет вызываться, когда SwingWorker завершит работу. - person assylias; 14.03.2012
comment
Я сделал то, что вы сказали, но в TestAction в методе done () ... runWhenDone () не создается правильно? - person Nandita; 14.03.2012
comment
Итак, я понимаю, что это делается()... Мне просто нужно добавить runWhenDone.run();.... я прав... - person Nandita; 14.03.2012
comment
@ user1249469 да - извините за опечатку - person assylias; 14.03.2012
comment
не проблема.... но проблема все же существует.... done() выполняется в конце цикла for... - person Nandita; 14.03.2012
comment
@ user1249469 Тогда я, вероятно, неправильно понял ваш вопрос - в вашем коде нет цикла for. Если все задачи выполняются одновременно, вы можете использовать один SwingWorker для каждой, чтобы done() выполнялось в конце каждой задачи, или вы можете добавить свойство, например, executeTask, и вызывать метод firePropertyChange("executedTask",previousTaskName,"Task x"), когда задача сделана. В вашем графическом интерфейсе вы можете зарегистрировать прослушиватель этих изменений, которые будут выполнять обновление вашего заголовка с правильным именем задачи... - person assylias; 14.03.2012
comment
можете ли вы привести пример изменения свойства, пожалуйста - person Nandita; 14.03.2012