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


481

多次批评我建议使用以下方法:

  1. setPreferredSize
  2. setMinimumSize
  3. setMaximumSize

Swing组件上。我想在显示的组件之间定义比例时,看不到任何替代方法。有人告诉我:

对于布局,答案始终是相同的:使用合适的LayoutManager

我在网上搜索了一下,但没有找到对该主题的任何全面分析。所以我有以下问题:

  1. 我应该完全避免使用那些方法吗?
  2. 出于某种原因定义了这些方法。那么我什么时候应该使用它们呢?在哪种情况下?出于什么目的?
  3. 使用这些方法的负面后果到底是什么?(我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。
  4. 我认为任何LayoutManager都无法完全满足所有所需的布局需求。我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?
  5. 如果对4的回答为“是”,这是否会导致LayoutManager类的泛滥而导致难以维护?
  6. 在需要定义子组件之间比例的情况下(例如,child1应该使用10%的空间,child2 40%,child3 50%的空间),是否可以在不实现自定义LayoutManager的情况下实现呢?

Answers:


236
  1. 我应该完全避免使用那些方法吗?

    是的,用于应用程序代码。

  2. 出于某种原因定义了这些方法。那么我什么时候应该使用它们呢?在哪种情况下?出于什么目的?

    我不知道,我个人认为这是API设计事故。复合组件稍微强加了对子项大小有特殊想法的组件。“轻微”,因为他们应该使用自定义LayoutManager来实现他们的需求。

  3. 使用这些方法的负面后果到底是什么?(我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性。)

    某些技术原因(不完整,不幸的是,由于SwingLabs迁移到java.net而导致链接断开),例如,在“规则”(hehe)或他/她对我的答案的评论中找到的@bendicott 链接中提到了技术原因。在社交上,将大量工作交给不幸的同事,他必须维护代码并必须查找损坏的布局。

  4. 我认为任何LayoutManager都无法完全满足所有所需的布局需求。我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

    是的,有足够强大的LayoutManagers可以很好地满足“所有布局需求”。前三个是JGoodies FormLayout,MigLayout,DesignGridLayout。因此,实际上,除了简单的高度专业化的环境外,您很少编写LayoutManager。

  5. 如果对4的回答为“是”,这是否会导致LayoutManager类的泛滥而导致难以维护?

    (对4的回答为“否”。)

  6. 在需要定义Component的子项之间的比例的情况下(例如,子项1应该使用10%的空间,子项2应该使用40%的空间,子项3应该使用50%的空间),是否可以在不实现自定义LayoutManager的情况下实现这一点?

    三巨头中的任何一个都不能甚至不可以使用GridBag(永远不要操心真正的大师,以太少的力气就麻烦很多)。


4
我不确定在至少两种情况下是否同意此建议。1)自定义呈现的组件2)JEditorPane与本身并不暗示宽度的HTML一起使用。OTOH我不确定是否错过了什么。我将仔细查看对该主题的答复,但是如果您有任何意见,尤其是对后一种情况,请关注。
Andrew Thompson

2
@Andrew Thompson 1)自定义组件:组件本身负责返回有用的布局提示,如果它们不暗示显示错误,则2)甚至核心组件也存在错误;-) 3)我不介意空格(尽管不是)这次是有意的,谢谢:-)
kleopatra 2011年

8
我不敢相信可接受的答案就是说避免使用setXXX()方法的答案。有时,您只需要它们即可向布局管理器提供提示。如果要布置面板,则在必要时绝对可以随意使用这些方法。说我想,如果您使用适当的布局管理器,您会发现自己并不经常需要这些方法,但是有时您只需要它们。尝试将JComboBox或JSpinner放在X_AXIS BoxLayout中,不要使用它们,相信您会发现在那里需要setMaximumSize()。
迈克尔

5
@Michael不,我绝对不需要它-答案是总是使用像样的LayoutManager并在管理器级别(相对于组件级别)进行任何细微调整
kleopatra 2013年

5
在整个堆栈溢出过程中,您始终会说“使用体面的LayoutManager并告诉它想要什么尺寸”,但是您从未给出“体面的” LayoutManager的任何特定示例。而且,没有任何标准管理人员允许直接控制尺寸。
Ti Strga 2014年

100

