3

正如我们所知MouseEvent,迷失在 中JScrollPane,即未交付给父母,这是一个尚未修复的旧错误: https ://forums.oracle.com/forums/thread.jspa?threadID=1362237

因此,我通过使用临时侦听器捕获事件JScrollPane然后将事件分派给它的父级来使用真正的侦听器进行处理来使用变通方法。

    private class DispatchListener extends MouseAdapter {
    @Override
    public void mousePressed (MouseEvent me) {
        System.out.println("dispatch.mousePressed: " + me.getButton());
        preDispatchEvent(me);
    }

    @Override
    public void mouseReleased (MouseEvent me) {
        preDispatchEvent(me);
    }

    @Override
    public void mouseDragged (MouseEvent me) {
        System.out.println("dispatch.mouseDragged");
        preDispatchEvent(me);
    }

    private void preDispatchEvent (MouseEvent me) {
        JScrollPane pane = (JScrollPane)me.getSource();
        MouseEvent newMe = SwingUtilities.convertMouseEvent(pane.getViewport(), me, tablePanel);
        dispatchEvent(newMe);
    }
}

它工作正常,但使用 Java 7 的人开始抱怨鼠标单击在应用程序中没有反应。降级到 Java 6 后问题得到解决,但现在我正在测试AppletChrome强制我将插件升级到版本 7。

调试后,我发现convertMouseEvent将按钮设置为MouseEvent.NOBUTTON与传递的按钮无关

MouseEvent newMe = SwingUtilities.convertMouseEvent(pane.getViewport(), me, tablePanel);

来自 Eclipse 中的源代码

else {
        newEvent = new MouseEvent(newSource,
                                  sourceEvent.getID(),
                                  sourceEvent.getWhen(),
                                  sourceEvent.getModifiers(),
                                  p.x,p.y,
                                  sourceEvent.getXOnScreen(),
                                  sourceEvent.getYOnScreen(),
                                  sourceEvent.getClickCount(),
                                  sourceEvent.isPopupTrigger(),
                                  MouseEvent.NOBUTTON ); //!!!
    }
    return newEvent;

我不知道为什么它是这样实现的?它是另一个错误或功能吗?

似乎我需要创建自己的对象,而无需SwingUtilities.convertMouseEvent从 sourceEvent 调用和设置按钮。

4

2 回答 2

3

这是一个有趣的问题。MouseEvent.NOBUTTONin SwingUtilities.convertMouseEventsure的使用看起来很奇怪。但是,我无法重现 Java 7 的问题;对我来说,button转换后的鼠标事件字段对于 Java 7 和 6 是正确的(在 Windows 7 笔记本电脑上使用 1.7.0-b147 64 位和 1.6.0_21-b07 64 位)。

通过MouseEvent构造函数进行调试,我看到虽然该button字段最初设置为零,但setNewModifiers在构造函数末尾的调用会button根据该字段发生变化(该字段从在构造转换的鼠标事件时modifiers接收其值)。sourceEvent.getModifiersSwingUtilities.convertMouseEvent

通过单击转换的鼠标事件如下所示(对于 Java 7):

java.awt.event.MouseEvent[MOUSE_PRESSED,(185,175),absolute(593,305),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,381x259,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_RELEASED,(185,175),absolute(593,305),button=1,modifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,381x259,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]

回答您的问题:我认为MouseEvent.NOBUTTON是传递给MouseEvent构造函数,因为该button字段的值将由该字段的值决定modifiers。在我的笔记本电脑上,Java 7 和 Java 6 都按我预期的那样工作,所以对我来说它看起来不像是一个错误。您的应用程序是否在浏览器中运行,这对鼠标事件的转换方式有影响吗?您是否已经创建了解决该问题的解决方法,或者您可以分享一些小程序代码吗?


其他事件类型创建一个或一个对象
处理的前两种情况。两个构造函数(最终)都调用带有参数的构造函数。(在我的笔记本电脑上查看这些事件(没有转换),a 的字段始终为零(我的鼠标只有一个滚轮)。对于事件,对象等于 1,否则为零,而字段始终等于.) 所以它看起来作为构造函数的参数非常流行。SwingUtilities.convertMouseEventMouseWheelEventMenuDragMouseEventMouseEventMouseEvent.NOBUTTONbuttonMouseWheelEventMenuDragMouseEventbuttonmenuDragMouseReleasedmodifiersBUTTON1_MASKMouseEvent.NOBUTTONMouseEvent

于 2013-01-26T23:44:39.807 回答
0

请参阅http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7181403 - 看起来 convertMouseEvent() 最近没有更改,因此其他代码更改必须对您在 Java 7 中看到的更改负责(我可以在这里也可以使用 1.7.0_21 重现此问题)。

无论如何,看起来这个问题已经在 J​​ava 8 中解决了。

于 2013-06-07T10:39:32.150 回答