【发布时间】:2012-02-27 00:02:23
【问题描述】:
我正在使用 Java 制作一个 n-puzzle 游戏(请参阅http://en.wikipedia.org/wiki/N-puzzle)。 我目前让它在 JFrame 中工作,这样 JFrame 包含一个 JTextField,它接收要移动的瓷砖的数量,然后移动它;一个 JTextArea ,其中包含一个从转换拼图内容的方法传递给它的字符串(这是一个称为 Tile 的二维对象数组);和几个 JButtons 来重新启动或重新排列拼图。如果您想尝试,代码如下(仅适用于方形拼图,即行数和列数相等)。
这是我的问题 - 我想更改 JFrame 的工作方式,以便代替 TextArea 和 TextField 我希望它有一个 JButton 数组,而不是链接到拼图中的相关图块。有点像这样;
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--;
}
}
然后有一个 ActionListener,当按下它时,会像这样调用 PuzzleFrame 类中的 slideTile 方法;
//set up ActionListener
PuzzleFrame.slideTile(thisPuzzleFrame, this); //method to slide the tile that has been pressed
但是,我在试图让其中任何一项工作时遇到困难。如果有人可以,我很想学习如何将 JButton 链接到这样的 Tile,并找到一些将任意数量的 JButtons 添加到 JFrame 的动态方法,这样如果用户想要做一个 5x5 的拼图,相关的 JButtons 将出现在 JFrame 上的正确位置。
我没有遇到任何编译器问题等。我只是在询问将我的对象 Tile 链接到 JButton 的理论,如上所述。以下只是当前代码的 sn-ps,以备不时之需
这应该是相关的方法和对象,以防有人希望查看它们 - 它们不是问题的一部分,而只是问题的背景
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!");
}
}
}
【问题讨论】:
-
天哪,这很长。请将其编辑为相关部分。这可能需要您一点时间,但您可能会在此过程中找到答案。
-
@MichaelPetrotta 您无需通读最终代码区域中的代码 - 这不是问题,只是它的背景。我包含了完整的代码,这样如果有人想使用它就可以运行和编译它。上面我从程序中发布实际代码的所有内容都是完全有效的问题。
-
@MichaelPetrotta - 代码已被修剪为相关的方法和对象。对不起,时间太长了。如果还是太长,请随时告诉我,我会尽量缩短。
-
如需尽快获得更好的帮助,请发帖SSCCE。 (如果您想知道:不,将两个公共类混搭到一个 229 行的代码列表中是不是 SSCCE!)
-
请学习java命名约定并遵守它们
标签: java swing icons jbutton paintcomponent