【问题标题】:Java Swing: problems with widthJava Swing:宽度问题
【发布时间】:2012-10-24 16:53:04
【问题描述】:

我无法理解我的应用程序的行为。我想创建一个简单的窗口(1000x700px),分为两部分(分别为 250px750px 宽度)。我尝试了以下代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Example extends JFrame
{
    private static final long serialVersionUID = 1L;

    public Example()
    {
        this.setSize(1000, 700);
        this.setTitle("Example");
        this.setResizable(false);
        this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));

        JPanel navigation_panel_wrap = new JPanel();
        JPanel content_panel_wrap = new JPanel();
        navigation_panel_wrap.setPreferredSize(new Dimension(250, 700));
        content_panel_wrap.setPreferredSize(new Dimension(750, 700));
        content_panel_wrap.setBackground(Color.green);
        navigation_panel_wrap.setBackground(Color.red);
        this.getContentPane().add(navigation_panel_wrap);
        this.getContentPane().add(content_panel_wrap);
    }

    public static void main(String[] args)
    {
        Example example = new Example();
        example.setVisible(true);
    }
}

如您所见,我为JFrame 手动设置了布局管理器(FlowLayout 而不是BorderLayout水平和垂直间隙为零)。当然,我可以只使用BorderLayout 而不是使用带有BorderLayout.EASTBorderLayout.WEST 参数的add() 方法,但我想了解FlowLayout 有什么问题。 当我运行我的应用程序时,我得到以下信息(没有绿色 JPanel):

如果我减小例如content_panel_wrap 的宽度并将其设为 744px 而不是 750px,则一切正常。 所以问题是 - 这些奇怪的 6 个像素是什么?我不确定这个值对于所有操作系统都是恒定的,所以我想了解它的来源。

【问题讨论】:

  • 看到这个Q&A
  • 非常感谢,非常有用的链接。

标签: java swing layout layout-manager preferredsize


【解决方案1】:

FlowLayout 没有问题,但您需要调用 pack() 来调整所有组件的大小。

【讨论】:

    【解决方案2】:

    至于您的代码问题(向@Reimeus +1)调用pack() 是解决方案。 根据文档:

    调整此窗口的大小以适合首选大小和布局 的子组件。如果窗口和/或其所有者尚未 可显示的,在计算之前都可以显示 首选尺寸。 Window 将在preferredSize 之后进行验证 计算出来的。

    提示:

    • 不要不必要地扩展JFrame
    • 在创建和更改 UI 组件时使用Event Dispatch Thread

      SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            // create UI components etc here
          }
        });
      
    • 不要调用setPreferredSize(),而是覆盖组件的getPrefferedSize()
    • 不要在JFrame 上调用setSize(...),而是在设置为可见之前调用JFrame#pack()
    • 不要忘记调用JFrame#defaultCloseOperation(..),否则当JFrame 关闭时,您的初始/EDT 线程将不会终止。

    这是一个结合了我的建议和您的代码的示例:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class Example {
    
        private final JFrame frame;
    
        public Example() {
            frame = new JFrame();
            frame.setTitle("Example");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//app exited when frame closes
            frame.setResizable(false);
            frame.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
    
            JPanel navigation_panel_wrap = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(250, 700);
                }
            };
            JPanel content_panel_wrap = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(750, 700);
                }
            };
    
            content_panel_wrap.setBackground(Color.green);
            navigation_panel_wrap.setBackground(Color.red);
    
            frame.add(navigation_panel_wrap);
            frame.add(content_panel_wrap);
            //pack frame (size components to preferred size)
            frame.pack();
            frame.setVisible(true);//make frame visible
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Example();
                }
            });
        }
    }
    

    【讨论】:

    • 感谢您提供如此详细的回答!除了两件事之外,一切都很清楚: 1. 不要不必要地扩展 JFrame。 我不应该扩展所有 Swing 类,如 JLabel、JPanel 等,还是只扩展 JFrame?这样做的原因是什么? 2. 重写 getPreferredSize() 比使用 setPreferredSize() 有什么好处?
    • @user1600356 +1 很高兴。至于JFrame 扩展问题:1)你只扩展类来添加功能2)一旦你扩展JFrame,你就不能扩展另一个你可能实际上需要的类。至于您的问题:覆盖 getPreferredSize() 与使用 setPreferredSize() 相比有什么优势? 请参阅此链接:Should I avoid the use of set[Preferred|Maximum|Minimum]Size methods in Java Swing?
    猜你喜欢
    • 2016-04-19
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    相关资源
    最近更新 更多