一些启发式:

  • 不要使用set[Preferred|Maximum|Minimum]Size(),当你真的要重写get[Preferred|Maximum|Minimum]Size(),因为可能会创建自己的组件,显示做在这里

  • 如此和以下所示,请不要使用set[Preferred|Maximum|Minimum]Size()您可以依赖于组件被仔细重写的内容。getPreferred|Maximum|Minimum]Size

  • 务必用于set[Preferred|Maximum|Minimum]Size()导出后validate()几何图形,如下所示和此处

  • 如果某个组件没有首选的大小,例如JDesktopPane,您可能必须调整容器的大小,但是任何这样的选择都是任意的。发表评论可能有助于澄清意图。

  • 如发现这些注释中所述,当您发现必须遍历许多组件以获得派生的大小时,请考虑使用备用布局或自定义布局。

在此处输入图片说明

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * @see /programming/7229226
 * @see /programming/7228843
 */
public class DesignTest {

    private List<JTextField> list = new ArrayList<JTextField>();
    private JPanel panel = new JPanel();
    private JScrollPane sp = new JScrollPane(panel);

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                DesignTest id = new DesignTest();
                id.create("My Project");
            }
        });
    }

    private void addField(String name) {
        JTextField jtf = new JTextField(16);
        panel.add(new JLabel(name, JLabel.LEFT));
        panel.add(jtf);
        list.add(jtf);
    }

    private void create(String strProjectName) {
        panel.setLayout(new GridLayout(0, 1));
        addField("First Name:");
        addField("Last Name:");
        addField("Address:");
        addField("City:");
        addField("Zip Code:");
        addField("Phone:");
        addField("Email Id:");
        KeyboardFocusManager.getCurrentKeyboardFocusManager()
            .addPropertyChangeListener("permanentFocusOwner",
            new FocusDrivenScroller(panel));
        // Show half the fields
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        sp.validate();
        Dimension d = sp.getPreferredSize();
        d.setSize(d.width, d.height / 2);
        sp.setPreferredSize(d);

        JInternalFrame internaFrame = new JInternalFrame();
        internaFrame.add(sp);
        internaFrame.pack();
        internaFrame.setVisible(true);

        JDesktopPane desktopPane = new JDesktopPane();
        desktopPane.add(internaFrame);

        JFrame frmtest = new JFrame();
        frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmtest.add(desktopPane);
        frmtest.pack();
        // User's preference should be read from java.util.prefs.Preferences
        frmtest.setSize(400, 300);
        frmtest.setLocationRelativeTo(null);
        frmtest.setVisible(true);
        list.get(0).requestFocusInWindow();
    }

    private static class FocusDrivenScroller implements PropertyChangeListener {

        private JComponent parent;

        public FocusDrivenScroller(JComponent parent) {
            this.parent = parent;
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Component focused = (Component) evt.getNewValue();
            if (focused != null
                && SwingUtilities.isDescendingFrom(focused, parent)) {
                parent.scrollRectToVisible(focused.getBounds());
            }
        }
    }
}

2
(您可能已经猜到了:-)与“外部因素”不同意:XXSize属性表示内部需求。从外部进行调整是滥用,也就是黑客入侵。如果您想要一个(内部或J-)框架,且具有相对于其首选大小的特定大小...调整框架的大小,而不是内容的大小
kleopatra 2011年

2
@kleopatra:坚持一点:如果永远不应该从外部使用setXXSize方法,为什么不声明为私有或受保护?这不是缺乏设计吗?公共修饰符是否暗中告诉用户可以使用这些方法?
Heisenbug

2
我必须同意@kleopatra:setPreferredSize()始终用任意选择替换组件的计算。
2011年

1
@trashgod +100给我,我认为覆盖这些方法,甚至调用它们都没有问题(但是,这当然意味着您有一个自定义组件,因此覆盖会更好)
David Kroukamp 2012年

5
@DavidKroukamp:谢谢。我尊重kleopatra的丰富经验,但我认为严格审查相反的观点很有价值。
垃圾神2012年

47

我应该完全避免使用那些方法吗?

不可以,没有正式证据表明不允许调用或覆盖这些方法。实际上,Oracle说这些方法用于给出大小提示:http : //docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment

扩展时也可能会覆盖它们(这是Swing的最佳实践) Swing组件时(而不是在自定义组件实例上调用方法)。

