将调度事件转移到多级容器

时间:2011-08-26 22:20:45

标签: 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 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中触发了mouseClicked事件,它就会使用dispatchEvent传播到父面板。但是对于具有JTextField的子面板,似乎MouseClicked事件只到达APanel。然后它打印APanel的父亲是APanel!。所以在我看来,dispatchEvent只将事件发送到下一个直接容器而不再发送。

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

1 个答案:

答案 0 :(得分:2)

您会看到此行为,因为MouseEvent#getSource()会返回JTextField,其父级为APanel。您希望getSource()返回APanel

看起来你可以通过调用getParent().getParent()上升到另一个级别来达到预期的效果。请记住,这是一个非常脆弱和糟糕的解决方案,因为如果您决定在APanelJTextField之间需要另一个组件,它将会中断。

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