简体   繁体   中英

How to fill a GridLayout top-to-bottom and then left-to-right?

The default behavior of a GridLayout is that the components are filled row by row, and from left to right. I wonder if I can use it so that the components are filled by columns (from left to right)? Thanks.

Such use case is not supported by the GridLayout manager.

I suggest you have a look at GridBagLayout instead, which allows you to set the location through GridBagConstraints.gridx and GridBagConstraints.gridy .

(To get a behavior similar to GridLayout be sure to set the weights and fill properly.)

You can extend GridLayout and override just one method instead of int i = r * ncols + c; use int i = c * nrows + r; I think that's enough.

public void layoutContainer(Container parent) {
  synchronized (parent.getTreeLock()) {
    Insets insets = parent.getInsets();
    int ncomponents = parent.getComponentCount();
    int nrows = rows;
    int ncols = cols;
    boolean ltr = parent.getComponentOrientation().isLeftToRight();

    if (ncomponents == 0) {
        return;
    }
    if (nrows > 0) {
        ncols = (ncomponents + nrows - 1) / nrows;
    } else {
        nrows = (ncomponents + ncols - 1) / ncols;
    }
    int w = parent.width - (insets.left + insets.right);
    int h = parent.height - (insets.top + insets.bottom);
    w = (w - (ncols - 1) * hgap) / ncols;
    h = (h - (nrows - 1) * vgap) / nrows;

    if (ltr) {
        for (int c = 0, x = insets.left ; c < ncols ; c++, x += w + hgap) {
        for (int r = 0, y = insets.top ; r < nrows ; r++, y += h + vgap) {
            int i = r * ncols + c;
            if (i < ncomponents) {
            parent.getComponent(i).setBounds(x, y, w, h);
            }
        }
        }
    } else {
        for (int c = 0, x = parent.width - insets.right - w; c < ncols ; c++, x -= w + hgap) {
        for (int r = 0, y = insets.top ; r < nrows ; r++, y += h + vgap) {
            int i = r * ncols + c;
            if (i < ncomponents) {
            parent.getComponent(i).setBounds(x, y, w, h);
            }
        }
        }
    }
  }
}

You can't achieve this with a single GridLayout . However, you could have a GridLayout of one row that each cell had a GridLayout of a single column with several rows. Although using a different LayoutManager like TableLayout might be an easier choice.

I suggest you try MigLayout . You can switch the flow direction with:

setLayout(new MigLayout("flowy"));
add(component1);
add(component2);
add(component3, "wrap");
add(component4);
add(component5);
add(component6);

There are a many ways to achieve this with MigLayout, and I find it SO much friendlier to use than GridBagLayout and just as capable, if not more so. You won't need BorderLayout, FlowLayout, BoxLayout, etc. anymore, MigLayout does all that too.

You can just recalculate the position of each component:

Int row = ROWS;//amount of ROWS in the grid
Int col = COLUMs;//amount of COLUMS in the grid
Int x = i / row;// i is the component index(0,1,2,3...)
Int y = i - x * row;
Int position=col * x + y;
Panel.add(component, position);//the panel with gridlayout

You may need to fill initially the panel in order to avoid a nullPointer on a position that don't exists:

For(i=0 to i= ROWS){
For(j =0 to j=columns){
Panel.add(new ...(random component)
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM