Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Сброс очереди сообщений для JButton (например)


Автор: NiТR0 10.7.2007, 09:42
Народ, помогите.

Есть кнопка, после нажатия ставлю Enable = false и начинаю делать свои черные делишки, после чего возвращаю Enable в true. Но! Если в то время когда кнопа не активна по ней потыкать мыхой или клавой, то после выполнения нужных действий все запускается по новой столько раз, сколько было нажатий, т.е. прут накопленные за время ее неактивности сообщения о нажатии. Как скинуть очередь системных сообщений, чтобы все сообщения пока кнопка неактивна игнорировались, но когда она станет активной, по ней можно будет тыкнуть вновь.

Заранее спасибо.

Автор: ecologist 10.7.2007, 10:56
Так ты "черные" делтшки прямо в обработчике для кнопки делаешь ? Или в отдельном потоке ?

Потому как если интерфейс уже способен принимать нажатия клавиш и кнопка не активна - не должно быть такого по идее.

Автор: NiТR0 10.7.2007, 12:08
Делаю прям в обработчике. Не должно , но есть. 
Похоже ничего с этим не сделать. Вот тут эта тема обсуждается подробно (cut), но пока никаких результатов.


M
LSD
NiТR0 если ты пришел сюда за ответом, то опиши проблему здесь (я думаю это не так трудно?), а не пиши проблема обсудается/описана и т.п. там-то там-то.

Автор: fixxer 10.7.2007, 13:14
Вот немного переделанный пример из соседней ветки про прогрессбар

Код

public class ProgressTestFrame extends JFrame {

    public static int MAX_VALUE = 10;

    private JProgressBar progressBar;

    private JButton button;

    public ProgressTestFrame() throws HeadlessException {
        super("ProgressTest");
        progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, MAX_VALUE);
        button = new JButton(new GoAction());
        getContentPane().add(progressBar, BorderLayout.NORTH);
        getContentPane().add(button, BorderLayout.SOUTH);
    }

    private static void buildAndShowGUI() {
        JFrame f = new ProgressTestFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(320, 240);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                buildAndShowGUI();
            }
        });
    }

    private class Worker implements Runnable {
        public void run() {
            try {
                SwingUtilities.invokeLater(new ButtonEnabler(false));
                for (int i = 0; i <= MAX_VALUE; i++) {
                    Thread.sleep(100);
                    SwingUtilities.invokeLater(new ProgressUpdater(i));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                SwingUtilities.invokeLater(new ButtonEnabler(true));
            }
        }
    }

    private class ProgressUpdater implements Runnable {

        private int value;

        public ProgressUpdater(int value) {
            this.value = value;
        }

        public void run() {
            progressBar.setValue(value);
        }
    }

    private class ButtonEnabler implements Runnable {

        private boolean enabled;

        public ButtonEnabler(boolean enabled) {
            this.enabled = enabled;
        }

        public void run() {
            button.setEnabled(enabled);
        }
    }

    private class GoAction extends AbstractAction {
        public GoAction() {
            super("Go!");
        }

        public void actionPerformed(ActionEvent e) {
            new Thread(new Worker()).start();
        }
    }

}

Автор: AntonSaburov 10.7.2007, 13:48
Цитата(NiТR0 @  10.7.2007,  12:08 Найти цитируемый пост)
Делаю прям в обработчике. Не должно , но есть. 

Так именно это и не очень верно. Лучше в обработчике задизаблить кнопку и запустить отдельный тред, который будет выполнять работу. Тогда обработчик очень быстро отработает и функицональность будет корректной.

Автор: NiТR0 10.7.2007, 14:19
Большое всем спасибо за помощь.

fixxer, помогло, спасибо.

Сделал так:

Код

...
    jButton1.addActionListener(new MyActionListener()); // Установка слушателя события
...
    // Класс слушателя
    private class MyActionListener implements ActionListener {
        // Вызываемый метод при получении объекта события
        public void actionPerformed(ActionEvent e) {
            new Thread(new Worker()).start();   // Запуск потока основного класса
        }
    }
    
    // Основной класс работы
    private class Worker implements Runnable {
        public void run() {    
            SwingUtilities.invokeLater(new ButtonEnabler(false));
            try{
                System.out.println("CLICK!");
                Thread.sleep(5000);
            }catch(InterruptedException ex){
                System.out.println(ex);
            }
            SwingUtilities.invokeLater(new ButtonEnabler(true));
        }
    }
    
    // Класс изменения состояния кнопки
    private class ButtonEnabler implements Runnable {
        private boolean enabled;

        public ButtonEnabler(boolean enabled) {
            this.enabled = enabled;
        }

        public void run() {
            jButton1.setEnabled(enabled);
            jButton1.update(jButton1.getGraphics());
        }
    }
...


P.S. (для модераторов)
За линк прошу меня извинить smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)