刷新后更新JTable

问题描述 投票:0回答:1

我有一个正在尝试更新的 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 方法应该可以解决这个问题。为什么不起作用?

java swing jtable
1个回答
0
投票

让我们检查一下你的代码...(它有一些小问题)。

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对象移动玩家,更改级别,创建新的DataState对象,分配它们,它只是缺少洗衣服......一堆任务。 您的代码创建了一个新的 State ,其中 cooldown - 1,我不清楚这是否反映在游戏中(在我看来,changeLevel 方法应该在其他类中)。 提示:重写你的代码(你几乎已经完成了所有事情),小类,小方法。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.