我使用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);
}
}
}
}
}
答案 0 :(得分:1)
我建议你提一些建议:
正如本answer所指出的那样,你仍然有一个由本地变量隐藏的类变量data
。
请注意,无论如何你都不需要Object[][] data
。您可以通过以下方式初始化DefaultTableModel
:model = new DefaultTableModel(columnNames, 0);
并添加以下行:model.addRow(row)
,其中row
为Object[]
。
考虑使用SwingWorker
将文件中的数据加载到表模型中。看一下这个例子:Simple Background Tasks
请考虑使用BufferedReader而不是Scanner
来使用readLine()方法读取文件。我可以从您的代码中推断出文件的每一行都是表格中的一行。通过空格获取行split此字符串(您将获得String[]
)并将结果添加到模型中:model.addRow()
答案 1 :(得分: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
列,则需要访问它们索引:0-2
。您根本不需要此for
循环。尝试逐行保存数据,然后逐行加载,你已经有了一个函数:addRow(Object[] objects)
,使用它。
model.addRow(new Object[]{name, games, won})
games
和won
是Integer的实例。
第二个问题:Data[][]
本地Statistics()
隐藏了在班级上下文中声明的字段成员Data[][]
。并且使用DefaultTableModel(Object[] columnNames, int rowCount)
构造函数来创建模型是可取的。对于空表rowCount
是0
;
第三个问题:将数据保存(或加载)到另一个线程中,并从那里更新Swing表。处理这项任务并不容易。 SingWorker
是你的朋友。查看教程:Worker Threads and SwingWorker