【问题标题】:Mouse events from JTextField do not get propagated来自 JTextField 的鼠标事件不会被传播
【发布时间】:2012-04-02 03:41:58
【问题描述】:

我正在尝试监听来自 JLabel 和 JTextField 的鼠标事件。但是,我只能从 JLabel 中监听鼠标事件,而不能从 JTextField 中监听。

考虑这段代码:

class FieldPanel extends JPanel{
  JLabel label;
  JTextField text;

  public FieldPanel(){
    label = new JLabel("This is a test label");
    text = new JTextField("This is a test field");
    add(label);
    add(text);
  } 
}

class OuterPanel extends JPanel{
  FieldPanel fieldPanel;

  public OuterPanel(){
    fieldPanel = new FieldPanel();
    fieldPanel.addMouseListener(new MouseAdapter(){
        @Override
        public void mousePressed(MouseEvent event) {
            System.out.println("Mouse pressed !!");
        }
    });
    add(fieldPanel);
  }
}

public class UITest{
    public static void main (String args[]){
        JFrame frame = new JFrame();
        OuterPanel outerPanel = new OuterPanel();
        frame.getContentPane().add(outerPanel);
        frame.pack();
        frame.setVisible(true);
    }
}

“鼠标按下!!”单击 JLabel 时会显示消息。但是,当我单击 JTextField 时它不会显示。为什么会这样?

谢谢!

【问题讨论】:

  • 请在你想监听事件的组件上添加鼠标监听器,在本例中是'label'和'text'而不是'fieldPanel'
  • 嗯,但问题是我希望将事件传播到上面的几层 - 从 FieldPanel 到 OuterPanel 再到更多外部面板。我在上面几层添加了鼠标监听器。 JLabel 的鼠标事件得到正确传播,但 JTextField 没有。
  • 签出这篇文章,stackoverflow.com/questions/3605086/…,这也有同样的问题。
  • 这是设计使然:mouseEvents 被传递给为它们启用(f.i. 通过注册 mouseListener)的第一个孩子(z 顺序的顶部),它们不会冒泡向上层级。 JLabel 不感兴趣,而 JTextField 感兴趣:所以 mouseEvent 被传递给前者的父级并由后者使用。从 jdk7 开始,你可以用 JLayer 装饰一个容器来查看所有事件,对于 jdk6,它的前身是 java net 上的一个项目jxlayer.java.net

标签: java swing mouseevent jtextfield


【解决方案1】:

我认为这是一个有趣的问题,它有点意外地扼杀了这个发现。下面我将使用sn-p代码进行解释。

class FieldPanel extends JPanel
{
    //JLabel label;
    JTextField text;

    public FieldPanel()
    {
        //label = new JLabel("This is a test label");
        text = new JTextField("This is a test field");
        //add(label);
        add(text);          
    }
}

当您运行带有上述更改的代码时,我们期望输出的只是文本字段吗?然后,如果您单击文本字段 outside 区域的 near 区域,检查控制台输出,它实际上会打印出 Mouse press !!

所以我更深入地研究了JTextField,它实际上由JTextField 和JTextComponent 组成。当您调用构造函数new JTextField("This is a test field"); 时,文本实际上设置为 JTextComponent 而不是 JTextField 我猜这就是为什么当您单击 text 时,它不会触发 mousePressed 事件但它仅触发JTextField

以下是我的完整代码。如果您希望文本字段知道鼠标按下,请考虑在您的FieldPanel 类中实现MouseAdapter(),并为textlabel 添加addMouseListener(this)

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class MyMouseEvent extends JPanel
{

    public MyMouseEvent()
    {
        FieldPanel fieldPanel;
        fieldPanel = new FieldPanel();
        fieldPanel.addMouseListener(new MouseAdapter() {
               @Override
                public void mousePressed(MouseEvent event)
               {
                    System.out.println("Mouse pressed !!");
                }
        });
        add(fieldPanel);

    }

    class FieldPanel extends JPanel
    {
        //JLabel label;
        JTextField text;

        public FieldPanel()
        {
            //label = new JLabel("This is a test label");
            text = new JTextField("This is a test field");
            //add(label);
            add(text);          
        }
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        MyMouseEvent evt = new MyMouseEvent();
        evt.setOpaque(true);
        frame.setContentPane(evt);

        frame.pack();
        frame.setVisible(true);     
    }

    public static void main (String args[])
    {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() 
            {
                createAndShowGUI();             
            }
        });

    }


}

【讨论】:

    【解决方案2】:

    感谢大家的回答。

    我找到了某种解决方法。我正在更改我的代码,以便直接收听JTextField 组件,而不是收听面板。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      相关资源
      最近更新 更多