Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将一个jPanel上的click事件传递给另一个jPanel_Java_Swing_Jpanel_Mouseevent - Fatal编程技术网

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

Java 将一个jPanel上的click事件传递给另一个jPanel,java,swing,jpanel,mouseevent,Java,Swing,Jpanel,Mouseevent,我有一个外部面板,在外部面板上放置了另一个jPanel 如果我在内部面板上单击鼠标右键,外部面板的右键单击操作应该会发生。如果我在内部面板上单击鼠标左键,它自己的内部面板的单击操作就会发生 是否可以将单击事件从一个面板传递到另一个面板?您是否在内部面板中尝试过类似的操作 void mouseClicked(MouseEvent e) { if ( e.getButton() == MouseEvent.BUTTON2 ) { outter.mouseClicked

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

如果我在内部面板上单击鼠标右键,外部面板的右键单击操作应该会发生。如果我在内部面板上单击鼠标左键,它自己的内部面板的单击操作就会发生


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

您是否在内部面板中尝试过类似的操作

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

        }

你在你的内板上试过类似的东西吗

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

        }

您需要解决一些问题才能使其正常工作

第一个是理解鼠标事件与创建它的组件相关,特别是位置信息。单击点是源组件x/y位置的偏移量(鼠标事件的偏移量为0x0)。这意味着,如果要重新修补事件,至少需要将位置上下文转换为父组件空间

源组件也应该更改。如果不这样做,可能会导致API的其他部分出现问题,这些部分可能依赖于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);
        }

    }

}

您需要解决一些问题才能使其正常工作

第一个是理解鼠标事件与创建它的组件相关,特别是位置信息。单击点是源组件x/y位置的偏移量(鼠标事件的偏移量为0x0)。这意味着,如果要重新修补事件,至少需要将位置上下文转换为父组件空间

源组件也应该更改。如果不这样做,可能会导致API的其他部分出现问题,这些部分可能依赖于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);
        }

    }

}

下面的代码对我有用

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

谢谢下面的代码为我工作

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

谢谢大家

设计是否扩展了JPanel?若然,原因为何?另外,
MouseListener
是一个非常低级的监听器,可以添加到
JPanel
。右键单击会发生什么?是的,它扩展了jPanel。两个不同的动态菜单。这些菜单将在运行时决定。设计是否扩展JPanel?若然,原因为何?另外,
MouseListener
是一个非常低级的监听器,可以添加到
JPanel
。右键单击会发生什么?是的,它扩展了jPanel。两个不同的动态菜单。这些菜单将在运行时决定。问题在于
MouseEvent
所需的信息与内部面板相关,即
源代码和
位置等信息与内部面板相关。如果OP想要独立地使用这些值(即,outter面板不需要决定鼠标事件的状态),这可能会严重地把事情搞砸。
MouseEvent
所需的信息与内部面板相关,也就是说,
source
position
是相对于内面板的。如果OP想要独立地使用这些值,这可能会把事情搞砸(也就是说,outter面板不需要对鼠标事件的状态做出决定)这不会将
MouseEvent
转换为父组件上下文,并且
MouseMotionListener
没有
mouseClicked
事件…是。你的答案是一个更好的解决方案感谢这不会将
MouseEvent
转换为父组件上下文,并且
MouseMotionListener
没有
mouseClicked
事件…是。你的答案是一个更好的解决方案谢谢