重新调用时JTable不重绘

时间:2014-12-06 17:43:17

标签: java swing jtable repaint

嗨我的计数器事件发生时我的数据表没有重新绘制时遇到困难。我正在检查我正在制作的游戏中的玩家连接性。当玩家连接JTable时应改变以显示玩家已连接;但是,即使填充表格的变量正在发生变化,表格也不会改变。

我的GUI代码链接如下,基本上当播放器连接时,GUI代码中的字符串变量发生变化,然后我的计时器应该每秒重绘一次表并注意到更改并使用正确的信息重绘。变量正在变化,我可以在控制台中看到输出,但表格不会相应更新。

感谢您的关注。

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

@SuppressWarnings("serial")
public class DPServerGUI extends JFrame implements ActionListener
{
  private DPServerTest mainServer;

  private JPanel serverPanel;
  private JButton startButton;
  private JButton loadServerButton;
  private JLabel serverLabel;
  String[] header = {"Players", "Connected To Server"};
  private JTable connectedClientsList;
  private DefaultTableModel tableModel;
  private JScrollPane scrollPane;
  private static Dimension dim;
  private Timer timer;
  public static String player1Connected = "No";
  public static String player2Connected = "No";
  public static String player3Connected = "No";
  public static String player4Connected = "No";

  public DPServerGUI()
  {
    serverPanel = new JPanel();

    startButton = new JButton("Start Game");
    startButton.addActionListener(this);

    loadServerButton = new JButton("Load Server");
    loadServerButton.addActionListener(this);

    tableModel =  new DefaultTableModel();
    scrollPane = new JScrollPane(getTable());

    serverLabel = new JLabel("Server Not Running");
    dim = Toolkit.getDefaultToolkit().getScreenSize();

    serverPanel.add(serverLabel);
    serverPanel.add(startButton);
    serverPanel.add(loadServerButton);
    serverPanel.add(scrollPane);
    this.add(serverPanel);
  }

  private JTable getTable()
  {
    String[][] table = 
    {
        {"Player 1", player1Connected},
        {"Player 2", player2Connected},
        {"Player 3", player3Connected},
        {"Player 4", player4Connected}
    };
    connectedClientsList = new JTable(table, header);
    return connectedClientsList;
  }
  public void updatePlayerList()
  {
    String [][] playerList = mainServer.exportPlayerList();
    connectedClientsList = new JTable(playerList, header);
  }
  @Override
  public void actionPerformed(ActionEvent event)
  {
    if (event.getSource() == loadServerButton)
    {
      System.out.println("Load server clicked!");
      loadServerButton.setEnabled(false);
      mainServer = new DPServerTest(8888);
      serverLabel.setText("Server Loaded!");
      timer = new Timer(1000, this);
      timer.start();
    }
    if (event.getSource() == startButton)
    {
      serverLabel.setText("Game Started");
    }
    if (event.getSource() == timer)
    {
      mainServer.playerConnectionStatus();
      String[][] table = 
        {
            {"Player 1", player1Connected},
            {"Player 2", player2Connected},
            {"Player 3", player3Connected},
            {"Player 4", player4Connected}
        };
      connectedClientsList = new JTable(table, header);
      if (player1Connected != "No") System.out.println(player1Connected);
      repaint();
    }
  }

  public static void main(String[] args)
  {
    DPServerGUI serverGUI = new DPServerGUI();
    serverGUI.setTitle("Dark Project Server GUI");
    serverGUI.setSize(800,600);
    serverGUI.setLocationRelativeTo(null);
    serverGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    serverGUI.setVisible(true);
  }
}

1 个答案:

答案 0 :(得分:5)

问题在于您正在重新创建新的JTable而不是重新使用现有的TableModel(此外,您不会删除旧的替换它以替换新的,所以新的没有机会被展示过。)

而是更新JTable的{​​{1}}。使用提供的默认值(您可以通过调用JTable.getModel()来获取)DefaultTableModel或通过扩展AbstractTableModel(以及调用fireXXX()方法)来实现您自己的方法可以使用JTable.setModel()进行设置。

查看How to use tables上的Swing教程,尤其是TableModel

上的部分

其他提示:远离static变量,他们总是受伤。

稍微更新的代码(不是特别漂亮,但显示了这个想法):

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.table.AbstractTableModel;

@SuppressWarnings("serial")
public class DPServerGUI extends JFrame {

    private JPanel serverPanel;
    private JButton startButton;
    private JButton loadServerButton;
    private JLabel serverLabel;

    private JTable connectedClientsList;
    private JScrollPane scrollPane;
    public String player1Connected = "No";
    public String player2Connected = "No";
    public String player3Connected = "No";
    public String player4Connected = "No";

    public DPServerGUI() {
        serverPanel = new JPanel();

        startButton = new JButton("Start Game");

        loadServerButton = new JButton("Load Server");

        scrollPane = new JScrollPane(getTable());

        serverLabel = new JLabel("Server Not Running");

        serverPanel.add(serverLabel);
        serverPanel.add(startButton);
        serverPanel.add(loadServerButton);
        serverPanel.add(scrollPane);
        this.add(serverPanel);
    }

    private PlayerTableModel tableModel;

    public class PlayerTableModel extends AbstractTableModel {

        private String[] header = { "Players", "Connected To Server" };
        private String[][] table = { { "Player 1", player1Connected }, { "Player 2", player2Connected }, { "Player 3", player3Connected },
                { "Player 4", player4Connected } };

        @Override
        public String getColumnName(int column) {
            return header[column];
        }

        @Override
        public int getRowCount() {
            return table.length;
        }

        @Override
        public int getColumnCount() {
            return header.length;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return table[rowIndex][columnIndex];
        }

        public void setPlayerConnected(int rowIndex, boolean connected) {
            table[rowIndex][1] = connected ? "Yes" : "No";
            fireTableCellUpdated(rowIndex, 1);
        }

    }

    private JTable getTable() {
        tableModel = new PlayerTableModel();
        connectedClientsList = new JTable(tableModel);
        return connectedClientsList;
    }

    public static void main(String[] args) {
        final DPServerGUI serverGUI = new DPServerGUI();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                serverGUI.setTitle("Dark Project Server GUI");
                serverGUI.setSize(800, 600);
                serverGUI.setLocationRelativeTo(null);
                serverGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                serverGUI.setVisible(true);
            }
        });

        // Dummy thread that simulates user connecting and disconnecting randomly.
        Timer t = new Timer(2000, new ActionListener() {

            Random random = new Random();

            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < serverGUI.tableModel.getRowCount(); i++) {
                    serverGUI.tableModel.setPlayerConnected(i, random.nextBoolean());
                }

            }
        });
        t.start();
    }

}