выберите родителя JPanel сзади - PullRequest
3 голосов
/ 25 августа 2011

Ниже приводится SSCCE, чтобы описать мою проблему.

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

public class APanel extends JPanel{

public APanel() {

    this.setVisible(true);
    this.setBackground(Color.red);
    this.addMouseListener(new MouseListener() {

        public void mouseClicked(MouseEvent e) {
            if(e.getClickCount()==2)
            {

            }
            System.out.println("Child panel clicked!");
        }
        public void mousePressed(MouseEvent e) { }
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) { }
        public void mouseExited(MouseEvent e) {}
    });
  }
}


    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();
        panel2 = new APanel();
        panel2.setBackground(Color.yellow);
        panel3 = new APanel();
        panel3.setBackground(Color.green);
        this.add(panel1);
        this.add(panel2);
        this.add(panel3);
        this.setBackground(Color.blue);
         this.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                System.out.println("Parent panel clicked!");
            }
            public void mousePressed(MouseEvent e) { }
            public void mouseReleased(MouseEvent e) {}
            public void mouseEntered(MouseEvent e) { }
            public void mouseExited(MouseEvent e) {}
        });
    }

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

Как мне сделать следующее:

  • Если e.getClickCount () == 1, тогда родительский MouseListener будетактивен, и он напечатает «родительская панель нажата!».
  • Если e.getClickCount () == 2, то дочерний MouseListner будет активен и выведет «дочерняя панель нажата!».

    Edit1: ближе к предлагаемому решению.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class APanel extends JPanel {
    
    private static final long serialVersionUID = 1L;
    private Point pt;
    
    public APanel() {
        timer.setRepeats(false);
        addMouseListener(new MouseAdapter() {
    
            @Override
            public void mouseClicked(MouseEvent e) {
                if (timer.isRunning() && !e.isConsumed() && e.getClickCount() > 1) {
                    System.out.println("double from child");
                    pt = null;
                    timer.stop();
                } else {
                    pt = e.getPoint();
                    Component component = (Component)e.getSource();
                    component.getParent().dispatchEvent(e);
                    timer.restart();
                }
            }
        });
        setBackground(Color.red);
        setVisible(true);
    }
    
    private Timer timer = new Timer(200, new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            //System.out.println("single from child");
        }
    });
    

    }

В случае, если mouseEvent должен пройти через многоуровневые контейнеры, эта ссылка может представлять интерес.

Ответы [ 2 ]

3 голосов
/ 25 августа 2011

Если вы решите интерпретировать двойной щелчок, рассмотрите возможность использования предпочтительного интервала пользователя, как предложено здесь .

Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
2 голосов
/ 25 августа 2011

Я думаю (насколько я знаю), что невозможно перенаправить событие Mouse от дочернего к его родительскому элементу, просто получить родительский элемент от Component, который находится под MouseCursor, или получить родительский элемент от Component, который получил Events от MouseClick

Конечно, может быть, кто-то может помочь вам с этим :-), но вот код, который вам нужен для успеха с этим

родителем:

import java.awt.*;
import javax.swing.*;

public class PPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private APanel panel1;
    private APanel panel2;
    private APanel panel3;

    public PPanel() {
        setLayout(new GridLayout(0, 1));
        panel1 = new APanel();
        panel2 = new APanel();
        panel2.setBackground(Color.yellow);
        panel3 = new APanel();
        panel3.setBackground(Color.green);
        add(panel1);
        add(panel2);
        add(panel3);
        setBackground(Color.blue);
    }

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

            @Override
            public void run() {
                JFrame frame = new JFrame();
                PPanel panel = new PPanel();
                frame.add(panel);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setPreferredSize(new Dimension(350, 300));
                frame.setTitle("Demo");
                frame.setLocationRelativeTo(null);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Ребенок:

import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import javax.swing.Timer;

public class APanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private Point pt;

    public APanel() {
        timer.setRepeats(false);
        addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (timer.isRunning() && !e.isConsumed() && e.getClickCount() > 1) {
                    System.out.println("double from child");
                    pt = null;
                    timer.stop();
                } else {
                    pt = e.getPoint();
                    timer.restart();
                }
            }
        });
        setBackground(Color.red);
        setVisible(true);
    }

    private Timer timer = new Timer(400, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("single from child");
        }
    });
}
...