问题描述
我想要一个名为mainPanel
的JPanel
并在上面添加几个组件;我还定义了一个mouseAdapter
并添加到我的mainPanel
中,它覆盖了mouseEntered
和mouseExited
以例如在鼠标输入时更改mainPanel
的背景色.但是,当鼠标进入mainPanel
并进入我在其上添加的组件(例如标签)时,将调用mouseExited
事件.但是我不希望这样,因为鼠标位于mainPanel
区域中.我希望它在鼠标退出mainPanel
区域时被调用;并且也想要mouseEntered
.我以前在mainPanel
上的组件中添加了mouseListeners
,但这不是一个明确的解决方案.谁能告诉我一个清晰的方法来达到我的目的?
I want to have a JPanel
called mainPanel
and add several components on it; Also I defined a mouseAdapter
and added to my mainPanel
that overrides mouseEntered
and mouseExited
to for example change background color of mainPanel
when mouse entered it. But when mouse entered to mainPanel
and entered to components I added on it (for example labels) mouseExited
event is called; But I don't want this as mouse is in area of mainPanel
; I want it be called just when mouse exited mainPanel
area; and also want this for mouseEntered
. I previously added mouseListeners
to components on mainPanel
but it is not a clear solution. Can anyone tell me a clear way for my purpose?
感谢您的关注;好锁
推荐答案
您希望在完全边界上调用mouseEntered
和mouseExited
.如您所注意到的,这对于正常" MouseListener
是不可能直接实现的.
You want the mouseEntered
and mouseExited
to be called on full boundaries. This is, as you have noticed, not directly possible with the "normal" MouseListener
.
最简单的方法是将侦听器添加到面板的所有子组件中:
The simplest way is to add the listener to all child-components of the panel:
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 然后自己检查范围:
Another workaround (previous answer)...
...is to set a GlassPane and check bounds yourself:
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);
}
您需要查看一些内容...事件重新分配是其中之一,在您的情况下可能是个问题.遵循此示例并实施玻璃窗格上的事件分发侦听器:
There are some stuff you need to look in to... Event redistribution is one and might be a problem in your case. Follow this example and implement an event distribution listener on the glass pane:
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:为鼠标事件定义单位组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!