如何避免mouseExited在任何嵌套组件上触发

时间:2015-10-07 13:20:55

标签: java swing mouselistener

在我的代码中我有:

一个扩展JComponent的抽象类,它包含一些JTextField。 JTextFields不可编辑。 JComponent类实现MouseListener: - 当mouseEntered事件触发时,会向其添加边框。 - 当mouseExited事件触发边框时被删除。 - 当mouseClicked事件触发时,该组件的所有字段都设置为可编辑。

这应该以这种方式运作:

  • 用户想要编辑字段。
  • 他将鼠标悬停在jComponent的任何一点
  • 在jComponent上绘制边框以突出显示它
  • 用户点击并触发mouseClicked方法,这会触发其内容。

问题是: 当鼠标在任何JTextField上移动时,mouseExited将触发。 你会如何解决这个问题?

下面是一个简单的类,它将向您展示一个窗口,其中包含一个jTextField,该窗口包含一个实现MouseListener的面板,其方式与上述方法非常类似。不要考虑它是如何写的,只是出于目的!

public static void main(String[] args)  {       
        SwingUtilities.invokeLater(new Runnable() {
            public void run(){   
                int i=0;
                //mainWindow
                    JFrame mainWindow = new JFrame("MyFrame");
                    mainWindow.setLayout(new BorderLayout());
                    mainWindow.setMinimumSize(new Dimension(200,200));

                    JPanel viewPort = new JPanel();

                    final JTextField text = new JTextField("SOME_RANDOM_TEXT");
                    text.setEditable(false);

                    final JPanel panel = new JPanel();
                    panel.add(text);
                    panel.setBackground(Color.green);
                    panel.addMouseListener(new MouseListener() {
                        @Override
                        public void mouseReleased(MouseEvent e) {
                            //NOTHING
                        }
                        @Override
                        public void mousePressed(MouseEvent e) {
                            //NOTHING
                        }

                        @Override
                        public void mouseExited(MouseEvent e) {
                            panel.setBorder(BorderFactory.createEmptyBorder());
                        }

                        @Override
                        public void mouseEntered(MouseEvent e) {
                            panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
                        }

                        @Override
                        public void mouseClicked(MouseEvent e) {
                            ((JTextField)panel.getComponent(0)).setEditable(true);
                            panel.getComponent(0).requestFocus();
                        }
                    });
                    viewPort.add(panel);
                    mainWindow.add(viewPort,BorderLayout.CENTER);
                    mainWindow.setVisible(true);
            }
        });
    }

2 个答案:

答案 0 :(得分:3)

您可以检查事件的鼠标点以确定该点是否仍然在面板的边界内:

panel.addMouseListener(new MouseAdapter()
{
    @Override
    public void mouseExited(MouseEvent e)
    {
        Rectangle r = e.getComponent().getBounds();
        Point p = e.getPoint();

        if (p.x < 0 || p.x >= r.width
        ||  p.y < 0 || p.y >= r.height)
            panel.setBorder( null );
    }

    @Override
    public void mouseEntered(MouseEvent e)
    {
        panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
    }
});

扩展MouseAdapter更容易,然后您只需要覆盖要自定义的方法。

答案 1 :(得分:2)

问题是你将MouseListener设置为JPanel,这没有多大意义(对于所需的描述行为)。

只需将MouseListener更改为JTextField

即可
text.addMouseListener(new MouseListener() {

这对我很好。

<强>更新

  

你错过了一些伙伴:)请快速回答,但是,我的JPanel可以包含多个单一的textField,它可以包含例如10个!

示例可以作为示例,但在现实生活中,您将不会创建内部侦听器,您将创建一个类。

class MyMouseListener implements MouseListener {
    // define methods and behaviour
}

然后您将其添加到您的可选区域,例如:

MyMouseListener listener = new MyMouseListener()
panel1.addMouseListener(listener);
panel2.addMouseListener(listener);
panel3.addMouseListener(listener);

提示:请记住MouseEvent来自ComponentEventgetComponent()方法developers.google

  

返回事件的发起者。