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

在我的代码中我有:

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

这应该以这种方式工作:

  • 用户想要编辑字段。
  • 他将鼠标hover在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); } }); } 

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

 panel.addMouseListener(new MouseAdapter() { @Override public void mouseExited(MouseEvent e) { Rectangle r = e.getComponent().getBounds(); Point p = e.getPoint(); if (px < 0 || px >= r.width || py < 0 || py >= r.height) panel.setBorder( null ); } @Override public void mouseEntered(MouseEvent e) { panel.setBorder(BorderFactory.createLineBorder(Color.BLUE)); } }); 

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

问题是你将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); 

提示:记得MouseEventComponentEvent扩展而来,它有一个很好的方法getComponent()

返回事件的发起者。