I put a bunch of JButtons in a 2D array into a GridLayout. I want the user to be able to change the size of this grid at run time, but I tried resetting the row/cols, re-adding the buttons, remaking the panel that this grid is in - all to no avail. How do I accomplish this?

Thanks for any help!

Recommended Answers

All 14 Replies

Remove all and recreate it

I tried removing it with removeLayoutComponent but it didn't work for some reason. Is there something else I should/can use?

Can you make a small,simple program that compiles, executes and shows what you are trying to do?

Something along the lines of this:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Test extends JFrame  {

   JButton[][] grid;
   int size;
   int newSize;
   Scanner in;
   GridLayout layout;

   Test() {

      super( "Test" );
      size = 5;
      layout = new GridLayout( size, size );
      setLayout( layout );
      setSize( 500, 500 );

      grid = new JButton[size][size];

      for( int i = 0; i < size; i++ ) {
         for( int j = 0; j < size; j++ ) {
            grid[i][j] = new JButton();
            add( grid[i][j] );
         }
      }

      grid[0][0].setText( "PROMPT" );
      grid[0][0].addActionListener( new ACT() );

      in = new Scanner( System.in );

   }

   private class ACT implements ActionListener {
      public void actionPerformed( ActionEvent e ) {
         prompt();
      }
   }

   public void prompt() {
      System.out.println( "Enter some size" );
      newSize = in.nextInt();
      remakeGrid();
   }

   void remakeGrid() {
      for( int i = 0; i < size; i++ ) {
         for( int j = 0; j < size; j++ ) {
            layout.removeLayoutComponent( grid[i][j] );
         }
      }
      size = newSize;
      layout.setRows( size );
      layout.setColumns( size );
      for( int i = 0; i < size; i++ ) {
         for( int j = 0; j < size; j++ ) {
            grid[i][j] = new JButton();
            add( grid[i][j] );
         }
      }
      pack();
   }

   public static void main( String[] args ) {

      Test app = new Test();
      app.setVisible( true );
      app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

   }

}

What happens when you execute this code? I get the following:
lang.ArrayIndexOutOfBoundsException: 5

Recommendation for testing code: Don't require user input. Hardcode a test value:

  newSize = 7; //in.nextInt();                      //<<<<<<<<<<<<<<<<

When I execute it and put in a number smaller than the original size (5), it'll add a bunch of new buttons to the existing ones. I don't know why it doesn't work for larger numbers either since I (at least seem to have) changed the rows and cols of the layout before looping through and adding new things--error occurs right before the adding-for loop. I guess I'm going about setRows/setColumns wrong since they're apparently not doing anything?

put in a number smaller than the original size

That is the reason I suggested you use a hardcoded value so we would all test with the same data.

Try removing everything and rebuiding the GUI's contents.

Yes, I have changed it to a hardcoded value. Removing everything is to be a big part in the problem though, since it's apparently not even happening despite the method call.

Can you show the code?

Haven't changed the code at all - just replaced newSize = in.nextInt(); with newSize = 7; as you suggested. I still have no idea what the problem is with regards to removing components (in remakeGrid()) so I don't know what else to change further.

what the problem is

You are not removing the components.

And the problem is that I don't know how to. The only solution I've searched up repeatedly is removeLayoutComponents, but that doesn't do anything here.

Where do you remove the components from the container? Your code removes them from the layout manager.
Won't you need a new layout manager when the size of the grid changes?

Where do you remove the components from the container?

Alright, thanks - that's what I was having trouble with. The first time I tried calling remove(), I got an error, so I thought that wasn't the way to go but from your reminder I tried it again and it's fine now.

Apparently I don't need a new layout manager, as far as I've tested it...

Thanks for all the help!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.