当前位置: 首页 > 面试题库 >

寻找用于GridBagLayout组件创建的通用方法

葛勇锐
2023-03-14
问题内容

我正在设计一个包含20个左右组件的GUI:10个标签,4个文本字段,4个按钮和2个文本区域。使用GridBagLayout似乎是个好主意。但是,由于本书需要为每个组件执行所有实例变量(即不重用),因此添加组件的通用方法似乎是必须的。我真的以为这可以工作:

(注意:HORIZ是GridBagConstraints.HORIZONTAL的缩写;
CENTER是GridBagConstraints.CENTER的缩写。)

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,0,0);
    JFrame frame = new JFrame();
    label = new JLabel("Blablablah");   
    addComponent(frame, label, 0,0, 1,1, 0,0, 0.5f,0, HORIZ, CENTER, insets);

但是我在收到消息“无法添加到布局:约束必须为字符串(或null)” f.add(c.gbc)

我想我理解错误:在调用之前frame没有GridBagConstraintsaddComponent并且gbc在方法的第一行中不属于参数f(或其他任何东西)。

所以我略微修改了方法签名,省略了Container

public static void addComponent(                  Component c, 
                                  int     x,        int   y, 
... (rest unchanged)

我这样修改了问题行:

frame.add(c, gbc);

因此frame,当我希望将其作为参数传递时,我使用的是全局变量。

两个问题:

(1)有没有一种方法可以最少地修改我的代码以允许传递frameaddComponent

(2)是否有任何理由要这样做?我想这等于问,你会怎么做?

PS这是对经过修改的的调用addComponent,它们匆忙地组合在一起,以使我所要的前几行看起来有些相似。此刻间隔间距-
我需要猴子的插图,ipads,填充-但实际上是可用的。(的新名称frameGUI。)

private static void createAndShowGUI() {
  GUI = new JFrame();
  GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  gbl = new GridBagLayout();
  GUI.setLayout(gbl);

  addComponent(lblRootNode, 0,0, 1,1, 0,0, 0.5f,0, HORIZONTAL, CENTER, new Insets(0,0,0,0));    
  addComponent(txtRootNode, 1,0, 5,1, 60,0, 0.5f,0, HORIZONTAL, CENTER, new Insets(0,0,0,0));    
  addComponent(btnBrowse,   6,0, 1,1, 0,0, 0.5f,0, HORIZONTAL, CENTER, new Insets(0,0,0,0));    
  addComponent(lblFilenamePat, 0,1, 2,1, 0,0, 0.5f,0, HORIZONTAL, EAST, new Insets(0,0,0,0));    
  addComponent(txtFilenamePat, 2,1, 4,1, 0,0, 0.5f,0, HORIZONTAL, LINE_END, new Insets(0,0,0,0));    
  addComponent(lblDates, 0,2, 2,1, 0,0, 0.5f,0, HORIZONTAL, CENTER, new Insets(0,0,0,0));    
  addComponent(lblSizes, 2,2, 2,1,   0,0, 0.5f,0, HORIZONTAL, CENTER, new Insets(0,0,0,0));


问题答案:

我经常使用GridBagLyout,但是像我之前的许多人一样,我很快发现它可能很冗长。网上有许多示例,说明用户如何编写实用程序方法和/或类来帮助他们生成GBL代码。我会告诉你我的工作。

1)首先,我创建2个枚举作为针对包装 填充
的GridBagConstraints字段。我更喜欢枚举与整数的类型检查,这也使我可以编写更简洁的代码(稍后将看到)。是的,我仍将较旧的“方向”值用于锚点。我永远无法完全适应的首选值PAGE_START等。使用您喜欢的任何东西。

Anchor.java:

软件包gbl;

导入java.awt。*;

/ **
 *方便枚举,将所有可能的值都排除在外
 * GridBagConstraints **锚点** 属性。
 * /
公共枚举锚
{
  NORTH(GridBagConstraints.NORTH),
  SOUTH(GridBagConstraints.SOUTH),
  EAST(GridBagConstraints.EAST),
  WEST(GridBagConstraints.WEST),
  东北(GridBagConstraints.NORTHEAST),
  西北(GridBagConstraints.NORTHWEST),
  东南(GridBagConstraints.SOUTHEAST),
  西南(GridBagConstraints.SOUTHWEST),
  CENTER(GridBagConstraints.CENTER);

  私有int约束;

  私人锚点(int gbConstraint)
  {
    约束= gbConstraint;
  }

  公共诠释getConstraint()
  {
    返回约束;
  }
}

Fill.java:

软件包gbl;

导入java.awt。*;

/ **
 *方便枚举,将所有可能的值都排除在外
 * GridBagConstraints **填充** 属性。
 * /
公共枚举
{
  NONE(GridBagConstraints.NONE),
  水平(GridBagConstraints.HORIZONTAL),
  垂直(GridBagConstraints.VERTICAL),
  BOTH(GridBagConstraints.BOTH);

  私有int约束;

  私人填写(int gbConstraint)
  {
    约束= gbConstraint;
  }

  公共诠释getConstraint()
  {
    返回约束;
  }
}

2)然后,我创建了GridBagConstraints的子类,该子类允许我仅在需要它们时才“链接”属性,同时利用常见的默认值:

