将一个jPanel上的click事件传递给另一个JPAnel

时间:2014-01-30 06:38:48

标签: java swing jpanel mouseevent

我有一个外面板,在外面板上我放置了另一个jPanel。

如果我右键单击内部面板,则应执行外部面板的右键单击操作。如果我左键单击内部面板,则应该发生其自己的内部面板的单击操作。

是否可以将点击事件从一个面板传递到另一个面板?

3 个答案:

答案 0 :(得分:4)

为解决此问题,您需要解决一些问题。

首先要了解鼠标事件是创建它的组件的上下文,特别是位置信息。点击点是源组件x / y位置的偏移量(鼠标事件将为0x0)。这意味着如果要重新调度事件,则至少需要将位置上下文转换为父组件空间。

还应更改源组件。如果不这样做可能会导致API的其他部分出现问题,这些部分可能依赖于它来进行确定(例如弹出窗口,它会将位置信息从组件空间转换到屏幕空间)。

其次,你不应该对父母做出任何假设。也就是说,您不应该假设父级可能实现或不实现鼠标侦听器接口。

一种可能的解决方案是使用SwingUtilities.convertMouseEvent转换内部面板中引发的MouseEvent以与外部面板兼容,然后使用Component#dispatchEvent来模仿标准事件处理流程,例如......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class TestTree {

    public static void main(String[] args) {
        new TestTree();
    }

    public TestTree() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new OutterPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class InnerPane extends JPanel {

        public InnerPane() {
            setBackground(Color.RED);
            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    System.out.println("Inner was clicked at : " + e.getPoint());
                    MouseEvent convertMouseEvent = SwingUtilities.convertMouseEvent(e.getComponent(), e, getParent());
                    getParent().dispatchEvent(convertMouseEvent);
                }

            });
        }

    }

    public class OutterPane extends JPanel {

        public OutterPane() {
            setLayout(new BorderLayout());
            setBorder(new EmptyBorder(10, 10, 10, 10));
            add(new InnerPane());

            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    System.out.println("Outter was clicked at : " + e.getPoint());
                }

            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

答案 1 :(得分:0)

您是否尝试过内部面板中的内容?

void mouseClicked(MouseEvent e) {
        if ( e.getButton() == MouseEvent.BUTTON2 ) {
        outter.mouseClicked( e );
        }
    else { 
     // do job for your inner panel
    }

        }

答案 2 :(得分:0)

以下代码为我工作

JPanel parent = (JPanel) me.getComponent().getParent();
MouseMotionListener[] ml = parent.getMouseMotionListeners();
ml[0].mouseClicked(me);

全部谢谢