问题
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.
回答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 overridegetPrefferedSize()
of component. - Dont call
setSize(...)
onJFrame
rather callJFrame#pack()
before setting it visible. - Dont forget to call
JFrame#defaultCloseOperation(..)
or your initial/EDT thread will not be terminated whenJFrame
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