I'm a JavaScript coder trying to teach myself Java using online tutorials and ebooks. I have now created my very first applet but feel it only really goes to show the depth of my unappreciation for Java's capabilities. Please, give me some advice as to how to use Java better so that my future projects can be less effort to make, easier to read, easier to maintain and altogether more smoothly designed, just like Java apps are supposed to be.
How would you have implemented the following applet? What would you have done differently? I really don't know what I'm doing here and wish I did because I get the feeling Java's gonna be great once I'm approaching things more sensibly.
import java.applet.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
@SuppressWarnings("serial")
public class SlidePuzz extends Applet implements MouseMotionListener, MouseListener {
int gridDim = 3;
int animal = -1;
int pieceDim = 0;
int a; int b;
int gapX = -1; int gapY = -1;
int moveX = -1; int moveY = -1;
Image[][] pieces = new Image[7][7];
int[][] placement = new int[7][7];
String stage = "grid";
String[] imgUrl = { "7028/6814220663_4813a81531",
"7162/6814220921_acb3aa92ee", "7029/6814221019_41323ace8b" };
String imgUrlFlickr = "http://farm8.staticflickr.com/";
Image img;
MediaTracker tr;
public void init() {
setSize(420, 420);
addMouseMotionListener(this);
addMouseListener(this);
}
public void paint(Graphics g) {
if(stage=="grid") {
g.setColor(Color.lightGray);
g.fillRect(0,0,60*gridDim,60*gridDim);
g.setColor(Color.white);
g.fillRect(60*gridDim,0,(7-gridDim)*60,420);
g.fillRect(0,60*gridDim,60*gridDim,(7-gridDim)*60);
g.setColor(Color.black);
for (int i=1; i<7; i++) {
g.drawLine(i*60,0,i*60,460);
g.drawLine(0,i*60,460,i*60);
}
g.setColor(Color.black);
g.fillRect(120,0,180,20);
g.setColor(Color.white);
g.drawString("click to choose "+gridDim+"x"+gridDim+" grid", 145, 15);
} else if (stage=="animal") {
g.setColor(Color.white);
g.fillRect(0,0,420,420);
g.setColor(Color.black);
g.drawString("Please click an animal...", 80, 100);
g.setFont(new Font("Courier New", Font.BOLD, 22));
g.drawString("Mouse", 80, 150);
g.drawString("Cat", 80, 200);
g.drawString("Dog", 80, 250);
} else if (stage=="game") {
// download selected image and chop into pieces
if (gapX<0) {
g.setColor(Color.white);
g.fillRect(0,0,420,420);
g.setColor(Color.black);
g.setFont(new Font("Courier New", Font.PLAIN, 12));
g.drawString("Loading image...", 120, 50);
tr = new MediaTracker(this);
img = getImage(getCodeBase(), imgUrlFlickr+imgUrl[animal]+"_o.jpg");
tr.addImage(img,0);
try { tr.waitForID(0); }
catch (InterruptedException e) { e.printStackTrace(); }
for(int x=0; x<gridDim; x++) {
for(int y=0; y<gridDim; y++) {
pieces[x][y] = createImage(new FilteredImageSource(img.getSource(),
new CropImageFilter(x*pieceDim, y*pieceDim, pieceDim, pieceDim)));
placement[x][y] = (x==gridDim-1 && y==gridDim-1) ? -2 : -1;
tr.addImage(pieces[x][y],0);
}
}
try { tr.waitForID(0); }
catch (InterruptedException e) { e.printStackTrace(); }
Random r = new Random();
Boolean placed;
for(int x=0; x<gridDim; x++) {
for(int y=0; y<gridDim; y++) {
// if its the gap, no need to draw anything
if (placement[x][y]==-2) break;
// keep looping until piece is selected thats not already drawn
do {
do {
a = r.nextInt(gridDim);
b = r.nextInt(gridDim);
} while (a==gridDim-1 && b==gridDim-1);
placed = false;
for(int c=0; c<gridDim; c++) {
for(int d=0; d<gridDim; d++) {
if(placement[c][d]==a*10+b) placed=true;
}
}
} while (placed);
// draw on the screen and record what's gone here
g.drawImage(pieces[a][b], x*pieceDim, y*pieceDim, this);
placement[x][y] = a*10+b;
}
}
// record where the gap is
gapX = gridDim-1; gapY = gridDim-1;
// a piece needs to be moved
} else if (moveX>=0){
g.setColor(Color.white);
g.fillRect(moveX*pieceDim, moveY*pieceDim, pieceDim, pieceDim);
b = placement[moveX][moveY]%10;
a = (placement[moveX][moveY]-b)/10;
g.drawImage(pieces[a][b], gapX*pieceDim, gapY*pieceDim, this);
placement[gapX][gapY] = a*10+b;
placement[moveX][moveY] = -2;
gapX = moveX; gapY = moveY;
moveX = -1; moveY = -1;
// screen may need refreshing so draw all pieces again
} else {
for(int x=0; x<gridDim; x++) {
for(int y=0; y<gridDim; y++) {
if (placement[x][y]==-2) continue;
b = placement[x][y]%10;
a = (placement[x][y]-b)/10;
g.drawImage(pieces[a][b], x*pieceDim, y*pieceDim, this);
}
}
}
}
}
public void mouseMoved(MouseEvent me) {
if(stage=="grid") {
int mousePos = me.getX()>me.getY() ? me.getX() : me.getY();
int oldGridSize = gridDim;
gridDim = (mousePos/60)+1;
if(gridDim<3) gridDim=3;
if (gridDim!=oldGridSize) repaint();
}
}
public void mousePressed (MouseEvent me) {
int x = me.getX();
int y = me.getY();
if(stage=="grid") {
stage = "animal";
repaint();
} else if(stage=="animal") {
if(x<150 && x>80 && y<150 && y>130) animal=0;
else if(x<150 && x>80 && y<200 && y>180) animal=1;
else if(x<150 && x>80 && y<250 && y>130) animal=2;
if (animal>-1) {
stage="game";
pieceDim = 420/gridDim;
repaint();
}
} else if(stage=="game") {
x /= pieceDim;
y /= pieceDim;
Boolean right = (x-1==gapX && y==gapY);
Boolean left = (x+1==gapX && y==gapY);
Boolean down = (x==gapX && y-1==gapY);
Boolean up = (x==gapX && y+1==gapY);
if (right || left || down || up) {
moveX = x;
moveY = y;
repaint();
}
}
}
public void update(Graphics g) { paint(g); }
public void mouseDragged (MouseEvent me) {}
public void mouseExited (MouseEvent me) {}
public void mouseEntered (MouseEvent me) {}
public void mouseClicked (MouseEvent me) {}
public void mouseReleased (MouseEvent me) {}
}