Grid Bag Layout不识别我的命令?

时间:2015-05-18 22:34:06

标签: java swing layout layout-manager gridbaglayout

我正在创建一个使用大量构造函数的应用程序,我明白你不能使用netbeans的拖放工具来构建一个构造函数,我认为学习如何编写完全组织的窗口是个好主意,无论如何我读了一本DEITEL Java书,它使用一种方法将对象添加到容器中,这里是:

private void addobject(Component componente, int column, int row, int width
int height){

//C will be the GridBagConstraints
//And I made a new GridBagLayout called "v"
//My Panel or container is called objcontainer and the LayoutManager is v 

c.gridx = column;
c.gridy = row; 

c.gridwidth = width;
c.gridheight = height;

v.setConstraints(componente, c);    
objcontainer.add(componente);

}

该方法在构造函数所在的同一个类中声明,它只能用一个gridy分隔。但是当我把它放在2或者更远的地方时,如果我放1,它就会保持最后一个物体。

我不知道如果它是如何工作的,锚也不能很好地工作,除了LINE START之外,中心的都失败了。

以下是代码,无论如何,谢谢:

package Windows;

import java.awt.*;

import javax.swing.*;


public class agregaringreso extends JDialog{

    private int ingreso;
    private String nombreingreso;   
    private String Frecuencia [] = {"Solo una vez", "Cada semana","Cada 2 semanas", "Cada 3 semanas", "Cada mes,"};

    Container contenedor;
    JPanel objcontainer;
    GridBagLayout esquema;
    GridBagConstraints c;

    JButton aceptar;
    JLabel title;
    JLabel ingreso2;
    JLabel nombreingreso2;
    JLabel frecuencia2;

    JTextField ingreso3;
    JTextField nombreingreso3;
    JComboBox frecuencia3;

    private void addobjeto(Component componente, int columna, int fila, int ancho, int alto){

        c.gridx = columna;  
        c.gridy = fila;

        c.gridwidth = ancho;
        c.gridheight = alto;

        esquema.setConstraints(componente, c);
        objcontainer.add(componente);


        }

  public agregaringreso(){

      setDefaultCloseOperation(DISPOSE_ON_CLOSE);
      setTitle("Agregar Nuevo Ingreso - EkPek");
      pack();
      setResizable(false);
      setSize(500, 200);
      setLocationRelativeTo(null);

      //FASE DE INICIALIZACION

      contenedor = getContentPane();
      objcontainer = new JPanel();
      esquema = new GridBagLayout();
      c = new GridBagConstraints();

      aceptar = new JButton("Aceptar");
      title = new JLabel("Agregar Nuevo Ingreso");
      ingreso2 = new JLabel("Monto del Ingreso: ");
      nombreingreso2 = new JLabel("Nombre del Ingreso: ");
      frecuencia2 = new JLabel("Frecuencia con la cual recibe el ingreso: ");
      ingreso3 = new JTextField("Escriba aqui el monto");


      nombreingreso3 = new JTextField("Escriba aqui el nombre");

      frecuencia3 = new JComboBox(Frecuencia);

      //FASE DE ACOMODO

      c.anchor = GridBagConstraints.CENTER;
      addobjeto(title, 0, 0, 1, 1);

      c.anchor = GridBagConstraints.LINE_START;
      addobjeto(nombreingreso2 , 0, 4, 1, 1);
      addobjeto(nombreingreso3, 1, 4, 1, 1);

      addobjeto(ingreso2, 0, 5, 1, 1);
      addobjeto(ingreso3, 1, 5, 1, 1 );

      addobjeto(frecuencia2, 0 , 6, 1, 1);
      addobjeto(frecuencia3, 1, 6, 1, 1);

      c.anchor = GridBagConstraints.CENTER;
      addobjeto(aceptar,0 ,7 ,1, 1);


      contenedor.add(objcontainer);
      objcontainer.setLayout(esquema);




      setVisible(true);

}


}

2 个答案:

答案 0 :(得分:2)

你做事的顺序非常重要。做一些像......一样毫无意义的事情。

objcontainer = new JPanel();
esquema = new GridBagLayout();
// Add a bunch of stuff
objcontainer.setLayout(esquema);