最重要的是,无论您如何指定组件的大小,请确保组件的容器使用的布局管理器尊重组件所请求的大小。

出于某种原因定义了这些方法。那么我什么时候应该使用它们呢?在哪种情况下?出于什么目的?

当您需要向容器布局管理器提供自定义的尺寸提示时,可以很好地布局组件

使用这些方法的负面后果到底是什么?(我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。

  • 许多布局管理器并不关注组件所请求的最大大小。然而,BoxLayoutSpringLayout做。此外,GroupLayout还提供了显式设置最小,首选或最大尺寸的功能,而无需接触组件。

  • 确保您确实需要设置组件的确切大小。每个Swing组件都有不同的首选大小,具体取决于其使用的字体和外观。因此,设置大小可能会在不同系统上产生不同的UI 外观

  • GridBagLayout文本字段有时会遇到问题,其中,如果容器的大小小于首选大小,则会使用最小大小,这可能导致文本字段显着缩小。

  • JFrame不强制重写getMinimumSize()仅调用setMinimumSize(..)其工作

我认为任何LayoutManager都无法完全满足所有所需的布局需求。我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

如果实现是指使用,则可以。LayoutManger每个人都无法应付一切LayoutManager都有其优点和缺点,因此可以一起使用以产生最终的布局。

参考:


3
提供自定义的尺寸提示本身就是一个矛盾:提供尺寸提示(以px!为单位)是组件的专有任务。它根据内部状态详细信息来计算它们,除了自身以外,其他任何一方都无法知道(也无法跟踪)。从客户端的角度来看,自定义的方法可以是组件上合适的LayoutManager和/或专用api,从而可以根据“语义”与大小相关的属性,文本组件中的行数/列数来配置大小要求
kleopatra

3
@kleopatra我仍然很想知道为什么Oracle会告诉我们如何使用这些方法以及正确的使用方法。我们可能有自己的偏好,但是我们不能说设计师在没有证据表明它不被使用时建议不要使用它。但这就是为什么我提供赏金的原因,看看它是否会吸引其他人,这些人可能会从可靠的来源提供信息,而oracle则声明根本不使用这些方法(因此,如果这样做,这将是一种不好的做法,例如setMinimumSize必须是可以调用JSplitPane之类的东西,这可以在Oracle拆分窗格教程中看到
David Kroukamp,2012年

4
@大卫:我来看看setXxxSize方法为红色标志,我可能结业这里,即使在文档建议它。我几乎总是应该重写getXxxSize,可以访问所需的几何体。甚至简短的示例也比我想的要多。+1表示布局管理器之间的差异并引用了本教程。
垃圾神

1
D'oh,在上面的评论中,我想在这里引用答案。
垃圾神2012年

13
+1“不,没有正式证据表明不允许调用或重写这些方法。” 发现。标为答案的帖子是普通BS。
TT。

25

这里有很多很好的答案,但是我想补充一些有关您通常应该避免使用这些原因的原因(这个问题在重复的主题中又出现了):

除少数例外,如果您使用这些方法,则可能会在特定的外观(以及系统特定的设置,例如首选的桌面字体等)上对GUI进行微调以使其看起来不错。这些方法本身并不是天生的邪恶,但是使用它们的典型原因。在其他平台上,一旦开始调整布局中的像素位置和大小,就会冒着GUI破裂(或至少看起来很糟)的风险。

例如,尝试更改应用程序的默认外观。即使仅使用平台上可用的选项,您也可能会对结果的渲染效果感到惊讶。

因此,以在所有平台上保持GUI正常运行和美观的名义(请记住,Java的主要优点之一是其跨平台性),您应该依靠布局管理器等来自动调整大小。您的组件,以便在特定的开发环境之外正确呈现。

综上所述,您当然可以设想这些方法合理的情况。同样,它们并不是天生的邪恶,但是它们的用法通常是一个大的红色标记,表明潜在的GUI问题。只需确保您意识到使用并发症的高可能性,并始终尝试思考是否存在另一种与外观无关的解决方案,但往往会发现这些方法不是必需的。

顺便说一句,如果您发现自己对标准布局管理器感到沮丧,那么有很多不错的免费,开源的第三方管理器,例如JGoodies'FormLayoutMigLayout。某些GUI构建器甚至内置了对第三方布局管理器的支持-例如,Eclipse的WindowBuilder GUI编辑器附带对FormLayout和的支持MigLayout


2
+1一个体贴的答案-只是不同意他们并不是天生的邪恶,仅因为它们是:-)通常,外部客户没有机会猜测任何东西-而且只有假设是局外人可以得到的-中途正确的布局提示:仅组件本身确实随时拥有所有信息,以返回任何有用的信息。而且由于外来者立即干预,因此有责任将这些提示保持最新,而这是他们无法接受的。
kleopatra 2014年

1
好吧,你知道,我对这类事情有更多的“枪不杀人,人杀人”的观点。:) 如果有人使用这些方法,他们需要注意一些事情,例如关于不可预知的布局提示使用的优点(这就是为什么很少使用这些方法的情况确实很少)。
杰森·C

