将一个 JPanel 上的组件置于最前面 (Java)

10
在VB中,您可以使用zOrder。在.Net中,则是.SetChildIndex
在这种情况下,如果您有两个组件重叠在一起,如何更改它们显示后的顺序呢?
我有一个按钮与另一个组件(标签)部分重叠,因为空间不足。我将JLabel添加到表单中以使其出现在按钮之前,当表单加载时,看起来很好。但是当用户单击按钮时,JLabel会回到后面,使一部分消失。有没有办法让它保持在最前面?我尝试在按钮的ActionListener中放置label.grabFocus(),但没有效果。

2
对我来说,这听起来像是一个糟糕的设计。能否发布一个SSCCE,以便我们可以可能建议另一种方法? - mre
5
顺便提一下,如果你打算使用Swing,你迫切需要学习如何使用布局管理器。 - jzd
2
使用repaint是解决问题的一种不好的方式。 - sasidhar
我将尝试使用分层窗格,看看会得到什么结果。 - David
5个回答

8

默认情况下,Swing假定组件不重叠,因此可以更有效地重新绘制组件。这意味着当您更改组件的属性时,只需要重新绘制该组件。

当组件在面板上重叠时,您需要告诉面板,以便它可以确保所有组件以正确的ZOrder重新绘制:

您可以通过覆盖JPanel的isOptimizedDrawingEnabled()方法并返回false来实现此目的。

JPanel panel = new JPanel()
{
    @Override
    public boolean isOptimizedDrawingEnabled()
    {
        return false;
    }
}

你如何设置“ZOrder”? - Cardinal System
1
@CardinalSystem,默认情况下,当您将组件添加到面板时,ZOrder会自动设置。每添加一个组件,ZOrder都会增加。Swing实际上是按照它们被添加的相反顺序绘制组件的,因此您可以更改添加组件的顺序。或者,您可以使用Container.setComponentZOrder(...)方法在事后操作ZOrder。 - camickr

7

3
首先,这似乎是一个糟糕的设计。虽然 label.repaint() 可以工作,但这不是你应该做的方式。你没有明确指定这些组件如何彼此重叠。更好的方法是使用 Layered Panes。Java 中 zOrder 的对应物是 Layered Pane。这个链接应该会帮助你:http://download.oracle.com/javase/tutorial/uiswing/components/layeredpane.html 如果有问题,请告诉我。

1

我不确定,但是重新绘制会起作用吗?如果可以的话,这有点像黑客技巧,也许其他人能找到更好的方法...


标签.repaint()在动作监听器中的效果非常好。我没想到过。谢谢!很快会接受。 - David
看我的答案。API解决方案是覆盖面板的isOptimizedDrawingEnabled()方法。让按钮ActionListener知道周围绘制的组件并不是一个很好的解决方案。 - camickr

1

让重叠的组件以正确的方式运作并不是那么明显。最受支持的方法是在您的面板中使用OverlayLayout。


一个LayeredPane是最受支持的方式。OverlayLayout甚至没有在这里列出:http://download.oracle.com/javase/tutorial/uiswing/layout/visual.html - jzd
@jzd,你是对的,但这仍然是一个有效的答案- [OverlayLayout示例](http://www.java2s.com/Tutorial/Java/0240__Swing/1401__OverlayLayout.htm) - mre
@jzd 实际上所有答案都是有效的,无论它是否是“良好实践”。实际上,在这种情况下,我并不是在寻找“最佳实践”或“最佳方式”,而是寻找需要使用最少努力的最短答案。 - David
使用OverlayLayout是一个有效的答案。我的问题是将其描述为“最受支持的方式”。 - jzd
1
@David,学习正确的方法比使用最小的努力进行快速修复更有长远意义。 - camickr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接