Java Swing:宽度问题 [英] Java Swing: problems with width
问题描述
我在理解我的应用程序的行为时遇到了问题.我想创建一个简单的窗口( 1000x700px ),分为两个部分(分别为 250px 和 750px 宽度).我尝试了以下代码:
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
,而不是将add()
方法与BorderLayout.EAST
和BorderLayout.WEST
参数一起使用,但是我想了解FlowLayout
的问题.
运行我的应用程序时,得到以下内容(没有绿色JPanel
): >
如果我减小例如content_panel_wrap
的宽度并使其变为 744px 而不是 750px ,则一切正常.
所以问题是-这些奇怪的6像素是什么?我不确定该值是否在所有操作系统上都恒定,因此我想了解其来源.
至于您的代码问题(+1到@Reimeus),调用pack()
是解决方案.
根据文档:
使此窗口的大小适合所需的大小和布局 它的子组件.如果窗口和/或其所有者还没有 可显示的,在计算 首选大小. Window将在preferredSize之后验证 是计算出来的.
提示:
- 不要不必要地扩展
JFrame
. -
在创建时使用事件调度线程并更改UI组件:
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();
}
});
}
}
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.
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();
}
});
}
}
这篇关于Java Swing:宽度问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!