Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该避免在JavaSwing中使用set(首选的|最大|最小)大小方法吗?_Java_Swing_Layout Manager - Fatal编程技术网

我应该避免在JavaSwing中使用set(首选的|最大|最小)大小方法吗?

我应该避免在JavaSwing中使用set(首选的|最大|最小)大小方法吗?,java,swing,layout-manager,Java,Swing,Layout Manager,我曾多次因建议使用以下方法而受到批评: setPreferredSize setMinimumSize setMaximumSize 在Swing组件上。当我想定义显示组件之间的比例时,我看不到任何替代方法。有人告诉我: 对于布局,答案总是一样的:使用合适的 布局经理 我在网上搜索了一下,但没有找到任何关于这个主题的全面分析。因此,我有以下问题: 我应该完全避免使用这些方法吗 定义这些方法是有原因的。那么我应该什么时候使用它们呢?在哪种情况下?为了什么目的 使用这些方法的负面后果到底是什么?(我

我曾多次因建议使用以下方法而受到批评:

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

    对于布局,答案总是一样的:使用合适的 布局经理

    我在网上搜索了一下,但没有找到任何关于这个主题的全面分析。因此,我有以下问题:

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


    也许
    GridBagLayout
    能满足您的需求。除此之外,网络上有大量的布局管理器,我敢打赌有一个适合您的要求。

    如果您在Java Swing中遇到布局问题,那么我可以强烈推荐由Karsten Lentzsch作为表单免费软件库的一部分免费提供的JGoodies
    FormLayout

    这个非常流行的布局管理器非常灵活,允许开发非常完善的Java UI

    您将在中找到Karsten的文档,以及eclipse中一些相当不错的文档

  • 我应该完全避免使用这些方法吗

    申请代码是

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

    我不知道,我个人认为这是一个API设计事故。对子尺寸有特殊想法的复合组件稍微施加压力。“轻微”,因为他们应该通过定制的LayoutManager实现他们的需求

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

    一些(不完整,不幸的是,由于SwingLabs迁移到java.net,链接被破坏)技术原因在他/她的评论中提到。在社交方面,把大量的工作强加给你的不幸伙伴,他必须维护代码,并且必须追踪一个坏的布局

  • 我认为任何布局经理都不能完全满足所有期望的布局需求。我真的需要为布局上的每一个小变化实施一个新的LayoutManager吗

    是的,有足够强大的布局管理器,能够很好地满足“所有布局需求”。三大布局分别是JGoodies FormLayout、MigLayout、DesignGridLayout。因此,实际上,除了简单的高度专业化的环境之外,您很少编写LayoutManager

  • 如果对4的回答是“是”,这是否会导致LayoutManager类的激增,这将变得难以维护

    (4的答案是“否”。)

  • 在需要定义组件子级之间比例的情况下(例如,子级1应使用10%的空间,子级2应使用40%,子级3应使用50%),是否可以在不实施自定义LayoutManager的情况下实现这一点

    三巨头中的任何一个都可以,甚至连GridBag都不能(从来都懒得真正掌握,太麻烦了,功率太小了)

  • 一些启发式方法:

    • 如图所示,当您真的想覆盖
      获取[Preferred | Maximum | Minimum]Size()
      时,不要使用
      设置[Preferred | max | Minimum]Size()

    • 当您可以依赖组件的仔细覆盖的
      getPreferred | Maximum | Minimum]大小时,不要使用
      set[Preferred | Maximum | Minimum]Size()
      ,如下所示

    • 一定要使用
      set[首选的|最大|最小]Size()
      来推导post-
      validate()
      几何图形,如下所示和

    • 如果组件没有首选大小,例如
      JDesktopPane
      ,则可能需要调整容器的大小,但任何此类选择都是任意的。评论可能有助于澄清意图

    • 当您发现必须循环通过许多组件才能获得衍生尺寸时,请考虑备用布局或自定义布局,如下文所述

    导入java.awt.Component;
    导入java.awt.Dimension;
    导入java.awt.EventQueue;
    导入java.awt.GridLayout;
    导入java.awt.KeyboardFocusManager;
    导入java.beans.PropertyChangeEvent;
    导入java.beans.PropertyChangeListener;
    导入java.util.ArrayList;
    导入java.util.List;
    导入javax.swing.JComponent;
    导入javax.swing.JDesktopPane;
    导入javax.swing.JFrame;
    导入javax.swing.JInternalFrame;
    导入javax.swing.JLabel;
    导入javax.swing.JPanel;
    导入javax.swing.JScrollPane;
    导入javax.swing.JTextField;
    导入javax.swing.SwingUtilities;
    /**
    *@见https://stackoverflow.c
    
    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());
                }
            }
        }
    }
    
    <pre>
    +--------------+--------+
    | ###JTABLE### | [Add]  | 
    | ...data...   |[Remove]|
    | ...data...   |        |
    | ...data...   |        |
    +--------------+--------+
    </pre>