什么时候AWT(扩展)修饰符保证有效?

时间:2012-05-11 03:08:23

标签: java swing awt mouseevent

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

这是一个简单的主函数,其中包含JComboBox,其下有一个组件,也可以接收鼠标事件。

Screenshot of window with 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并点击“one”项时,我会收到这些事件。带有extModifiers = Button1的mouse_entered没有意义,因为在<{strong> mouse_released event之后发送了!这是一个简化的日志,从我点击组合框,然后单击第一个项目。看看底部的粗体事件:

  1. MetalComboBoxButton [...]
  2. 上的MouseEvent [MOUSE_PRESSED,(1,13),button = 1,modifiers = Button1,extModifiers = Button1,clickCount = 1]
  3. MetalComboBoxButton [...]
  4. 上的MouseEvent [MOUSE_RELEASED,(1,13),button = 1,modifiers = Button1,clickCount = 1]
  5. MetalComboBoxButton [...]
  6. 上的MouseEvent [MOUSE_MOVED,(0,14),button = 0,clickCount = 0]
  7. MetalComboBoxButton [...]
  8. 上的MouseEvent [MOUSE_EXITED,( - 2,15),button = 0,clickCount = 0]
  9. JComboBox上的MouseEvent [MOUSE_ENTERED,(81,15),button = 0,clickCount = 0] [...]
  10. JComboBox上的MouseEvent [MOUSE_MOVED,(81,15),button = 0,clickCount = 0] [...]
  11. (更多动作)
  12. JComboBox上的MouseEvent [MOUSE_EXITED,(69,24),button = 0,clickCount = 0] [...]
  13. ComboPopup.popup上的MouseEvent [MOUSE_ENTERED,(69,0),button = 0,clickCount = 0]
  14. ComboPopup.popup上的MouseEvent [MOUSE_MOVED,(69,0),button = 0,clickCount = 0]
  15. ComboPopup.popup上的MouseEvent [MOUSE_EXITED,(68,2),button = 0,clickCount = 0]
  16. ComboBox.list上的MouseEvent [MOUSE_ENTERED,(67,1),button = 0,clickCount = 0]
  17. ComboBox.list上的MouseEvent [MOUSE_MOVED,(67,1),button = 0,clickCount = 0]
  18. (更多动作)
  19. ComboBox.list上的MouseEvent [MOUSE_PRESSED,(57,9),button = 1,modifiers = Button1,extModifiers = Button1,clickCount = 1]
  20. ComboBox.list上的MouseEvent [MOUSE_RELEASED,(57,9),button = 1,modifiers = Button1,clickCount = 1]
  21. JButton上的MouseEvent [MOUSE_ENTERED,(25,10),button = 1,modifiers = Button1, extModifiers = Button1 ,clickCount = 1] [...]
  22. JButton上的MouseEvent [MOUSE_MOVED,(26,10),button = 0,clickCount = 0] [...]
  23. 问题:mouse_pressed / mouse_released的顺序何时与其他鼠标事件的修饰符不一致?只有mouse_entered / mouse_exited事件与不一致的修饰符一起发生?只有在点击JComboBox的弹出窗口时才会发生这种情况吗?

    我在Ubuntu上运行Java 1.6。

    编辑:为了清晰起见,包含更长的日志。

1 个答案:

答案 0 :(得分:1)

在我的平台上,“点击JComboBox并点击一个”项会产生下面显示的事件。

结果可能取决于com.apple.laf.AquaComboBoxButton平台的ComboBoxUI代表。我无法说明您的结果中缺少MOUSE_CLICKED。点击JComboBox后我没有移动鼠标;看来你做了,并且记录了结果。

请注意,“Extended modifiers代表所有模态键的状态,例如ALTCTRLMETA以及之后的鼠标按钮事件发生了,“因此extModifiers在某些事件中的存在似乎并不一致。我没有看到任何表明MOUSE_MOVED事件包含任何修饰符的内容。

除了重新检查合成MOUSE_RELEASED事件的需要之外,我不知道底层问题的解决方案。作为替代方法,您可以通过检查containment hierarchy来验证是否删除了某个组件。

May 11, 2012 10:36:36 AM DemoEvents$1 eventDispatched
INFO: java.awt.event.MouseEvent[MOUSE_PRESSED,(85,9),absolute(124,58),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on com.apple.laf.AquaComboBoxButton[…]
May 11, 2012 10:36:36 AM DemoEvents$1 eventDispatched
INFO: java.awt.event.MouseEvent[MOUSE_RELEASED,(85,9),absolute(124,58),button=1,modifiers=Button1,clickCount=1] on com.apple.laf.AquaComboBoxButton[…]
May 11, 2012 10:36:36 AM DemoEvents$1 eventDispatched
INFO: java.awt.event.MouseEvent[MOUSE_CLICKED,(85,9),absolute(124,58),button=1,modifiers=Button1,clickCount=1] on com.apple.laf.AquaComboBoxButton[…]
May 11, 2012 10:36:38 AM DemoEvents$1 eventDispatched
INFO: java.awt.event.MouseEvent[MOUSE_ENTERED,(91,6),absolute(124,58),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on ComboBox.list
May 11, 2012 10:36:38 AM DemoEvents$1 eventDispatched
INFO: java.awt.event.MouseEvent[MOUSE_PRESSED,(91,6),absolute(124,58),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on ComboBox.list
May 11, 2012 10:36:38 AM DemoEvents$1 eventDispatched
INFO: java.awt.event.MouseEvent[MOUSE_RELEASED,(91,6),absolute(124,58),button=1,modifiers=Button1,clickCount=1] on ComboBox.list