将鼠标事件分派到最深的可见 JComponent
dispatching mouse events to the deepest visible JComponent
屏幕顶部有一个透明的JPanel
,还有一个背景JPanel
和一个JButton
添加到它上面(都是可见的并且有鼠标监听器)
在透明面板的侦听器中处理鼠标事件后,它们应该被分派到下一个更深的组件(即背景面板或其按钮)
点击背景面板没问题,但点击按钮会导致不需要的 ClassCastException
。
示例:
//making frame
frame=new JFrame();
frame.setVisible(true);
//making layered pane
layeredPane = new JLayeredPane();
frame.add(layeredPane);
//transparent panel on top
frontPanel = new JPanel();
frontPanel.setOpaque(false);
layeredPane.add(frontPanel,Integer.valueOf(1));
//background panel containing a button
backPanel = new JPanel();
JButton button = new JButton();
backPanel.add(button);
layeredPane.add(backPanel,Integer.valueOf(0));
//listeners
button.addMouseListener(new MouseListener()...a blank listener...);
backPanel.addMouseListener(new MouseListener()...a blank listener...);
frontPanel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.getDeepestComponentAt(backPanel, e.getX(), e.getY()).dispatchEvent(e);
}
@Override
public void mousePressed(MouseEvent e) {
SwingUtilities.getDeepestComponentAt(backPanel, e.getX(), e.getY()).dispatchEvent(e);
}
@Override
public void mouseReleased(MouseEvent e) {
SwingUtilities.getDeepestComponentAt(backPanel, e.getX(), e.getY()).dispatchEvent(e);
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
//setting dimensions
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frontPanel.setSize(screenSize);
backPanel.setSize(screenSize);
frame.setSize(screenSize);
//now clicking on the button cause a ClassCastException: JPanel cannot be cast to javax.swing.AbstractButton. why?
您不能只调度旧事件。旧事件包含有关原始事件(即组件源)的信息。
您需要创建一个新的 MouseEvent
才能发送。
例如,请参阅 How to Use Root Panes 上的 Swing 教程中的 GlassPaneDemo
。
屏幕顶部有一个透明的JPanel
,还有一个背景JPanel
和一个JButton
添加到它上面(都是可见的并且有鼠标监听器)
在透明面板的侦听器中处理鼠标事件后,它们应该被分派到下一个更深的组件(即背景面板或其按钮)
点击背景面板没问题,但点击按钮会导致不需要的 ClassCastException
。
示例:
//making frame
frame=new JFrame();
frame.setVisible(true);
//making layered pane
layeredPane = new JLayeredPane();
frame.add(layeredPane);
//transparent panel on top
frontPanel = new JPanel();
frontPanel.setOpaque(false);
layeredPane.add(frontPanel,Integer.valueOf(1));
//background panel containing a button
backPanel = new JPanel();
JButton button = new JButton();
backPanel.add(button);
layeredPane.add(backPanel,Integer.valueOf(0));
//listeners
button.addMouseListener(new MouseListener()...a blank listener...);
backPanel.addMouseListener(new MouseListener()...a blank listener...);
frontPanel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.getDeepestComponentAt(backPanel, e.getX(), e.getY()).dispatchEvent(e);
}
@Override
public void mousePressed(MouseEvent e) {
SwingUtilities.getDeepestComponentAt(backPanel, e.getX(), e.getY()).dispatchEvent(e);
}
@Override
public void mouseReleased(MouseEvent e) {
SwingUtilities.getDeepestComponentAt(backPanel, e.getX(), e.getY()).dispatchEvent(e);
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
//setting dimensions
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frontPanel.setSize(screenSize);
backPanel.setSize(screenSize);
frame.setSize(screenSize);
//now clicking on the button cause a ClassCastException: JPanel cannot be cast to javax.swing.AbstractButton. why?
您不能只调度旧事件。旧事件包含有关原始事件(即组件源)的信息。
您需要创建一个新的 MouseEvent
才能发送。
例如,请参阅 How to Use Root Panes 上的 Swing 教程中的 GlassPaneDemo
。