我应该避免在Java Swing中使用set(Preferred | Maximum | Minimum)Size方法吗?

本文翻译自:Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

Several times I've been criticized for having suggested the use of the following methods: 多次批评我建议使用以下方法:

  1. setPreferredSize 有必要对setPreferredSize
  2. setMinimumSize 了setMinimumSize
  3. setMaximumSize setMaximumSize

on Swing components. Swing组件上。 I don't see any alternative to their use when I want to define proportions between displayed components. 我想在显示的组件之间定义比例时,看不到任何替代方法。 I have been told this: 有人告诉我:

With layouts the answer is always the same: use a suitable LayoutManager 对于布局,答案始终是相同的:使用合适的LayoutManager

I have searched the web a little bit, but I haven't found any comprehensive analysis of the subject. 我在网上搜索了一下,但没有找到对该主题的任何全面分析。 So I have the following questions: 所以我有以下问题:

  1. Should I completely avoid the use of those methods? 我应该完全避免使用那些方法吗?
  2. The methods have been defined for a reason. 出于某种原因定义了这些方法。 So when should I use them? 那么我什么时候应该使用它们呢? In which context? 在哪种情况下? For what purposes? 出于什么目的?
  3. What exactly are the negative consequences of using those methods? 使用这些方法的负面后果到底是什么? (I can only think adding portability between systems with different screen resolution). (我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。
  4. I don't think any LayoutManager can exactly satisfy all desired layout needs. 我认为任何LayoutManager都无法完全满足所有所需的布局需求。 Do I really need to implement a new LayoutManager for every little variation on my layout ? 我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?
  5. If the answer to 4 is "yes", won't this lead to a proliferation of LayoutManager classes which will become difficult to maintain? 如果对4的回答为“是”,这是否会导致LayoutManager类的泛滥而使维护变得困难?
  6. In a situation where I need to define proportions between children of a Component (eg, child1 should use 10% of space, child2 40% ,child3 50%), is it possible to achieve that without implementing a custom LayoutManager? 在需要定义Component的子代之间比例的情况下(例如,child1应该使用10%的空间,child2 40%,child3 50%的空间),是否可以在不实现自定义LayoutManager的情况下实现?

#1楼

参考:https://stackoom.com/question/UKeQ/我应该避免在Java-Swing中使用set-Preferred-Maximum-Minimum-Size方法吗


#2楼

Should I completely avoid the use of those methods? 我应该完全避免使用那些方法吗?

No, there is no formal evidence to suggest calling or overriding these methods is not allowed. 不可以,没有正式证据表明不允许调用或覆盖这些方法。 In fact, Oracle says these methods are used for giving size hints: http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment . 实际上,Oracle说这些方法用于给出大小提示: http : //docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment

They may also be overridden (which is the best practice for Swing) when extending a Swing component (rather than calling the method on the custom component instance) 扩展 Swing组件时(而不是在自定义组件实例上调用方法),它们也可能被覆盖(这是Swing的最佳实践)。

Most importantly no matter how you specify your component's size, be sure that your component's container uses a layout manager that respects the requested size of the component. 最重要的是,无论您如何指定组件的大小,请确保组件的容器使用的布局管理器尊重组件所请求的大小。

The methods have been defined for a reason. 出于某种原因定义了这些方法。 So when should I use them? 那么我什么时候应该使用它们呢? In which context? 在哪种情况下? For what purposes? 出于什么目的?

When you need to provide customized size hints to the containers Layout manager so that the component will be laid out well 当您需要向容器布局管理器提供自定义的尺寸提示时,可以很好地布局组件

What exactly are the negative consequences of using those methods? 使用这些方法的负面后果到底是什么? (I can only think to add portability between systems with different screen resolution). (我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。

  • Many layout managers do not pay attention to a component's requested maximum size. 许多布局管理器并不关注组件所请求的最大大小。 However, BoxLayout and SpringLayout do. 但是, BoxLayoutSpringLayout可以。 Furthermore, GroupLayout provides the ability to set the minimum, preferred or maximum size explicitly, without touching the component. 此外, GroupLayout提供了显式设置最小,首选或最大尺寸的功能,而无需接触组件。

  • Make sure that you really need to set the component's exact size. 确保您确实需要设置组件的确切大小。 Each Swing component has a different preferred size, depending on the font it uses and the look and feel. 每个Swing组件都有不同的首选大小,具体取决于其使用的字体和外观。 Thus having a set size might produce varied looks of the UI on different Systems 因此,设置大小可能会在不同系统上产生不同的UI 外观

  • sometimes problems can be encountered with GridBagLayout and text fields, wherein if the size of the container is smaller than the preferred size, the minimum size gets used, which can cause text fields to shrink quite substantially. 有时, GridBagLayout和文本字段可能会遇到问题,其中,如果容器的大小小于首选大小,则会使用最小大小,这可能导致文本字段显着缩小。

  • JFrame does not enforce overriden getMinimumSize() only calling setMinimumSize(..) on its works JFrame不会在其工作中仅调用setMinimumSize(..)来强制执行重写的getMinimumSize() setMinimumSize(..)

I don't think any LayoutManager can exactly satisfy all desired layout needs. 我认为任何LayoutManager都无法完全满足所有所需的布局需求。 Do I really need to implement a new LayoutManager for every little variation on my layout? 我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

If by implementing you mean using then yes. 如果实现是指使用,则可以。 Not one LayoutManger can handle everything, each LayoutManager has its pros and cons thus each can be used together to produce the final layout. 没有一个LayoutManger可以处理所有事情,每个LayoutManager都有其优缺点,因此可以一起使用以生成最终的布局。

Reference: 参考:


#3楼

These methods are poorly understood by most people. 大多数人对这些方法知之甚少。 You should absolutely not ignore these methods. 您绝对不应忽略这些方法。 It is up to the layout manager if they honor these methods. 如果他们采用这些方法,则取决于布局管理器。 This page has a table that shows which layout managers honor which of those methods: 该页面具有一个表,该表显示哪些布局管理器支持以下哪种方法:

http://thebadprogrammer.com/swing-layout-manager-sizing/ http://thebadprogrammer.com/swing-layout-manager-sizing/

I have been writing Swing code for 8+ years and the layout managers included in the JDK have always served my needs. 我已经写了8年以上的Swing代码,并且JDK中包含的布局管理器始终可以满足我的需求。 I have never needed a 3rd party layout manager to achieve my layouts. 我从不需要第三方布局经理来完成我的布局。

I will say that you shouldn't try to give the layout manager hints with these methods until you are sure you need them. 我会说,在确定您需要这些方法之前,您不应尝试通过这些方法为布局管理器提供提示。 Do your layout without giving any sizing hints (ie let the layout manager do its job) and then you can make minor corrections if you need to. 在不给出任何大小调整提示的情况下进行布局(即让布局管理器完成其工作),然后您可以根据需要进行较小的更正。


#4楼

There are a lot of good answers here but I want to add a little more about the reasons why you should normally avoid these (the question just came up again in a duplicate topic): 这里有很多很好的答案,但是我想补充一些有关您通常应该避免使用这些原因的原因 (这个问题在重复的主题中又出现了):

With few exceptions, if you are using these methods you are probably fine-tuning your GUI to look good on a specific look-and-feel (and with your system-specific settings, eg your preferred desktop font, etc.). 除少数例外,如果您使用这些方法,则可能会在特定的外观(以及系统特定的设置,例如首选的桌面字体等)上对GUI进行微调以使其看起来不错。 The methods themselves aren't inherently evil, but the typical reasons for using them are . 方法本身并不是天生的邪恶,但是使用它们的典型原因 As soon as you start tuning pixel positions and sizes in a layout you run the risk of your GUI breaking (or at minimum, looking bad), on other platforms. 在其他平台上,一旦开始调整布局中的像素位置和大小,就会冒着GUI破裂(或至少看起来很糟)的风险。

As an example of this, try changing your application's default look-and-feel. 例如,尝试更改应用程序的默认外观。 Even just with the options available on your platform, you may be surprised at how poorly the results can be rendered. 即使仅使用平台上可用的选项,您也可能会对结果的渲染效果感到惊讶。

So, in the name of keeping your GUI functional and nice-looking on all platforms (remember, one of the major benefits of Java is its cross-platformness), you should rely on layout managers, etc., to automatically adjust the sizes of your components so that it renders correctly outside of your specific development environment. 因此,以在所有平台上保持GUI正常运行和美观的名义(请记住,Java的主要优点之一是它的跨平台性),您应该依靠布局管理器等来自动调整大小。您的组件,以便在特定的开发环境之外正确呈现。

All that said, you can certainly conceive of situations where these methods are justified. 综上所述,您当然可以设想这些方法合理的情况。 Again, they aren't inherently evil, but their usage is normally a big red flag indicating potential GUI issues. 同样,它们并不是天生的邪恶,但它们的用法通常是一个大的红旗,表明潜在的GUI问题。 Just make sure you are aware of the high potential for complications if/when you use them, and always try and think if there is another look-and-feel-independent solution to your problems -- more often than not you will find that these methods are not necessary. 只需确保您意识到使用并发症的高可能性,并始终尝试思考是否存在另一种与外观无关的解决方案,但往往会发现这些方法不是必需的。

By the way, if you find yourself getting frustrated with standard layout managers, there are a lot of good free, open-source third-party ones, for example JGoodies' FormLayout , or MigLayout . 顺便说一句,如果您发现自己对标准布局管理器感到沮丧,那么有很多不错的免费开源第三方,例如JGoodies的FormLayoutMigLayout Some GUI builders even have built-in support for third-party layout managers -- Eclipse's WindowBuilder GUI editor, for example, ships with support for FormLayout and MigLayout . 一些GUI构建器甚至内置了对第三方布局管理器的支持-例如,Eclipse的WindowBuilder GUI编辑器附带对FormLayoutMigLayout支持。


#5楼

I am seeing it differenty than the accepted answer. 我看到的与接受的答案有所不同。

1) Should I completely avoid the use of those methods? 1)我应该完全避免使用那些方法吗?