GBConstraints.java:

软件包gbl;

导入java.awt。*;

/ **
 *便利类,简化了GridBagConstraints对象的创建。
 * /
公共类GBConstraints扩展了GridBagConstraints
{
  公共GBConstraints(int gridX,int gridY)
  {
    超();

    this.gridx = gridX;
    this.gridy = gridY;

    this.gridwidth = 1;
    this.gridheight = 1;
    this.weightx = 0;
    this.weighty = 0;
    this.anchor = NORTHWEST; //旧的默认值为CENTER
    this.fill = NONE;
    this.insets =新的Insets(1,2,1,2); //旧的默认值为(0,0,0,0)
    this.ipadx = 1; //旧的默认值为0
    this.ipady = 1; //旧的默认值为0
  }

  公共GB约束锚(锚锚)
  {
    this.anchor = anchor.getConstraint();
    返回这个
  }

  公共GB约束填充(填充)
  {
    this.fill = fill.getConstraint();

    / *
     *为方便起见,请适当设置权重,因为这些值是
     *几乎总是与给定的Fill一起使用。来电者可以随时
     *如果不需要这些默认值,请稍后调用weight(...)方法。 
     * /
    开关(填充)
    {
      案例水平:
        this.weightx = 1;
        this.weighty = 0;
        打破;
      案例垂直:
        this.weightx = 0;
        this.weighty = 1;
        打破;
      案例:
        this.weightx = 1;
        this.weighty = 1;
        打破;
      默认:
        this.weightx = 0;
        this.weighty = 0;
        打破;
    }

    返回这个
  }

  公共GBConstraints插入(int长度)
  {
    返回插图(长度,长度,长度,长度);
  }

  公共GBConstraints插入(int顶部,int左侧,int底部,int右侧)
  {
    this.insets =新的Insets(顶部,左侧,底部,右侧);
    返回这个
  }

  公共GB约束ipad(int ipadX,int ipadY)
  {
    this.ipadx = ipadX;
    this.ipady = ipadY;
    返回这个
  }

  公共GB约束范围(int gridWidth,int gridHeight)
  {
    this.gridwidth = gridWidth;
    this.gridheight = gridHeight;
    返回这个
  }

  公共GBConstraints spanX(int gridWidth)
  {
    this.gridwidth = gridWidth;
    返回这个
  }

  公共GB约束spanY(int gridHeight)
  {
    this.gridheight = gridHeight;
    返回这个
  }

  公共GB约束权重(double weightX,double weightY)
  {
    this.weightx = weightX;
    this.weighty = weightY;
    返回这个
  }

  公共GB约束weightX(double weightX)
  {
    this.weightx = weightX;
    返回这个
  }

  公共GB约束weightY(double weightY)
  {
    this.weighty = weightY;
    返回这个
  }
}

3)放在一起,这是演示如何使用上述类的演示。这大大简化了IMHO的GridBagLayout的使用。旁注:我通常不会使用静态导入,但是在这种情况下我喜欢它。

演示:

软件包gbl;

导入静态gbl.Anchor。*;
导入静态gbl.Fill。*;

导入java.awt。*;
导入javax.swing。*;

