2012-03-15 60 views
2

之間的事件後調用我試圖仿效使用下面的代碼在Swing單擊事件:允許事件在Swing

event = new MouseEvent(target, MouseEvent.MOUSE_PRESSED, ...) 
java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event); 
event = new MouseEvent(target, MouseEvent.MOUSE_RELEASED, ...) 
java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event); 
event = new MouseEvent(target, MouseEvent.MOUSE_CLICKED, ...) 
java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event); 

這適用於大多數的部件,但問題是,如果組件產生它是自己的事件,例如,如果組件接收MOUSE_PRESSED,它會生成一些事件並使用dispatchEvent(newEvent)提交它們;與正常的單擊事件順序應該是:

MOUSE_PRESSED 
newEvent 
MOUSE_RELEASED 
MOUSE_CLICKED 

但是因爲我的代碼順序是:

MOUSE_PRESSED  
MOUSE_RELEASED 
MOUSE_CLICKED 
newEvent 

而且它打破了應用程序邏輯。我可以通過在我的postEvent()調用之間添加Thread.sleep()調用來輕鬆修復它,但我不想這樣做,因爲此方法被稱爲很多,我不希望它變慢,特別是因爲當前代碼在95%的情況下起作用。

我將如何模擬事件序列,從而允許在它們之間創建新事件?我無法訪問組件代碼,所以我只能修改我的仿真方法。

回答

3

你可以把你自己的事件隊列這將使你的事件進行全面控制。例如:

class SchedulingEventQueue extends EventQueue 
    { 
     // Use Map< AWTEvent, List<AWTEvent> > to support multiple events 
     private final Map< AWTEvent, AWTEvent > eventSchedule = new HashMap< AWTEvent, AWTEvent >(); 

     public void scheduleEvent(final AWTEvent event, final AWTEvent dependentEvent) 
     { 
     eventSchedule.put(dependentEvent, event); 
     } 

     @Override 
     protected void dispatchEvent(final AWTEvent event) 
     { 
     try 
     { 
      super.dispatchEvent(event); 
     } 
     finally 
     { 
      // Dispatch any dependent event 
      AWTEvent scheduledEvent = eventSchedule.remove(event); 
      if(scheduledEvent != null) 
      { 
      postEvent(scheduledEvent); 
      } 
     } 
     } 
    } 

    // Now the code to post the events becomes: 
    { 
     SchedulingEventQueue eventQueue = new SchedulingEventQueue(); 

     Toolkit.getDefaultToolkit().getSystemEventQueue().push(eventQueue); 

     MouseEvent pressEvent = new MouseEvent(target, MouseEvent.MOUSE_PRESSED, ...) 
     MouseEvent releaseEvent = new MouseEvent(target, MouseEvent.MOUSE_RELEASED, ...) 
     MouseEvent clickEvent = new MouseEvent(target, MouseEvent.MOUSE_CLICKED, ...) 

     eventQueue.scheduleEvent(clickEvent, releaseEvent); 
     eventQueue.scheduleEvent(releaseEvent, pressEvent); 
     eventQueue.postEvent(pressEvent); 
    } 

你剛纔鏈中的事件一起,使它們不會發布直到前一事件已派出允許由組件產生的任何中間事件分派期間發佈之前,你的下一個事件發佈。我沒有嘗試過,但它應該可以工作。

+0

或者,您可以實施postEvents(列表< AWTEvent >事件),並在內部處理調度,以防止調用代碼必須以正確的順序獲取scheduleEvent()和postEvent()調用。您可以按相反順序遍歷列表,調度每個列表,然後發佈第一個事件。 – nicktalbot 2012-03-15 16:56:41

+0

這很好,很少問題:1)getSystemEventQueue()。push(eventQueue),我應該每次模擬鼠標點擊時調用它,還是推動一次並重復使用?當我不再需要它時,我沒有看到任何方法從系統中刪除我的eventQueue 2)我試圖修改它以檢查它何時完成處理事件,http://pastebin.com/h6zFMfH3,工作正常事件創建一個模塊對話框,它阻止dispatchEvent,我如何檢查當前事件被阻止?再次感謝! – 2012-03-15 17:23:06

+0

您只需要推送一次事件隊列,然後僅爲每組事件重用單個SchedulingEventQueue實例。 – nicktalbot 2012-03-15 17:42:39

3

您可以使用e.consume()事件從鼠標/鍵盤事件,和/或替換/生成自己連(S)到EventQueue