3

我正在将 AWT 事件(mouse_pressedmouse_releasedkey_pressedkey_released等)记录到日志中,以便在单元测试中使用 Robot 重播它们。但我发现有时我需要在mouse_released事件丢失时插入事件,因为我的一些组件会自行移除,mouse_pressed因此mouse_released永远不会调度。我认为一个好的方法是mouse_released每当看到一个具有modifiersEx=的鼠标事件Button1后跟一个具有modifiersEx= 0 的事件时插入,除非第二个事件已经是 mouse_released。但是我在使用JComboBox.

这是一个简单的 main 函数,其中包含一个JComboBox在其下的组件,该组件也接收鼠标事件。

带有 JComboBox 的窗口截图

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.InputEvent;
import java.util.logging.Logger;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class DemoEvents {
    public static void main(String[] argv) {
        JFrame jframe = new JFrame("Test events");
        jframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        Container contentPane = jframe.getContentPane();
        contentPane.setLayout(new BorderLayout());
        JComboBox jcomboBox = new JComboBox(new String[]{"one", "two", "three"});
        JButton jbutton = new JButton("Hello");
        JPanel outerPanel = new JPanel();
        JPanel innerPanel = new JPanel();
        innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.PAGE_AXIS));
        innerPanel.add(jcomboBox);
        innerPanel.add(jbutton);
        outerPanel.add(innerPanel);
        contentPane.add(outerPanel, BorderLayout.CENTER);
        jframe.setSize(200, 200);
        jframe.setVisible(true);

        long mask =
            AWTEvent.MOUSE_EVENT_MASK |
            AWTEvent.MOUSE_WHEEL_EVENT_MASK |
            AWTEvent.MOUSE_MOTION_EVENT_MASK;

        final Logger logger = Logger.getLogger("awt-events");
        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
            @Override
            public void eventDispatched(AWTEvent event) {
                InputEvent ev = (InputEvent)event;
                logger.info(ev.toString());
            }
        }, mask);
    }
}

当单击JComboBox并单击项目“一”时,我得到了这些事件。with extModifiers mouse_entered=Button1 没有意义,因为它是mouse_released event! 这是我单击组合框然后单击第一项时的简化日志。查看底部加粗的事件:

  1. MouseEvent[MOUSE_PRESSED,(1,13),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] 在 MetalComboBoxButton[...]
  2. MouseEvent[MOUSE_RELEASED,(1,13),button=1,modifiers=Button1,clickCount=1] on MetalComboBoxButton[...]
  3. MouseEvent[MOUSE_MOVED,(0,14),button=0,clickCount=0] 在 MetalComboBoxButton[...]
  4. MouseEvent[MOUSE_EXITED,(-2,15),button=0,clickCount=0] 在 MetalComboBoxButton[...]
  5. MouseEvent[MOUSE_ENTERED,(81,15),button=0,clickCount=0] 在 JComboBox[...]
  6. MouseEvent[MOUSE_MOVED,(81,15),button=0,clickCount=0] 在 JComboBox[...]
  7. (更多动作)
  8. MouseEvent[MOUSE_EXITED,(69,24),button=0,clickCount=0] 在 JComboBox[...]
  9. ComboPopup.popup 上的 MouseEvent[MOUSE_ENTERED,(69,0),button=0,clickCount=0]
  10. ComboPopup.popup 上的 MouseEvent[MOUSE_MOVED,(69,0),button=0,clickCount=0]
  11. ComboPopup.popup 上的 MouseEvent[MOUSE_EXITED,(68,2),button=0,clickCount=0]
  12. ComboBox.list 上的 MouseEvent[MOUSE_ENTERED,(67,1),button=0,clickCount=0]
  13. ComboBox.list 上的 MouseEvent[MOUSE_MOVED,(67,1),button=0,clickCount=0]
  14. (更多动作)
  15. MouseEvent[MOUSE_PRESSED,(57,9),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] 在 ComboBox.list
  16. ComboBox.list 上的 MouseEvent[MOUSE_RELEASED,(57,9),button=1,modifiers=Button1,clickCount=1]
  17. MouseEvent[MOUSE_ENTERED,(25,10),button=1,modifiers=Button1, extModifiers=Button1 ,clickCount=1] 在 JButton[...]
  18. MouseEvent[MOUSE_MOVED,(26,10),button=0,clickCount=0] 在 JButton[...]

问题:什么时候mouse_pressed/的顺序mouse_released与其他鼠标事件的修饰符不一致?是否只有mouse_entered/mouse_exited事件发生在修饰符不一致的情况下?这仅在单击JComboBox弹出窗口时发生吗?

我在 Ubuntu 上运行 Java 1.6。

编辑:为清楚起见,包括更长的日志。

4

1 回答 1

1

在我的平台上,“单击JComboBox并单击第一项”会产生如下所示的事件。

结果可能取决于com.apple.laf.AquaComboBoxButton平台的ComboBoxUI委托。我无法解释MOUSE_CLICKED你的结果中没有。点击后我没有移动鼠标JComboBox;看来您做到了,并且记录了该结果。

请注意,“扩展修饰符表示事件发生所有模态键的状态,例如ALT, CTRL,META和鼠标按钮”,因此在某些事件上的存在似乎并不矛盾。我没有看到任何表明事件包含任何修饰符的信息。extModifiersMOUSE_MOVED

我不知道潜在问题的解决方案,除了重新检查对合成MOUSE_RELEASED事件的需求。作为替代方案,您可以通过检查包含层次结构来验证组件是否已删除。

2012 年 5 月 11 日 10:36:36 AM DemoEvents$1 eventDispatched
信息:java.awt.event.MouseEvent[MOUSE_PRESSED,(85,9),absolute(124,58),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on com.apple.laf.AquaComboBoxButton[ …]
2012 年 5 月 11 日 10:36:36 AM DemoEvents$1 eventDispatched
信息:com.apple.laf.AquaComboBoxButton[...] 上的 java.awt.event.MouseEvent[MOUSE_RELEASED,(85,9),absolute(124,58),button=1,modifiers=Button1,clickCount=1]
2012 年 5 月 11 日 10:36:36 AM DemoEvents$1 eventDispatched
信息:com.apple.laf.AquaComboBoxButton[...] 上的 java.awt.event.MouseEvent[MOUSE_CLICKED,(85,9),absolute(124,58),button=1,modifiers=Button1,clickCount=1]
2012 年 5 月 11 日 10:36:38 AM DemoEvents$1 eventDispatched
信息:ComboBox.list 上的 java.awt.event.MouseEvent[MOUSE_ENTERED,(91,6),absolute(124,58),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1]
2012 年 5 月 11 日 10:36:38 AM DemoEvents$1 eventDispatched
信息:ComboBox.list 上的 java.awt.event.MouseEvent[MOUSE_PRESSED,(91,6),absolute(124,58),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1]
2012 年 5 月 11 日 10:36:38 AM DemoEvents$1 eventDispatched
信息:ComboBox.list 上的 java.awt.event.MouseEvent[MOUSE_RELEASED,(91,6),absolute(124,58),button=1,modifiers=Button1,clickCount=1]
于 2012-05-11T15:48:22.383 回答