Never avoid! 永远不要回避! They're there to express the size constraints of your components to the layout manager. 它们在那里可以向布局管理器表达组件的尺寸限制。 You can avoid using them if you're not using any layout manager and try to manage the visual layout on your own. 如果不使用任何布局管理器,而是尝试自己管理视觉布局,则可以避免使用它们。

Unfortunately, Swing is not coming with reasonable default dimensions. 不幸的是,Swing没有附带合理的默认尺寸。 However, instead of setting the dimensions of a component, it is better OOP to descend your own component with reasonable defaults. 但是,与其设置组件的尺寸,不如通过合理的默认值将自己的组件降级为OOP,这更好。 (In that case you call setXXX in your descendant class.) Alternatively, you can override the getXXX methods for the same effect. (在这种情况下,您在子孙类中调用setXXX。)或者,您可以重写getXXX方法以达到相同的效果。

2) The methods have been defined for a reason. 2)由于某种原因定义了方法。 So when should I use them? 那么我什么时候应该使用它们呢? In which context? 在哪种情况下? For what purposes? 出于什么目的?

Always. 总是。 When you create a component, set its realistic min/preferred/max size according to the use of that component. 创建组件时,请根据该组件的用途设置其实际的最小/首选/最大大小。 For example, if you have a JTextField for entering country symbols such as UK, its preferred size shall be as wide to fit two chars (with the current font, etc.) but probably it is meaningless to let it grow any bigger. 例如,如果您有一个用于输入国家符号(例如UK)的JTextField,则其首选大小应与两个字符(使用当前字体等)一样宽,但是将其增大可能毫无意义。 After all, country symbols are two chars. 毕竟,国家/地区符号是两个字符。 As opposite, if you have a JTextField for entering eg a customer name, it can have a preferred size for like the pixel size for 20 chars, but can grow to bigger if the layout is resized, so set the maximum size to more. 相反,如果您有一个用于输入例如客户名称的JTextField,则它可以具有首选大小,例如20个字符的像素大小,但是如果调整布局大小,则可以增长到更大,因此将最大大小设置为更大。 At the same time, having a 0px wide JTextField is pointless, so set a realistic minimum size (I would say the pixel size of 2 chars). 同时,具有0px宽的JTextField是没有意义的,因此请设置一个实际的最小大小(我要说2个字符的像素大小)。

