getWidth()/getHeight() 和 getPreferredSize().width/height 有什么区别?
What is the difference between getWidth()/getHeight(), and getPreferredSize().width/height?
我正在尝试使用在调整 JFrame 大小时动态调整大小的键来绘制键盘。此外,键可以有不同的大小。
我有一个面板,其布局设置为 BorderLayout
。在中心,我放置了一个面板,其布局设置为 GridLayout(5,1)
.
网格的每一行都是 JPanel
和 FlowLayout
。在每一行中,我计算每个按钮并通过调用 setPreferredSize
方法设置其首选大小。
当运行程序时,我只看到一些外观怪异的按钮。当我使用 getWidth()/getHeight()
和 getPreferredSize().width/height
检查行面板时,我得到了不同的值:对于 getPrefereedSize().width
,我得到了我真正设置的宽度,但是对于 getWidth()
我的价值明显偏低。
getWidth()
和 getPreferredSize().width
这两种方法有区别吗?
组件的 getWidth/getHeight return 当前尺寸。 getPreferredSize return 是组件想要获取的内容。例如,带有文本的按钮将 return 首选大小,因此文本将完全可见。
合理的布局管理器会向子组件询问它们的首选尺寸,并为它们提供这些尺寸。这将导致父组件的首选大小。如果父组件设置较小的尺寸,它就不能再强制子组件的首选尺寸,要么隐藏一些,要么使组件变小。
(这个问题有一个对应的问题:Java: Difference between the setPreferredSize() and setSize() methods in components。还有一些关于getSize()
和getPreferredSize()
的问题,但我没有找到一个可以被认为是重复的。所以我们开始...)
Swing 中的组件通常有一个首选大小。这是调用 getPreferredSize
方法时 returned 的大小。这是组件 "like" 为了正确显示而应具有的大小。例如,具有特定文本和字体的 JLabel
将具有刚好足以显示整个文本的首选大小。
但是当一个组件显示在屏幕上时,可能无法以首选尺寸显示它(一些原因将在下面解释)。因此,当调用 getSize
时,该方法将 return 组件 当前 在屏幕上的 实际 大小。调整包含框架的大小时,组件也可能会调整大小,然后 return 又是一个不同的值。
(请注意,getSize()
基本上 return 是一个包含与 getWidth()
和 getHeight()
编辑的 return 相同值的对象。
为什么不能始终确保实际尺寸与首选尺寸匹配:
Swing 中的布局通常由布局管理器处理。有关详细信息,请参阅有关 Laying Out Components Within a Container 的教程,但我将在此处尝试总结与此问题相关的部分。
此类布局管理器将尝试 以其首选大小布置组件。可以想象这是困难的,有时甚至是不可能的。想象一个带有 GridLayout(1,2)
的面板包含另外两个面板:
+---------------------+---------------------+
| | |
| Preferred Size: | Preferred Size |
| 400 x 300 | 100 x 200 |
| | |
+---------------------+---------------------+
在GridLayout
中,所有组件的大小必须相同。但他们的首选尺寸不同。所以布局管理器只是不能确保面板的实际尺寸与其首选相同] 尺寸。因此它以介于两者之间的折衷大小显示它们。 (它还可能考虑到最小和最大尺寸,使其更加困难......)。最后,例如,两个面板的大小可能是 (300,200) 像素,即使首选大小是 (400,300) 和 (100,200) 像素。
特别是关于您描述的布局:请注意 FlowLayout
在这里有点特殊。它将按照首选大小布置组件,如果 足够space。如果不够space,那么有些组件可能不可见。因此,您可以尝试将行中的 FlowLayout
更改为 GridLayout(1,n)
,其中 n
是该行中的键数。
我正在尝试使用在调整 JFrame 大小时动态调整大小的键来绘制键盘。此外,键可以有不同的大小。
我有一个面板,其布局设置为 BorderLayout
。在中心,我放置了一个面板,其布局设置为 GridLayout(5,1)
.
网格的每一行都是 JPanel
和 FlowLayout
。在每一行中,我计算每个按钮并通过调用 setPreferredSize
方法设置其首选大小。
当运行程序时,我只看到一些外观怪异的按钮。当我使用 getWidth()/getHeight()
和 getPreferredSize().width/height
检查行面板时,我得到了不同的值:对于 getPrefereedSize().width
,我得到了我真正设置的宽度,但是对于 getWidth()
我的价值明显偏低。
getWidth()
和 getPreferredSize().width
这两种方法有区别吗?
组件的 getWidth/getHeight return 当前尺寸。 getPreferredSize return 是组件想要获取的内容。例如,带有文本的按钮将 return 首选大小,因此文本将完全可见。
合理的布局管理器会向子组件询问它们的首选尺寸,并为它们提供这些尺寸。这将导致父组件的首选大小。如果父组件设置较小的尺寸,它就不能再强制子组件的首选尺寸,要么隐藏一些,要么使组件变小。
(这个问题有一个对应的问题:Java: Difference between the setPreferredSize() and setSize() methods in components。还有一些关于getSize()
和getPreferredSize()
的问题,但我没有找到一个可以被认为是重复的。所以我们开始...)
Swing 中的组件通常有一个首选大小。这是调用 getPreferredSize
方法时 returned 的大小。这是组件 "like" 为了正确显示而应具有的大小。例如,具有特定文本和字体的 JLabel
将具有刚好足以显示整个文本的首选大小。
但是当一个组件显示在屏幕上时,可能无法以首选尺寸显示它(一些原因将在下面解释)。因此,当调用 getSize
时,该方法将 return 组件 当前 在屏幕上的 实际 大小。调整包含框架的大小时,组件也可能会调整大小,然后 return 又是一个不同的值。
(请注意,getSize()
基本上 return 是一个包含与 getWidth()
和 getHeight()
编辑的 return 相同值的对象。
为什么不能始终确保实际尺寸与首选尺寸匹配:
Swing 中的布局通常由布局管理器处理。有关详细信息,请参阅有关 Laying Out Components Within a Container 的教程,但我将在此处尝试总结与此问题相关的部分。
此类布局管理器将尝试 以其首选大小布置组件。可以想象这是困难的,有时甚至是不可能的。想象一个带有 GridLayout(1,2)
的面板包含另外两个面板:
+---------------------+---------------------+
| | |
| Preferred Size: | Preferred Size |
| 400 x 300 | 100 x 200 |
| | |
+---------------------+---------------------+
在GridLayout
中,所有组件的大小必须相同。但他们的首选尺寸不同。所以布局管理器只是不能确保面板的实际尺寸与其首选相同] 尺寸。因此它以介于两者之间的折衷大小显示它们。 (它还可能考虑到最小和最大尺寸,使其更加困难......)。最后,例如,两个面板的大小可能是 (300,200) 像素,即使首选大小是 (400,300) 和 (100,200) 像素。
特别是关于您描述的布局:请注意 FlowLayout
在这里有点特殊。它将按照首选大小布置组件,如果 足够space。如果不够space,那么有些组件可能不可见。因此,您可以尝试将行中的 FlowLayout
更改为 GridLayout(1,n)
,其中 n
是该行中的键数。