如何避免在任何嵌套组件上触发 mouseExited
how to avoid mouseExited to fire while on any nested component
在我的代码中我有:
一个抽象 class 扩展 JComponent,其中包含一些 JTextFields。
JTextFields 不可编辑。
JComponent class 实现 MouseListener:
- 当 mouseEntered 事件触发时,会添加一个边框。
- 当 mouseExited 事件触发时,边框被移除。
- 当 mouseClicked 事件触发时,该组件的所有字段都设置为可编辑。
这应该是这样工作的:
- 用户想要编辑字段。
- 他将鼠标悬停在jComponent的任意点上
- 边框在 jComponent 上绘制以突出显示它
- 用户点击并触发 mouseClicked 方法,该方法执行其操作。
问题是:
当鼠标经过任何 JTextField 时,将触发 mouseExited。
你会如何解决这个问题?
接下来是一个简单的 class,它将向您展示一个 window,其中一个 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);
}
});
}
问题是您将 MouseListener
设置为 JPanel
,这没有多大意义(对于所需的描述行为)。
只需将 MouseListener
更改为 JTextField
:
text.addMouseListener(new MouseListener() {
对我来说效果很好。
更新:
You missed something mate :) Thx for the fast answer, but, my JPanel
can contains more then a single textField, it could contains for example, 10 of them!
这个例子可以作为例子,但在现实生活中你不会创建一个内部监听器,你会创建一个 class。
class MyMouseListener implements MouseListener {
// define methods and behaviour
}
然后您将其添加到您的可选区域,例如:
MyMouseListener listener = new MyMouseListener()
panel1.addMouseListener(listener);
panel2.addMouseListener(listener);
panel3.addMouseListener(listener);
提示:记住MouseEvent
extends from ComponentEvent
that has a great method getComponent()
Returns the originator of the event.
您可以通过查看事件的鼠标点来判断该点是否仍在面板的边界内:
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更简单,只需要覆盖你想自定义的方法即可。
在我的代码中我有:
一个抽象 class 扩展 JComponent,其中包含一些 JTextFields。 JTextFields 不可编辑。 JComponent class 实现 MouseListener: - 当 mouseEntered 事件触发时,会添加一个边框。 - 当 mouseExited 事件触发时,边框被移除。 - 当 mouseClicked 事件触发时,该组件的所有字段都设置为可编辑。
这应该是这样工作的:
- 用户想要编辑字段。
- 他将鼠标悬停在jComponent的任意点上
- 边框在 jComponent 上绘制以突出显示它
- 用户点击并触发 mouseClicked 方法,该方法执行其操作。
问题是: 当鼠标经过任何 JTextField 时,将触发 mouseExited。 你会如何解决这个问题?
接下来是一个简单的 class,它将向您展示一个 window,其中一个 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);
}
});
}
问题是您将 MouseListener
设置为 JPanel
,这没有多大意义(对于所需的描述行为)。
只需将 MouseListener
更改为 JTextField
:
text.addMouseListener(new MouseListener() {
对我来说效果很好。
更新:
You missed something mate :) Thx for the fast answer, but, my
JPanel
can contains more then a single textField, it could contains for example, 10 of them!
这个例子可以作为例子,但在现实生活中你不会创建一个内部监听器,你会创建一个 class。
class MyMouseListener implements MouseListener {
// define methods and behaviour
}
然后您将其添加到您的可选区域,例如:
MyMouseListener listener = new MyMouseListener()
panel1.addMouseListener(listener);
panel2.addMouseListener(listener);
panel3.addMouseListener(listener);
提示:记住MouseEvent
extends from ComponentEvent
that has a great method getComponent()
Returns the originator of the event.
您可以通过查看事件的鼠标点来判断该点是否仍在面板的边界内:
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更简单,只需要覆盖你想自定义的方法即可。