Swing 将调度事件切换到多个级别的容器

Swing 将调度事件切换到多个级别的容器,swing,events,event-handling,Swing,Events,Event Handling,下面是演示我的问题的代码: 父类: import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JFrame; import javax.swing.JPanel; public class PPanel exte

下面是演示我的问题的代码: 父类:

    import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PPanel extends JPanel{
    private APanel panel1;
    private APanel panel2;
    private APanel panel3;
    public PPanel() {
        this.setLayout(new GridLayout(0,1));
        panel1 = new APanel();
        panel1.setLayout(new GridLayout(0,1));

        panel2 = new APanel();
        panel2.setBackground(Color.yellow);
        panel2.setLayout(new GridLayout(0,1));
        panel3 = new APanel();
        panel3.setBackground(Color.green);
        //panel3.setLayout(new GridLayout(0,1));
        this.add(panel1);
        this.add(panel2);
        this.add(panel3);
        this.setBackground(Color.blue);
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Parent panel clicked!");
            }               
        });
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        PPanel panel = new PPanel();
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(350, 300));
        frame.setTitle("Demo");
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
子面板类:

import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class APanel extends JPanel{
    private JTextField tf;
    public APanel() {
        tf = new JTextField("Double click");
        tf.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Textfiled");
                Component source = (Component) e.getSource();
                System.out.println(source.getParent());
                source.getParent().dispatchEvent(e);
            }
        });
        this.add(tf);
        this.setVisible(true);
        this.setBackground(Color.red);

        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Child panel clicked!");
                Component source = (Component) e.getSource();
                System.out.println("Parent container of APanel is " + source.getParent());
                if(source.getParent() instanceof PPanel)
                    source.getParent().dispatchEvent(e);
            } 
        });
    }
}
我希望一旦JTextField中触发了mouseclick事件,就会使用dispatchEvent将其传播到父面板。但对于具有JTextField的子面板,MouseClicked事件似乎只能访问APanel。然后打印APanel的父对象是APanel!。所以在我看来,dispatchEvent只将事件发送到下一个即时容器,而不再发送


我怎样才能解决这个问题?有没有一种方法可以将事件直接发送到另一个容器?

您看到这种行为是因为
MouseEvent\getSource()
返回
JTextField
,其父对象是
APanel
。您希望
getSource()
返回
APanel

看起来您可以通过调用
getParent().getParent()
来达到所需的效果。请记住,这是一个非常脆弱和糟糕的解决方案,因为如果您决定在
APanel
和它的
JTextField
之间需要另一个组件,它将崩溃


也许您可以使用递归方法来遍历组件层次结构,调用
getParent()
,直到到达
PPanel
,此时您可以调用
dispatchEvent

,对于更好的解决方案,您有何建议+getParent()为1。getParent()解决了我的问题。啊,是的。我正在考虑使用一个循环,并使用instanceof检查发送事件的desire容器。事实上,我可以使用循环分派到所有其他容器,直到getParent()返回null!是的,您可以在组件层次结构上递归调用
dispatchEvent
,直到
getParent()
返回
null
!Swing中是否有一个实用程序方法可以自动将事件分派到父容器?另外,我看到您使用的是
MouseListener
,但只定义了一个方法-check out,它提供了所有侦听器方法的空实现,允许您重写和定义您感兴趣的方法。哦,没关系。这个例子只是我的问题的一个基本演示,所以我不得不减少到简单的方法(保持简短)来显示主要问题。再次阅读我自己的评论,现在我意识到我没有完全注意到你的评论。我的意思是,我使用Netbeans来编写这个示例,所以它为我导入了所有这些方法。又快又脏!正如您所注意到的,mouseEvents位于感兴趣的最上面的组件(aka:is mouseEnabled或has mouseListeners),而不是更进一步——原因很好:想象一下,所有这些事件在容器层次结构中向上移动,而大多数情况下都不感兴趣。那么,你为什么想在父面板上看到mouseEvent?@kleopatra:原因是我可以使用mouseListener MouseClicked和MouseDragged来移动和拖动主(父)面板。但是,由于添加了所有3个子面板,它们是第一个与mouseEvent交互的面板,因此我无法拖动和移动主面板。将mouseEvent移动到父面板让我再次拥有此功能。