Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 允许在Swing中的postEvent调用之间在队列中发布事件_Java_Swing_Events - Fatal编程技术网

Java 允许在Swing中的postEvent调用之间在队列中发布事件

Java 允许在Swing中的postEvent调用之间在队列中发布事件,java,swing,events,Java,Swing,Events,我尝试使用以下代码模拟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.getDefa

我尝试使用以下代码模拟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);
这对大多数组件来说都很好,但问题是组件是否正在生成自己的事件,例如,当组件接收到按下的鼠标时,它会生成一些事件并使用dispatchEvent(newEvent)提交它们;正常点击事件顺序为:

MOUSE_PRESSED
newEvent
MOUSE_RELEASED
MOUSE_CLICKED
但由于我的代码顺序是:

MOUSE_PRESSED    
MOUSE_RELEASED
MOUSE_CLICKED
newEvent
它打破了应用程序逻辑。我可以通过在postEvent()调用之间添加Thread.sleep()调用来轻松修复它,但我不想这样做,因为这个方法调用太多,而且我不希望它太慢,特别是因为当前代码在95%的情况下都能工作


我将如何模拟允许在它们之间创建新事件的事件序列?我没有访问组件代码的权限,因此只能修改我的模拟方法。

您可以使用鼠标/键盘事件中的事件,和/或替换/生成自己的偶数到
事件队列

您可以推送自己的事件队列,从而完全控制事件。例如:

    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 );
    }
类SchedulingEventQueue扩展了EventQueue
{
//使用Map>支持多个事件
私有最终映射eventSchedule=newhashmap();
public void scheduleEvent(最终awteEvent事件,最终awteEvent从属事件)
{
eventSchedule.put(依赖事件、事件);
}
@凌驾
受保护的无效dispatchEvent(最终AWTEEvent事件)
{
尝试
{
超级调度事件(事件);
}
最后
{
//发送任何相关事件
AWTEvent scheduledEvent=eventSchedule.remove(事件);
if(scheduledEvent!=null)
{
事件后(scheduledEvent);
}
}
}
}
//现在,发布事件的代码变为:
{
SchedulingEventQueue eventQueue=新建SchedulingEventQueue();
Toolkit.getDefaultToolkit().getSystemEventQueue().push(eventQueue);
MouseEvent pressEvent=新的MouseEvent(目标,MouseEvent.MOUSE_按下,…)
MouseEvent releaseEvent=新的MouseEvent(目标,MouseEvent.MOUSE_release,…)
MouseEvent clickEvent=新的MouseEvent(目标,MouseEvent.MOUSE_CLICKED,…)
eventQueue.scheduleEvent(clickEvent,releaseEvent);
eventQueue.scheduleEvent(释放事件,按事件);
eventQueue.postEvent(按事件);
}

您只需将事件链接在一起,以便在发送前一个事件之前不会发布它们,从而允许在发送期间发布由组件创建的任何中间事件,然后再发布下一个事件。我没有尝试过这个方法,但它应该可以工作。

或者,您可以实现一个postEvents(Listevents),并在内部处理调度,以防止调用代码必须以正确的顺序获取scheduleEvent()和postEvent()调用。您可以按相反的顺序迭代列表,安排每个列表,然后发布第一个事件。这非常有效,没有几个问题:1)getSystemEventQueue().push(eventQueue),我应该在每次模拟鼠标单击时调用它,还是每次推一次并重用它?当我不再需要eventQueue时,我看不到任何从系统中删除eventQueue的方法2)我正在尝试修改它,以检查它何时完成处理事件,,工作正常,直到事件创建阻止dispatchEvent的模式对话框,如何检查当前事件是否被阻止?再次感谢!您只需要推送事件队列一次,然后对每组事件重用单个SchedulingEventQueue实例。