3) What exactly are the negative consequences of using those methods? 3)使用这些方法的负面后果到底是什么?

(I can only think adding portability between systems with different screen resolution). (我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。

No negative consequences. 没有负面影响。 These are hints for the layout manager. 这些是布局管理器的提示。

4) I don't think any LayoutManager can exactly satisfy all desired layout needs. 4)我认为任何LayoutManager都不能完全满足所有所需的布局需求。

Do I really need to implement a new LayoutManager for every little variation on my layout ? 我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

No, definitely not. 不,绝对不是。 The usual approach is to cascade different basic layoutmanagers such as horizontal and vertical layout. 通常的方法是级联不同的基本布局管理器,例如水平和垂直布局。

For example, the layout below: 例如,下面的布局:

<pre>
+--------------+--------+
| ###JTABLE### | [Add]  | 
| ...data...   |[Remove]|
| ...data...   |        |
| ...data...   |        |
+--------------+--------+
</pre>

is having two parts. 有两个部分。 The left and right parts are a horizontal layout. 左右部分是水平布局。 The right part is a JPanel added to the horizontal layout, and this JPanel is having a vertical layout which lays out the buttons vertically. 右侧是添加到水平布局的JPanel,此JPanel具有垂直布局,可垂直放置按钮。

Of course, this can grow tricky with a real life layout. 当然,在现实生活中布局可能会变得棘手。 Therefore grid-based layout managers such as MigLayout are much better if you're about to develop anything serious. 因此,如果您要开发任何严肃的东西,则基于网格的布局管理器(例如MigLayout)会更好。

