I am trying to be able to implement JFileChooser to be able to select from two .txt files made from another program. I have a fairly simple JTable created that will load in the data from one of the .txt files depending on which path I give it. But I am lost on how to make a JTable implement JFileChooser to be able to select either file and have the data shown in the correct cells. Below is the code for the JTable and a small sample of data from one of the files
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; } } } }
Data from .txt
Data Set Size (n): 100 Iterative Selection Sort Results: Average Critical Operation Count: 1090 Standard Deviation of Count: 770 Average Execution Time: 10340
Advertisement
Answer
DICLAIMER: This answer was originally posted to a duplicate question by the same user, so I’m reposting it here to keep everything in the same place for the sake of future readers.
You have multiple issues that need to be fixed before you can even begin to address the main problem — the code you posted doesn’t even compile.
This is your code, below. Can you spot the problem?
public void getCoefTime(int coefTime) { this.coefTime = coefTime; }
It should read as follows (your compiler would have alerted you to the issue):
// 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; }
Your table model is missing a mandatory method. Any time you create an implementation which extends an Interface, you are required to implement all method signatures from that Interface. In your case, you’re missing the following method, and again, your compiler would have warned you about the issue:
@Override public int getColumnCount() { return columnNames.length; }
Your data file is organized in a less than desirable manner. You seem to have written it as if its primary function was to supply information to a person, rather than a program, so you have these nice labels oriented vertically instead of horizontally, even though you want your JTable
to display horizontally.
Instead of
Average Critical Operation Count: 30791 Standard Deviation of Count: 32884 Average Execution Time: 282750 Standard Deviation of Time: 241038
you should have maybe a comma separated value (CSV) file, like
trial 1,30791,32884,282750,241038 trial 2,30791,32884,282750,241038 trial 3,30791,32884,282750,241038 trial 4,30791,32884,282750,241038
You were getting ArrayIndexOutOfBoundsException
because your code was reading the line
Recursive Selection Sort Results:
as line1
, and when you call line1[1]
, there’s nothing there. You split
on colon, but there’s nothing to the right of the colon, so the split
method doesn’t bother to make a new token.
Get rid of all the nice headers and such because you’ll just have to read those lines and throw them away later — they’re worse than useless because they actually introduce problems when your code doesn’t anticipate their presence.
Now, you seem to have based your file reading code on a misunderstanding of how files are read. Whatever your current understanding of file reading is, forget it and pretend you’ve never heard of it before. The goal is to read lines one by one, break the line up into chunks of data (we’ll call them tokens) and package them into a Line
object before moving to the next line — we’re not reading five lines at a time here.
This kind of stuff is no longer necessary once you organize your input data sensibly:
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(":");
Now, all you have to do is something like this:
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... }
Fix all this stuff and your table will display your data.