Разрешить публикацию событий в EvenQueue между вызовами postEvent в Swing - PullRequest
2 голосов
/ 15 марта 2012

Я пытаюсь эмулировать события клика в 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

И это нарушает логику приложения. Я могу легко это исправить, добавив вызовы Thread.sleep () между моими вызовами postEvent (), но я не хочу этого делать, так как этот метод вызывается часто, и я не хочу, чтобы он был медленным, особенно с учетом текущего код работает в 95% случаев.

Как бы я эмулировал последовательность событий, позволяющую создавать новые события между ними? У меня нет доступа к коду компонента, поэтому я могу только изменить свой метод эмуляции.

Ответы [ 2 ]

3 голосов
/ 15 марта 2012

Вы можете выдвинуть свою собственную очередь событий, которая даст вам полный контроль над событиями.Например:

    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 );
    }

Вы просто связываете события вместе, чтобы они не публиковались до тех пор, пока не будет отправлено предыдущее событие, позволяя опубликовать любые промежуточные события, созданные компонентом, во время отправки до вашего следующего события.размещенЯ не пробовал это, но оно должно работать.

3 голосов
/ 15 марта 2012

вы можете использовать e.consume () для событий от событий мыши / клавиатуры и / или заменять / генерировать собственные четные значения для EventQueue

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...