在下面的代码中,当没有将JPanel添加到JFrame扩展中时,程序运行良好,但随后,我注释掉了JPanel并使用了GridLayout,所有内容都被正确、良好地放置在JFrame上。JPanel显示对象的方式会受到一些限制吗?在代码中,我注释了以下语句:
this.setLayout(new GridLayout(3,2));
this.add(nameLabel);
this.add(name);
this.add(urlLabel);
this.add(url);
this.add(typeLabel);
this.add(type);
程序显示错误,但如果上面的语句未被注释,下面的语句被注释:
//add some panes..
JPanel panel = new JPanel();
panel.add(nameLabel);
panel.add(name);
panel.add(urlLabel);
panel.add(url);
panel.add(typeLabel);
panel.add(type);
this.add(panel);
,那么程序运行良好。。以下是完整的代码摘录。
[CODE]
public class FeedInfo extends JFrame {
private JLabel nameLabel = new JLabel("Name:", SwingConstants.RIGHT);
private JTextField name;
private JLabel urlLabel = new JLabel("URL",SwingConstants.RIGHT);
private JTextField url;
private JLabel typeLabel = new JLabel("Type",SwingConstants.RIGHT);
private JTextField type;
public FeedInfo()
{
super("Feed Information");
this.setSize(400,105);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String response1 = JOptionPane.showInputDialog(null,"Enter the site name:");
name = new JTextField(response1,20);
String response2 = JOptionPane.showInputDialog(null,"Enter the site address:");
url = new JTextField(response2, 20);
String[] choices ={"Personal","Commercial","Unkown"};
int response3 = JOptionPane.showOptionDialog(null, "what type of site is it?",
"site Type",0, JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
type = new JTextField(choices[response3],20);
//add some panes..
JPanel panel = new JPanel();
panel.add(nameLabel);
panel.add(name);
panel.add(urlLabel);
panel.add(url);
panel.add(typeLabel);
panel.add(type);
this.add(panel);
/*this.setLayout(new GridLayout(3,2));
this.add(nameLabel);
this.add(name);
this.add(urlLabel);
this.add(url);
this.add(typeLabel);
this.add(type);
*/
this.setVisible(true);
}
[/CODE]
JPanel
本身不执行布局,它使用LayoutManager
。在您的情况下,您希望覆盖默认的FlowLayout
并使用GridLayout
(就像您对JFrame
所做的那样)。那就这么做吧!
JPanel panel = new JPanel(new GridLayout(3, 2));
...
JPanel panel = new JPanel();
panel.add(nameLabel);
panel.add(name);
panel.add(urlLabel);
panel.add(url);
panel.add(typeLabel);
panel.add(type);
this.add(panel);
当您这样做时,您将JPanel添加到JFrame上,但JFrame的布局没有更改,这意味着它默认具有BorderLayout。尝试将最后一行更改为:add(panel, BorderLayout.CENTER);
你可以在这里阅读更多关于JFrame的
此外,JPanel默认为FlowLayout,这意味着对象将被添加到"流动线"中。您应该在JPanel上设置布局,以获得所需的结果
您的程序在第二部分代码中没有按预期工作,因为您使用的是
JPanel panel = new JPanel();
默认情况下,通过这行,正如您从JPanel API中看到的,您正在创建布局为FlowLayout
的JPanel。JPanel API报告,关于空构建器:
JPanel()
Creates a new JPanel with a double buffer and a flow layout.
一般来说,流布局是JPanel最简单的布局,并且不可能以可理解和简单的方式加载Swing内容。您正在使用的GridLayout提供了在网格中加载组件的能力,这对于显示Java应用程序的GUI很好。
现在,你知道了,因为这个程序有一个基本的FlowLayout,并没有像代码的第一部分那样,在使用GridLayout时显示所有的swing组件。如果你想创建一个带有GridLayout的JPanel,只需键入:
JPanel panel = new JPanel(new GridLayout(3, 2));
在这个页面和这里有一些关于JPanel和布局的教程。
有两个重要的事实需要了解。JFrame默认使用BorderLayout。JPanel默认使用Flowlayout。这就是为什么你会看到不同的行为,取决于你将其他组件添加到哪个组件
FlowLayout几乎毫无价值,所以当使用JPanel时,你几乎总是想更改它。@Mark Peters向你展示了如何做到这一点。BorderLayout几乎总是完美地用于顶级容器,我很少改变这一点。我倾向于将BoxLayout几乎完全用于我的嵌套JPanels。