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); } } 同样,这只是您在网上找到的众多方式之一.希望这可以帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |