我遇到了一個問題,似乎MouseListener們相互重疊。
在我的應用程式的 GUI 類中,我添加了 @camickr 的 ComponentResizer 類并注冊了我的 JFrame。當沒有子組件時,或者其他情況下,當我不向子組件添加其他MouseListener時,它作業正常。但是當我這樣做時,子組件似乎擁有監聽器的優先權,而且我無法調整北邊框的大小。
我嘗試了addAWTEventListener()方法,如下:
Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
if (event instanceof MouseEvent) {
MouseEvent e = (MouseEvent) event;
if (e.getSource() == MainGUI.getMainFrame() ) {
switch (e.getID()) {
case MouseEvent.MOUSE_CLICKED -> mouseClicked(e)。
case MouseEvent.MOUSE_PRESSED -> mousePressed(e)。
case MouseEvent.MOUSE_RELEASED -> mouseReleased(e)。
case MouseEvent.MOUSE_ENTERED -> mouseEntered(e);
case MouseEvent.MOUSE_EXITED -> mouseExited(e)。
case MouseEvent.MOUSE_DRAGGED -> mouseDragged(e);
case MouseEvent.MOUSE_MOVED -> mouseMoved(e)。
default -> {}。
}
}
}
}, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK)。)
但是結果非常奇怪,框架中的所有組件都可以同時調整大小。
下面是該問題的SSCCE:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainGUI {
private static JFrame mainFrame;
private static JPanel contentPane;
private static JPanel titleBar;
private static ComponentResizer resizer = new ComponentResizer() 。
public static void init(){
mainFrame = new JFrame() 。
contentPane = new JPanel();
titleBar = new JPanel();
titleBar.add(new JLabel("this is a title"))。
titleBar.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1))。
//有問題的部分。沒有它,調整器可以正常作業。
titleBar.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
System.out.println("你點擊了我!")。
}
});
contentPane.setLayout(new BorderLayout())。
contentPane.add(titleBar, BorderLayout.NORTH);
mainFrame.setContentPane(contentPane);
mainFrame.setPreferredSize(new Dimension(600, 400) 。)
mainFrame.setUndecorated(true)。
resizer.registerComponent(mainFrame)。
}
public static void display() {
mainFrame.pack();
mainFrame.setLocationRelativeTo(null)。
mainFrame.setEnabled(true)。
mainFrame.setVisible(true)。
mainFrame.requestFocus()。
}
public static JFrame getMainFrame() {
return mainFrame。
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName() )。
} catch (ClassNotFoundException | InstantiationException |
非法訪問例外|不支持的外觀例外 e) {
e.printStackTrace()。
}
MainGUI.init()。
MainGUI.display();
});
}
}
而這里是ComponentResizer類:
http://www.camick.com/java/source/ComponentResizer.java
因此問題是,是否有辦法讓JFrame的監聽器保持在子組件監聽器的 "頂部"?
uj5u.com熱心網友回復:
是否有辦法讓JFrame的監聽器保持在子組件監聽器的 "頂部"?
據我所知,并沒有。只有一個組件可以接收 MouseEvent。
Swing 將從底部(父/子組件鏈)到頂部搜索組件,以找到一個具有 MouseListener 的組件,并將事件傳遞給該組件。因此,第一個找到的具有監聽器的組件將接收該事件。
一個解決方案是為您的標題欄提供一個帶有Border的 "包裝 "面板。
例如:
// Create wrapper panel with a border
JPanel wrapper = new JPanel(new BorderLayout()) 。
包裝器。 setBorder( new EmptyBorder(5, 5, 5, 5) ) 。
wrapper.add(titleBar);
contentPane.add(wrapper, BorderLayout.NORTH);
//contentPane.add(titleBar, BorderLayout.NORTH);/span>
現在你的標題欄將不會延伸到框架的邊緣,所以當滑鼠在邊緣的5像素范圍內時,MouseEvent將被傳遞給框架。
如果您希望 LineBorder 完全延伸到框架的邊緣,您也可以從標題欄中移除 Border 并在包裝面板上使用 CompoundBorder。
注意您可能也會向BorderLayout的CENTER添加組件。如果這些組件中的任何一個有一個MouseListener,你將會遇到同樣的問題。根據你的要求,你可能想考慮將 EmptyBorder 添加到框架的內容窗格中。這樣你就可以有效地在整個框架中添加一個Border。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/310288.html
標籤:
