Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:为鼠标事件定义单元组件_Java_Swing_User Interface_Components_Mouseevent - Fatal编程技术网

Java:为鼠标事件定义单元组件

Java:为鼠标事件定义单元组件,java,swing,user-interface,components,mouseevent,Java,Swing,User Interface,Components,Mouseevent,我想要一个名为mainPanel的JPanel,并在其上添加几个组件;此外,我还定义了一个mouseAdapter,并将其添加到我的mainPanel中,该面板覆盖mouseEntered和mouseExited,例如,当鼠标进入mainPanel时更改其背景色。但当鼠标进入mainPanel并进入我添加到其上的组件(例如标签)时,mouseExited事件被调用;但我不想要这个,因为鼠标在主面板的区域中;我想在鼠标退出主面板时调用它;还希望将此用于鼠标插入。我之前在主面板上的组件中添加了鼠标侦

我想要一个名为
mainPanel
JPanel
,并在其上添加几个组件;此外,我还定义了一个
mouseAdapter
,并将其添加到我的
mainPanel
中,该面板覆盖
mouseEntered
mouseExited
,例如,当鼠标进入
mainPanel
时更改其背景色。但当鼠标进入
mainPanel
并进入我添加到其上的组件(例如标签)时,
mouseExited
事件被调用;但我不想要这个,因为鼠标在
主面板的区域中;我想在鼠标退出主面板时调用它;还希望将此用于
鼠标插入
。我之前在
主面板上的组件中添加了
鼠标侦听器
,但这不是一个明确的解决方案。有人能告诉我一个明确的方法吗

感谢您的关注;
良好锁定

您希望在完整边界上调用
鼠标插入
鼠标退出
。正如您所注意到的,这在“普通”鼠标侦听器中是不可能直接实现的

最简单的方法是将侦听器添加到面板的所有子组件:

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);
}

另一个解决方法(上一个答案)。。。 …是设置并自己检查边界:

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);
}

有一些东西你需要注意。。。事件重新分布就是其中之一,在您的案例中可能是一个问题。遵循并在玻璃窗格上实现事件分发侦听器:

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);

获取组件及其所有子组件的鼠标事件是。。。很难做到正确。您可能会考虑依赖稳定的(和广泛的测试:)代码。jdk7的方法是使用JLayer(它在内部注册一个AWTEventListener,因为它拥有所有特权)。对于早期版本,您可以使用它的前身

也许一个代码示例会有所帮助。开始。请参阅[此][1]问题的答案。[1] :谢谢。我看了演示,是的,它很有效。但它是如此复杂和特殊的例子。我正在寻找一种简单的方法。@sajad:添加了另一个示例(第一个),其中我为所有子组件添加了相同的侦听器。这够简单吗?