2013-09-03 2 views
3

Я пытался простой код Java для теста, только кнопки, когда и нажмите на нее она спит в течение 5 секунд, вот обработчиккнопки делают отвечать на запросы на некоторое время Явы

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {            
    try { 
     System.out.println ("hiiii"); 
     Thread.sleep (5000); 
     System.out.println ("bye");   
    } catch (InterruptedException ex) { 
     Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

Я хочу, чтобы эта кнопка Безразлично» т получать любые события, пока он не закончит работать (5 секунд), я пытался отключить и включить его в обработчик, но напрасно

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           

    jButton1.setEnabled(false); 

    try { 
     System.out.println ("hiiii"); 
     Thread.sleep (5000); 
     System.out.println ("bye");   
    } catch (InterruptedException ex) { 
     Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    jButton1.setEnabled(true); 
} 
+2

'sleep' блокирует EDT. Вместо этого используйте ['Timer'] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html). – Maroun

+0

Чтобы преодолеть проблемы, которые могут возникать из-за сна или таймеров, я использовал петли задержки, но основная проблема все еще существует. –

+1

@MohamedYacoutAbouSamra. Он по-прежнему блокирует EDT. – Maroun

ответ

2

Вы должен переместить любые затянувшиеся задачи (в вашем случае это просто вызов сна) вне EDT (Thread Dispatch Thread) - этот поток используется для визуализации пользовательского интерфейса, если вы заблокируете его с помощью некоторого o peration - вы блокируете весь свой интерфейс одновременно.

Вот правильный пример того, как можно отключить/включить кнопку:

import javax.swing.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

/** 
* @author Mikle Garin 
* @see http://stackoverflow.com/a/18590057/909085 
*/ 

public class ButtonSleep 
{ 
    public static void main (String[] args) 
    { 
     JFrame frame = new JFrame ("Custom list renderer"); 

     final JButton button = new JButton ("Make me sleep 5 seconds"); 
     button.addActionListener (new ActionListener() 
     { 
      @Override 
      public void actionPerformed (ActionEvent e) 
      { 
       button.setEnabled (false); 
       new Thread (new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         try 
         { 
          Thread.sleep (5000); 
         } 
         catch (InterruptedException e1) 
         { 
          // 
         } 
         SwingUtilities.invokeLater (new Runnable() 
         { 
          @Override 
          public void run() 
          { 
           button.setEnabled (true); 
          } 
         }); 
        } 
       }).start(); 
      } 
     }); 
     frame.add (button); 

     frame.pack(); 
     frame.setLocationRelativeTo (null); 
     frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
     frame.setVisible (true); 
    } 
} 

Да, это кажется странным, но вы должны переместить свои операции в отдельном потоке (не имеет значения, какой поток) и вы должны выполнить любые операции с пользовательским интерфейсом (в данном случае - кнопкой включения/отключения) внутри EDT - вот почему я вызываю setEnabled в invokeLater, а не внутри отдельного потока.

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

+0

Это сработало для меня, но я не нашел причины запуска setEnabled внутри invokeLater, поскольку я удалил его (invokeLater), и код все еще работает правильно. –

+1

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

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