我有一个正在尝试更新的 JTable。
GUI 类有 2 个表。 SmallTable 在窗口顶部显示 2 个值,而 table 显示 2D 数组。
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class GUI extends JFrame {
private data boardData;
private int lines;
private int cols;
private int windowWidth;
private int windowHeight;
public GUI(data boardData) {
this.boardData = boardData;
this.lines = boardData.getState().monsters.length;
this.cols = boardData.getState().monsters[0].length;
windowWidth = boardData.getBoard()[0].length * 50;
windowHeight = boardData.getBoard().length * 50;
setTitle("Title");
setSize(windowWidth, windowHeight);
setResizable(true);
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
windowWidth = getWidth();
windowHeight = getHeight();
updateData(boardData);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultTableModel tableModel = new DefaultTableModel(boardData.getBoard().length, boardData.getBoard()[0].length);
JTable table = new JTable(tableModel) {
@Override
public Class<?> getColumnClass(int column) {
return Object.class;
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public boolean isCellSelected(int row, int column){
return false;
}
};
table.setCellSelectionEnabled(false);
table.setFocusable(false);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().clearSelection();
table.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent e) {
table.clearSelection();
}
});
for (int i = 0; i < boardData.getBoard().length; i++) {
for (int j = 0; j < boardData.getBoard()[i].length; j++) {
int value = boardData.getBoard()[i][j];
table.setValueAt(String.valueOf(value), i, j);
}
}
DefaultTableModel smallTableModel = new DefaultTableModel(2, 1);
JTable smallTable = new JTable(smallTableModel) {
@Override
public Class<?> getColumnClass(int column) {
return Object.class;
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
smallTable.setCellSelectionEnabled(false);
smallTable.setFocusable(false);
smallTable.setValueAt("Health: " + boardData.getState().health, 0, 0);
smallTable.setValueAt("Cooldown: " + boardData.getState().cooldown, 1, 0);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setFocusable(false);
panel.add(smallTable);
panel.add(table);
JScrollPane scrollPane = new JScrollPane(panel);
add(scrollPane);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
boolean moved = false;
boolean cd = false;
switch (key) {
case KeyEvent.VK_DOWN:
moved = boardData.movePlayer(0, 1);
break;
case KeyEvent.VK_H:
cooldown = boardData.helpPlayer(boardData.getState().cooldown);
break;
}
if (moved) {
for (int i = 0; i < boardData.getBoard().length; i++) {
for (int j = 0; j < boardData.getBoard()[i].length; j++) {
int value = boardData.getBoard()[i][j];
table.setValueAt(String.valueOf(value), i, j);
}
}
updateData(boardData);
} else if(cd){
boardData.getState().cooldown += 2;
smallTable.setValueAt("cooldown: " + boardData.getState().cooldown, 2, 0);
}
}
});
setFocusable(false);
}
public void updateData(data newBoardData) {
this.boardData = newBoardData;
setSize(windowWidth, windowHeight);
JTable table = (JTable) ((JPanel) ((JScrollPane) getContentPane().getComponent(0)).getViewport().getView()).getComponent(1);
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
tableModel.setRowCount(boardData.getBoard().length);
tableModel.setColumnCount(boardData.getBoard()[0].length);
for (int i = 0; i < boardData.getBoard().length; i++) {
for (int j = 0; j < boardData.getBoard()[i].length; j++) {
int value = boardData.getBoard()[i][j];
table.setValueAt(String.valueOf(value), i, j);
}
}
setFocusable(true);
requestFocus();
JTable smallTable = (JTable) ((JPanel) ((JScrollPane) getContentPane().getComponent(0)).getViewport().getView()).getComponent(0);
smallTable.setValueAt("health: " + boardData.getState().health, 0, 0);
smallTable.setValueAt("Health: " + boardData.getState().cooldown, 1, 0);
}
}
Data 类负责级别转换:
public class Data {
private int width;
private int height;
private int[][] board;
private int posX, posY;
private State state;
private int[][] board1;
private int[][] board2;
private int cooldown;
private GUITable gui;
public Data(State state) {
this.width = state.board2[0].length;
this.height = state.board2.length;
board = new int[height][width];
posX = state.heroPos[1];
posY = state.heroPos[0];
this.state = state;
board1 = state.board1;
board2 = state.board2;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (board1[i][j] != 0){
board[i][j] = -1 * board1[i][j];
} else if(board2[i][j] != 0){
board[i][j] = board2[i][j];
}
}
}
board[posY][posX] = 2;
this.cooldown = state.cooldown;
}
public int[][] getBoard() {
return board;
}
public int getPosX() {
return posX;
}
public int getPosY() {
return posY;
}
public State getState() {
return this.state;
}
public void setState(State newState) {
this.state = newState;
}
public void setPlayerPos(int x, int y) {
board[y][x] = 2;
posX = x;
posY = y;
}
public void erasePlayerPos(int x, int y) {
board[y][x] = 0;
}
public boolean movePlayer(int dx, int dy) {
int newX = posX + dx;
int newY = posY + dy;
if (newX < 0 || newX >= width || newY < 0 || newY > height || dy == -1) {
return false;
}
if (dx == 1) {
if (movedLeft) {
return false;
}
movedRight = true;
}
if (dx == -1) {
if (movedRight) {
return false;
}
movedLeft = true;
}
if (dy == 1 && posY == height - 1) {
changeLevel();
} else {
erasePlayerPos(posX, posY);
setPlayerPos(newX, newY);
}
return true;
}
public void changeLevel(){
erasePlayerPos(posX, posY);
width += 1;
height += 1;
int[][] newboard1 = new int[height][width];
int[][] newboard2 = new int[height][width];
int[][] newLevel = new int[height][width];
for (int i = 0; i < height - 1; i++) {
for (int j = 0; j < width - 1; j++) {
newLevel[i][j] = newboard2[i][j] - newboard1[i][j];
}
}
posY = 0;
int[] newPos = {posY, posX};
newLevel[newPos[0]][newPos[1]] = 2;
board = newLevel;
int health = this.state.heroHealth;
if(cooldown > 0){
cooldown -= 1;
}
State newState = new State(newPos, health, newboard1, newboard2, cooldown);
Data newData = new Data(newState);
gui.setData(newData);
gui.updateData(newData);
newData.setGui(gui);
if(gui != null){
gui.updateData(newData);
}
}
public void setGui(GUITable gui) {
this.gui = gui;
}
}
State 类有几个字段,基本上是用来模仿结构的:
public class State {
int[] pos;
int health;
int[][] board1;
int[][] board2;
int cooldown;
public State(int[] pos, int health, int[][] board1, int[][] board2, int cooldown) {
this.pos = pos;
this.health = health;
this.board1 = board1;
this.board2 = board2;
this.cooldown = cooldown;
}
}
在main方法中,GUI是这样启动的:
State state = new State(new int[]{0, 3}, 100, board1, board2, 0);
Data data = new Data(state);
SwingUtilities.invokeLater(() -> {
GUI gui = new GUI(data);
data.setGui(gui);
gui.setVisible(true);
});
当玩家按下桌子底部的向下箭头时,他们会进入下一个级别。如果他们按“H”,冷却时间就会增加,并且smallTable的单元格会发生变化以反映这一点。我的问题是,当玩家达到下一个级别时,冷却时间并没有减少。 changeLevel 方法应该可以解决这个问题。为什么不起作用?
让我们检查一下你的代码...(它有一些小问题)。
int[][] newboard1 = new int[ height ][ width ];
int[][] newboard2 = new int[ height ][ width ];
int[][] newLevel = new int[ height ][ width ];
for( int i = 0; i < height - 1; i ++ ) {
for( int j = 0; j < width - 1; j ++ ) {
newLevel[ i ][ j ] = newboard2[ i ][ j ] - newboard1[ i ][ j ];
}
}
当您像前面几行一样创建一个数组时,您创建了一个用“0”填充的数组,因此,您创建了三个用零填充的数组,然后,您分配给第三个数组......减法......他们生来就是“0”,并以“0”延续。
int[][] newboard1 = new int[ height ][ width ];
int[][] newboard2 = new int[ height ][ width ];
int[][] newLevel = new int[ height ][ width ];
仅此而已。
几行之后,我们发现:
int health = this.state.heroHealth;
State还没有heroHealth属性。
然后我们有:
State newState = new State( newPos, health, newboard1, newboard2, cooldown );
Data newData = new Data( newState );
gui.setData( newData );
gui.updateData( newData );
newData.setGui( gui );
if( gui != null ) {
gui.updateData( newData );
}
Data对象创建一个新的Data对象并将其分配给“GUI*,执行update(最后两个我们不知道它们做什么,因为未显示GUITable类),将 GUI 分配给新对象,然后重复该操作,验证该对象不为 null(它没有执行之前)...
我认为你最大的问题是你的编码方式,“不”任务分离,在这里,
Data对象移动玩家,更改级别,创建新的Data和State对象,分配它们,它只是缺少洗衣服......一堆任务。
您的代码创建了一个新的 State ,其中 cooldown - 1,我不清楚这是否反映在游戏中(在我看来,changeLevel 方法应该在其他类中)。
提示:重写你的代码(你几乎已经完成了所有事情),小类,小方法。