java - 我希望我的 JLayeredPane 能够捕获所有事件

标签 java swing

我有一个 JFrame,我想在某些加载过程中将其设置为禁用。为此,我创建了 DisablingLayeredPane 类:

public class DisablingLayeredPane extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
        g2d.setColor(Color.BLACK); // With 0.2f alpha it looks like light gray
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.dispose();
    }
}

在加载过程开始时,我调用

frame.getLayeredPane().add(darkeningPane, JLayeredPane.MODAL_LAYER);

但问题是,这个变暗的 Pane 没有捕获任何事件,我仍然可以按下框架上的按钮。我还尝试使用 AWTEventListener 来消耗此框架的所有事件,但还有另一个问题:有时我需要显示模式对话框进行一些确认,并且模式对话框的事件也被消耗(我可以不要按任何按钮)。当然,我可以使用一些技巧,例如在框架上方使用透明窗口而不是变暗 Pane ,或者在以下位置使用大量if-else语句AWTEventListener,但我正在寻找一些漂亮的解决方案(如果有的话)。

提前致谢。

UPD: 我还尝试将 Mouse and Key Listeners 添加到分层面板,但出现了一个新问题:如果使用 JDialog 而不是 JFrame,分层面板的 KeyListener 不会捕获 ESC 按键,对话框将被处理。

UPD2: 我尝试了 frame.setGlassPane(darkeningPane) 而不是设置为图层,但没有效果。

最佳答案

通过添加一个简单的组件作为JLayeredPane的层来拦截事件是不可能的。看来很多开发者并没有意识到这一点。事件通常会直接分派(dispatch)到包含鼠标事件坐标的最深子组件,或者在按键事件忽略父级的情况下分派(dispatch)到聚焦组件,更不用说甚至不是目标组件的父级的层了。

幸运的是,Java 7 中添加了一个组件,可以为您完成复杂的任务,JLayer ,不要与 JLayeredPane 混淆。

以下是如何使用它的示例:

JFrame f=new JFrame("Disabling via JLayer");
final JLayer<JTree> layer = new JLayer<JTree>(new JTree(), new LayerUI<JTree>() {
  @Override
  public void eventDispatched(AWTEvent e, JLayer<? extends JTree> l) {
    if(e instanceof InputEvent) ((InputEvent)e).consume();
  }
  @Override
  public void paint(Graphics g, JComponent c) {
    super.paint(g, c);
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
    g2d.setColor(Color.BLACK);
    g2d.fillRect(0, 0, c.getWidth(), c.getHeight());
    g2d.dispose();
  }
});
f.setContentPane(layer);
layer.setLayerEventMask(~0);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);

关于java - 我希望我的 JLayeredPane 能够捕获所有事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25501039/

相关文章:

java - GWT uiBinder 与继承一起工作?

java - 使用最合适的数据结构简化嵌套的 if-else 结构

java - 如何使用 JMockit 模拟 Spring 注入(inject)类

java - 什么时候应该重写Java中的equal方法

java - 使用 Boxlayout 导致我的面板只有父面板大小的一半

java - 如何使用FEST获取某个组件

java - 将 LocalDate.MAX 转换为日期

java - jFreeChart重新加载数据集问题

java - 如何将菜单集成到布局 (Java GUI) 中?

java - Swing 部件加倍