挥发调度事件到多级容器 [英] swing dispatch event to multiple level of containers

查看:96
本文介绍了挥发调度事件到多级容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Here is come code to demo my problem: Parent class:

    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);
            } 
        });
    }
}

我希望一旦mouseClicked事件在JTextField,它将通过使用dispatchEvent传播到父面板。但是对于具有JTextField的子面板,似乎MouseClicked事件只能到达APanel。然后打印APanel的父母是APanel!所以在我看来,dispatchEvent只会将事件发送到下一个即时容器,而不会再发送。

I was hoping that once a mouseClicked event triggered in the JTextField, it will be propagated to the parent panel by using dispatchEvent. But for child panel that have JTextField, it seems that the MouseClicked event only gets to APanel. Then it prints parent of APanel is APanel!. So it appears to me that dispatchEvent only sends event to next immediate container and no more.

我该如何解决?有没有办法将事件直接发送到另一个容器?<​​/ p>

How can I solve this? Is there a way I can dispatch an event directly to another container?

推荐答案

你看到这个行为是因为 MouseEvent#getSource()返回 JTextField ,其父级是 APanel 。您期待 getSource()返回 APanel

You're seeing this behavior because MouseEvent#getSource() returns the JTextField, whose parent is the APanel. You were expecting getSource() to return APanel.

看起来你可以通过调用 getParent()getParent()来获得所需的效果水平。请记住,这是一个非常脆弱和可怜的解决方案,因为如果您决定在 APanel 和其 JTextField之间需要另一个组件,它将会中断

It looks like you could achieve the desired effect by calling getParent().getParent() to go up another level. Do keep in mind that this is a very brittle and poor solution because it will break if you decide that you need another component between your APanel and its JTextField.

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

Perhaps you can use a recursive approach to walk up the component hierarchy, calling getParent() until you've reached a PPanel, at which point you can call dispatchEvent.

这篇关于挥发调度事件到多级容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