提问者:小点点

如何在JTable中使用JFileChooser在JTable中选择文件和显示数据


我试图能够实现JFileChooser能够从两个. txt文件中选择从另一个程序.我有一个相当简单的JTable创建将加载的数据从一个.txt文件取决于我给它的路径.但我迷失在如何使JTable实现JFileChooser能够选择任一文件并有数据显示在正确的单元格.下面是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

共2个答案

匿名用户

DICLAIMER:这个答案最初是由同一个用户发布到一个重复的问题上的,所以我在这里重新发布它,以便为未来的读者保留所有内容。

在开始解决主要问题之前,您需要修复多个问题——您发布的代码甚至无法编译。

下面是您的代码。你能发现问题吗?

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;
}

您的表模型缺少一个强制方法。每当您创建扩展接口的实现时,您都需要从该接口实现所有方法签名。在您的情况下,您缺少以下方法,并且您的编译器会再次警告您该问题:

@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:

作为line1,当您调用line1[1]时,那里什么都没有。您在冒号上拆分,但冒号右侧没有任何内容,因此拆分方法不必费心制作新标记。

去掉所有漂亮的标题之类的,因为你只需要阅读这些行,然后把它们扔掉——它们比无用更糟糕,因为当你的代码没有预料到它们的存在时,它们实际上会引入问题。

现在,你似乎把你的文件读取代码建立在对文件读取方式的误解上。不管你目前对文件读取的理解是什么,忘记它,假装你以前从未听说过它。目标是逐行读取,将行分解成数据块(我们称之为标记),并在移动到下一行之前将它们打包到Line对象中——我们这里不是一次读取五行。

一旦你合理地组织你的输入数据,这种东西就不再是必需的了:

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...
}  

修复所有这些东西,您的表将显示您的数据。

匿名用户

JFileChooser与问题无关。

你需要开始的是学习如何创建你的列表

首先对要读取的文件名进行硬编码。然后创建一个BufferedReader来读取文件。

然后,对于文件中的每一行数据,您将:

  1. 解析数据以获取您的大小、计数和时间值
  2. 使用上面的值来创建您的Line对象
  3. 的实例
  4. Line对象添加到您的ArrayList

读完文件后,您可以在WorkentTableModel上调用setList(…)方法。

因此,首先使用硬编码的文件名使上述逻辑正常工作。然后一旦成功,您就可以使用JFileChooser动态获取文件名。

编辑:

我不确定我是否正确解析数据

告诉我们您发布的代码如何创建Line对象。

你为什么在“”上做拆分()。在我看来,数据是用“:”分隔的。

根据看起来有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 );