5) If the answer to 4 is "yes", won't this lead to a proliferation of LayoutManager classes which will become difficult to maintain? 5)如果对4的答案为“是”,这是否会导致LayoutManager类的泛滥而导致难以维护?

No, you definitely shall not develop layout managers, unless you need something very special. 不,除非您需要非常特殊的东西,否则您绝对不会开发布局管理器。

6) In a situation where I need to define proportions... 6)在需要定义比例的情况下...

between children of a Component (eg, child1 should use 10% of space, child2 40% ,child3 50%), is it possible to achieve that without implementing a custom LayoutManager? 组件的子项之间(例如,child1应该使用10%的空间,child2 40%,child3 50%),是否可以在不实现自定义LayoutManager的情况下实现?

Basically, once the preferred sizes are set right, you may not want to do anything in percentage. 基本上,一旦正确设置了首选大小,您可能就不想按百分比进行任何操作。 Simply, because percentages are pointless (eg it is pointless to have a JTextField 10% of the window size - since one can shrink the window so that JTextField becomes 0px wide, or can expand the window so that the JTextField is across two displays on a multi-display setup). 简而言之,因为百分比是无意义的(例如,使JTextField占窗口大小的10%是没有意义的-因为一个人可以缩小窗口以使JTextField变为0px宽,或者可以扩展窗口以使JTextField跨一个显示器上的两个显示器多显示器设置)。

But, may times you may use the percentages to control sizes of bigger building blocks of your gui (panels, for example). 但是,有时您可能会使用百分比来控制gui较大的构建基块(例如面板)的大小。

You can use JSplitPane where you can pre-set the ratio of the two sides. 您可以使用JSplitPane预先设置两侧的比例。 Or, you can use MigLayout which allows you to set such constraints in percentage, pixels, and other units. 或者,您可以使用MigLayout,它允许您以百分比,像素和其他单位设置此类约束。


#6楼

Should I completely avoid the use of those methods? 我应该完全避免使用那些方法吗? I wouldn't say "avoid" them. 我不会说“避免”它们。 I'd say that if you think you need them, you're probably doing something wrong. 我想说的是,如果您认为自己需要它们,那可能是您做错了什么。 Component sizes are determined in context. 组件的大小取决于上下文。 For example, Text component sizes are determined by the number of rows and columns you specify, combined with the font you may have chosen. 例如,文本组件的大小取决于您指定的行数和列数以及您可能选择的字体。 Your button and label size will be the size of the graphic, if you set one, or the space needed to display the text you set. 如果设置了一个,则按钮和标签的大小将是图形的大小,或者是显示设置的文本所需的空间。 Each component has a natural size, and the layout managers will use those to lay everything out without you needing to specify sizes. 每个组件都有一个自然的大小,布局管理器将使用这些大小来布局所有内容,而无需指定大小。 The main exception is the JScrollPane, which has a size independent of whatever it contains. 主要的例外是JScrollPane,它的大小与其所包含的内容无关。 For those, I will sometimes call setSize() , and let that size determine the initial window size, by calling JFrame.pack() . 对于这些,有时我会调用setSize() ,并通过调用JFrame.pack()来确定初始窗口的大小。 Usually, I will let the window size determine the JScrollPane size. 通常,我将让窗口大小确定JScrollPane的大小。 The user will determine the size of the window. 用户将确定窗口的大小。 Many layout managers ignore the sizes you set anyway, so they often don't do much good. 无论如何,许多布局管理器都会忽略您设置的尺寸,因此它们通常做得不好。

