0

我正在使用 DefaultTableModel 来显示一个简单的用户统计信息页面。我已成功将数据保存到文件中,但无法将其读回(参见loadData()底部的方法)。所以,我需要它做的是,当我启动我的程序时,它会读取文件,将值设置为模型并在表中显示现有数据(在 JPanel 中)。这是我的代码,它只是看起来“错误”,但我不确定在哪里。谁能给我一个提示?谢谢 IA

public class Statistics extends JPanel {
    public Object[][] data;
    public DefaultTableModel model;
    public PrintWriter saveStats;

public Statistics() {
    super(new GridLayout(1,0));
    String[] columnNames = {"Name", "Games Played", "Games Won"};
    Object[][] data = {};
    model = new DefaultTableModel(data, columnNames);
    JTable table = new JTable(model);
    table.setFillsViewportHeight(true);
    table.setVisible(true);
    table.setEnabled(false);

    JScrollPane scrollPane = new JScrollPane(table);
    add(scrollPane);
}

public void addRow(Object[] objects) {
    model.addRow(objects);

}

public void updateGamesPlayed(String userFolderName, int gamesPlayed) {
    int rowCount = model.getRowCount();
    int columnCount = model.getColumnCount();

    for (int i = 0; i < rowCount; i++){
        for(int j = 0; j < columnCount; j++){
            if (model.getValueAt(i,j) == userFolderName){
                int count = (Integer) model.getValueAt(i, j+1);
                count += gamesPlayed;
                model.setValueAt(gamesPlayed, i, j+1);
            }
        }
    }
    saveGameStats(model);
}

public void saveGameStats(DefaultTableModel model){
    this.model = model;

    File gameStats;
    try {
        gameStats = new File("GameStats.txt");


    System.out.print(gameStats);

    saveStats = new PrintWriter(gameStats);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    for (int i = 0; i < model.getRowCount(); i++){
        for (int j = 0; j < model.getColumnCount(); j++){
            saveStats.print(model.getValueAt(i,j)+ " ");
        }
    }
    saveStats.close();
}

public void loadData() {
    String name = "";
    int games = 0;
    int won = 0;
    Scanner loadData = new Scanner("GameStats.txt");
    while(loadData.hasNextLine()){
        if (loadData.hasNext()){
              name = loadData.next();}
            else if (loadData.hasNextInt()){
              games = loadData.nextInt();}
            else if (loadData.hasNextInt()){
              won = loadData.nextInt();}
        for (int i = 0; i < model.getRowCount(); i++){
            for (int j = 0; j < model.getColumnCount(); j++){
                model.setValueAt(name,i,j);
                model.setValueAt(games, i, j+1);
                model.setValueAt(won, i, j+2);
            }
        }
    }

}
}
4

2 回答 2

1

我会给你一些建议:

  • 正如在这个答案中指出的那样,您仍然有一个data被局部变量隐藏的类变量。

  • 请注意,您仍然不需要Object[][] data。您可以DefaultTableModel以这种方式初始化您的:model = new DefaultTableModel(columnNames, 0);并添加如下行:model.addRow(row),其中rowObject[].

  • 考虑使用 aSwingWorker将数据从文件加载到表模型。看看这个例子:简单的后台任务

  • 考虑使用BufferedReader而不是Scanner使用readLine()方法读取文件。我可以从您的代码中推断出文件的每一行都是表中的一行。获取该行,用空格分割这个字符串(你会得到一个String[])并将结果添加到你的模型中:model.addRow()

于 2013-10-23T13:25:15.850 回答
1

第一个问题:在您尝试加载数据时的 内部loadValue()函数,以下代码片段根本不起作用:

 for (int i = 0; i < model.getRowCount(); i++){
        for (int j = 0; j < model.getColumnCount(); j++){
            model.setValueAt(name,i,j);
            model.setValueAt(games, i, j+1);
               // ArrayIndexOutOfBoundsException exception when j = 2
            model.setValueAt(won, i, j+2); // same exception

        }
    }

您将获得 AIOutOfB-EX 的原因是,如果您有3列,则需要访问它们 index: 0-2inclusive。你根本不需要这个for循环。尝试逐行保存数据,并逐行加载它们,您已经有了一个功能:addRow(Object[] objects),使用它。

model.addRow(new Object[]{name, games, won})

games并且won是整数的实例。

第二个问题Data[][]local toStatistics()隐藏Data[][]了在类上下文中声明的字段成员。并且最好使用DefaultTableModel(Object[] columnNames, int rowCount)构造函数来创建模型。对于一个空表rowCount0;

第三个问题:在另一个线程中保存(或加载)您的数据并从那里更新 Swing 表。处理这项任务并不容易。SingWorker是你的朋友吗?查看教程:Worker Threads and SwingWorker

于 2013-10-23T13:50:50.790 回答