Как работает диспетчеризацию событий - Java
Формулировка задачи:
Объясните пожалуйста, как работает диспетчеризация событий.
Для опыта написал вот что:
Здесь создаются 3 кнопки и метка. При нажатии каждой кнопки обработчик дописывает к метке свой номер и ждет 1,5 сек.
Зачем нужен этот invokeLater()? В книге Герберта Шилдта объяснено непонятно. Я быстро нажимаю кнопки в разном порядке и цифры в метке появляются в том же порядке. Очередь вроде работает одинаково что с инвоком, что без него. В чем прикол? Это для меня очень мозголомная тема. О потоках представление имею из его-же книги для начинающих, если что.
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 (); } }
Решение задачи: «Как работает диспетчеризацию событий»
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 (); } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д