SwingUtilities.convertMouseEvent()在Java7中将按钮设置为NOBUTTON

时间:2013-01-22 07:41:26

标签: java swing applet jscrollpane swingutilities

正如我们所知MouseEventJScrollPane中丢失,即没有传递给父母,这是一个尚未修复的旧bug: 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后,问题得到了解决,但现在我正在测试Applet并且Chrome迫使我将插件升级到版本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设置按钮。

2 个答案:

答案 0 :(得分:3)

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

通过MouseEvent构造函数调试我看到button字段最初设置为零,构造函数末尾的setNewModifiers调用基于button更改modifierssourceEvent.getModifiers字段(在SwingUtilities.convertMouseEvent中构建转换后的鼠标事件时从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=] 接收其值。

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

MouseEvent.NOBUTTON

回答您的问题:我认为MouseEvent已传递给button构造函数,因为modifiers字段的值将由值确定无论如何,SwingUtilities.convertMouseEvent字段。在我的笔记本电脑上,事情按照我对Java 7和6的预期工作,所以它看起来不像是一个bug。您的应用程序是否在浏览器中运行,这是否会改变鼠标事件的转换方式?您是否已经创建了一个解决问题的工作,或者您可以共享一些applet代码吗?


其他事件类型
MouseWheelEvent处理的前两个案例会创建MenuDragMouseEventMouseEvent个对象。两个构造函数(最终)都使用MouseEvent.NOBUTTON参数调用button构造函数。 (在我的笔记本电脑上查看这些事件(没有转换),MouseWheelEvent的{​​{1}}字段始终为零(我的鼠标只有一个滚轮)。对于MenuDragMouseEvent个对象{{1} }等于button事件的一个,否则为零,而menuDragMouseReleased字段总是等于modifiers。)所以看起来BUTTON1_MASK很受欢迎MouseEvent.NOBUTTON构造函数的参数。

答案 1 :(得分:0)

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

无论如何,看起来问题已经在Java 8中解决了。