java – 寻找GridBagLayout组件创建的一般方法
|
我正在设计一个包含20个左右组件的GUI:10个标签,4个文本字段,4个按钮和2个文本区域.使用GridBagLayout似乎是一个好主意.但是,对于每个组件,本书需要执行所有实例变量(即,不重用),添加组件的一般方法似乎是必须的.我真的认为这可行:
(注意:HORIZ是GridBagConstraints.HORIZONTAL的缩写; public static void addComponent(Container f,Component c,int x,int y,int w,int h,int ipadx,int ipady,float wtx,float wty,int fill,int anchor,Insets insets){
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x; gbc.gridy = y;
gbc.gridwidth = w; gbc.gridheight = h;
gbc.fill = fill;
gbc.ipadx = ipadx; gbc.ipady = ipady;
gbc.insets = insets; gbc.anchor = anchor;
gbc.weightx = wtx; gbc.weighty = wty;
f.add(c,gbc);
}
我这样打电话: Insets insets = new Insets(0,0);
JFrame frame = new JFrame();
label = new JLabel("Blablablah");
addComponent(frame,label,1,0.5f,HORIZ,CENTER,insets);
但是我在f.add(c.gbc)得到消息“无法添加到布局:约束必须是字符串(或null)”. 我想我理解错误:框架在调用addComponent之前没有GridBagConstraints,而方法的第一行中的gbc不属于参数f(或其他任何东西?). 所以我略微修改了方法签名,省略了Container: public static void addComponent( Component c,... (rest unchanged) 我像这样修改了问题行: frame.add(c,gbc); 所以当我宁愿将它作为参数传递时,我正在使用全局变量frame. 两个问题: (1)有没有办法最小化修改我的代码以启用将帧传递给addComponent? (2)有什么理由要这样做吗?我想这相当于问,你会做什么? 附:这里是对修改后的addComponent的调用,匆匆抛出,以获得我想要的前几行的一些相似之处.此刻的间距令人沮丧 – 我需要用插图,ipads,填充来实现 – 但它实际上是可用的. (框架的新名称是GUI.) private static void createAndShowGUI() {
GUI = new JFrame();
GUI.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
gbl = new GridBagLayout();
GUI.setLayout(gbl);
addComponent(lblRootNode,HORIZONTAL,new Insets(0,0));
addComponent(txtRootNode,5,60,0));
addComponent(btnBrowse,6,0));
addComponent(lblFilenamePat,2,EAST,0));
addComponent(txtFilenamePat,4,LINE_END,0));
addComponent(lblDates,0));
addComponent(lblSizes,0));
… 解决方法
我使用GridBagLyout相当多,但和我之前的许多其他人一样,我很快发现它可能非常冗长.网上有很多关于用户如何编写实用程序方法和/或类来帮助他们生成GBL代码的例子.我会告诉你我做了什么.
1)首先,我创建了2个枚举,它们是锚点和填充GridBagConstraints字段的包装器.我更喜欢enums与int的类型检查,它还允许我编写更简洁的代码(稍后你会看到).是的,我仍然使用较旧的“方向”值为Anchor.我永远不会习惯于PAGE_START之类的首选值.用你喜欢的任何东西. Anchor.java:
package gbl;
import java.awt.*;
/**
* Convenience enum that aliases out all possible values for the
* GridBagConstraints anchor property.
*/
public enum Anchor
{
NORTH(GridBagConstraints.NORTH),SOUTH(GridBagConstraints.SOUTH),EAST(GridBagConstraints.EAST),WEST(GridBagConstraints.WEST),NORTHEAST(GridBagConstraints.NORTHEAST),NORTHWEST(GridBagConstraints.NORTHWEST),SOUTHEAST(GridBagConstraints.SOUTHEAST),SOUTHWEST(GridBagConstraints.SOUTHWEST),CENTER(GridBagConstraints.CENTER);
private int constraint;
private Anchor(int gbConstraint)
{
constraint = gbConstraint;
}
public int getConstraint()
{
return constraint;
}
}
Fill.java:
package gbl;
import java.awt.*;
/**
* Convenience enum that aliases out all possible values for the
* GridBagConstraints fill property.
*/
public enum Fill
{
NONE(GridBagConstraints.NONE),HORIZONTAL(GridBagConstraints.HORIZONTAL),VERTICAL(GridBagConstraints.VERTICAL),BOTH(GridBagConstraints.BOTH);
private int constraint;
private Fill(int gbConstraint)
{
constraint = gbConstraint;
}
public int getConstraint()
{
return constraint;
}
}
2)然后,我创建了一个GridBagConstraints的子类,它允许我在需要时“链接”属性,同时利用常见的默认值: GBConstraints.java:
package gbl;
import java.awt.*;
/**
* Convenience class to simplify the creation of a GridBagConstraints object.
*/
public class GBConstraints extends GridBagConstraints
{
public GBConstraints(int gridX,int gridY)
{
super();
this.gridx = gridX;
this.gridy = gridY;
this.gridwidth = 1;
this.gridheight = 1;
this.weightx = 0;
this.weighty = 0;
this.anchor = NORTHWEST; // old default was CENTER
this.fill = NONE;
this.insets = new Insets(1,2); // old default was (0,0)
this.ipadx = 1; // old default was 0
this.ipady = 1; // old default was 0
}
public GBConstraints anchor(Anchor anchor)
{
this.anchor = anchor.getConstraint();
return this;
}
public GBConstraints fill(Fill fill)
{
this.fill = fill.getConstraint();
/*
* As a convenience,set the weights appropriately since these values are
* almost always used in tandem with the given Fill. The caller can always
* call the weight(...) method later if these defaults aren't desired.
*/
switch (fill)
{
case HORIZONTAL:
this.weightx = 1;
this.weighty = 0;
break;
case VERTICAL:
this.weightx = 0;
this.weighty = 1;
break;
case BOTH:
this.weightx = 1;
this.weighty = 1;
break;
default:
this.weightx = 0;
this.weighty = 0;
break;
}
return this;
}
public GBConstraints insets(int length)
{
return insets(length,length,length);
}
public GBConstraints insets(int top,int left,int bottom,int right)
{
this.insets = new Insets(top,left,bottom,right);
return this;
}
public GBConstraints ipad(int ipadX,int ipadY)
{
this.ipadx = ipadX;
this.ipady = ipadY;
return this;
}
public GBConstraints span(int gridWidth,int gridHeight)
{
this.gridwidth = gridWidth;
this.gridheight = gridHeight;
return this;
}
public GBConstraints spanX(int gridWidth)
{
this.gridwidth = gridWidth;
return this;
}
public GBConstraints spanY(int gridHeight)
{
this.gridheight = gridHeight;
return this;
}
public GBConstraints weight(double weightX,double weightY)
{
this.weightx = weightX;
this.weighty = weightY;
return this;
}
public GBConstraints weightX(double weightX)
{
this.weightx = weightX;
return this;
}
public GBConstraints weightY(double weightY)
{
this.weighty = weightY;
return this;
}
}
3)将所有内容放在一起,这是一个演示如何使用上述类的演示.这大大简化了使用GridBagLayout,恕我直言.旁注:我通常远离静态导入,但在这种情况下我喜欢它. 演示:
package gbl;
import static gbl.Anchor.*;
import static gbl.Fill.*;
import java.awt.*;
import javax.swing.*;
public class GridBagDemo implements Runnable
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new GridBagDemo());
}
public void run()
{
JLabel lblFirst = new JLabel("First Name");
JLabel lblLast = new JLabel("Last Name");
JLabel lblStreet = new JLabel("Street");
JLabel lblCity = new JLabel("City");
JLabel lblState = new JLabel("State");
JLabel lblZip = new JLabel("ZIP");
JLabel lblNotes = new JLabel("Notes");
JTextField txfFirst = new JTextField(15);
JTextField txfLast = new JTextField(20);
JTextField txfStreet = new JTextField(40);
JTextField txfCity = new JTextField(15);
JTextField txfState = new JTextField(5);
JTextField txfZip = new JTextField(10);
JTextArea txaNotes = new JTextArea(5,50);
JScrollPane scrNotes = new JScrollPane(txaNotes);
scrNotes.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
Component spacer1 = Box.createHorizontalStrut(5);
Component spacer2 = Box.createHorizontalStrut(5);
JPanel panel = new JPanel(new GridBagLayout());
panel.add(spacer1,new GBConstraints(0,0));
panel.add(lblFirst,1));
panel.add(txfFirst,new GBConstraints(1,1));
panel.add(lblLast,new GBConstraints(2,1));
panel.add(txfLast,new GBConstraints(3,1).spanX(3).fill(HORIZONTAL));
panel.add(lblStreet,2));
panel.add(txfStreet,2).spanX(5).fill(HORIZONTAL));
panel.add(lblCity,3));
panel.add(txfCity,3));
panel.add(lblState,3).anchor(EAST));
panel.add(txfState,3));
panel.add(lblZip,new GBConstraints(4,3));
panel.add(txfZip,new GBConstraints(5,3).fill(HORIZONTAL));
panel.add(lblNotes,4));
panel.add(scrNotes,4).spanX(5).fill(BOTH));
panel.add(spacer2,5));
JFrame frame = new JFrame("Grid Bag Demo");
frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(panel),BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
同样,这只是您在网上找到的众多方式之一.希望这可以帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