您基本上已将组件添加到容器(使用FlowLayout),然后更改了布局管理器。约束不会贯穿,它们通常在布局之间不兼容(无论如何FlowLayoutGridBagConstraints有关)

相反,首先设置布局

objcontainer = new JPanel();
esquema = new GridBagLayout();
objcontainer.setLayout(esquema);
// Add components.

这也适用于建立窗口时......

public agregaringreso(){

    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setTitle("Agregar Nuevo Ingreso - EkPek");
    pack();
    setResizable(false);
    setSize(500, 200);
    setLocationRelativeTo(null);

这一切毫无意义,因为你实际上没有在窗口中添加任何内容,所以pack实际上无法完成它的任务(它没有任何东西可以打包)

相反,首先构建UI,“设置”窗口属性......

public agregaringreso(){

    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setTitle("Agregar Nuevo Ingreso - EkPek");

    //FASE DE INICIALIZACION
    contenedor = getContentPane();
    contenedor.setBackground(Color.RED);
    objcontainer = new JPanel();
    esquema = new GridBagLayout();
    objcontainer.setLayout(esquema);
    c = new GridBagConstraints();

    // Add components

    setResizable(false);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
}

答案 1 :(得分:0)

  

它只能用一个网格分开。但是当我把它放在2或者更远的地方时,如果我放1,它就会保持最后一个物体。

如果你的意思是跳过gridy的价值并没有做任何事情,而不是你的意思。网格只包含行和列,其中包含组件。

示例:如果您有2个组件,第一个位于(0,0),第二个位于(0,4),则gridy值1到3不计算在内。结果是第二个组件实际上是(0,1)。同样适用于gridx

  

锚也不能很好地工作,除了LINE START之外,中心的失败了。

在您的示例中,CENTER anchor值按预期运行。如果组件小于其可用空间(并且没有指示用fill填充该空间),则它将与空间的中心对齐。

您可能希望组件位于整个网格的中心,而不是位于其可用空间的中心。要执行此操作,必须对其进行设置,以便组件通过适当地设置其gridwidth来跨越网格的宽度(或高度)。

图片比较

enter image description here enter image description here

@MadProgrammer's answer已经解释了如何修复您的设置(我将在下面的注释中提到它)。你应该在这些修正之后获得最佳图片。红线分隔行,蓝线分隔列 - 这是你的网格。

您会看到第一行和最后一行中的组件以第0列为中心,因为这是它们的可用空间。在下图中,由于我指示它们跨越2列,因此它们在两列中居

我还注意到顶部图片中的空格差异带有黄色矩形。发生这种情况是因为组件未填满所有可用空间。虽然这是您的选择,但在此类布局中,通常会按照下图所示进行操作。

代码比较

c.anchor = GridBagConstraints.CENTER; // Redundant - default
addobjeto(title, 0, 0, 2, 1);

c.anchor = GridBagConstraints.LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
addobjeto(nombreingreso2, 0, 1, 1, 1);
addobjeto(nombreingreso3, 1, 1, 1, 1);

addobjeto(ingreso2, 0, 2, 1, 1);
addobjeto(ingreso3, 1, 2, 1, 1);

addobjeto(frecuencia2, 0, 3, 1, 1);
addobjeto(frecuencia3, 1, 3, 1, 1);

c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.NONE;
addobjeto(aceptar, 0, 4, 2, 1);
  • gridwidth的{​​{1}}和title设置为2(aceptar也可以),以允许它们跨越2列。
  • 对于其余组件,设置GridBagConstraints.REMAINDER以允许它们与自身对齐(黄色矩形)。如果您不希望按钮拉伸,请务必为c.fill = GridBagConstraints.HORIZONTAL;重置c.fill = GridBagConstraints.NONE;
  • 为第一个组件指定aceptar是多余的,因为它是默认值,但它可以使代码更清晰。

注意:

  • 您不需要将c.anchor = GridBagConstraints.CENTER;作为字段,因为您可能不需要提及它们。局部变量也会这样做,并会减少内存使用量。
  • 类名称应以大写(JLabel)开头。
  • 至于我的"设置" (正如MadProgrammer所解释的):在添加组件之前我有

    Agregaringreso

    最后我有

    esquema = new GridBagLayout();
    objcontainer = new JPanel(esquema);
    c = new GridBagConstraints();
    

    (您不需要保留对内容窗格的引用。)