在 JLabel 上设置大小会替换 Java 中的其他组件



我正在为程序中的错误消息设置 JLabel,因此最初标签为空label.setText(""),但是当出现错误时,它应该更改为类似label.setText("Error, you have entered invalid data...")的内容。

如果我在标签上使用setSize(x,y),它会在出现错误消息时强制其他组件替换。但是使用setPreferredSize(Dimension(x,y))不会影响它们。

问题 1.为什么?

问题 2.setSize(x,y)setPreferredSize(Dimension(x,y))有什么区别

问题 3.它与布局有什么关系吗?

提前感谢您的解释!

附言我正在使用GridBagLayout将我的组件定位在JPanel上。

不要使用 setSize 方法。

setSize 由 LayoutManagers 调用,如 GridBagLayout,用于布局子组件。 当你显式调用setSize时,你正在与GridBagLayout作斗争。 最终,GridBagLayout 将撤消您的 setSize 调用,当它出于自己的目的调用 setSize 时。

换句话说,任何对 setSize 的调用最终都会被父布局清除。

设置首选大小不会被清除。 大多数布局管理器,包括GridBagLayout,都尽力尊重组件的首选大小。

但是,您不应该调用 setPreferredSize。 默认情况下,组件已经具有首选大小,并且几乎可以肯定它比您能想到的任何数字都要好。 例如,JLabel 的默认首选大小是刚好足以容纳其文本、图标和边框的大小。

计算首选大小比您想象的要难。 文本使用多少像素? 12 磅字体高多少像素? 12 磅不是12 像素。 12 点是1272英寸。 那是多少像素? 这取决于用户的显示器和图形分辨率。 所有这些都是 Swing 渲染系统已知的,JLabel 使用所有这些信息来确定其默认的首选大小。 你不应该试图重新发明所有这些工作,你也不应该试图用更简单的东西来取代这项工作,因为它是不够的。

如果你只是让JLabel保持其首选尺寸,GridBagLayout将尽最大努力适应它。 如果窗口本身没有空间显示 JLabel 的新文本,你可能应该在更改文本后调用窗口的 pack() 方法。

更新:这似乎是一个 XY 问题 - 您确实想要一条可以显示和隐藏的消息。

您希望布局足够大,以便在创建消息文本后立即容纳它。 这通常是通过 CardLayout 完成的,它允许您将多个组件放在彼此之上,在任何给定时刻只有一个组件可见。 由于您根本不希望显示任何文本,因此最初,您将添加一个空的 JLabel 作为 CardLayout 中的第一个组件,因此默认情况下会显示它:

JLabel label = new JLabel("Error, you have entered invalid data...");
CardLayout messageLayout = new CardLayout();
JPanel messagePane = new JPanel(messageLayout);
messagePane.add(new JLabel(), "blank");
messagePane.add(label, "message");
// Do not add label directly to your user interface.
// Add messagePane instead.
mainWindow.add(messagePane);
// ...
// Show message
messageLayout.show(messagePane, "message");
// ...
// Hide message
messageLayout.show(messagePane, "blank");

用户永远不会看到"message""blank"。 它们只是卡片布局中每个组件("卡")的唯一标识符。 你可以让他们做任何你想要的东西。

setSize() 函数设置的大小不基于任何 LayoutManager。这就是为什么在使用 LayoutManager 时应该始终使用 setPrefferedSize() 的原因。setPrefferedSize() 首先尝试与 LayoutManagers 维度保持一致,如果可能的话,Java 会尝试根据您的 setPrefferedSize() 输入设置标签的大小。

所以是的,它确实与布局有关。如果可能的话,你应该只使用 setPrefferedSize() 当你使用布局管理器时。

最新更新