如何在 JTable 中使用 JFileChooser 到 select 文件并在 JTable 中显示数据
How to use JFileChooser in a JTable to select files and display data in the JTable
我正在尝试实现 JFileChooser 以便能够 select 来自另一个程序制作的两个 .txt 文件。我创建了一个相当简单的 JTable,它将根据我给它的路径从其中一个 .txt 文件加载数据。但是我不知道如何使 JTable 实现 JFileChooser 能够 select 任一文件并将数据显示在正确的单元格中。下面是 JTable 的代码和来自其中一个文件的一小部分数据示例
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
public class Maingui {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
new Maingui().createUI();
}
};
EventQueue.invokeLater(r);
}
private void createUI() {
try {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
JTable table = new JTable();
TableModel tableModel = new TableModel();
BufferedReader file = new BufferedReader(new FileReader("/Users/Will/Desktop/BenchmarkSortIterative.txt"));
String line;
file.readLine();
List<Line> iterativeList = new ArrayList<Line>();
while((line = file.readLine()) != null) {
String splits[] = line.split(" ");
String digits = line.replaceAll("[^0-9.]", "");
}
tableModel.setList(iterativeList);
table.setModel(tableModel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.setTitle("Benchmark Sorter");
frame.pack();
frame.setVisible(true);
} catch(IOException ex) {}
}
class Line {
private int size;
private int avgCount;
private int coefCount;
private int avgTime;
private int coefTime;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getAvgCount() {
return avgCount;
}
public void setAvgCount(int avgCount) {
this.avgCount = avgCount;
}
public int getCoefCount() {
return coefCount;
}
public void setCoefCount(int coefCount) {
this.coefCount = coefCount;
}
public int getAvgTime() {
return avgTime;
}
public void setAvgTime(int avgTime) {
this.avgTime = avgTime;
}
public int getCoefTime() {
return coefTime;
}
public void getCoefTime(int coefTime) {
this.coefTime = coefTime;
}
}
class TableModel extends AbstractTableModel {
private List<Line> list = new ArrayList<Line>();
private String[] columnNames = { "Size", "Avg Count", "Coef Count", "Avg Time", "Coef Time"};
public void setList(List<Line> list) {
this.list = list;
fireTableDataChanged();
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
public int getRowCount() {
return list.size();
}
public int getColumnCount() {
return columnNames.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return list.get(rowIndex).getSize();
default:
return null;
}
}
}
}
来自 .txt 的数据
Data Set Size (n): 100
Iterative Selection Sort Results:
Average Critical Operation Count: 1090
Standard Deviation of Count: 770
Average Execution Time: 10340
JFileChooser 确实与问题无关。
您需要开始学习如何使用文件中的数据创建 List<Line>
ArrayList,以便调用 setList()
方法。
首先对您要阅读的文件名进行硬编码。然后创建一个BufferedReader来读取文件。
然后对于文件中的每一行数据,您将:
- 解析数据以获得您的大小、计数和时间值
- 使用上面的值创建
Line
对象的实例
- 将
Line
对象添加到您的 ArrayList
当您读完文件后,您可以在 StudentTableModel
.
上调用 setList(…)
方法
因此,首先使用硬编码文件名使上述逻辑起作用。然后一旦成功,您就可以使用 JFileChooser 动态获取文件名。
编辑:
I am not sure if I am parsing the data correctly
告诉我们您发布的代码如何创建 Line
对象。
为什么要对“ ”执行 split()。在我看来,数据是由“:”分隔的。
根据似乎有 5 行数据的文件格式,您需要单独解析,因此您的代码需要类似于:
String[] line1 = file.readLine().split(":");
String[] line2 = file.readLine().split(":");
String[] line3 = file.readLine().split(":");
String[] line4 = file.readLine().split(":");
String[] line5 = file.readLine().split(":");
Line line = new Line();
line.setSize( Integer.parseInt(line1[1].trim()) );
…
line.setAvgTime( Integer.parseInt(line5[1].trim()) );
iterativeList.add( line );
tableModel.setList( iterativeList );
免责声明:此答案最初由同一用户发布到 duplicate question,因此为了将来的读者,我将其重新发布到此处以将所有内容保留在同一位置。
在开始解决主要问题之前,您有多个问题需要解决 -- 您发布的代码甚至无法编译。
下面是您的代码。你能发现问题吗?
public void getCoefTime(int coefTime) {
this.coefTime = coefTime;
}
它应该如下所示(你的编译器会提醒你这个问题):
// this method should be a setter not a getter
// your code called for setCoefTime(), but that method didn't exist
public void setCoefTime(int coefTime) {
this.coefTime = coefTime;
}
您的 table 模型缺少强制方法。任何时候创建扩展接口的实现时,都需要实现该接口的所有方法签名。在你的情况下,你缺少以下方法,你的编译器会再次警告你这个问题:
@Override
public int getColumnCount()
{
return columnNames.length;
}
您的数据文件的组织方式不尽如人意。你似乎把它写得好像它的主要功能是向人提供信息,而不是向程序提供信息,所以你有这些漂亮的垂直方向而不是水平方向的标签,即使你希望你的 JTable
水平显示。
而不是
Average Critical Operation Count: 30791
Standard Deviation of Count: 32884
Average Execution Time: 282750
Standard Deviation of Time: 241038
您应该有一个逗号分隔值 (CSV) 文件,例如
trial 1,30791,32884,282750,241038
trial 2,30791,32884,282750,241038
trial 3,30791,32884,282750,241038
trial 4,30791,32884,282750,241038
您得到 ArrayIndexOutOfBoundsException
因为您的代码正在读取行
Recursive Selection Sort Results:
as line1
,而当你调用 line1[1]
时,那里什么也没有。你 split
在冒号上,但是冒号右边没有任何东西,所以 split
方法不会费心去创建一个新的标记。
摆脱所有好的 headers 之类的,因为你只需要阅读这些行并在以后扔掉它们——它们比无用更糟糕,因为它们实际上会在你的代码没有出现时引入问题'预料到他们的存在。
现在,您的文件读取代码似乎是基于对文件读取方式的误解。无论您目前对文件读取的理解是什么,忘掉它并假装您以前从未听说过它。目标是一行一行地读取行,将行分解成数据块(我们称它们为标记)并将它们打包成 Line
object,然后再移动到下一行——我们这里不是一次读五行。
一旦您明智地组织输入数据,就不再需要这种东西了:
String[] line1 = file.readLine().split(":");
String[] line2 = file.readLine().split(":");
String[] line3 = file.readLine().split(":");
String[] line4 = file.readLine().split(":");
String[] line5 = file.readLine().split(":");
现在,您所要做的就是这样:
while((line = bufferedReader.readLine()) != null)
{
// for purposes of clarity, we're changing the name of your Line object
// in this example to TrialRecord
String[] tokens = line.split(",");
TrialRecord record = new TrialRecord();
record.setSize( Integer.parseInt(tokens[0]));
// the rest of your code...
}
解决所有这些问题,您的 table 将显示您的数据。
我正在尝试实现 JFileChooser 以便能够 select 来自另一个程序制作的两个 .txt 文件。我创建了一个相当简单的 JTable,它将根据我给它的路径从其中一个 .txt 文件加载数据。但是我不知道如何使 JTable 实现 JFileChooser 能够 select 任一文件并将数据显示在正确的单元格中。下面是 JTable 的代码和来自其中一个文件的一小部分数据示例
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
public class Maingui {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
new Maingui().createUI();
}
};
EventQueue.invokeLater(r);
}
private void createUI() {
try {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
JTable table = new JTable();
TableModel tableModel = new TableModel();
BufferedReader file = new BufferedReader(new FileReader("/Users/Will/Desktop/BenchmarkSortIterative.txt"));
String line;
file.readLine();
List<Line> iterativeList = new ArrayList<Line>();
while((line = file.readLine()) != null) {
String splits[] = line.split(" ");
String digits = line.replaceAll("[^0-9.]", "");
}
tableModel.setList(iterativeList);
table.setModel(tableModel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.setTitle("Benchmark Sorter");
frame.pack();
frame.setVisible(true);
} catch(IOException ex) {}
}
class Line {
private int size;
private int avgCount;
private int coefCount;
private int avgTime;
private int coefTime;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getAvgCount() {
return avgCount;
}
public void setAvgCount(int avgCount) {
this.avgCount = avgCount;
}
public int getCoefCount() {
return coefCount;
}
public void setCoefCount(int coefCount) {
this.coefCount = coefCount;
}
public int getAvgTime() {
return avgTime;
}
public void setAvgTime(int avgTime) {
this.avgTime = avgTime;
}
public int getCoefTime() {
return coefTime;
}
public void getCoefTime(int coefTime) {
this.coefTime = coefTime;
}
}
class TableModel extends AbstractTableModel {
private List<Line> list = new ArrayList<Line>();
private String[] columnNames = { "Size", "Avg Count", "Coef Count", "Avg Time", "Coef Time"};
public void setList(List<Line> list) {
this.list = list;
fireTableDataChanged();
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
public int getRowCount() {
return list.size();
}
public int getColumnCount() {
return columnNames.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return list.get(rowIndex).getSize();
default:
return null;
}
}
}
}
来自 .txt 的数据
Data Set Size (n): 100
Iterative Selection Sort Results:
Average Critical Operation Count: 1090
Standard Deviation of Count: 770
Average Execution Time: 10340
JFileChooser 确实与问题无关。
您需要开始学习如何使用文件中的数据创建 List<Line>
ArrayList,以便调用 setList()
方法。
首先对您要阅读的文件名进行硬编码。然后创建一个BufferedReader来读取文件。
然后对于文件中的每一行数据,您将:
- 解析数据以获得您的大小、计数和时间值
- 使用上面的值创建
Line
对象的实例 - 将
Line
对象添加到您的 ArrayList
当您读完文件后,您可以在 StudentTableModel
.
setList(…)
方法
因此,首先使用硬编码文件名使上述逻辑起作用。然后一旦成功,您就可以使用 JFileChooser 动态获取文件名。
编辑:
I am not sure if I am parsing the data correctly
告诉我们您发布的代码如何创建 Line
对象。
为什么要对“ ”执行 split()。在我看来,数据是由“:”分隔的。
根据似乎有 5 行数据的文件格式,您需要单独解析,因此您的代码需要类似于:
String[] line1 = file.readLine().split(":");
String[] line2 = file.readLine().split(":");
String[] line3 = file.readLine().split(":");
String[] line4 = file.readLine().split(":");
String[] line5 = file.readLine().split(":");
Line line = new Line();
line.setSize( Integer.parseInt(line1[1].trim()) );
…
line.setAvgTime( Integer.parseInt(line5[1].trim()) );
iterativeList.add( line );
tableModel.setList( iterativeList );
免责声明:此答案最初由同一用户发布到 duplicate question,因此为了将来的读者,我将其重新发布到此处以将所有内容保留在同一位置。
在开始解决主要问题之前,您有多个问题需要解决 -- 您发布的代码甚至无法编译。
下面是您的代码。你能发现问题吗?
public void getCoefTime(int coefTime) {
this.coefTime = coefTime;
}
它应该如下所示(你的编译器会提醒你这个问题):
// this method should be a setter not a getter
// your code called for setCoefTime(), but that method didn't exist
public void setCoefTime(int coefTime) {
this.coefTime = coefTime;
}
您的 table 模型缺少强制方法。任何时候创建扩展接口的实现时,都需要实现该接口的所有方法签名。在你的情况下,你缺少以下方法,你的编译器会再次警告你这个问题:
@Override
public int getColumnCount()
{
return columnNames.length;
}
您的数据文件的组织方式不尽如人意。你似乎把它写得好像它的主要功能是向人提供信息,而不是向程序提供信息,所以你有这些漂亮的垂直方向而不是水平方向的标签,即使你希望你的 JTable
水平显示。
而不是
Average Critical Operation Count: 30791
Standard Deviation of Count: 32884
Average Execution Time: 282750
Standard Deviation of Time: 241038
您应该有一个逗号分隔值 (CSV) 文件,例如
trial 1,30791,32884,282750,241038
trial 2,30791,32884,282750,241038
trial 3,30791,32884,282750,241038
trial 4,30791,32884,282750,241038
您得到 ArrayIndexOutOfBoundsException
因为您的代码正在读取行
Recursive Selection Sort Results:
as line1
,而当你调用 line1[1]
时,那里什么也没有。你 split
在冒号上,但是冒号右边没有任何东西,所以 split
方法不会费心去创建一个新的标记。
摆脱所有好的 headers 之类的,因为你只需要阅读这些行并在以后扔掉它们——它们比无用更糟糕,因为它们实际上会在你的代码没有出现时引入问题'预料到他们的存在。
现在,您的文件读取代码似乎是基于对文件读取方式的误解。无论您目前对文件读取的理解是什么,忘掉它并假装您以前从未听说过它。目标是一行一行地读取行,将行分解成数据块(我们称它们为标记)并将它们打包成 Line
object,然后再移动到下一行——我们这里不是一次读五行。
一旦您明智地组织输入数据,就不再需要这种东西了:
String[] line1 = file.readLine().split(":");
String[] line2 = file.readLine().split(":");
String[] line3 = file.readLine().split(":");
String[] line4 = file.readLine().split(":");
String[] line5 = file.readLine().split(":");
现在,您所要做的就是这样:
while((line = bufferedReader.readLine()) != null)
{
// for purposes of clarity, we're changing the name of your Line object
// in this example to TrialRecord
String[] tokens = line.split(",");
TrialRecord record = new TrialRecord();
record.setSize( Integer.parseInt(tokens[0]));
// the rest of your code...
}
解决所有这些问题,您的 table 将显示您的数据。