我认为设置首选大小根本不是一个大障碍。相反,未设置它一个很大的危险信号。让我详细说明。布局管理器-多么聪明-都不知道gui小部件的逻辑功能。例如,布局管理器无法区分用于输入邮政编码的JTextField和用于输入名称的JTextField。同样,它无法区分JTextField旁边的工具按钮还是表单底部的大OK按钮。因此,要么需要更好的窗口小部件集,要么需要一些调整提示,不是吗?
Gee Bee

@GeeBee不,实际上,这是一个红旗的典型例子。你应该做的是利用JTextField.setColumns设置列数,这相应地调整首选大小。如果这样做,setPreferredSize则会对大小进行硬编码,这将取决于平台字体大小而破坏布局。这是网格袋布局中的一些文本字段,带有setColumns适当的。对于按钮,请使用适当的布局/网格权重来控制大小。
Jason C

@GeeBee现在,正确完成此操作,请注意当我减小字体大小时如何减小文本字段宽度:i.snag.gy/ZULulh.jpg。现在即使即时更改字体大小也可以自动进行,而不是您,例如,您必须重新计算所有文本字段的宽度并再次分别显式调用setPreferredSize,您要做的就是使布局无效,并且它们的大小将调整。
Jason C

20

如果您在使用Java Swing中的布局时遇到麻烦,那么我强烈建议您在此处FormLayout免费推荐作为Karsten Lentzsch的Forms免费软件库的一部分免费提供的JGoodies 。

这个非常流行的布局管理器非常灵活,可以开发非常优美的Java UI。

您可以在这里找到Karsten的文档,并在Eclipse中找到一些相当不错的文档。


16

大多数人对这些方法知之甚少。您绝对不应忽略这些方法。如果他们采用这些方法,则取决于布局管理器。该页面具有一个表,该表显示哪些布局管理器支持以下哪种方法:

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

我已经写了8年以上的Swing代码,并且JDK中包含的布局管理器始终可以满足我的需求。我从不需要第三方布局经理来完成我的布局。

我会说,在确定需要它们之前,您不应该尝试通过这些方法为布局管理器提供提示。在不给出任何大小调整提示的情况下进行布局(即让布局管理器执行其工作),然后可以根据需要进行较小的更正。


1
无论是有轻微的误解(你的一部分)或误解(对我而言),把你的选择:-)你不断重复(在这里,在你的博客,在你的答案相关的BoxLayout)的 XXSize作为重要的-实际上LayoutManager对XXSize感兴趣(或不感兴趣),即大小调整提示与它的产生方式无关(由组件进行内部计算或由应用程序代码手动强制执行)
kleopatra 2013年

1
我不确定我明白你在这里得到什么。我在上面提到了XXSize()方法只是提示。如果需要的话,我确实没有给布局管理器一些提示的任何错误。在我的挥杆代码中,您会偶然发现setXXSize()方法。数量不多,但偶尔我会发现它们是必需的。JComboBox和JSpinner经常需要提示。特别是在实现后填充的JComboBox。您似乎反对这些方法的所有使用,我也不知道为什么。(也许我是那个想念这艘船的人)。
迈克尔

5
不是方法是提示,而是属性:组件应该为所有提示报告合理的内容,有些(例如JComboBox)则不行-返回maxInteger左右。那是一个错误,应该由组合修复。关于您的习惯:当维护人员的同事必须清理它们时,请确保远离:)硬编码的提示往往在最小的变化下就破坏了布局,并且很难将其识别为布局损坏的原因。
kleopatra

