Почему запуск цикла потока в компоненте AWT препятствует выполнению WindowHandler? - PullRequest
1 голос
/ 09 января 2012

Я изменил пример кода для Activator, размещенного на странице учебника по Oracle / Sun AWT здесь

Модификация выглядит следующим образом

f.add(new MyCanvas(f.getGraphicsConfiguration()), 
             BorderLayout.CENTER); 

Метод рисования в MyCanvas переопределяется следующим образом

MyCustomRunnable mcr = new MyCustomRunnable();
Thread th = new Thread(mcr);

th.start();

while(Thread.currentThread().isAlive()){
    mcr.getData();
    //do UI stuff 
    Thread.yield();
}

Аналогично MyCustomRunnable имеет соответствующий цикл в run()

public void run(){
    while(Thread.currentThread().isAlive){
        //do Stuff
        Thread.yield();
    }
}

Runnable и Canvas paint (оба) запускают цикл. С этим битом кода, закрытие системного меню в окне пользовательского интерфейса не вызывается. Почему?

Ответы [ 3 ]

3 голосов
/ 09 января 2012

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

3 голосов
/ 09 января 2012

Короткий ответ: paint() вызывается в потоке событий, который также является потоком, который обрабатывает все события пользовательского интерфейса, и вы захватываете этот поток и помещаете его в бесконечный цикл.

Когда вы делаете это в методе рисования ...

while(Thread.currentThread().isAlive()){
   ...
}

... "текущий поток", над которым вы работаете, - это тот же поток, в который вы ввели этот метод, то есть поток обработки событий».Я думаю, что вы действительно хотели запустить фоновый поток, который периодически перерисовывает представление.Вы можете сделать это в конструкторе вашего компонента AWT:

new Thread() {
   public void run() {
      while(runBackgroundThread) {
         mcr.getData();
         repaint();
      }
   }
}.start();

Обратите внимание, что я также создал логическую переменную runBackgroundThread, которая будет изменчивым полем в классе компонента.Установка значения false остановит поток загрузки.Напротив, Thread.currentThread().isAlive() будет всегда истинным - текущий поток должен по определению быть живым.

1 голос
/ 09 января 2012

Нет смысла начинать фоновый поток, если все, что вы собираетесь сделать, - это дождаться его завершения. Вместо этого вы можете заставить фоновый поток делать то, что вы хотите, чтобы он завершился.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...