Java JLayeredPane重写Cursor

时间:2014-06-05 21:58:26

标签: java swing cursor jlayeredpane

我有一个多层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);
}

1 个答案:

答案 0 :(得分: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图层和位置”更改为“黄色”并取消选中该复选框,则光标将针对所有标签进行更改。

  

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

一种可能的解决方案是“将鼠标事件重新发送”到顶层下面的组件。有关此方法的示例,请查看How to Use Root Panes

上的Swing教程中的GlassPaneDemo.java

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

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

    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);