java - AWT(扩展)修饰符何时保证有效?

标签 java swing awt mouseevent

我正在记录 AWT 事件(mouse_pressedmouse_releasedkey_pressedkey_released 等)以在单元测试中使用 Robot 重播它们的日志。但是我发现有时我需要在它们丢失时插入 mouse_released 事件,因为我的一些组件在 mouse_pressed 上自行删除所以 mouse_released 是从未派出。我认为一个好的方法是在看到具有 modifiersEx=Button1 的鼠标事件时插入 mouse_released 后跟具有 modifiersEx=0,除非第二个事件已经 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 没有意义,因为它是在mouse_released 事件之后分派(dispatch)的!这是我单击组合框然后单击第一项时的简化日志。查看底部的粗体事件:

  1. MetalComboBoxButton[...] 上的 MouseEvent[MOUSE_PRESSED,(1,13),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1]
  2. MetalComboBoxButton[...] 上的 MouseEvent[MOUSE_RELEASED,(1,13),button=1,modifiers=Button1,clickCount=1]
  3. MetalComboBoxButton[...] 上的 MouseEvent[MOUSE_MOVED,(0,14),button=0,clickCount=0]
  4. MetalComboBoxButton[...] 上的 MouseEvent[MOUSE_EXITED,(-2,15),button=0,clickCount=0]
  5. JComboBox[...] 上的 MouseEvent[MOUSE_ENTERED,(81,15),button=0,clickCount=0]
  6. JComboBox[...] 上的 MouseEvent[MOUSE_MOVED,(81,15),button=0,clickCount=0]
  7. (更多 Action )
  8. JComboBox[...] 上的 MouseEvent[MOUSE_EXITED,(69,24),button=0,clickCount=0]
  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. (更多 Action )
  15. ComboBox.list 上的 MouseEvent[MOUSE_PRESSED,(57,9),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1]
  16. ComboBox.list 上的 MouseEvent[MOUSE_RELEASED,(57,9),button=1,modifiers=Button1,clickCount=1]
  17. JButton[...] 上的 MouseEvent[MOUSE_ENTERED,(25,10),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1]
  18. JButton[...] 上的 MouseEvent[MOUSE_MOVED,(26,10),button=0,clickCount=0]

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

我在 Ubuntu 上运行 Java 1.6。

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

最佳答案

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

结果可能取决于 com.apple.laf.AquaComboBoxButton,即平台的 ComboBoxUI 委托(delegate)。我无法解释您的结果中缺少 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

关于java - AWT(扩展)修饰符何时保证有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10544909/

相关文章:

Java 应用程序 Bundled for Mac 无法启动

java - 图形 (java.awt.Graphics) 无法在调用时工作

java - jpanel 与其他组件重叠

java使用机器人类发送击键

java - AppEngine ChannelAPI 警告 : No file found for:/_ah/channel/connected/

java - Andengine,如何用触摸屏移动 Sprite

java - 尽管在主要 Activity 中工作,但 native 函数在自定义 View 中抛出 UnsatisfiedLinkError

java - 如何从另一个类访问具有多个 swing 组件的方法? ( java )

Java创建画笔描边 Action

java - Swing 和 AWT : ContentPane items not showing in JFrame