свинг событие отправки на несколько уровней контейнеров - PullRequest
2 голосов
/ 27 августа 2011

Вот код для демонстрации моей проблемы: Родительский класс:

    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 только отправляет событие в следующий непосредственный контейнер и не более.

Как я могу решить это?Есть ли способ отправить событие напрямую в другой контейнер?

1 Ответ

2 голосов
/ 27 августа 2011

Вы видите это поведение, потому что MouseEvent#getSource() возвращает JTextField, чьим родителем является APanel. Вы ожидали, что getSource() вернет APanel.

Похоже, что вы могли бы достичь желаемого эффекта, позвонив getParent().getParent(), чтобы подняться на другой уровень. Помните, что это очень хрупкое и плохое решение, потому что оно сломается, если вы решите, что вам нужен другой компонент между вашим APanel и его JTextField.

Возможно, вы можете использовать рекурсивный подход для перехода по иерархии компонентов, вызывая getParent(), пока не достигнете PPanel, после чего вы можете позвонить dispatchEvent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...