15

在需要定义子组件之间的比例的情况下(子组件1应使用10%的空间,子组件2应占40%的空间,子组件3应占50%的空间),是否可以在不实现自定义布局管理器的情况下实现?

也许GridBagLayout会满足您的需求。除此之外,网络上还有大量的布局管理器,我敢打赌,这可以满足您的要求。


感谢您的回答。我必须假设您的意思也是:“根本不使用setPreferredSize”,对吗?
Heisenbug

1
GridBagLayout使用约束,您可以在其中为给定组件在X和Y中指定“权重”,因此LayoutManager可以决定如何使用调整大小的额外空间。但是您仍然需要/可以使用setPreferredSize来确定每个组件的首选大小,请注意,“ preferred”并不意味着它将始终受到尊重。在特殊情况下,您可能仍然需要setMinimumSize和setMaximumSize。他们不是邪恶的,不要屈服于此。docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
マルちゃんだよ

5

我看到的与接受的答案有所不同。

1)我应该完全避免使用那些方法吗?

永远不要回避!它们在那里可以向布局管理器表达组件的尺寸限制。如果不使用任何布局管理器,而是尝试自己管理视觉布局,则可以避免使用它们。

不幸的是,Swing没有附带合理的默认尺寸。但是,与其设置组件的尺寸,不如通过合理的默认值将自己的组件降级为OOP,这更好。(在这种情况下,您在子孙类中调用setXXX。)或者,您可以重写getXXX方法以达到相同的效果。

2)由于某种原因定义了方法。那么我什么时候应该使用它们呢?在哪种情况下?出于什么目的?

总是。创建组件时,请根据该组件的用途设置其实际的最小/首选/最大大小。例如,如果您有一个用于输入国家符号(例如UK)的JTextField,则其首选大小应尽可能宽以适合两个字符(使用当前字体等),但是让它变大可能没有任何意义。毕竟,国家/地区符号是两个字符。相反,如果您有一个用于输入例如客户名称的JTextField,则它可以具有首选大小,例如20个字符的像素大小,但是如果调整布局大小,则可以增长到更大,因此将最大大小设置为更大。同时,具有0px宽的JTextField是没有意义的,因此请设置一个实际的最小大小(我要说2个字符的像素大小)。

3)使用这些方法的负面后果到底是什么?

(我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。

没有负面影响。这些是布局管理器的提示。

4)我认为任何LayoutManager都不能完全满足所有所需的布局需求。

我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

不,绝对不是。通常的方法是级联不同的基本布局管理器,例如水平和垂直布局。

例如,下面的布局:

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

有两个部分。左右部分是水平布局。右侧是添加到水平布局的JPanel,此JPanel具有垂直布局,可垂直放置按钮。

当然,在现实生活中布局可能会变得棘手。因此,如果您要开发任何严肃的东西,则基于网格的布局管理器(例如MigLayout)会更好。

5)如果对4的答案为“是”,这是否会导致LayoutManager类的泛滥而导致难以维护?

不,除非您需要非常特殊的东西,否则您绝对不会开发布局管理器。

6)在需要定义比例的情况下...

组件的子项之间(例如,child1应该使用10%的空间,child2 40%,child3 50%),是否可以在不实现自定义LayoutManager的情况下实现?

基本上,一旦正确设置了首选大小,您可能就不想按百分比进行任何操作。简而言之,因为百分比是无意义的(例如,将JTextField设置为窗口大小的10%是毫无意义的-因为一个人可以缩小窗口以使JTextField变为0px宽,或者可以扩展窗口以使JTextField跨一个显示器上的两个显示器多显示器设置)。

但是,有时您可能会使用百分比来控制gui较大的构建基块(例如面板)的大小。

您可以使用JSplitPane预先设置两侧的比例。或者,您可以使用MigLayout,它允许您以百分比,像素和其他单位设置此类约束。


真?这是0?这比100次以上的公认答案更好。基本上就是说“您应该nevar使用setPreferredSize!” 这是可怕的。在我的工作中,有很多特定的尺寸要求,例如“安全要求,触摸屏上的按钮必须为[X]乘[Y],且间隔为[M] x [N]”。btnBar.setPreferredSize( dimTouchBtn );是做到这一点的最佳方法。简单明了,无需自定义布局管理器。在方便时,我大多GridBagLayoutBorderLayout和一起使用BoxLayout。这是一个强大的组合,易于使用。
Loduwijk

