PDA

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




jsmwoolf
Feb 19, 2012, 10:29 PM
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.
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?

Any help would be appreciated.
EDIT: None of the paintComponent methods from the Cell and Board features can be accessed after the board is drawn, so this is very weird.
EDIT #2: Found my problem in another section of code that did not have to do with drawing.
EDIT #3: Fixed! Error under my own code.