将一个jPanel上的click事件传递给另一个JPAnel [英] Passing the click event on one jPanel to another JPanel

查看:177
本文介绍了将一个jPanel上的click事件传递给另一个JPAnel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have one outer panel, in the outer panel I have another jPanel placed on it.

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

if i do a right click on the inner panel, outer panel's right click action should happen. if i do left click on the inner panel, its own inner panel's click action should happen.

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

Is it possible to pass click event from one panel to another panel?

推荐答案

要解决这个问题需要解决一些问题。

There are a number issues you need to resolve for this to work.

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

The first is understanding that a mouse event is contextual to the component that created it, in particular, the location information. The click point is the offset from the source components x/y position (which will be 0x0 for the mouse event). This means if you want to redispatch the event, you need to, at least, translate the location context into the parent components space.

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

The source component should also be changed. Failing to do this could cause issues for other parts of the API that may rely on it to make determinations (such as a popup, which will want to translate the location information from the component space to the screen space).

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

Secondly, you should make no assumptions about the parent. That is, you should make no assumption that the parent may or may not implement a mouse listener interfaces.

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

A possible solution would be to use SwingUtilities.convertMouseEvent to convert the MouseEvent raised in the inner panel to be compatible with the outer panel and then use Component#dispatchEvent to mimick the standard event handling process, for example...

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上的click事件传递给另一个JPAnel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