我想要一个名为JPanelmainPanel并在上面添加几个组件;另外,我定义了一个mouseAdapter并添加到我的mainPanel中,它覆盖了mouseEnteredmouseExited,例如,当鼠标输入时,更改mainPanel的背景颜色。但是,当鼠标进入mainPanel并进入我在其上添加的组件(例如标签)时,就会调用mouseExited事件;但是我不希望这样,因为鼠标位于mainPanel区域中;我希望它在鼠标退出mainPanel区域时被调用;并且也想要mouseEntered。我以前在mouseListeners的组件上添加了mainPanel,但这不是一个明确的解决方案。谁能告诉我一个明确的方法呢?

感谢您的关注;
锁好

最佳答案

您希望在完整边界上调用mouseEnteredmouseExited。正如您所注意到的,使用“正常”的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/

10-08 21:26