如何避免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);
提示:记得MouseEvent
从ComponentEvent
扩展而来,它有一个很好的方法getComponent()
返回事件的发起者。