【问题标题】:Java JLayeredPane Overrides CursorJava JLayeredPane 覆盖光标
【发布时间】:2014-06-05 21:58:26
【问题描述】:

我有一个多层 Java 应用程序,其中包含一系列需要手形光标的 JLabel 按钮,例如:

button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); 

但是,我在上面有一层覆盖整个应用程序的边界(用于绘制弹出窗口等)。现在我已经添加了上面的图层,我的光标不再改变。我已经尝试将上面图层的光标设置为null,但没有任何影响。

这是图层的基本布局:

private void create() {
    this.addWindowListener(windowAdapter);
    this.setLayout(new BorderLayout());

    layers = new JLayeredPane();
    layers.setPreferredSize(this.getSize());

    dashboard = new DashBoard.DashBoardLayer();
    dashboard.setBounds(0, this.getHeight()-275, this.getWidth(),275);

    application = new App.ApplicationLayer();
    application.setBounds(0,0,this.getWidth(),this.getHeight()-145);

    filter = new FilterLayer();
    filter.setBounds(0,195,this.getWidth(),490);

    menuBG = MenuLayerBg.getInstance();
    menuBG.setBounds(0,0,this.getWidth(),this.getHeight());

    menuPanes = MenuLayer.getInstance();
    menuPanes.setBounds(0,0,this.getWidth(),this.getHeight());

    layers.add(application, new Integer(0));
    layers.add(filter, new Integer(1));
    layers.add(dashboard, new Integer(2));
    layers.add(menuBG, new Integer(3));
    layers.add(menuPanes, new Integer(4));

    this.add(layers, BorderLayout.CENTER);
}

【问题讨论】:

    标签: java swing cursor jlayeredpane


    【解决方案1】:

    MouseEvent 只调度到顶部的组件。因此,如果您的顶层完全覆盖了底层的组件,它们将不会收到 MouseEvent。

    查看 How to Use Layered Panes 上的 Swing 教程中的 LayeredPaneDemo.java 代码。我对代码进行了以下更改:

        for (int i = 0; i < layerStrings.length; i++) {
            JLabel label = createColoredLabel(layerStrings[i],
                                              layerColors[i], origin);
            layeredPane.add(label, new Integer(i));
            origin.x += offset;
            origin.y += offset;
    
      label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // added
        }
    

    每个组件的大小固定小于整个框架,因此顶部组件下方的组件将接受事件。

    当您运行代码时,光标会在顶部的两个标签上发生变化。

    如果您将“Dukes Layer and Position”更改为“Yellow”并取消选中该复选框,则所有标签的光标都会发生变化。

    但是,我在上面有一个覆盖整个应用程序的层

    一种可能的解决方案是将鼠标事件“重新分配”到顶层以下的组件。有关此方法的示例,请查看 How to Use Root Panes 上的 Swing 教程中的 GlassPaneDemo.java

    或者对于完全不同的方法,您可以尝试覆盖组件的 contains(...) 方法以始终返回 false。这样鼠标事件将永远不会被分派到您的组件,因为鼠标点不属于该组件。我以前从未尝试过,所以我不知道这是否会导致其他问题。

    我在 LayeredPaneDemo 中通过将以下内容更改为 createColoredLabel(...) 方法进行了尝试:

        JLabel label = null;
    
        if (color.equals(Color.green))
        {
            label = new JLabel(text)
            {
                @Override
                public boolean contains(int x, int y)
                {
                    return false;
                }
            };
        }
        else
            label = new JLabel(text);
    
        //JLabel label = new JLabel(text);
    

    【讨论】:

    • 我发现像你最后提到的那样为图层编辑包含功能效果很好。通过使覆盖层在不可见时返回 false 允许较低层表达它们的光标,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多