これを標準的な方法で行うことは可能ですか?
これがシナリオです。
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 秒後にトグル ボタンの状態が変化した場合、マウス イベントはトグル ボタンによって受信され、トラップされませんでした。
カーソルがビジーに見える間、生成されたマウス (およびその他の) イベントが破棄されるようにします。
ありがとう。