Java Swing: problems with width

二次信任 提交于 2019-12-11 02:00:44

问题


I have problems with understanding the behavior of my application. I want to create a simple window (1000x700px), divided into two parts (250px and 750px width respectively). I tried the following code:

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);
    }
}

As you can see I manually set layout manager for JFrame (FlowLayout instead of BorderLayout with zero horizontal and vertical gaps). Of course, I can just use BorderLayout and than use add() method with BorderLayout.EAST and BorderLayout.WEST parameters, but I want to understand what's wrong with FlowLayout. When I run my application, I get the following (no green JPanel):

If I decrease width of, for example, content_panel_wrap and make it 744px instead of 750px, everything works correctly.

So the question is - what are these strange 6 pixels? I'm not sure this value is constant for all operating systems, so I want to understand its origin.

回答1:


As for your codes problem (+1 to @Reimeus) calling pack() is the solution. as per docs:

Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. If the window and/or its owner are not yet displayable, both are made displayable before calculating the preferred size. The Window will be validated after the preferredSize is calculated.

Tips:

  • Dont extend JFrame unnecessarily.
  • Use Event Dispatch Thread when creating and changing UI components:

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
          // create UI components etc here
        }
      });
    
  • Dont call setPreferredSize() rather override getPrefferedSize() of component.
  • Dont call setSize(...) on JFrame rather call JFrame#pack() before setting it visible.
  • Dont forget to call JFrame#defaultCloseOperation(..) or your initial/EDT thread will not be terminated when JFrame is closed.

Here is an example combining my advice and your code:

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();
            }
        });
    }
}



回答2:


There's nothing wrong with FlowLayout but you will need to call pack() for all components to be sized.



来源:https://stackoverflow.com/questions/13053919/java-swing-problems-with-width

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!