我在上面的评论中仓促。这是我接受的答案后看到的第一个答案。为什么不按投票排序呢?我认为这是最初计票的核心原因之一。尽管如此,我仍然支持原始评论。这是更好的答案之一。除了它的第6点,那个还不算太好。调整大小的原因有很多(少数仍然可以有很多),而GridBagLayout在我遇到的大多数情况下都很好地支持了。
Loduwijk

我认为调整大小与不调整大小不应视为一项宗教决定。在某些情况下,没有人会想要调整任何大小,例如,如果您使用预设的固定分辨率为信息亭开发GUI。如果您有不同的目标,例如工业HMI显示器和“按钮”的情况,那么是的,触摸屏上的按钮必须至少有1cm x 1cm。在这种情况下,屏幕的DPI会设置您调整大小的方式。其他输入(例如文本字段)可能根本无法垂直调整大小,有时(例如邮政编码)水平调整大小也毫无意义。
Gee Bee

0

我应该完全避免使用那些方法吗? 我不会说“避免”它们。我想说的是,如果您认为自己需要它们,那可能是您做错了什么。组件的大小取决于上下文。例如,文本组件的大小取决于您指定的行数和列数以及您可能选择的字体。如果设置了一个,则按钮和标签的大小将是图形的大小,或者是显示设置的文本所需的空间。每个组件都有一个自然的大小,布局管理器将使用这些大小来布局所有内容,而无需指定大小。主要的例外是JScrollPane,它的大小与其所包含的内容无关。对于这些,我有时会调用setSize(),然后通过调用该大小来确定初始窗口大小JFrame.pack()。通常,我将让窗口大小确定JScrollPane的大小。用户将确定窗口的大小。无论如何,许多布局管理器都会忽略您设置的尺寸,因此它们通常做得不好。

出于某种原因定义了这些方法。那么我什么时候应该使用它们呢?在哪种情况下?出于什么目的? 我相信添加它们是为了向布局管理器提供提示。他们之所以写是因为历史原因,因为布局经理是新来的,人们并不完全信任他们。我知道一些开发人员避免布局管理器,而是手动放置所有内容,只是因为他们不想为学习新的范式而烦恼。这是一个可怕的主意。

使用这些方法的负面后果到底是什么?(我只能考虑在具有不同屏幕分辨率的系统之间增加可移植性)。 它们效果不佳,并且布局不好,物体被挤压或拉伸到非自然尺寸。而且布局会很脆弱。更改窗口大小有时会破坏布局并将东西放置在错误的位置。

我认为任何LayoutManager都无法完全满足所有所需的布局需求。我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?您不应该“实现”新的LayoutManager。您应该实例化现有的。我经常在一个窗口中使用多个布局管理器。每个JPanel都有自己的布局管理器。有些人不愿使用嵌套布局,因为它们很难维护。当我使用它们时,我给每个人自己的创建方法,以便更轻松地查看每个人的工作。但是我从来没有“实现”布局管理器。我只是实例化它们。

如果对4的回答为“是”,这是否会导致LayoutManager类的泛滥而导致难以维护? 如果您要实现新的布局管理器类以使布局略有变化,那么您使用的是错误的。如果您只是实施新的布局管理器,则可能是做错了什么。我唯一扩展LayoutManager类的方法是向JScrollPane添加缩放滑块。

在需要定义Component的子代之间的比例的情况下(例如,child1应该使用10%的空间,child2应该使用40%的空间,child3应该使用50%的空间),是否可以在不实现自定义LayoutManager的情况下实现? JSplitPane有一种方法可以指定每个组件应获得的百分比。默认情况下,分隔线是可移动的,但是您可以根据需要将其关闭。我没有太多使用该功能。我通常有一些组件会占据一定的大小,其余空间则由滚动窗格占据。滚动窗格的大小将根据窗口大小进行调整。如果有两个并排的滚动窗格,则可以将它们放在JSplitPane中,并在用户扩展和收缩窗口时指定分配给每个滚动窗格的新空间的百分比。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.