我有一個外面板,外面板上有另一個jPanel。將一個jPanel上的點擊事件傳遞給另一個JPanel
如果我在內部面板上點擊右鍵,外部面板的右擊動作應該會發生。如果我在內部面板上單擊左鍵,則會發生其自己的內部面板的單擊操作。
是否可以將點擊事件從一個面板傳遞到另一個面板?
我有一個外面板,外面板上有另一個jPanel。將一個jPanel上的點擊事件傳遞給另一個JPanel
如果我在內部面板上點擊右鍵,外部面板的右擊動作應該會發生。如果我在內部面板上單擊左鍵,則會發生其自己的內部面板的單擊操作。
是否可以將點擊事件從一個面板傳遞到另一個面板?
爲解決此問題需要解決多個問題。
第一個是理解鼠標事件對創建它的組件是上下文的,特別是位置信息。點擊點是源組件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);
}
}
}
你有沒有試過類似於你的內部面板?
void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON2) {
outter.mouseClicked(e);
}
else {
// do job for your inner panel
}
}
與此相關的問題是'MouseEvent'是內部面板的上下文需要的信息,即'source'和'position'是與內部面板相關的。如果OP想要獨立使用這些值(這就是說,外部面板不需要對鼠標事件的狀態做出決定),這可能會嚴重地影響事物 – MadProgrammer
下面的代碼爲我工作
JPanel parent = (JPanel) me.getComponent().getParent();
MouseMotionListener[] ml = parent.getMouseMotionListeners();
ml[0].mouseClicked(me);
感謝所有
這不會將'MouseEvent'轉換爲父組件上下文和'MouseMotionListener'沒有'mouseClicked'事件... – MadProgrammer
是的。你的答案是更好的解決方案。 :) 謝謝 – CrazyProgrammer
設計是否'延伸JPanel'?如果是這樣,爲什麼?此外,'MouseListener'是一個非常低級的偵聽器,可以添加到'JPanel'中。 *假設*在右鍵點擊時發生了什麼? –
是的,它擴展jPanel。兩個不同的動態菜單。這些菜單將根據運行時間決定。 – CrazyProgrammer