Можно ли сделать это стандартным образом?
Вот сценарий.
Начните делать что-то дорогое в EDT (EDT блокируется, пока дорогая операция не закончится).
Пока EDT был заблокирован, пользователь продолжал нажимать / перетаскивать кнопки мыши. Все действия мыши где-то записаны.
Когда EDT свободен (выполняется с дорогими вещами), он начинает обрабатывать события мыши.
Что я хочу на шаге 3 - это отменить накопившиеся события мыши. После освобождения EDT любое новое событие мыши должно обрабатываться обычным образом.
Любые идеи о том, как этого добиться.
PS: я не могу предотвратить блокировку EDT (я не контролирую поведение некоторых модулей в моей программе).
EDIT:
Если я могу смело вызывать "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;
}
Запустить SSCCE
Нажмите на кнопку «Подождите 3 секунды». Имитирует дорогостоящую операцию. Курсор мыши изменится на занятое.
Пока курсор занят, нажмите на кнопку «Нажми меня». Если по истечении трех секунд кнопка переключения меняет свое состояние, то событие мыши было получено кнопкой переключения и не было захвачено.
Я хочу, чтобы, в то время как курсор выглядит занятым, генерируемые события мыши (и другие) отбрасываются.
Спасибо.