我想要一个名为JPanel
的mainPanel
并在上面添加几个组件;另外,我定义了一个mouseAdapter
并添加到我的mainPanel
中,它覆盖了mouseEntered
和mouseExited
,例如,当鼠标输入时,更改mainPanel
的背景颜色。但是,当鼠标进入mainPanel
并进入我在其上添加的组件(例如标签)时,就会调用mouseExited
事件;但是我不希望这样,因为鼠标位于mainPanel
区域中;我希望它在鼠标退出mainPanel
区域时被调用;并且也想要mouseEntered
。我以前在mouseListeners
的组件上添加了mainPanel
,但这不是一个明确的解决方案。谁能告诉我一个明确的方法呢?
感谢您的关注;
锁好
最佳答案
您希望在完整边界上调用mouseEntered
和mouseExited
。正如您所注意到的,使用“正常”的MouseListener
无法直接实现。
最简单的方法是将侦听器添加到面板的所有子组件中:
private static void addListenerToAllComponents(JComponent c, MouseListener l) {
c.addMouseListener(l);
for (Component cc : c.getComponents())
if (cc instanceof JComponent)
addListenerToAllComponents((JComponent) cc, l);
}
完整示例:
public static void main(String[] args) {
final JFrame frame = new JFrame("Test");
frame.add(new JLabel("Testing"), BorderLayout.NORTH);
final JPanel panel = new JPanel(new GridLayout(2, 1));
panel.setBackground(Color.RED);
MouseListener l = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
panel.setBackground(Color.BLUE);
}
@Override
public void mouseExited(MouseEvent e) {
panel.setBackground(Color.RED);
}
};
panel.add(new JLabel("Hello"));
panel.add(new JTextField("World!"));
addListenerToAllComponents(panel, l);
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
另一个解决方法(先前的答案)...
...是要设置GlassPane并自己检查范围:
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.add(new JLabel("Testing"), BorderLayout.NORTH);
final JPanel panel = new JPanel(new GridLayout(2, 1));
frame.add(panel, BorderLayout.CENTER);
panel.add(new JLabel("Hello"));
panel.add(new JTextField("World!"));
class GlassPane extends JComponent {
GlassPane(final JComponent c) {
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = SwingUtilities.convertPoint(e.getComponent(),
e.getPoint(),
c);
if (c.contains(p))
c.setBackground(Color.BLUE);
else
c.setBackground(Color.RED);
}
});
addMouseListener(new MouseAdapter() {
public void mouseExited(MouseEvent e) {
c.setBackground(Color.MAGENTA);
}
});
}
}
GlassPane glass = new GlassPane(panel);
frame.setGlassPane(glass);
glass.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
您需要查看一些内容。事件重新分发是其中一项,在您的情况下可能是个问题。遵循this example并在玻璃窗格上实现事件分发侦听器:
MouseInputListener i = new MouseInputListener() {
private void redispatchMouseEvent(MouseEvent e) {
Point glassPanePoint = e.getPoint();
Container container = frame.getContentPane();
Point containerPoint = SwingUtilities.convertPoint(
GlassPane.this,
glassPanePoint,
container);
Component component =
SwingUtilities.getDeepestComponentAt(
container,
containerPoint.x,
containerPoint.y);
if (component != null) {
Point componentPoint = SwingUtilities.convertPoint(
GlassPane.this,
glassPanePoint,
component);
component.dispatchEvent(new MouseEvent(component,
e.getID(),
e.getWhen(),
e.getModifiers(),
componentPoint.x,
componentPoint.y,
e.getClickCount(),
e.isPopupTrigger()));
}
}
public void mouseMoved(MouseEvent e) {
redispatchMouseEvent(e);
}
public void mouseDragged(MouseEvent e) {
redispatchMouseEvent(e);
}
public void mouseClicked(MouseEvent e) {
redispatchMouseEvent(e);
}
public void mouseEntered(MouseEvent e) {
redispatchMouseEvent(e);
}
public void mouseExited(MouseEvent e) {
redispatchMouseEvent(e);
}
public void mousePressed(MouseEvent e) {
redispatchMouseEvent(e);
}
public void mouseReleased(MouseEvent e) {
redispatchMouseEvent(e);
}
};
addMouseListener(i);
addMouseMotionListener(i);
关于java - Java:为鼠标事件定义单位组件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7062154/