Как работает диспетчеризацию событий - Java

Узнай цену своей работы

Формулировка задачи:

Объясните пожалуйста, как работает диспетчеризация событий. Для опыта написал вот что:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
class Test
 {
  String txt = "";
  
  Test ()
   {
    JFrame wnd = new JFrame("Тестовая прога");
    
    wnd.setBounds(200, 100, 300, 200);
    wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    wnd.setLayout(new FlowLayout());
    
    JButton btn1 = new JButton("Click #1");
    JButton btn2 = new JButton("Click #2");
    JButton btn3 = new JButton("Click #3");
    wnd.add(btn1);
    wnd.add(btn2);
    wnd.add(btn3);
    
    JLabel lab = new JLabel(txt);
    wnd.add(lab);
    
    btn1.addActionListener(new ActionListener ()
                           {
                            public void actionPerformed (ActionEvent ae)
                             {
                              txt += "1,";
                              lab.setText(txt);
                              try
                               {
                                Thread.sleep(1500);
                               }
                              catch (InterruptedException ie)
                               {
                               }
                             }
                           });
    btn2.addActionListener(new ActionListener ()
                           {
                            public void actionPerformed (ActionEvent ae)
                             {
                              txt += "2,";
                              lab.setText(txt);
                              try
                               {
                                Thread.sleep(1500);
                               }
                              catch (InterruptedException ie)
                               {
                               }
                             }
                           });
    btn3.addActionListener(new ActionListener ()
                           {
                            public void actionPerformed (ActionEvent ae)
                             {
                              txt += "3,";
                              lab.setText(txt);
                              try
                               {
                                Thread.sleep(1500);
                               }
                              catch (InterruptedException ie)
                               {
                               }
                             }
                           });
    
    wnd.setVisible(true);
   }
  
  public static void main (String args []) throws InterruptedException
   {/*
    SwingUtilities.invokeLater(new Runnable ()
                                {
                                 public void run ()
                                  {
                                   new Test ();
                                  }
                                });*/
    new Test ();
   }
 }
Здесь создаются 3 кнопки и метка. При нажатии каждой кнопки обработчик дописывает к метке свой номер и ждет 1,5 сек. Зачем нужен этот invokeLater()? В книге Герберта Шилдта объяснено непонятно. Я быстро нажимаю кнопки в разном порядке и цифры в метке появляются в том же порядке. Очередь вроде работает одинаково что с инвоком, что без него. В чем прикол? Это для меня очень мозголомная тема. О потоках представление имею из его-же книги для начинающих, если что.

Решение задачи: «Как работает диспетчеризацию событий»

textual
Листинг программы
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
class UpdateProgress implements ActionListener
 {
  static final int UP = 1;
  static final int DOWN = -1;
  JProgressBar pb;
  JLabel lab;
  static boolean isRunning = false;
  int step;
  
  UpdateProgress (JProgressBar pb, JLabel lab, int step)
   {
    this.pb = pb;
    this.lab = lab;
    this.step = step;
   }
  
  public void actionPerformed (ActionEvent ae)
   {
    if (UpdateProgress.isRunning)
     return;
   
    class SetValueBar implements Runnable
     {
      JProgressBar pb;
      int newVal;
      
      SetValueBar (JProgressBar pb, int newVal)
       {
        this.pb = pb;
        this.newVal = newVal;
       }
      
      public void run ()
       {
        pb.setValue(newVal);
       }
     }
    
    lab.setText("Start");
//    UpdateProgress.isRunning = true; // Это исправление а ...
    
    new Thread (new Runnable ()
     {
      public void run ()
       {
        // Это уязвимость.
        // После нажатия второй кнопки в процессе создания потока ...
        // ... возникла "заминка".
        if (step == UpdateProgress.DOWN)
         try
          {
           Thread.sleep(4000);
          }
         catch (InterruptedException ie)
          {
          }
        
        UpdateProgress.isRunning = true; // ... первоначально было здесь. Ошибка!
        
        for (int i = pb.getValue(); step > 0 ? i < 20 : i >= 0; i += step)
         {
          try
           {
            Thread.sleep(500);
           }
          catch (InterruptedException ie)
           {
           }
          
          SwingUtilities.invokeLater(new SetValueBar (pb, i));
         }
        
        lab.setText("Ready !");
        UpdateProgress.isRunning = false;
       }
     }).start();
   }
 }
 
class Test extends JFrame
 {
  JProgressBar pb;
  JLabel lab;
  
  Test ()
   {
    super("Тест");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(400, 300, 190, 110);
    setLayout(new FlowLayout());
    setResizable(false);
    
    JButton btn1 = new JButton("UP");
    JButton btn2 = new JButton("DOWN");
    
    pb = new JProgressBar(0, 19);
    lab = new JLabel();
    
    btn1.addActionListener(new UpdateProgress (pb, lab, UpdateProgress.UP));
    btn2.addActionListener(new UpdateProgress (pb, lab, UpdateProgress.DOWN));
    
    add(btn1);
    add(btn2);
    add(pb);
    add(lab);
    
    setVisible(true);
   }
  
  public static void main (String args [])
   {
    SwingUtilities.invokeLater(new Runnable ()
                                {
                                 public void run ()
                                  {
                                   new Test ();
                                  }
                                });
//    new Test ();
   }
 }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.385 из 5