簡體   English   中英

將一個jPanel上的click事件傳遞給另一個JPanel

[英]Passing the click event on one jPanel to another JPanel

我有一個外部面板,在外部面板上有另一個jPanel。

如果我在內部面板上單擊鼠標右鍵,則應該執行外部面板的右鍵單擊操作。 如果我確實在內部面板上單擊鼠標左鍵,則應該發生其自身的內部面板的點擊動作。

是否可以將點擊事件從一個面板傳遞到另一面板?

要解決此問題,您需要解決許多問題。

首先是要了解鼠標事件與創建它的組件有關,尤其是位置信息。 點擊點是相對於源組件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);
        }

    }

}

您是否嘗試過在內部面板中進行類似的操作?

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

        }

下面的代碼為我工作

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

謝謝大家

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM