我正在为程序中的错误消息设置 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 点是12⁄72英寸。 那是多少像素? 这取决于用户的显示器和图形分辨率。 所有这些都是 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() 当你使用布局管理器时。