2013-09-13 3 views
0

Я создаю приложение поворота. Он состоит из вызова функции с использованием некоторого трудоемкого кода.Выполнение двух действий в порядке

Проблема заключается в «трудоемком коде», она вызывается до того, как будет установлен текст метки. Я хочу, чтобы метка была установлена ​​до того, как она перейдет на следующую строку. Почему это происходит?

myFunction() 
{ 
    myLabel.setText("Started"); 
//time consuming code which creates object of another class 
} 

Примечание: Я использовать java.awt.EventQueue.invokeLater при запуске всего приложения

ответ

1

Было бы надлежать вы узнаете о SwingWorker, который дает вам максимальную гибкость, когда дело доходит до резьбы. Вот короткая и тощая:

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

Во-первых, чтобы запустить что-нибудь на EDT, вы использовать этот код:

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     jLabel1.setText("Yay I'm on the EDT."); 
    } 
}); 

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

class Task extends SwingWorker<Void, Void> { 

    public Task() { 
     /* 
     * Code placed here will be executed on the EDT. 
     */ 
     jLabel1.setText("Yay I'm on the EDT."); 
     execute(); 
    } 

    @Override 
    protected Void doInBackground() throws Exception { 
     /* 
     * Code run here will be executed on a background, "worker" thread that will not interrupt your EDT 
     * events. Run your time consuming tasks here. 
     * 
     * NOTE: DO NOT run ANY Swing (GUI) code here! Swing is not thread-safe! It causes problems, believe me. 
     */ 
     return null; 
    } 

    @Override 
    protected void done() { 
     /* 
     * All code run in this method is done on the EDT, so keep your code here "short and sweet," i.e., not 
     * time-consuming. 
     */ 
     if (!isCancelled()) { 
      boolean error = false; 
      try { 
       get(); /* All errors will be thrown by this method, so you definitely need it. If you use the Swing 
         * worker to return a value, it's returned here. 
         * (I never return values from SwingWorkers, so I just use it for error checking). 
         */ 
      } catch (ExecutionException | InterruptedException e) { 
       // Handle your error... 
       error = true; 
      } 
      if (!error) { 
       /* 
       * Place your "success" code here, whatever it is. 
       */ 
      } 
     } 
    } 
} 

Затем вам нужно запустить свой SwingWorker с этим:

new Task(); 

Для получения дополнительной информации, ознакомьтесь с документацией Оракула: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

+3

может быть запущен swingworker (aka: вызов его выполнения) из любого потока, нет необходимости обертывать его в invokeLater – kleopatra

+0

Удивительный ответ. Спасибо :) – user2756339

+0

@ kleopatra, я всегда удивлялся, что, я только предположил, что это нужно EDT. Хорошо знать. Благодарю. – ryvantage

5

Вы должны запустить трудоёмкий код в отдельном потоке:

myFunction(){ 
    myLabel.setText("Started"); 
    new Thread(new Runnable(){ 
     @Override 
     public void run() { 
      //time consuming code which creates object of another class 
     } 
    }).start(); 

} 
+1

'старт() 'вместо' run() ', я полагаю. – kiheru

+0

@YAT Извините, но это не поможет. метка устанавливается за долю секунды до завершения потока. , который по-прежнему работает до установки метки. Это потому, что поскольку myFunction вызывается внутри качания, значит, новая Thread работает быстрее, чем качание? – user2756339

+1

@ user2756339 Не кажется очень трудоемким, если он заканчивается почти одновременно с заменой метки. Тем не менее, можно было бы попытаться отложить его после изменения метки, нажав блок 'new Thread() ...' в очередь событий, используя 'invokeLater()'. Менеджер перекраски все еще мог бы испортить план, чтобы он не гарантировал работу. – kiheru

Смежные вопросы