Using repaint() method.
- by owca
I'm still struggling to create this game : http://stackoverflow.com/questions/2844190/choosing-design-method-for-ladder-like-word-game .I've got it almost working but there is a problem though. When I'm inserting a word and it's correct, the whole window should reload, and JButtons containing letters should be repainted with different style. But somehow repaint() method for the game panel (in Main method) doesn't affect it at all. What am I doing wrong ? Here's my code:
Main:
import java.util.Scanner;
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args){
final JFrame f = new JFrame("Ladder Game");
Scanner sc = new Scanner(System.in);
System.out.println("Creating game data...");
System.out.println("Height: ");
//setting height of the grid
while (!sc.hasNextInt()) {
System.out.println("int, please!");
sc.next();
}
final int height = sc.nextInt();
/*
* I'm creating Grid[]game. Each row of game contains Grid of Element[]line.
* Each row of line contains Elements, which are single letters in the game.
*/
Grid[]game = new Grid[height];
for(int L = 0; L < height; L++){
Grid row = null;
int i = L+1;
String s;
do {
System.out.println("Length "+i+", please!");
s = sc.next();
} while (s.length() != i);
Element[] line = new Element[s.length()];
Element single = null;
String[] temp = null;
String[] temp2 = new String[s.length()];
temp = s.split("");
for( int j = temp2.length; j>0; j--){
temp2[j-1] = temp[j];
}
for (int k = 0 ; k < temp2.length ; k++) {
if( k == 0 ){
single = new Element(temp2[k], 2);
}
else{
single = new Element(temp2[k], 1);
}
line[k] = single;
}
row = new Grid(line);
game[L] = row;
}
//############################################
//THE GAME STARTS HERE
//############################################
//create new game panel with box layout
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBackground(Color.ORANGE);
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
//for each row of the game array add panel containing letters Single panel
//is drawn with Grid's paint() method and then returned here to be added
for(int i = 0; i < game.length; i++){
panel.add(game[i].paint());
}
f.setContentPane(panel);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
boolean end = false;
boolean word = false;
String text;
/*
* Game continues until solved() returns true. First check if given word matches the length,
* and then the value of any row. If yes - change state of each letter from EMPTY
* to OTHER_LETTER. Then repaint the window.
*/
while( !end ){
while( !word ){
text = JOptionPane.showInputDialog("Input word: ");
for(int i = 1; i< game.length; i++){
if(game[i].equalLength(text)){
if(game[i].equalValue(text)){
game[i].changeState(3);
f.repaint();
//simple debug - I'm checking if letter, and
//state values for each Element are proper
for(int k=0; k<=i; k++){
System.out.print(game[k].e[k].letter());
}
System.out.println();
for(int k=0; k<=i; k++){
System.out.print(game[k].e[k].getState());
}
System.out.println();
//set word to true and ask for another word
word = true;
}
}
}
}
word = false;
//check if the game has ended
for(int i = 0; i < game.length; i++){
if(game[i].solved()){
end = true;
}
else {
end = false;
}
}
}
}
}
Element:
import javax.swing.*;
import java.awt.*;
public class Element {
final int INVISIBLE = 0;
final int EMPTY = 1;
final int FIRST_LETTER = 2;
final int OTHER_LETTER = 3;
private int state;
private String letter;
public Element(){
}
//empty block
public Element(int state){
this("", 0);
}
//filled block
public Element(String s, int state){
this.state = state;
this.letter = s;
}
public JButton paint(){
JButton button = null;
if( state == EMPTY ){
button = new JButton(" ");
button.setBackground(Color.WHITE);
}
else if ( state == FIRST_LETTER ){
button = new JButton(letter);
button.setBackground(Color.red);
}
else {
button = new JButton(letter);
button.setBackground(Color.yellow);
}
return button;
}
public void changeState(int s){
state = s;
}
public void setLetter(String s){
letter = s;
}
public String letter(){
return letter;
}
public int getState(){
return state;
}
}
Grid:
import javax.swing.*;
import java.awt.*;
public class Grid extends JPanel{
public Element[]e;
private Grid[]g;
public Grid(){}
public Grid( Element[]elements ){
e = new Element[elements.length];
for(int i=0; i< e.length; i++){
e[i] = elements[i];
}
}
public Grid(Grid[]grid){
g = new Grid[grid.length];
for(int i=0; i<g.length; i++){
g[i] = grid[i];
}
Dimension d = new Dimension(600, 600);
setMinimumSize(d);
setPreferredSize(new Dimension(d));
setMaximumSize(d);
}
//for Each element in line - change state to i
public void changeState(int i){
for(int j=0; j< e.length; j++){
e[j].changeState(3);
}
}
//create panel which will be single row of the game. Add elements to the panel.
// return JPanel to be added to grid.
public JPanel paint(){
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, e.length));
panel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
for(int j = 0; j < e.length; j++){
panel.add(e[j].paint());
}
return panel;
}
//check if the length of given string is equal to length of row
public boolean equalLength(String s){
int len = s.length();
boolean equal = false;
for(int j = 0; j < e.length; j++){
if(e.length == len){
equal = true;
}
}
return equal;
}
//check if the value of given string is equal to values of elements in row
public boolean equalValue(String s){
int len = s.length();
boolean equal = false;
String[] temp = null;
String[] temp2 = new String[len];
temp = s.split("");
for( int j = len; j>0; j--){
temp2[j-1] = temp[j];
}
for(int j = 0; j < e.length; j++){
if( e[j].letter().equals(temp2[j]) ){
equal = true;
}
else {
equal = false;
}
}
if(equal){
for(int i = 0; i < e.length; i++){
e[i].changeState(3);
}
}
return equal;
}
//check if the game has finished
public boolean solved(){
boolean solved = false;
for(int j = 0; j < e.length; j++){
if(e[j].getState() == 3){
solved = true;
}
else {
solved = false;
}
}
return solved;
}
}