Java: JPanel won't repaint after setting a variable to zero

Discussion in 'Mac Programming' started by jsmwoolf, Feb 19, 2012.

  1. jsmwoolf, Feb 19, 2012
    Last edited: Jul 31, 2014

    macrumors regular

    Joined:
    Aug 17, 2011
    #1
    I'm trying to make a Bejeweled-like game and I figured out that using another class to tell information to a JPanel would help me with animation. However, while the JPanel will animate when it sets up the game board, it won't repaint the JPanel ever again afterward. This is the first time that I'm drawing Graphics on a JPanel as I usually use a JComponent.
    Code:
    import java.awt.*;
    
    import javax.swing.*;
    import java.awt.event.*;
    import java.util.Random;
    /*NOTE:y must go second in searches in for loops because the variable gameBoard contains the first section that works with the x-axis rather than y-axis.
    However, if were search vertical, then x may go second.
    z will always go first regardless.*/
    //TODO The main interface
    public class Sample {
    
    JFrame window = new JFrame("Sample"); //Creates our window
    
    JPanel row1 = new JPanel(); //This one holds the buttons which incorporates game modes
    JButton btClassic = new JButton("Classic");
    JButton btAction = new JButton("Action");
    JButton btBlitz = new JButton("Countdown");
    
    Board row2 = null; //A JPanel Class
    Cell[][] cell = null; //JComponent
    Rotator[] rotateUp = null; //To rotate up
    Rotator[] rotateSide = null; //To rotate side to side
    Rotator[] rotateDown = null; //To rotate down
    NullSpot[] nullspot = null; //A null spot to make it equal
    Control control = null;
    public Sample()
    {
    control = new Control(this);
    window.setSize(350,400);
    window.setBackground(Color.black);
    window.setResizable(false);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    FlowLayout layout = new FlowLayout();
    window.setLayout(layout);
    
    FlowLayout layout1 = new FlowLayout();
    row1.setLayout(layout1);
    row1.add(btClassic);
    row1.add(btAction);
    row1.add(btBlitz);
    window.add(row1);
    
    btClassic.addActionListener(control);
    GridLayout layout2 = new GridLayout(10,10);
    row2 = new Board(this);
    row2.setLayout(layout2);
    
    rotateUp=new Rotator[8]; //Used to rotate up
    rotateSide=new Rotator[16]; //Used to rotate side to side
    rotateDown=new Rotator[8]; //Used to rotate down
    cell = new Cell[8][8]; //Used to interact with the game
    nullspot = new NullSpot[4]; //Used to even everything
    
    for(int x = 0; x < 16; x++)
    {
    if(x <= 3){nullspot[x] = new NullSpot();} //Declare a null spot
    if(x<=7){
    rotateUp[x] = new Rotator(); //Declare up rotator
    rotateDown[x] = new Rotator(); //Declare down rotator
    }
    rotateSide[x] = new Rotator(); //Declare side rotator
    }
    
    //First part sets up two null spots and rotators
    row2.add(nullspot[0]);
    for(int x = 0; x<8;x++)
    {
    row2.add(rotateUp[x]); //Rotators
    }
    row2.add(nullspot[1]);
    
    //Then sets up rotators and the cells for interaction
    for(int x = 0; x < 8; x++)
    {
    row2.add(rotateSide[(x*2)]); //The left rotator
    for(int y = 0; y < 8; y++)
    {
    //NOTE:y goes first because the actual array treats x and y correctly.
    cell[x][y] = new Cell(row2,control);
    row2.add(cell[x][y]);
    cell[x][y].setXValue=((x*32)+32);
    cell[x][y].setYValue=((y*32)+32);
    cell[x][y].myArrayX=x;
    cell[x][y].myArrayY=y;
    cell[x][y].addMouseListener(control);
    //System.out.println(cell[x][y].setXValue + ","+cell[x][y].setYValue);
    }
    row2.add(rotateSide[(x*2)+1]); //The right rotator
    }
    
    //Lastly, sets up two null spots and rotators
    row2.add(nullspot[2]);
    for(int x = 0; x<8;x++)
    {
    row2.add(rotateDown[x]); //Down rotator
    }
    row2.add(nullspot[3]);
    row2.setPreferredSize(new Dimension(32*10,32*10));
    window.add(row2);
    window.setVisible(true);
    }
    public static void main(String[] args) {
    Sample game = new Sample(); //Creates our game here
    }
    
    }
    
    //TODO Handles all of the actions
    class Control implements ActionListener, MouseListener
    {
    Sample GUI;
    boolean gameBegan=false;
    boolean selected=false;
    int selectedX,selectedY;
    int[][][] gameBoard = new int[8][8][8];
    public Control(Sample GUI)
    {
    this.GUI=GUI;
    }
    
    //TODO
    public void actionPerformed(ActionEvent e) {
    Object input = e.getSource();
    if(input.equals(GUI.btClassic))
    {
    GUI.btClassic.setEnabled(false);
    GUI.btBlitz.setEnabled(false);
    GUI.btAction.setEnabled(false);
    gameBegan=true;
    setUpBoard();
    }
    }
    //TODO
    public void mousePressed(MouseEvent e) {
    Object input = e.getSource();
    if(gameBegan==true)
    {//for(int z =0; z < 8; z++)
    {
    for(int x= 0; x < 8; x++) //Y
    {
    for(int y= 0; y < 8; y++) //X
    {
    if(input.equals(GUI.cell[x][y])) //Find the cell
    {
    if(selected==true)//If there is something selected
    {
    if(GUI.cell[x][y].selected==true)
    {
    selected=false;
    GUI.cell[x][y].selected=false;
    System.out.println("("+y+","+x+")!");
    } //End Fourth If
    //This parts deals with the swapping of gems
    //Checks for down,right,up, and left
    if( (((x-1)==selectedX) && (y==selectedY)) || (((y-1)==selectedY)&& (x==selectedX)) || (((x+1)==selectedX)&& (y==selectedY)) ||(((y+1)==selectedY) && (x==selectedX))) //Down
    {
    swapCircle(x,y,0); //Deals with circle swapping
    }
    //If we clicked farther than what
    if(((y-1) > selectedY) || ((y+1) < selectedY) || ((x-1) > selectedX) ||((x+1) < selectedX)|| (((x-1)==selectedX)&&((y-1)==selectedY)) ||(((x+1)==selectedX)&&((y-1)==selectedY)) ||(((x-1)==selectedX)&&((y+1)==selectedY)) ||(((x+1)==selectedX)&&((y+1)==selectedY)))
    {
    GUI.cell[selectedX][selectedY].selected=false;
    GUI.cell[selectedX][selectedY].repaint();
    selectedX=x;
    selectedY=y;
    GUI.cell[x][y].selected=true;
    }
    }//End Third If
    else //If there is nothing selected
    {
    getSelected(x,y);
    } //End else
    }//End Second If
    refreshScreen();
    } //End Second For
    } //End First For
    }
    }//End First IF
    }
    
    // TODO Used to redraw the screen when a chain reaction occurs
    void refreshScreen()
    {
    for(int x = 0; x < 8; x++)
    {
    for(int y = 0; y < 8; y++)
    {
    GUI.cell[x][y].repaint();
    }
    }
    }
    
    //TODO
    void drawBoard()
    {
    //for(int z =0; z<8; z++)
    {
    for(int y = 0; y< 8; y++)
    {
    for(int x = 0; x < 8; x++)
    {
    System.out.print(gameBoard[x][y][0]);
    }
    System.out.print("\n");
    }
    System.out.print("\n");
    }
    }
    //TODO Deals with when the user clicks on the one vertically or horizontally away
    void swapCircle(int x, int y,int z)
    {
    int temporaryColor=gameBoard[y][x][z]; //Used for transferring colors
    System.out.println(temporaryColor);
    boolean check = false;
    int checkTimes=1;
    System.out.println("Selected: "+gameBoard[selectedY][selectedX][z]+" To switch: "+gameBoard[y][x][z]);
    gameBoard[y][x][z]=gameBoard[selectedY][selectedX][z];
    gameBoard[selectedY][selectedX][z]=temporaryColor;
    GUI.cell[x][y].circleColor=GUI.cell[selectedX][selectedY].circleColor;
    GUI.cell[selectedX][selectedY].circleColor=temporaryColor;
    System.out.println("Selected: "+gameBoard[selectedY][selectedX][z]+" To switch: "+gameBoard[y][x][z]);
    drawBoard();
    System.out.println(GUI.cell[x][y].circleColor + " at ("+(x+1)+","+(y+1)+")!");
    while(checkTimes>=0) //While the checking is not finished
    {
    /*First goes T-shape Match
    * Next goes L-shape Match
    * Last goes Single Row Match*/
    switch(checkTimes)
    {
    //case 1:check=checkMultiRowMatch(); break; //T and L shape
    case 0:check=checkSingleRowMatch(); break; //Single Row Match
    }//End Switch
    if((check==false)&&(checkTimes==0)) //If there is no match at all, put it back.
    {
    gameBoard[selectedY][selectedX][z]=gameBoard[y][x][z];
    gameBoard[y][x][z]=temporaryColor;
    GUI.cell[selectedX][selectedY].circleColor=GUI.cell[x][y].circleColor;
    GUI.cell[x][y].circleColor=temporaryColor;
    }
    else if(check==true)//If there is a match
    {
    int times=0; //Tracks the cascade
    checkTimes=1; //Resets the checking back to the highest
    while(checkTimes>=0)
    {
    if(check==true) //If there was a match, add it to the cascade
    {
    times++;
    checkTimes=1; //Go back to the highest
    }
    else //Otherwise, go to the next check
    {
    checkTimes--;
    }
    //generateNewCircles(); //Generate new circles to replace the matched ones
    switch(checkTimes)
    {
    //case 1:check=checkMultiRowMatch(); break; //T and L shape
    case 0:check=checkSingleRowMatch(); break; //3 Match
    }//End Switch
    }
    System.out.println("Occurred " + times +" times!");
    }
    checkTimes--;
    //System.out.println(checkTimes);
    }
    check=false;
    selected=false;
    GUI.cell[selectedX][selectedY].selected=false;
    }
    
    //TODO Grabs the selected
    void getSelected(int x, int y)
    {
    selected=true;
    selectedX=x; //Tracks the y coordinate for the Y
    selectedY=y; //Tracks the x coordinate for the X
    //System.out.println("("+y+","+x+")!");
    GUI.cell[x][y].selected=true;
    GUI.cell[x][y].repaint();
    }
    
    //TODO Only used at the beginning. This allows us to set up the board making sure that
    void setUpBoard()
    {
    Random generator = new Random();
    int pickedUpNumber=0; //Stores the picked number
    int occurred=0; //Tracks how many of the same color were used in a row
    boolean horizontalAndZAxisPass=true; //Turns false if it fails the vertical and z-axis test
    for(int z =0; z<8; z++)
    {
    for(int y = 0; y< 8; y++)
    {
    for(int x = 0; x < 8; x++)
    {
    for(;;)
    {
    horizontalAndZAxisPass=true;
    gameBoard[x][y][z]=Math.abs(generator.nextInt()%6)+1; //Pick a number at random
    if(pickedUpNumber==gameBoard[x][y][z])//If it's the same number, track it
    {
    occurred++;
    }
    //If the last number is not equal to the current number or if the same number has not occurred three times
    if((pickedUpNumber!=gameBoard[x][y][z]) || (occurred<2))
    {
    //Vertical Test-If the two top cells are not the same color(pass=false,fail=true)
    if((y>=2)&&(gameBoard[x][y-2][z]==gameBoard[x][y][z]) && (gameBoard[x][y-2][z]==gameBoard[x][y-1][z])) //The vertical test
    {
    horizontalAndZAxisPass=false;//There are two above of the same color
    }
    if((z>=2)&&(gameBoard[x][y][z-2]==gameBoard[x][y][z-1]) && (gameBoard[x][y][z]==gameBoard[x][y][z-1])) //The z-axis test
    {
    horizontalAndZAxisPass=false;//There are two on the z-axis of the same color
    }
    if(horizontalAndZAxisPass==true)
    {
    if(pickedUpNumber!=gameBoard[x][y][z]) //If it's a new number, reset the track
    {
    occurred=0;
    }
    break;
    }
    }
    }
    pickedUpNumber = gameBoard[x][y][z];
    //System.out.println(pickedUpNumber +" ("+(y+1)+","+(x+1)+")!");
    if(z==0)
    {
    GUI.cell[x][y].circleColor=gameBoard[x][y][z];
    GUI.cell[x][y].repaint();
    //System.out.println("("+(x+1)+","+(y+1)+"): "+GUI.cell[x][y].circleColor);
    }
    System.out.print(gameBoard[x][y][z]);
    }
    System.out.print("\n");
    }
    System.out.print("\n");
    } //End Loop
    }//End Function
    
    //TODO Check for single row match: The last one to go
    boolean checkSingleRowMatch()
    {
    int colorOccurance=0; //How many times has this color occurred?
    int currentColor=-1; //Tracks the recent color
    int numberCheck=8;
    while(numberCheck>=3)
    {
    //Horizontal check
    for(int z =0; z<8;z++)
    {
    for(int y = 0; y < 8; y++)
    {
    for(int x =0; x < 8; x++)
    {
    //System.out.println(gameBoard[x][y][z]);
    if((currentColor!=gameBoard[x][y][z])&& (gameBoard[x][y][z]!=0)) //If we're dealing with a new color, set it and reset the count
    {
    colorOccurance=1;
    currentColor=gameBoard[x][y][z];
    /*if(z==0)
    {
    System.out.println(currentColor + "at (" +(x+1)+","+(y+1)+")!");
    }*/
    }
    else if(gameBoard[x][y][z]!=0) //Otherwise
    {
    colorOccurance++;
    }
    if(colorOccurance==numberCheck)
    {
    for(int reverse=numberCheck-1; reverse >= 0;reverse--)//Deals with destroying the circles
    {
    GUI.row2.piece[x-reverse][y].removeSpot();
    gameBoard[x-reverse][y][z]=0;
    GUI.cell[x-reverse][y].circleColor=0;
    GUI.cell[x-reverse][y].repaint();
    }
    drawBoard();
    System.out.println(numberCheck+" Match Horizontal!");
    return true;
    }
    }
    colorOccurance=0;
    currentColor=-1;
    }}
    //Vertical check
    for(int z =0; z<8;z++)
    {
    for(int x = 0; x < 8; x++)
    {
    for(int y =0; y < 8; y++)
    {
    if((currentColor!=gameBoard[x][y][z]) && (gameBoard[x][y][z]!=0))
    {
    colorOccurance=1;
    currentColor=gameBoard[x][y][z];
    }
    else if(gameBoard[x][y][z]!=0)
    {
    colorOccurance++;
    }
    if(colorOccurance==numberCheck)
    {
    for(int reverse=numberCheck-1; reverse >= 0;reverse--)//Deals with destroying the circles
    {
    System.out.println("Found it!");
    GUI.row2.piece[x-reverse][y].colorPiece=0;
    gameBoard[y-reverse][x][z]=0;
    GUI.cell[x-reverse][y].circleColor=0;
    GUI.cell[x-reverse][y].repaint();
    }
    System.out.println(numberCheck+" Match!");
    return true;
    }
    }
    colorOccurance=0;
    currentColor=-1;
    }
    }
    numberCheck--;
    }
    return false;
    }
    
    @Override
    public void mouseClicked(MouseEvent arg0) {
    // TODO Auto-generated method stub
    
    }
    @Override
    public void mouseEntered(MouseEvent arg0) {
    // TODO Auto-generated method stub
    
    }
    @Override
    public void mouseExited(MouseEvent arg0) {
    // TODO Auto-generated method stub
    
    }
    
    
    
    @Override
    public void mouseReleased(MouseEvent arg0) {
    // TODO Auto-generated method stub
    
    }
    
    }
    
    //TODO Handles the animation portion
    class Board extends JPanel
    {
    Sample GUI;
    circlePiece[][] piece = new circlePiece[8][8];;
    public Board(Sample GUI)
    {
    this.GUI=GUI;
    validate();
    for(int x = 0; x < 8; x++)
    {
    for(int y= 0;y<8;y++)
    {
    piece[x][y] = new circlePiece(this);
    }
    }
    }
    
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    System.out.println("Printing!");
    for(int x = 0; x<8; x++)
    {
    for(int y = 0; y<8; y++)
    {
    if((GUI.control.gameBegan==true) && (piece[x][y].colorPiece!=0))//If the spot exists
    {
    switch(piece[x][y].colorPiece)
    {
    case 1: g.setColor(Color.blue);break;
    case 2: g.setColor(Color.red); break;
    case 3: g.setColor(Color.green); break;
    case 4: g.setColor(Color.yellow);break;
    case 5: g.setColor(new Color(255, 165, 0)); break;
    case 6: g.setColor(Color.white);break;
    }
    }
    else if (GUI.control.gameBegan==true)
    {
    g.setColor(getBackground());
    }
    if((piece[x][y].myY>=31) && (piece[x][y].colorPiece!=0))
    {
    g.fillOval(piece[x][y].myX,piece[x][y].myY, 31, 31);
    }
    }
    }
    }
    //Allows us to generate new pieces
    void generateCircle(int pieceNumber,int xArray, int yArray, int endY)
    {
    piece[xArray][yArray].colorPiece=pieceNumber;
    piece[xArray][yArray].myX=(xArray*32)+32;
    piece[xArray][yArray].myY=0;
    piece[xArray][yArray].endYValue=endY;
    piece[xArray][yArray].gravityTurnOn();
    }
    }
    
    //The actual piece
    class circlePiece implements ActionListener
    {
    int colorPiece=0; //Handles the piece part
    int myX=0;
    int myY=0;
    int endYValue;
    Board board;
    Timer animateDownGravity;//Deals with
    public circlePiece(Board board)
    {
    this.board=board;
    }
    
    int gravityMove=25;
    
    void removeSpot()
    {
    System.out.println("Will remove!");
    colorPiece=0;
    System.out.println(myY);
    board.repaint();
    }
    
    void gravityTurnOn()
    {
    if(animateDownGravity==null)
    {
    animateDownGravity = new Timer(1,this);
    animateDownGravity.start();
    }
    }
    
    public void actionPerformed(ActionEvent arg0) {
    if(animateDownGravity!=null)
    {
    myY++;
    board.repaint();
    if(myY==endYValue)
    {
    animateDownGravity.stop();
    animateDownGravity=null;
    }}
    }
    }
    
    //TODO Allows us to interact with the board
    class Cell extends JComponent
    {
    int circleColor=0;
    int setXValue=0;
    int setYValue=0;
    int myArrayX,myArrayY;
    boolean hasPiece=false; //Create the piece once
    boolean selected=false; //Determines whether the cell is selected
    
    Board board;
    Control control;
    public Cell(Board board,Control control)
    {
    this.board=board;
    this.control = control;
    }
    public void paintComponent(Graphics g)
    {
    //System.out.println("Printed!");
    super.paintComponent(g);
    g.setColor((selected==false?new Color(90,90,90):Color.cyan));
    g.drawRect(0, 0, 31, 31);
    if((hasPiece==false) && (control.gameBegan==true))
    {
    board.generateCircle(circleColor,myArrayX,myArrayY,setYValue);
    //board.repaint();
    hasPiece=true;
    }
    //g.drawOval(setXValue, setYValue, 31, 31);
    }
    }
      	
    - 	//TODO Handles the rotating part
    class Rotator extends JComponent
    {
    boolean canUse=true;
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    g.setColor((canUse==true?new Color(95, 158, 160):Color.gray));
    g.fillOval(0, 0, 31, 31);
    }
    }
      	
    	//TODO This is nothing and has to used sadly
    class NullSpot extends JComponent
    {
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    g.drawRect(0, 0, 31, 31);
    }
    }
    The Board class is where everything is drawn and circlePiece refers to each game piece that you're suppose to match. I already have written up a generating function from a previous project that replaces the pieces when needed. I'm just trying to make the pieces disappear when a match occurs. I have searched about this issue, but nothing tends to work. What am I doing wrong?


    EDIT: Been removed.
     

Share This Page