Как использовать JFileChooser в JTable для выбора файлов и отображения данных в JTable - PullRequest
0 голосов
/ 16 июня 2020

Я пытаюсь реализовать 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 ]

2 голосов
/ 17 июня 2020

ДИКЛАЙМЕР: Этот ответ был первоначально отправлен на повторяющийся вопрос одним и тем же пользователем, поэтому я перепубликую его здесь, чтобы сохранить все на одном месте для будущих читателей.

У вас есть несколько проблем, которые необходимо исправить, прежде чем вы сможете приступить к решению основной проблемы - опубликованный вами код даже не компилируется.

Это ваш код ниже. Сможете ли вы определить проблему?

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] там ничего нет. Вы split на двоеточии, но справа от двоеточия нет ничего, поэтому метод split не беспокоится о создании нового токена.

Избавьтесь от всех хороших заголовков и тому подобного, потому что вы мне просто нужно будет прочитать эти строки и выбросить их позже - они хуже, чем бесполезны, потому что они на самом деле создают проблемы, когда ваш код не ожидает их присутствия.

Итак, вы, кажется, основали свой код чтения файлов из-за неправильного понимания того, как файлы читаются. Каким бы ни было ваше нынешнее понимание чтения файлов, забудьте о нем и сделайте вид, что вы никогда о нем раньше не слышали. Цель состоит в том, чтобы прочитать строки одну за другой, разбить строку на блоки данных (мы назовем их токенами) и упаковать их в объект 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...
}  

Исправьте все это, и ваша таблица отобразит ваши данные.

1 голос
/ 17 июня 2020

JFileChooser действительно не имеет отношения к вопросу.

Для начала нужно научиться создавать свой List<Line> ArrayList с данными из файла, чтобы можно было вызвать метод setList().

Начните с жесткого кодирования имени файла, которое вы хотите прочитать. Затем создайте BufferedReader для чтения файла.

Затем для каждой строки данных в файле вы должны:

  1. проанализировать данные, чтобы получить ваш размер, количество и значения времени
  2. используйте значения, указанные выше, чтобы создать экземпляр вашего Line объекта
  3. добавьте объект Line в ваш ArrayList

Когда вы закончите чтение файла Затем вы вызываете метод setList(…) на своем StudentTableModel.

Итак, сначала получите лог c, работающий с жестко закодированным именем файла. Затем, как только это сработает, вы используете JFileChooser для динамического получения имени файла.

Изменить:

Я не уверен, правильно ли я разбираю данные

Расскажите нам, как опубликованный вами код создает объект 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 );
...