Search code examples
javaswinguser-interfacejbuttontetris

Tetris GUI by coloring JButtons. Problems with rendering


I am making a Tetris game and for my GUI I chose to color JButtons to use as my tetris board. I set up a grid of JButtons. I plan to loop through the Tetris grid that is returned from

newGrid = game.gamePlay(oldGrid);

and color each JButton based on the integer in each grid element. The Tetris grid returned is an array of integers, each number representing a color. As of now I have no user interaction, I am just trying to have the basic GUI where the blocks drop straight down.

final JPanel card3 = new JPanel();
// Tetris setup
JButton startGame = new JButton("START GAME");
card3.setLayout(new GridBagLayout());
GridBagConstraints gbc2 = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
card3.add(startGame, gbc2);
gbc.gridy = 1;
startGame.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    card3.remove(0); //remove start button

    Game game = new Game();
    int[][] oldGrid = null;
    int[][] newGrid = null;
    boolean firstTime = true;

    JButton[][] grid; // tetris grid of buttons
    card3.setLayout(new GridLayout(20, 10));
    grid = new JButton[20][10];
    for (int i = 0; i < 20; i++) {
        for (int j = 0; j < 10; j++) {
            grid[i][j] = new JButton();
            card3.add(grid[i][j]);
        }
    }               

    while (true) {
            if (firstTime) {
                newGrid = game.gamePlay(null);
            } else {
                newGrid = game.gamePlay(oldGrid);
            }

            //Coloring Buttons based on grid

            oldGrid = newGrid;
            firstTime = false;
            card3.revalidate();
        }
    }
});

And here is the code from the Game class

public class Game
{
    static Tetris game;

    public int[][] gamePlay(int[][] grid) {
        if (grid == null) {
            game = new Tetris();
            System.out.println("first time");
        }
        else {
                game.setGrid(grid);
            }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        game.move_Down();
        game.print_Game();

        return game.getGrid();
    }
}

The game.print_Game(); prints the grid to the console window so that I can see textually what is going on. But the card3.revalidate(); does not seem to be working because the GUI suspends when the printing begins. If I move the revalidate before the while loop and then comment out the while loop, the GUI outputs:

enter image description here

which is what I want. But in order to color the buttons a certain color, I need to do the revalidating in the while loop as the grid changes.

Any suggestions?


Solution

    1. use GridLayout (simpler LayoutManager) instead of GridBagLayout

    2. use Swing Timer instead of Runnable#Thread

    3. while (true) { is endless loop

    4. Thread.sleep(1000); can to freeze Swing GUI untill sleep ended, endless loop with Thread.sleep can caused unresponsible application

    5. can't see there JButton.setBackground(somecolor)

    6. use KeyBindings (add to the to JButtons container) for rotations