公共类GridBagDemo实现Runnable
{
  公共静态void main(String [] args)
  {
    SwingUtilities.invokeLater(new GridBagDemo());
  }

  公共无效run()
  {
    JLabel lblFirst =新的JLabel(“名字”);
    JLabel lblLast =新的JLabel(“ Last Name”);
    JLabel lblStreet =新的JLabel(“ Street”);
    JLabel lblCity =新的JLabel(“ City”);
    JLabel lblState =新的JLabel(“ State”);
    JLabel lblZip =新的JLabel(“ ZIP”);
    JLabel lblNotes =新的JLabel(“ Notes”);

    JTextField txfFirst =新的JTextField(15);
    JTextField txfLast =新的JTextField(20);
    JTextField txfStreet =新的JTextField(40);
    JTextField txfCity =新的JTextField(15);
    JTextField txfState =新的JTextField(5);
    JTextField txfZip =新的JTextField(10);

    JTextArea txaNotes =新的JTextArea(5,50);
    JScrollPane scrNotes =新的JScrollPane(txaNotes);
    scrNotes.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_​​ALWAYS);

    组件spacer1 = Box.createHorizo​​ntalStrut(5);
    组件spacer2 = Box.createHorizo​​ntalStrut(5);

    JPanel面板= new JPanel(new GridBagLayout());
    panel.add(spacer1,new GBConstraints(0,0));
    panel.add(lblFirst,新的GBConstraints(0,1));
    panel.add(txfFirst,新的GBConstraints(1,1));
    panel.add(lblLast,新的GBConstraints(2,1));
    panel.add(txfLast,新的GBConstraints(3,1).spanX(3).fill(HORIZONTAL));
    panel.add(lblStreet,新的GBConstraints(0,2));
    panel.add(txfStreet,新的GBConstraints(1,2).spanX(5).fill(HORIZONTAL));
    panel.add(lblCity,新的GBConstraints(0,3));
    panel.add(txfCity,新的GBConstraints(1,3));
    panel.add(lblState,新的GBConstraints(2,3).anchor(EAST));
    panel.add(txfState,新的GBConstraints(3,3));
    panel.add(lblZip,新的GBConstraints(4,3));
    panel.add(txfZip,新的GBConstraints(5,3).fill(HORIZONTAL));
    panel.add(lblNotes,新的GBConstraints(0,4));
    panel.add(scrNotes,new GBConstraints(1,4).spanX(5).fill(BOTH));
    panel.add(spacer2,new GBConstraints(0,5));

    JFrame frame = new JFrame(“ Grid Bag Demo”);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(新的JScrollPane(panel),BorderLayout.CENTER);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

同样,这只是您在线上找到的许多方式之一。希望这可以帮助。



 类似资料:
  • 问题内容: 该代码似乎不起作用,它将抛出异常: java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为… 有人可以告诉我如何创建具有通用类型的数组吗?谢谢。 问题答案: 您不能:必须将类作为参数传递:

  • 问题内容: 我想使用simpleJdbcInsert类和executeBatch方法 http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/simple/SimpleJdbcInsert.html 所以我需要传递一个as参数数组。如何创建这样的数组?我试过的是 错误:无法创建通用数组 A

  • 我想使用简单的Jdbc插入类和执行批处理方法 http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/simple/SimpleJdbcInsert.html 所以我需要传递一个< code>Map数组 这是错误:无法创建 Map 的通用数组

  • 引用脚本的内容: name 'Find Control IDs' outfile 'findctlID_MUI.exe' showinstdetails show InstallDir '$EXEDIR' var header !include mui.nsh ; 许可协议页面 !define MUI_PAGE_CUSTOMFUNCTION_PRE lic_pre !define MUI_P

  • 问题内容: 我正在使用具有多个唯一标识的从属进程的分布式应用程序,这些进程将通过启用SSL的套接字与主应用程序进行通信。该应用程序用Java编写。 我需要一些帮助来了解SSLSocket,或者更确切地说,是它们使用的证书。 我正在寻找的人可以告诉我我是否正确理解了证书链的基本工作原理,但是我也不会拒绝代码示例。 我想要一个服务器本身具有CA签名证书的设置,每个从属服务器都将获得由主应用程序创建的自

  • 问题内容: 嗨,我正在尝试创建一组六边形集(六边形是我创建的类)。 但是当我尝试编译时出现此错误 我该如何解决? 问题答案: 您不能使用泛型创建数组。使用或代替。 这是正式的解释。