java swing очистить очередь событий

Можно ли сделать это стандартным способом?

Вот сценарий.

  1. Начать делать что-то дорогостоящее в EDT (EDT заблокирован до тех пор, пока дорогостоящая операция не будет завершена. over).

  2. Пока EDT был заблокирован, пользователь продолжал щелкать / перетаскивать кнопки мыши. Все действия мыши где-то записываются.

  3. Когда EDT свободен (делается с дорогостоящими вещами), он начинает обрабатывать события мыши.

На шаге 3 я хочу отбросить накопившиеся события мыши. . После освобождения EDT любое новое событие мыши должно обрабатываться обычным образом.

Любые идеи о том, как этого добиться.

PS: Я не могу предотвратить блокировку EDT (я делаю не контролировать поведение некоторых модулей в моей программе).

РЕДАКТИРОВАТЬ: Если я могу безопасно вызвать SunToolkit.flushPendingEvents (), тогда я всегда могу поставить стеклянную панель перед тем, как начать дорогостоящую операцию в EDT. После завершения дорогостоящей операции в потоке EDT очистите все события - они перейдут на стеклянную панель, которая ничего не сделает. Затем позвольте EDT работать в обычном режиме.

EDIT2: Я добавил SSCCE, чтобы продемонстрировать проблему.


public class BusyCursorTest2 extends javax.swing.JFrame {

    public BusyCursorTest2() {

        javax.swing.JButton wait = new javax.swing.JButton("Wait 3 seconds");
        getContentPane().setLayout(new java.awt.GridLayout(2, 1, 0, 0));
        getContentPane().add(wait);
        getContentPane().add(new javax.swing.JToggleButton("Click me"));
        setTitle("Busy Cursor");
        setSize(300, 200);
        setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
        setVisible(true);

        wait.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent event) {

                final java.util.Timer timer = switchToBusyCursor(BusyCursorTest2.this);

                try {
                    //do something expensive in EDT
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        //do nothing
                    }
                } finally {
                    switchToNormalCursor(BusyCursorTest2.this, timer);
                }
            }

        });
    }

    public static java.util.Timer switchToBusyCursor(final javax.swing.JFrame frame) {
        startEventTrap(frame);
        java.util.TimerTask timerTask = new java.util.TimerTask() {

            public void run() {
                startWaitCursor(frame);
            }

        };
        final java.util.Timer timer = new java.util.Timer();
        timer.schedule(timerTask, DELAY_MS);
        return timer;
    }

    public static void switchToNormalCursor(final javax.swing.JFrame frame, final java.util.Timer timer) {
        timer.cancel();
        stopWaitCursor(frame);
        stopEventTrap(frame);
    }

    private static void startWaitCursor(javax.swing.JFrame frame) {
        frame.getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
        frame.getGlassPane().addMouseListener(mouseAdapter);
        frame.getGlassPane().setVisible(true);
    }

    private static void stopWaitCursor(javax.swing.JFrame frame) {
        frame.getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
        frame.getGlassPane().removeMouseListener(mouseAdapter);
        frame.getGlassPane().setVisible(false);
    }

    private static void startEventTrap(javax.swing.JFrame frame) {
        frame.getGlassPane().addMouseListener(mouseAdapter);
        frame.getGlassPane().setVisible(true);
    }

    private static void stopEventTrap(javax.swing.JFrame frame) {
        frame.getGlassPane().removeMouseListener(mouseAdapter);
        frame.getGlassPane().setVisible(false);
    }

    private static final java.awt.event.MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter() {
    };

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new BusyCursorTest2();
            }

        });

    }

    private static final int DELAY_MS = 250;

}
  1. Запустить SSCCE

  2. Нажмите кнопку «Подождите 3 секунды». Имитирует дорогостоящую операцию. Курсор мыши изменится на "занято".

  3. Пока курсор занят, нажмите кнопку переключения "Щелкните меня". Если через три секунды кнопка переключения меняет свое состояние, то событие мыши было получено кнопкой переключения и не было захвачено.

Я хочу, чтобы, пока курсор выглядит занятым, сгенерированные события мыши (и другие) отбрасывались.

Спасибо.

5
задан Zoyd 21 May 2014 в 21:22
поделиться