简体   繁体   English

我应该避免在 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设置首选大小
  2. setMinimumSize设置最小尺寸
  3. 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?在我需要定义组件子级之间比例的情况下(例如,child1 应该使用 10% 的空间,child2 40%,child3 50%),是否可以在不实现自定义 LayoutManager 的情况下实现这一点?
  1. Should I completely avoid the use of those methods?我应该完全避免使用这些方法吗?

    Yes for application code.是的应用程序代码。

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

    I don't know, personally I think of it as an API design accident.我不知道,我个人认为这是一个 API 设计事故。 Slightly forced by compound components having special ideas about child sizes.由对子尺寸有特殊想法的复合组件略微强迫。 "Slightly", because they should have implemented their needs with a custom LayoutManager. “稍微”,因为他们应该使用自定义 LayoutManager 实现他们的需求。

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

    Some (incomplete, and unfortunately the links are broken due to migration of SwingLabs to java.net) technical reasons are for instance mentioned in the Rules (hehe) or in the link @bendicott found in his/her comment to my answer .一些(不完整,不幸的是,由于 SwingLabs 迁移到 java.net,链接被破坏)技术原因在规则中提到(呵呵)或在他/她对我的回答的评论中找到的链接@bendicott 中提到。 Socially, posing tons of work onto your unfortunate fellow who has to maintain the code and has to track down a broken layout.在社交方面,将大量工作交给必须维护代码并必须追踪损坏布局的不幸同事。

  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 吗?

    Yes, there are LayoutManagers powerful enough to satisfy a very good approximation to "all layout needs".是的,有足够强大的 LayoutManagers 可以很好地满足“所有布局需求”。 The big three are JGoodies FormLayout, MigLayout, DesignGridLayout.三大巨头是 JGoodies FormLayout、MigLayout、DesignGridLayout。 So no, in practice, you rarely write LayoutManagers except for simple highly specialized environments.所以不,在实践中,除了简单的高度专业化的环境之外,你很少编写 LayoutManagers。

  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 类的激增而变得难以维护?

    (The answer to 4 is "no".) (4 的答案是“否”。)

  6. In a situation where I need to define proportions between children of a Component (for example, child 1 should use 10% of space, child 2 40%, child 3 50%), is it possible to achieve that without implementing a custom LayoutManager?在我需要定义组件子级之间比例的情况下(例如,子级 1 应该使用 10% 的空间,子级 2 40%,子级 3 50%),是否可以在不实现自定义 LayoutManager 的情况下实现这一点?

    Any of the Big-Three can, can't even GridBag (never bothered to really master, too much trouble for too little power). Big-Three 中的任何一个都可以,甚至 GridBag 都不能(从不费心去真正掌握,太小功率太麻烦)。

A few heuristics:一些启发式:

  • Don't use set[Preferred|Maximum|Minimum]Size() when you really mean to override get[Preferred|Maximum|Minimum]Size() , as might be done in creating your own component, shown here .不要使用set[Preferred|Maximum|Minimum]Size()时,你真的要覆盖get[Preferred|Maximum|Minimum]Size()因为可能会创建自己的组件,显示做在这里

  • Don't use set[Preferred|Maximum|Minimum]Size() when you could rely on a component's carefully overridden getPreferred|Maximum|Minimum]Size , as shown here and below.不要使用set[Preferred|Maximum|Minimum]Size()时,你可以依赖的组件上的精心覆盖getPreferred|Maximum|Minimum]Size ,如图所示这里及以下。

  • Do use set[Preferred|Maximum|Minimum]Size() to derive post- validate() geometry, as shown below and here .请使用set[Preferred|Maximum|Minimum]Size()来导出 post- validate()几何,如下所示和此处

  • If a component has no preferred size, eg JDesktopPane , you may have to size the container, but any such choice is arbitrary.如果组件没有首选大小,例如JDesktopPane ,您可能必须调整容器的大小,但任何此类选择都是任意的。 A comment may help clarify the intent.评论可能有助于澄清意图。

  • Consider alternate or custom layouts when you find that you would have to loop through many components to obtain derived sizes, as mentioned in these comments .当您发现必须遍历许多组件才能获得派生尺寸时,请考虑替代或自定义布局,如这些注释中所述

在此处输入图片说明

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 https://stackoverflow.com/questions/7229226
 * @see https://stackoverflow.com/questions/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());
            }
        }
    }
}

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不强制覆盖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都有其优点和缺点,因此每个LayoutManager都可以一起使用以生成最终布局。

Reference:参考:

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支持。

If you are having trouble with layouts in Java Swing, then I can highly recommend the JGoodies FormLayout provided freely as part of the Forms freeware library by Karsten Lentzsch here .如果您在 Java Swing 中遇到布局问题,那么我强烈推荐由 Karsten Lentzsch在这里免费提供的 JGoodies FormLayout作为 Forms 免费软件库的一部分。

This very popular layout manager is extremely flexible, allowing for very polished Java UIs to be developed.这个非常流行的布局管理器非常灵活,允许开发非常精美的 Java UI。

You'll find Karsten's documentation in here , and some rather good documentation from eclipse here .你会发现Karsten的文档中这里,并从Eclipse的一些比较好的文档在这里

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.我已经编写 Swing 代码超过 8 年,JDK 中包含的布局管理器一直满足我的需求。 I have never needed a 3rd party layout manager to achieve my layouts.我从来不需要第 3 方布局管理器来实现我的布局。

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.在不提供任何尺寸提示的情况下进行布局(即让布局管理器完成其工作),然后您可以根据需要进行较小的更正。

In a situation where I need to define proportions between children of a Component (child 1 should use 10% of space, child2 40% ,child3 50%), is it possible to achieve that without implementing a custom layout manager?在我需要定义组件子级之间比例的情况下(子级 1 应该使用 10% 的空间,child2 40%,child3 50%),是否可以在不实现自定义布局管理器的情况下实现这一点?

Maybe GridBagLayout would satisfy your needs.也许GridBagLayout会满足您的需求。 Besides that, there's a ton of layout managers on the web, and I bet there's one that fits your requirements.除此之外,网络上有大量的布局管理器,我敢打赌,总有一款适合您的要求。

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.例如,如果您有一个 JTextField 用于输入国家/地区符号,例如 UK,则其首选大小应尽可能宽以容纳两个字符(使用当前字体等),但让它变大可能毫无意义。 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).简单地说,因为百分比是没有意义的(例如,拥有一个窗口大小的 10% 的 JTextField 是没有意义的——因为可以缩小窗口使 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,它允许您以百分比、像素和其他单位设置此类约束。

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?在我需要定义组件子级之间比例的情况下(例如,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 中,并在用户扩展和收缩窗口时指定给每个窗格的新空间的百分比。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM