I'm using Java to make an n-puzzle game (see http://en.wikipedia.org/wiki/N-puzzle). I currently have it working within a JFrame such that the JFrame contains a JTextField which takes in the number of the tile to move, then moves it; a JTextArea which contains a string passed to it from a method which turns the contents of the puzzle(which is a 2-D array of objects called Tile); and a couple of JButtons to restart or reshuffle the puzzle. The code is below if you wish to try it (only works for square puzzles i.e. equal no. of rows and columns).
Here's my problem - I want to change the way the JFrame works so that instead of a TextArea and TextField I want it to have an array of JButtons instead which link to relevant tiles in the puzzle. Sorta like this;
PuzzleFrame thisPuzzleFrame = new PuzzleFrame(4, 4);
JButton[][] theseTiles = new JButton[4][4];
int p = 0, o = 0;
while (p < 4) {
for (int i = 0; i < 15; i++) {
for (o = 0; o < 4; o++) {
//link each button to an element of the PuzzleFrame Tile[][]
tiles[p][o] = new JButton(thisPuzzleFrame.Frame[p][o]); // this should refer a JButton to a Tile
tiles[p][o].setBounds(o, p, 4, 4);
tiles[p][o].setText(Tile.toString(thisPuzzleFrame.Frame[p][o]) // this sets the face on the button to be the number associated with the Tile in PuzzleFrame.Frame[p][o]
i++;
}
o = 0;
p++;
i--;
}
}
And then have an ActionListener which, when pressed, calls to the slideTile method in the PuzzleFrame class like this;
//set up ActionListener
PuzzleFrame.slideTile(thisPuzzleFrame, this); //method to slide the tile that has been pressed
However, I'm getting stuck trying to get any of this to work. If anyone could, I would love to learn how to link a JButton to a Tile like that, and find some dynamic way of adding any number of JButtons to a JFrame so that if the user wants to do a 5x5 puzzle, the relevant JButtons will appear on the JFrame in the correct places.
I'm not having any compiler problems etc. I am just asking about the theory of linking my object Tile to a JButton as is stated above. What follows is just snippets of the code as it is currently, in case it is needed
This should be the relevant methods and objects in case someone wishes to view them - they are not part of the question but merely background to it
public class GUI extends JFrame {
private static final long serialVersionUID = 1L;
public static JLabel label;
public static JTextField TextField;
public static JTextArea OutPut;
static int gRow, gColumn;
static PuzzleFrame thisPuzzleFrame;
public static JButton yes, no, shuffle, reset, setSolved;
public GUI() {
super("N Puzzle");
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.black);
setResizable(false);
setLayout(new FlowLayout());
label = new JLabel(
"Please enter the number of rows you would like to use: ");
add(label);
TextField = new JTextField(18);
add(TextField);
TextField.requestFocus();
TextField.setVisible(true);
final ActionListener InputListener1 = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
gRow = Integer.parseInt(GUI.TextField.getText());
label.setText("Please enter the number of columns you would like to use: ");
TextField.setText("");
ActionListener InputListener2 = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
gColumn = Integer.parseInt(GUI.TextField.getText());
label.setText("Please select the tile you wish to move: ");
shuffle.setVisible(true);
setSolved.setVisible(true);
reset.setVisible(true);
TextField.setText("");
thisPuzzleFrame = new PuzzleFrame(gRow, gColumn);
try {
PuzzleFrame.shufflePuzzle(GUI.thisPuzzleFrame,
100000);
} catch (Exception e) {
}
OutPut.setText(PuzzleFrame.toString(thisPuzzleFrame));
ActionListener InputListener3 = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int tileNo = Integer.parseInt(TextField
.getText());
try {
PuzzleFrame.findAndSlide(thisPuzzleFrame,
tileNo);
} catch (Exception e) {
}
OutPut.setText(PuzzleFrame
.toString(thisPuzzleFrame));
TextField.setText("");
TextField.removeAll();
TextField.addActionListener(InputListener3);
}
};
TextField.removeAll();
TextField.addActionListener(InputListener2);
}
};
TextField.addActionListener(InputListener1);
yes = new JButton("Yes");
no = new JButton("No");
yes.setVisible(false);
no.setVisible(false);
add(yes);
add(no);
}
public Tile(int rowIn, int columnIn, int no) {
row = rowIn;
column = columnIn;
Number = no;
}
public static String toString(Tile tile) {
String thisTile;
if (tile != PuzzleFrame.empty) {
thisTile = String.valueOf(tile.Number);
} else {
thisTile = " ";
}
return thisTile;
}
}
public class PuzzleFrame {
static Tile empty;
int rowLength, columnLength;
Tile[][] Frame;
public PuzzleFrame(int rows, int columns) {
rowLength = rows;
columnLength = columns;
Frame = MakePuzzleFrame(this);
}
public Tile[][] MakePuzzleFrame(PuzzleFrame thispuzzle) {
Tile[][] theTiles = new Tile[thispuzzle.rowLength][thispuzzle.columnLength];
int p = 0, o = 0;
while (p < thispuzzle.rowLength) {
for (int i = 0; i < ((thispuzzle.rowLength * thispuzzle.columnLength)); i++) {
for (o = 0; o < thispuzzle.columnLength; o++) {
Tile thisTile = new Tile(p, o, (i + 1));
thisTile.currentRow = p;
thisTile.currentColumn = o;
theTiles[p][o] = thisTile;
i++;
}
o = 0;
p++;
i--;
}
}
empty = new Tile(thispuzzle.rowLength - 1, thispuzzle.columnLength - 1,
0);
theTiles[thispuzzle.rowLength - 1][thispuzzle.columnLength - 1] = empty;
empty.currentColumn = thispuzzle.rowLength - 1;
empty.currentRow = thispuzzle.rowLength - 1;
return theTiles;
}
public static void slideTile(PuzzleFrame puzzle, Tile tile)
throws Exception {
switch (isMoveAllowed(puzzle, tile)) {
case 'D': {
puzzle.Frame[tile.currentRow + 1][tile.currentColumn] = tile;
puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
empty.currentColumn = tile.currentColumn;
empty.currentRow = tile.currentRow;
tile.currentRow = tile.currentRow + 1;
break;
}
case 'U': {
puzzle.Frame[tile.currentRow - 1][tile.currentColumn] = tile;
puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
empty.currentColumn = tile.currentColumn;
empty.currentRow = tile.currentRow;
tile.currentRow = tile.currentRow - 1;
break;
}
case 'L': {
puzzle.Frame[tile.currentRow][tile.currentColumn - 1] = tile;
puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
empty.currentColumn = tile.currentColumn;
empty.currentRow = tile.currentRow;
tile.currentColumn = tile.currentColumn - 1;
break;
}
case 'R': {
puzzle.Frame[tile.currentRow][tile.currentColumn + 1] = tile;
puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
empty.currentColumn = tile.currentColumn;
empty.currentRow = tile.currentRow;
tile.currentColumn = tile.currentColumn + 1;
break;
}
case 'N': {
GUI.OutPut.append("\nInvalid slide!");
}
}
}