我已经创建了一个JFrame,它带有一个包含不同组件的JPanel,例如,我希望当鼠标位于JPanel的边界内时,JPanel具有可见的边框和可见的图像。我的问题是,只要鼠标悬停在JPanel内的“可交互”组件上,它就会注册为鼠标退出JPanel。我希望它能够绘制这些内容,只要它“s在JPanel的边界内,当鼠标离开JPanel的边界时,边界和图像会“消失”。有什么方法可以实现这一点吗?
下面是一个小演示:
public class Test {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new TestFrame();
}
static class TestFrame extends JFrame{
JPanel panel;
JButton hoverButton;
JButton appearingButton;
public TestFrame() {
super();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBackground(Color.red);
hoverButton = new JButton("Hover me!");
appearingButton = new JButton("I appeared!");
appearingButton.setVisible(false);
panel.add(hoverButton);
panel.add(appearingButton);
panel.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
System.out.println("Entered!");
appearingButton.setVisible(true);
}
public void mouseExited(java.awt.event.MouseEvent evt) {
System.out.println("Exited!");
appearingButton.setVisible(false);
}
});
add(panel);
setSize(new Dimension(200, 200));
setVisible(true);
}
}
}
当鼠标位于JPanel内部(覆盖整个JFrame)时,第二个按钮将会出现。但是,将鼠标悬停在第一个按钮上会使第二个按钮消失。我希望只要您位于JPanel的边界内,第二个按钮就会显示。
4条答案
按热度按时间jtoj6r0c1#
这实际上比听起来要困难得多。您需要能够监视容器的子组件的所有鼠标事件。不幸的是,您要么得到一个全有或全无的解决方案。也就是说,您要么得到您现在遇到的问题,其中
MouseListener
在另一个组件开始捕获鼠标事件时停止报告鼠标事件(这是鼠标侦听器API的工作方式)或者可以看到系统正在处理的所有鼠标事件。这就需要提供某种类型的过滤过程,以便可以过滤掉那些您不感兴趣的事件,例如...
这基本上是将一个
AWTEventListener
附加到主事件处理框架中,它将告诉您已处理的特定类型的所有事件。然后,您需要检查所讨论的事件是否确实发生在您感兴趣的上下文(您自己或它的一个子事件)中,然后再采取适当的操作...Java 10(~ 8+?)/2018年
自从我写了最初的答案以来,事件机制的工作方式似乎发生了一些变化(我也犯了一些小错误🙄😓)
为了使
AWTListener
生成事件,所有“感兴趣”的组件都需要注册鼠标事件我做了一个非常基本的测试,创建了一个普通的旧
JPanel
(和一个按钮),并将它们添加到父容器中,然后使用...这将为按钮和面板生成事件
vmpqdwk32#
一种解决方案是向JPanel中的每个子组件添加鼠标侦听器。
使用您的代码,这里有一种方法:
ne5o7dgx3#
这实际上比你想象的要容易得多:
***if***语句将过滤掉鼠标仍在面板中时发生的所有***mouseExited***事件。
一个后果是,您最终将收到多个***mouseEntered***事件,而这些事件之间没有***mouseExited***,但由此导致的任何问题都可以轻松避免。
hgb9j2n64#
当编辑单元格时,我发现自己在使用
JTable
时遇到了类似的情况。JTable
有一个鼠标监听器,它可以跟踪鼠标的位置,但是一旦开始编辑单元格,表格就不会接收到mouseExited
/MOUSE_EXITED
事件。当收到 * 鼠标退出 * 事件时,它正在工作,但我发现有时当指针移动有点不同时,通常太快,则 * 鼠标退出 * 事件未触发,即使指针实际移出
JTable
。通过尝试MadProgrammer's solution,问题消失了。这里有一个小小的修改,使用边界执行检查,而不是遍历组件树。另外,我想发出与表相关的事件,而不是实际的源。
11.0.17+8-LTS基础数据库-aarch 64宏操作系统13.1