これを標準的な方法で行うことは可能ですか?
これがシナリオです。
EDT でコストのかかる作業を開始します (コストのかかる操作が終了するまで、EDT はブロックされます)。
EDT がブロックされている間、ユーザーはマウス ボタンをクリック/ドラッグし続けました。すべてのマウス操作はどこかに記録されます。
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("3 秒待ちます");
getContentPane().setLayout(new java.awt.GridLayout(2, 1, 0, 0));
getContentPane().add(待機);
getContentPane().add(new javax.swing.JToggleButton("Click me"));
setTitle("ビジー カーソル");
setSize(300, 200);
setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
setVisible(真);
wait.addActionListener(新しい java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent イベント) {
final java.util.Timer timer = switchToBusyCursor(BusyCursorTest2.this);
試す {
// EDT で高価なことをする
試す {
Thread.sleep(3000);
キャッチ(InterruptedException e){
//何もしない
}
} 最後に {
switchToNormalCursor(BusyCursorTest2.this, timer);
}
}
});
}
public static java.util.Timer switchToBusyCursor(最終の javax.swing.JFrame フレーム) {
startEventTrap(フレーム);
java.util.TimerTask timerTask = 新しい java.util.TimerTask() {
public void run() {
startWaitCursor(フレーム);
}
};
final java.util.Timer timer = new java.util.Timer();
timer.schedule(timerTask, DELAY_MS);
タイマーを返します。
}
public static void switchToNormalCursor(最終的な javax.swing.JFrame フレーム、最終的な java.util.Timer タイマー) {
timer.cancel();
stopWaitCursor(フレーム);
stopEventTrap(フレーム);
}
private static void startWaitCursor(javax.swing.JFrame フレーム) {
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.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.getGlassPane().addMouseListener(mouseAdapter);
frame.getGlassPane().setVisible(true);
}
private static void stopEventTrap(javax.swing.JFrame フレーム) {
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() {
新しい BusyCursorTest2();
}
});
}
プライベート静的最終 int DELAY_MS = 250;
}
SSCCE を実行する
「3 秒待つ」ボタンをクリックします。高価な操作をシミュレートします。マウス カーソルがビジーに変わります。
カーソルがビジー状態のときに、トグル ボタン [Click me] をクリックします。3 秒後にトグル ボタンの状態が変化した場合、マウス イベントはトグル ボタンによって受信され、トラップされませんでした。
カーソルがビジーに見える間、生成されたマウス (およびその他の) イベントが破棄されるようにします。
ありがとう。