2

我首先遇到了一个不同的问题,所以我发了这篇文章: Java JPanel mouse listener doesn't work over its components

答案让我找到了一个 java GlassPane。我看到了关于这个的其他帖子,他们都指向这篇文章: http ://weblogs.java.net/blog/alexfromsun/archive/2006/09/a_wellbehaved_g.html 。

我使用了文章 (FinalGlassPane.java) 中的示例并将其设置与测试应用程序中的完全一样:

GlassPane glass = new GlassPane(this);
getRootPane().setGlassPane(glass);
GestureListener gl = new GestureListener();
glass.addMouseMotionListener(gl);
glass.addMouseListener(gl);
glass.setVisible(true);
if (glass instanceof AWTEventListener) {
    AWTEventListener al = (AWTEventListener) glass;
    Toolkit.getDefaultToolkit().addAWTEventListener(al,
            AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
}

但是我仍然有同样的问题,玻璃阻止我点击它下面的任何按钮(JButton)。

如果您很友好地阅读了我最初的 SO 问题并认为 glassPane 不适合我,请给我发一个替代解决方案,否则请告诉我为什么这不起作用。

提前致谢。

编辑:它可以工作,但是当我添加自己的 MouseListener 时停止工作

请注意,在我的代码中我添加了我自己的GestureListener,我无法将我自己的 MouseListener 添加到这个实现中——这就是它不起作用的原因。我把这些线拿掉了,玻璃板现在可以正常工作了。

关于 MouseListener 的代码(FinalGlassPane.java)中有这个通知,我不太明白,所以我的新问题是如何将我自己的 MouseListener 添加到这个玻璃窗格中?

/**
 * If someone adds a mouseListener to the GlassPane or set a new cursor
 * we expect that he knows what he is doing
 * and return the super.contains(x, y)
 * otherwise we return false to respect the cursors
 * for the underneath components
 */
@Override
public boolean contains(int x, int y) {
    if (getMouseListeners().length == 0 && getMouseMotionListeners().length == 0
            && getMouseWheelListeners().length == 0
            && getCursor() == Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)) {
        return false;
    }
    return super.contains(x, y);
}

附加信息:

如果我总是在方法中返回 false,contains(int, int)按钮总是可以工作,但 GlassPane 上的 MouseListener 不能。如果我总是返回“super.contains(x,y)”,则会发生相反的情况:GlassPane 上的 MouseListener 可以工作,但我无法单击下面的任何组件。

最后编辑 所以我得出的结论是,我不能(或没有)有办法(使用 Java 6)让我的应用程序有 2 层可以同时接收 MouseListener 事件(mousePressed、mouseReleased)。最后,我在原始问题上使用了解决方案,即创建一个自定义 JButton 并将 MouseListener 添加到每个实例。

4

2 回答 2

2

如果您真的需要SwingUtilities中的 convertXxx 或 getXxx 方法,您的两个问题都不清楚

1)您可以将JLabel(调度鼠标事件)放到GlassPane,这JLabel可以放置/覆盖整个可用RectangleJFrame,或仅需要Bounds

2)您可以将JLabel(调度鼠标事件)放到JViewport,这JLabel可以放置/覆盖整个可用RectangleJScrollPane / JViewport,或仅需要Bounds

3)你可以使用JLayeredPane(最多6层)

4)您可以使用JLayer(Java7)基于JXLayer(对于Java6,也许是更好的选择)

于 2012-03-22T01:22:43.850 回答
0

请参阅 Java 教程中的“如何使用根窗格”,搜索单词“redispatches”(大约向下一页),这有一个类似于您尝试使用复选框实现的示例:

http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html

简而言之,您需要在平移鼠标光标的位置时使用SwingUtilities.getDeepestComponentAt(..)和。Component.dispatchEvent(..)

于 2012-03-22T00:30:54.567 回答