The methods have been defined for a reason. 出于某种原因定义了这些方法。 So when should I use them? 那么我什么时候应该使用它们呢? In which context? 在哪种情况下? For what purposes? 出于什么目的? I believe they were added to provide hints to the layout managers. 我相信添加它们是为了向布局管理器提供提示。 They may have been written for historical reasons, because layout managers were new, and people didn't fully trust them. 他们之所以写是因为历史原因,因为布局经理是新来的,人们并不完全信任他们。 I know a few developers who avoided layout managers and placed everything manually, just because they didn't want to bother with learning a new paradigm. 我知道一些开发人员避免布局管理器,而是手动放置所有内容,只是因为他们不想为学习新的范式而烦恼。 It's a terrible idea. 这是一个可怕的主意。

What exactly are the negative consequences of using those methods? 使用这些方法的负面后果到底是什么? (I can only think adding portability between systems with different screen resolution). (我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。 They're ineffective, and they produce bad layouts, with objects getting squeezed or stretched to non-natural sizes. 它们效果不佳,并且布局不好,物体被挤压或拉伸到非自然尺寸。 And the layouts will be brittle. 而且布局会很脆弱。 Changes to the window size will sometimes break the layout and put things in the wrong places. 更改窗口大小有时会破坏布局并将东西放置在错误的位置。

I don't think any LayoutManager can exactly satisfy all desired layout needs. 我认为任何LayoutManager都无法完全满足所有所需的布局需求。 Do I really need to implement a new LayoutManager for every little variation on my layout ? 我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗? You shouldn't "implement" a new LayoutManager. 您不应该“实现”新的LayoutManager。 You should instantiate existing ones. 您应该实例化现有的。 I often use several layout managers in a single window. 我经常在一个窗口中使用多个布局管理器。 Each JPanel will have its own layout manager. 每个JPanel都有自己的布局管理器。 Some people balk at nested layouts, because they're hard to maintain. 有些人不愿使用嵌套布局,因为它们很难维护。 When I use them, I give each one its own creation method to make it easier to see what each one does. 当我使用它们时,我给每个人自己的创建方法,以便更轻松地查看每个人的工作。 But I never "implement" a layout manager. 但是我从来没有“实现”布局管理器。 I just instantiate them. 我只是实例化它们。

If the answer to 4 is "yes", won't this lead to a proliferation of LayoutManager classes which will become difficult to maintain? 如果对4的回答为“是”,这是否会导致LayoutManager类的泛滥而使维护变得困难? If you're implementing new layout manager classes for slight variations in layout, you're using them wrong. 如果您要实现新的布局管理器类以使布局略有变化,那么您使用的是错误的。 If you're just implementing new layout managers, you're probably doing something wrong. 如果您只是实施新的布局管理器,则可能是做错了什么。 The only time I've extended a LayoutManager class, it was to add a zoom slider to a JScrollPane. 我唯一扩展LayoutManager类的方法是向JScrollPane添加缩放滑块。

In a situation where I need to define proportions between children of a Component (eg, child1 should use 10% of space, child2 40% ,child3 50%), is it possible to achieve that without implementing a custom LayoutManager? 在需要定义Component的子代之间比例的情况下(例如,child1应该使用10%的空间,child2 40%,child3 50%的空间),是否可以在不实现自定义LayoutManager的情况下实现? The JSplitPane has a way of specifying the percentage each component should get. JSplitPane有一种方法可以指定每个组件应获得的百分比。 The divider is movable by default, but you can turn that off if you want. 默认情况下,分隔线是可移动的,但是您可以根据需要将其关闭。 I don't use that feature much. 我没有太多使用该功能。 I usually have some components that take up a set size, and the rest of the space is taken up by a scroll pane. 我通常有一些组件会占据一定的大小,其余空间则由滚动窗格占据。 The scroll pane size will adjust with the window size. 滚动窗格的大小将根据窗口大小进行调整。 If you have two scroll panes side by side, you can put them in a JSplitPane and specify the percentage of new space given to each one as the user expands and contracts the windows. 如果有两个并排的滚动窗格,则可以将它们放在JSplitPane中,并在用户扩展和收缩窗口时指定分配给每个滚动窗格的新空间的百分比。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值