Iridio
Iridio

Reputation: 135

GridLayout throws illegal component position

By default GridLayout(5,3) would add the components in this way:

A B C
D E F
G H I
J K L
M N O 

To have the components disposed in the following positions:

A F K
B G L
C H M
D I N
E J O

I have this code:

//imports...

public class GridLayoutProblem {

    private static final int NUM_ROWS = 5, NUM_COLMS=3;
    private JPanel mainPanel = new JPanel();
    private JPanel buttonPannel = new JPanel(new GridLayout(NUM_ROWS, NUM_COLMS));

    private JButton btnA = new JButton("A");
    private JButton btnB = new JButton("B");
    //same with C, D...
    private JButton btnO = new JButton("O");

    private JComponent[] buttons = {
            btnA, btnB, btnC, btnD, btnE,
            btnF, btnG, btnH, btnI, btnJ,
            btnK, btnL, btnM, btnN, btnO
    };

    public GridLayoutProblem(){
        int i=0;
        for (JComponent button : buttons){
            int index = i%NUM_ROWS*NUM_COLMS+i/NUM_ROWS;
            buttonPannel.add(button,index);
            i++;
        }
        mainPanel.add(buttonPannel);
    }
    //...

But it results in: Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: illegal component position.

Upvotes: 2

Views: 2564

Answers (2)

Lukas Rotter
Lukas Rotter

Reputation: 4188

Change buttonPannel.add(button,index); to buttonPannel.add(buttons[index]);. (You don't need a foreach-loop) GridLayout always adds the components like you showed in the first example, but if you can make your calculation for index right (see other answer), so it adds it like "A,F,K,B...", you can achieve what you want.

Run the code below to see how the buttons are being added:

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

//imports...

public class GridLayoutProblem {

    private static final int NUM_ROWS = 5, NUM_COLMS=3;
    private static JPanel mainPanel = new JPanel();
    private JPanel buttonPannel = new JPanel(new GridLayout(NUM_ROWS, NUM_COLMS));

    private JButton btnA = new JButton("A");
    private JButton btnB = new JButton("B");
    private JButton btnC = new JButton("C");
    private JButton btnD = new JButton("D");
    private JButton btnE = new JButton("E");
    private JButton btnF = new JButton("F");
    private JButton btnG = new JButton("G");
    private JButton btnH = new JButton("H");
    private JButton btnI = new JButton("I");
    private JButton btnJ = new JButton("J");
    private JButton btnK = new JButton("K");
    private JButton btnL = new JButton("L");
    private JButton btnM = new JButton("M");
    private JButton btnN = new JButton("N");
    private JButton btnO = new JButton("O");

    private JComponent[] buttons = {
            btnA, btnB, btnC, btnD, btnE,
            btnF, btnG, btnH, btnI, btnJ,
            btnK, btnL, btnM, btnN, btnO
    };

    public static void main(String[] args) {
        new GridLayoutProblem();
    }

    public GridLayoutProblem(){
        JFrame frame = new JFrame();
        new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < NUM_ROWS * NUM_COLMS; i++) {
                    int index = i%NUM_COLMS*NUM_ROWS+i/NUM_COLMS;
                    buttonPannel.add(buttons[index]);
                    frame.revalidate();
                    frame.repaint();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        mainPanel.add(buttonPannel);
        frame.getContentPane().add(mainPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setVisible(true);
    }
}

Upvotes: 1

Codebender
Codebender

Reputation: 14438

I did a quick test and it seems you cannot skip indexes and add elements to higher index.

So your option is to do something like this,

    for (int i = 0; i < NUM_ROWS*NUM_COLMS; i++){
        int index = i%NUM_COLMS*NUM_ROWS+i/NUM_COLMS; // Note the change in calculation. Just interchange rows and colms from your algo.
        buttonPannel.add(button[index],i);
    }

Upvotes: 2

Related Questions