I'm using a grid layout for one of my programs and when i try to add JTextFields to the grid It doesn't show at all. If i try adding JButtons instead of JTextFields in the same method it works perfectly.
package suDUKO;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import javax.swing.JTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Gui_Class {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension blocksize;
private final int screenW=(int) (screenSize.getWidth()/2);
private final int screenH=(int) (screenSize.getHeight()/2);
JFrame frame;
JPanel panel;
public Gui_Class() {
frame=new JFrame("Suduko");
frame.setBounds((int) screenW-500,screenH-500,500,500);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
panel=new JPanel();
frame.add(panel);
panel.setVisible(true);
panel.setLayout(new GridLayout(9, 9));
JTextField [][] table = new JTextField[9][9];
for(int m = 0; m < 9; m++) {
for(int n = 0; n < 9; n++) {
table[m][n]=new JTextField(m+" "+n);
table[m][n].setVisible(true);
panel.add(table[m][n]);
}
}
}
}
There are a number of problems with this code. The main ones that you asked about, can be fixed by adding all the components, then calling pack() before finally calling setVisible(true);.
If the code as seen above does those things, the GUI won't be 500 x 500 in size, and will not be centered. Each has it's own best approach.
Firstly, it seems you want the content pane to be square (500 x 500), and that won't happen if the frame is 500 x 500, because it has a title bar and possibly borders to render. Then centering a GUI on screen is as simple as frame.setLocationRelativeTo(null).
You've already marked this correct, but was just preparing an example of what is written above, so here it is!
import java.awt.*;
import javax.swing.*;
public class Gui_Class {
JFrame frame;
JPanel panel;
public Gui_Class() {
frame = new JFrame("Suduko");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
panel = new JPanel(new GridLayout(9, 9));
frame.add(panel);
//panel.setVisible(true); //unnecessary
JTextField[][] table = new JTextField[9][9];
for (int m = 0; m < 9; m++) {
for (int n = 0; n < 9; n++) {
table[m][n] = new SquareTextField(m + " " + n);
panel.add(table[m][n]);
}
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable r = () -> {
new Gui_Class();
};
SwingUtilities.invokeLater(r);
}
}
class SquareTextField extends JTextField {
int size = 30;
SquareTextField(String s) {
super(s);
setFont(getFont().deriveFont((float)size));
int sz = size/6;
setMargin(new Insets(sz, sz, sz, sz));
}
#Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
int w = d.width;
int h = d.height;
int max = w>h ? w : h;
return new Dimension(max, max);
}
}
You just need to add:
frame.pack()
after the loops.
Add a frame.pack() at the end of the constructor. That will make the layout manager to, well, layout its components.
Related
Hi guys I'm using Eclipse and I'm trying to create a Connect4 Game Grid , which is an JPanel gridArray [6] [7]. I later add the different Panels for buttons and the grid into a main panel and add it into my frame.
My Problem:
I want to fill the gridArray JPanel with Pictures of an empty field(white color) but first of all i want to create a new Panel and insert it into my gridArray through a loop until gridArray has all 42 Panels inside it and is fully filled. I have my Code below but somehow it doesnt work, although my logic should be fine.
I tried it with using a helper Function to create a new JPanel and call the function for each loop in fillGrid();, basically calling it 42 times but it still wont work...
I will gladly appreciate some help!
package connect4;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class GridTest extends JFrame {
JFrame mainWindow;
JPanel buttonPanel, mainPanel;
JPanel gridPanel;
JPanel emptyPanel;
JPanel panel1;
ImageIcon emptyBox;
JPanel[][] gridArray;
JLabel emptyLabel;
JButton arrow1,arrow2,arrow3,arrow4,arrow5,arrow6,arrow7;
public GridTest() {
createGameGrid();
fillGrid();
}
public void createGameGrid() {
//creating window and mainpanel
mainWindow = new JFrame("Connect 4");
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
//defining top panel with 7 buttons;
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 7));
arrow1 = new JButton("V");
arrow2 = new JButton("V");
arrow3 = new JButton("V");
arrow4 = new JButton("V");
arrow5 = new JButton("V");
arrow6 = new JButton("V");
arrow7 = new JButton("V");
buttonPanel.add(arrow1);
buttonPanel.add(arrow2);
buttonPanel.add(arrow3);
buttonPanel.add(arrow4);
buttonPanel.add(arrow5);
buttonPanel.add(arrow6);
buttonPanel.add(arrow7);
//create Grind Panel
gridPanel = new JPanel();
gridPanel.setLayout(new GridLayout(6,7));
mainPanel.add(buttonPanel, BorderLayout.NORTH);
mainPanel.add(gridPanel, BorderLayout.SOUTH);
mainWindow.add(mainPanel);
mainWindow.pack();
mainWindow.setLocationRelativeTo(null);
mainWindow.setVisible(true);
}
private JPanel greateOnePanel(){
//here we need to insert the icon which is in empty box into a newly created panel
//ifirst wanted to insert black panels do ensure it works as intended but it doesnt
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
panel.setSize(50,50);
return panel;
}
//here we need to fill the grid with the panels created above from left to right...
public void fillGrid() {
for(int j = 0; j < 6; j++) {
for (int k = 0; k < 7; k++) {
gridPanel.add(greateOnePanel());
}
}
}
public static void main(String[] args) {
new GridTest();
}
}
i tried it with this method using gridArray, but it throws NullPointer Exeptions and wont fill the grid with simple textlabels "Hallo" (just for testing purposes)
public void fillGrid() {
for(int j = 0; j < 6; j++) {
for (int k = 0; k < 7; k++) {
JLabel label = new JLabel("Hallo");
gridArray[j][k] = new JPanel();
gridArray[j][k].setSize(50, 50);
gridArray[j][k].setBackground(Color.RED);
gridArray[j][k].add(label);
gridPanel.add(gridArray[j][k]);
}
}
}
Here is a short, self contained, code that should help with various aspects of the task.
There is no need for a panel in each cell. The only thing it helped with was setting a BG color. That can be done in a label as long as the background is set to opaque.
This code defines a SquareLabel which overrides getPreferredSize() to return the maximum of preferred width and height as the value of both (usually it is the width).
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class SquareLabelGrid {
int rows = 6;
int cols = 7;
JLabel[][] labelArray = new JLabel[cols][rows];
Font bigFont = new Font(Font.SANS_SERIF, Font.BOLD, 30);
Insets labelInsets;
SquareLabelGrid() {
JPanel gameBoard = new JPanel(new GridLayout(rows, cols));
// a border to make the cell boundaries more clear and add
// some space around the text
Border border = new CompoundBorder(
new LineBorder(Color.BLACK),new EmptyBorder(4,4,4,4));
for (int yy = 0; yy < rows; yy++) {
for (int xx = 0; xx < cols; xx++) {
JLabel l = getColoredSquareLabel(xx, yy);
labelArray[xx][yy] = l;
gameBoard.add(l);
l.setBorder(border);
}
}
JOptionPane.showMessageDialog(null, gameBoard);
}
private JLabel getColoredSquareLabel(int x, int y) {
SquareLabel label = new SquareLabel(
String.format("%1s,%1s", (x+1), (y+1)));
label.setFont(bigFont);
label.setOpaque(true); // so we can see the BG color
label.setBackground(Color.ORANGE); // I prefer orange!
// make the GUI less 'crowded'
label.setBorder(new EmptyBorder(4,4,4,4));
return label;
}
public static void main(String[] args) {
Runnable r = () -> {
new SquareLabelGrid();
};
SwingUtilities.invokeLater(r);
}
}
class SquareLabel extends JLabel {
SquareLabel(String label) {
super(label);
}
/* This will create a square component that accounts for the
size of the String / Icon it contains. No guesswork! */
#Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
int w = d.width;
int h = d.height;
int sz = w > h ? w : h;
return new Dimension(sz, sz);
}
}
The problem is that you have not initialized the grid array .
Otherwise it will throw Null pointer exception.
JPanel[][] gridArray = new JPanel[6][8];
Also set the preferred size of main panel to make the grids visible .
mainPanel.setPreferredSize(new Dimension(400, 200));
Here is what i can see when I run your code with the modifications mentioned here .
Also please execute it from main with following code .
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GridTest();
}
});
}
I am trying to build a matching game with icons attached to each button. Although, this isn't close to being finished, I have a problem with filling the panel with buttons.
With this code I get a grey colored frame. If i comment out the 3 methods i use under "//execution" the panel will be all black (which is how i am testing to see if the buttons are filling the space or not.)
For some reaso,n my buttons aren't being populated onto the panel.
I need some help!!! Where am I going wrong?
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MemoryMainFrame extends JFrame implements ActionListener {
JButton button[] = new JButton[16];
private static final int SIXTEEN_BUTTONS = 16;
JPanel mainPanel = new JPanel();
double dim = Math.sqrt(SIXTEEN_BUTTONS);
int numOfColumns = (int) (dim);
int numOfRows = (int) (dim);
public static void main(String[] args) {
new MemoryMainFrame();
}
public MemoryMainFrame() {
this.setTitle("MemoryGame!!!");
this.setSize(400, 400);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
mainPanel.setBackground(Color.BLACK);
mainPanel.setLayout(new GridBagLayout());
// execution
FillButtonArray(SIXTEEN_BUTTONS);
AddButtonListener(SIXTEEN_BUTTONS);
ButtonToPanel(SIXTEEN_BUTTONS);
this.add(mainPanel);
}
public void FillButtonArray(int numOfButtons) {
int i = 0;
while (i < numOfButtons) {
button[i] = new JButton("asdf");
}
}
public void AddButtonListener(int numOfButtons) {
int i = 0;
while (i < numOfButtons) {
button[i].addActionListener(this);
}
}
public void ButtonToPanel(int numOfButtons) {
int n = 0;
GridBagConstraints gbc = new GridBagConstraints();
for (int i = 0; i < numOfColumns; i++) {
for (int j = 0; j < numOfRows; j++) {
gbc.gridx = i;
gbc.gridy = j;
n++;
button[n].setBorder(BorderFactory.createLineBorder(
Color.DARK_GRAY, 2));
mainPanel.add(button[n]);
}
}
}
public void actionPerformed(ActionEvent arg0) {
JFrame j = new JFrame();
j.setSize(300, 300);
j.setVisible(true);
}
}
I use the "asdf" as a test to see if the buttons work as well.
also, the actionperformed was a test as well. That part of the code is irrelevant.
You're creating your GridBagConstraints but you're not using them.
Change this:
mainPanel.add(button[n]);
to this:
// passes both the component and the GBC into the container
mainPanel.add(button[n], gbc);
Edit
You've also got a never-ending loop here:
while (i < numOfButtons) {
button[i] = new JButton("asdf");
}
and likewise for the AddButtonListener(...) method.
You'll want to fix this by using either a for loop or else changing i within the loop.
Also per Andrew Thompson's comment, you're setting the JFrame visible too early, before all components have been added.
Also your use of Math.sqrt then casting the result to int is very risky and risks getting unexpected results. Just declare the side length to 8 and square the int if you need to.
For an example of GridBagLayout, please check out:
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial") // avoid extending JFrame if possible
public class MemoryMainPanel extends JPanel {
private static final int ROWS = 8;
private static final Color BACKGROUND = Color.black;
private static final int I_GAP = 5;
private static final Insets BTN_INSETS = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
private JButton[][] buttons = new JButton[ROWS][ROWS];
public MemoryMainPanel() {
setBackground(BACKGROUND);
setLayout(new GridBagLayout());
for (int row = 0; row < buttons.length; row++) {
for (int col = 0; col < buttons[row].length; col++) {
JButton btn = new JButton(new ButtonAction(row, col));
add(btn, createGbc(row, col));
buttons[row][col] = btn;
}
}
}
private GridBagConstraints createGbc(int y, int x) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = BTN_INSETS;
return gbc;
}
private class ButtonAction extends AbstractAction {
private int row;
private int col;
public ButtonAction(int row, int col) {
super("asdf");
this.row = row;
this.col = col;
}
#Override
public void actionPerformed(ActionEvent e) {
String text = String.format("Column, Row: [%d, %d]", col + 1, row + 1);
Component parentComponent = MemoryMainPanel.this;
String message = text;
String title = "Button Pressed";
int messageType = JOptionPane.PLAIN_MESSAGE;
Icon icon = null;
JOptionPane.showMessageDialog(parentComponent, message, title, messageType, icon);
}
}
private static void createAndShowGui() {
MemoryMainPanel mainPanel = new MemoryMainPanel();
JFrame frame = new JFrame("MemoryMainPanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
So I'm new to Java and im definitely new to Swing.
I've got a 80 X 80 array thats going to be used by a maze. I need my gui to have 80 X 80 buttons so they can be tied to the values in my array.
I cant figure out why I'm only getting five or six large buttons from this code. If anyone can tell me how I can get this to work then thank you in advance because I'm stumped.
Just run it and you'll see what I mean...also I guess I've not figured out how to change the color of the buttons and I changed the background color instead.
Heres my code:
public static void draw() {
JFrame f = new JFrame();
f.setTitle("Maze");
f.setSize(800, 800);
f.setVisible(true);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel c = (JPanel)f.getContentPane();
GridLayout gridLayout = new GridLayout();
c.setLayout(gridLayout);
for(int i =0;i<80;i++){
for(int j =0;j<80;j++){
JButton b = new JButton();
c.add(b, i,j);
b.setSize(10, 10);
b.setOpaque(true);
b.setBackground(Color.red);
}
}
}
}
80 * 10 > f.setSize(800, 800); and your code is not possible to fit in FullHd monitor
use f.pack() instead of f.setSize(800, 800);
f.pack() and f.setVisible(true); (could be a main issue) should be last code lines in non_static and renamed to !public void DrawMe() {!, because draw() is reserved word for/in Java API
c.add(b, i,j); should be last code line too (logical ordering),
c.add(b, i,j); set row and columns for GridLayout instead of injecting the JButton to virtual grid in GridLayout
make me some sense (starting with the numbers of elements)
from
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawMe {
private JFrame frame = new JFrame();
private JPanel c = new JPanel();
private static final int column = 10;
private static final int row = 10;
public DrawMe() {
c.setLayout(new GridLayout(row, column));
for (int i = 0; i < column; i++) {
for (int j = 0; j < row; j++) {
JButton b = new JButton((i + 1) + " " + (j + 1));
c.add(b);
}
}
frame.add(c);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new DrawMe();
}
});
}
}
I have a JTabbedPane with 2 JPanels set to GridLayout(13, 11). The first JPanel has enough of the cells filled out that it leaves the empty cells.
The second JPanel has significantly fewer cells filled and this results in each button getting stretched to fill an entire row.
Is there any way to get GridLayout to honor the empty cells, so the buttons in both JPanels are the same size?
Is there any way to get GridLayout to honor the empty cells, so the buttons in both JPanels are the same size?
It is certainly doable with GridLayout, simply 'fill' the blank squares with a JLabel that has no text.
E.G. Here are two grid layouts, both padded to 3 rows.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.LineBorder;
class FillGridLayout {
public static final JComponent getPaddedGrid(
ArrayList<BufferedImage> images, int width, int height) {
JPanel p = new JPanel(new GridLayout(height, width, 2, 2));
p.setBorder(new LineBorder(Color.RED));
int count = 0;
for (BufferedImage bi : images) {
p.add(new JButton(new ImageIcon(bi)));
count++;
}
for (int ii=count; ii<width*height; ii++ ) {
// add invisible component
p.add(new JLabel());
}
return p;
}
public static void main(String[] args) {
final ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
int s = 16;
for (int ii = s/4; ii < s; ii+=s/4) {
images.add(new BufferedImage(ii, s, BufferedImage.TYPE_INT_RGB));
images.add(new BufferedImage(s, ii, BufferedImage.TYPE_INT_RGB));
}
Runnable r = new Runnable() {
#Override
public void run() {
JPanel gui = new JPanel(new BorderLayout(3,3));
gui.add(getPaddedGrid(images, 3, 3), BorderLayout.LINE_START);
gui.add(getPaddedGrid(images, 4, 3), BorderLayout.LINE_END);
JOptionPane.showMessageDialog(null, gui);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
Use nested layouts to get your desired result. Some layouts respect the preferred size of components and some don't. GridLayout is one of the ones that don't. Have a look at this answer to see which one's do and which one's don't.
For example, you could nest the 13 buttons in a GridLayout nested in another JPanel with a FlowLayout
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEADING));
JPanel p2 = new JPanel(new GridLayout(13, 1));
for (int i = 0; i < 13; i++) {
p2.add(new JButton("Button " + i));
}
p1.add(p2);
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test6 {
public Test6() {
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEADING));
JPanel p2 = new JPanel(new GridLayout(13, 1));
for (int i = 0; i < 13; i++) {
p2.add(new JButton("Button " + i));
}
p1.add(p2);
JFrame frame = new JFrame("Test Card");
frame.add(p1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Test6 test = new Test6();
}
});
}
}
add empty JLabel to the empty cell
content.add(new JLabel(""));
This question already has an answer here:
getting Exception : java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
(1 answer)
Closed 9 years ago.
I have researched this error and I cannot seem to find a solution. I am trying to create a grid of 800 JButtons with 40 columns and 20 rows. This will eventually be used to control a domino setting up robot I am making that will tip over dominoes. I have already successfully created a grid using GridLayout, but due to the nature of the project, I would like every other row to be offset by half a button. By this I mean like how keys on a computer keyboard are set up. (I would have added a helpful picture of what I am trying to explain, but apparently beginners who have trouble explaining things aren't allowed to add pictures, whatever).
I try to do this by creating a JPanel array of 20 panels called panel. Then I add to the panel the 40 JButtons. Then I use GridBagConstraints to offset every other row. I read that you shouldn't mix awt and swing so that could be the problem, but i don't know. Here is the code, I figured this out from youtube tutorials as I am a very beginner. Forgive me if anything I have said does not make sense. Code:
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class OffsetGrid {
public static void main (String [] args){
JFrame Frame = new JFrame();
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid= new GridLayout();
GridBagConstraints gbca= new GridBagConstraints();
GridBagConstraints gbcb= new GridBagConstraints();
JPanel[] panel=new JPanel[20];
for (int row=0;row<20; row++){
panel[row]=new JPanel(new GridBagLayout());
gbca.gridx=1;
gbca.gridy=row;
gbcb.gridx=0;
gbcb.gridy=row;
for (int y=0; y<40;y++){
grid=new GridLayout(1,40);
panel[row].setLayout(grid);
JButton[] button = new JButton[40];
button[y]=new JButton();
button[y].setOpaque(true);
panel[row].add(button[y]);
}
if (row%2==0){
Frame.add(panel[row], gbcb);
}
else {
Frame.add(panel[row], gbca);
}
}
Frame.setVisible(true);
Frame.setLocationRelativeTo(null);
Frame.pack();
}
}
error:
Exception in thread "main" java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
at java.awt.BorderLayout.addLayoutComponent(BorderLayout.java:426)
at javax.swing.JRootPane$1.addLayoutComponent(JRootPane.java:531)
at java.awt.Container.addImpl(Container.java:1120)
at java.awt.Container.add(Container.java:998)
at javax.swing.JFrame.addImpl(JFrame.java:562)
at java.awt.Container.add(Container.java:966)
at OffsetGrid.main(OffsetGrid.java:38)
Please help me figure out the problem and get it working. Thanks
edit: I am still confused on exactly how to use gridbagconstraints so I don't even know if gridy and gridx are even the right things to use here. Or even if i should use gridbagconstraints. Please offer any suggestions to get the job done. Thanks
edit: this seems to work.
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
public class OffsetGrid {
public static void main (String [] args){
JFrame Frame = new JFrame();
Frame.setLayout(new GridBagLayout());
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid= new GridLayout();
GridBagConstraints gbca= new GridBagConstraints();
GridBagConstraints gbcb= new GridBagConstraints();
JPanel[] panel=new JPanel[20];
for (int row=0;row<20; row++){
panel[row]=new JPanel(new GridBagLayout());
gbca.insets=new Insets(0,100,0,0);
gbca.gridy=row;
gbcb.insets=new Insets(0,0,0,0);
gbcb.gridy=row;
for (int y=0; y<40;y++){
grid=new GridLayout(1,40);
panel[row].setLayout(grid);
JButton[] button = new JButton[40];
button[y]=new JButton();
button[y].setOpaque(true);
panel[row].add(button[y]);
}
if (row%2==0){
Frame.add(panel[row], gbcb);
}
else {
Frame.add(panel[row], gbca);
}
}
Frame.setVisible(true);
Frame.setLocationRelativeTo(null);
Frame.pack();
}
}
You did this:
Frame.add(panel[row], gbcb);
But you forgot to set the frame's layout:
JFrame Frame = new JFrame();
Frame.setLayout(new GridBagLayout());
Now the exception is not thrown. However......
I wonder if this is what you want:
I've made some change to my code in the case that user resize the window. You can still find the older code in revision
import static javax.swing.BorderFactory.createEmptyBorder;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
public class OffsetGrid {
public static final int ROWS = 10;
public static final int COLUMNS = 10;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(ROWS, 1));
final JPanel[] panel = new JPanel[ROWS];
final JButton[][] button = new JButton[ROWS][COLUMNS];
for (int row = 0; row < ROWS; row++) {
panel[row] = new JPanel(new GridLayout(1, COLUMNS));
for (int y = 0; y < COLUMNS; y++) {
button[row][y] = new JButton(row + "-" + y);
button[row][y].setOpaque(true);
panel[row].add(button[row][y]);
}
int padding = button[row][0].getPreferredSize().width / 2;
if (row % 2 == 0)
panel[row].setBorder(createEmptyBorder(0, 0, 0, padding));
else
panel[row].setBorder(createEmptyBorder(0, padding, 0, 0));
frame.add(panel[row]);
}
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
for (int row = 0; row < ROWS; row++) {
int padding = button[row][0].getSize().width / 2;
panel[row].setBorder(createEmptyBorder(0, 0, 0, padding));
if (++row == ROWS)
break;
padding = button[row][0].getSize().width / 2;
panel[row].setBorder(createEmptyBorder(0, padding, 0, 0));
}
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}