我想创建一个显示 JTable 中数据的文件读取器。文件中的数据以“,”,“;”分隔, 或者 '。'人物。这是其中的一小部分
txt 文件
12345;Βασ.ίλειος;Τζης;Περικλής;Μαρία;28/06/1984;α1
12346;Βασίλ.ειος;Τζόγλου;Πέτρος;Μαρία;29/06/1984;α1
12347;Βα.σίλειος;Τζόπουλος;Παύ.λος;Μαρία;30/06/1984;α1
12348;Βασίλ.ειος;Τζάκης;Πανα.γιώτης;Μαρία;27/06/1984;α1
我使用默认分隔符(“;”)打开这些记录,如下图所示
当我尝试选择另一个分隔符时,程序必须再次读取文件,然后使用新的分隔符分隔数据。可以看到数据毕竟无法刷新。经过催促,我将所有必要的代码放入一个类中以便可以运行。另外,我使用 openCSV。
public class NewClass extends JFrame{
private CSVReader reader;
private DefaultTableModel defaultTableModel;
private final Handle handle;
private final List<String> studentColumnNames;
private FileInputStream fileInputStream;
private InputStreamReader fileReader;
private int numberOfColumns, numberOfRows;
private final JComboBox split;
private final JTable dataDemoTable;
private String[] nextLine;
private String[][] rowData;
CharsetDecoder UTF8_CHARSET;
Container container;
FlowLayout flowLayout;
List<String[]> myEntries;
public NewClass(){
this.studentColumnNames = new ArrayList<>();
this.studentColumnNames.add("A");
this.studentColumnNames.add("B");
this.studentColumnNames.add("C");
this.studentColumnNames.add("D");
this.studentColumnNames.add("E");
this.studentColumnNames.add("F");
this.studentColumnNames.add("G");
this.split = new JComboBox();
this.split.addItem(";");
this.split.addItem(".");
this.split.addItem("tab");
read();
populateData();
this.dataDemoTable = new JTable(new DefaultTableModel(this.rowData, studentColumnNames.toArray()));
this.dataDemoTable.setFont(new Font("Calibri", Font.PLAIN,18));
this.dataDemoTable.setPreferredScrollableViewportSize(new Dimension(490,290));
this.dataDemoTable.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(this.dataDemoTable);
container = getContentPane();
flowLayout = new FlowLayout();
container.setLayout(flowLayout);
container.add(scrollPane);
container.add(this.split);
close();
this.handle = new Handle();
this.split.addItemListener(handle);
}
private int getNumberOfColumnsFromFile(){
//Estimating number of columns from file
this.numberOfColumns = 0;
try {
this.nextLine = this.reader.readNext();
} catch (IOException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
if(this.nextLine != null){
this.numberOfColumns = this.nextLine.length;
}
return this.numberOfColumns;
}
private void close(){
try {
this.fileInputStream.close();
this.fileReader.close();
this.reader.close();
}
catch (IOException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void populateData(){
try {
myEntries = this.reader.readAll();
} catch (IOException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
this.rowData = myEntries.toArray(new String[0][]);
}
private void read(){
try {
this.fileInputStream = new FileInputStream("D:\\Book2.txt"); //the txt file above
UTF8_CHARSET = StandardCharsets.UTF_8.newDecoder();
UTF8_CHARSET.onMalformedInput(CodingErrorAction.REPLACE);
this.fileReader = new InputStreamReader(this.fileInputStream, UTF8_CHARSET);
this.reader = new CSVReader(this.fileReader, this.split.getSelectedItem().toString().charAt(0));
if(getNumberOfColumnsFromFile() > studentColumnNames.size()){
int remainder = getNumberOfColumnsFromFile()-studentColumnNames.size();
for(int i = 1; i <= remainder; i++){
//add one more name to studentColumnNames
studentColumnNames.add("" + (i) + "");
}
}
}
catch (FileNotFoundException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void setVisibilityToView(){setVisible(true);}
public void setNumberOfColumns(int numberOfColumns){this.numberOfColumns = numberOfColumns;}
public void setSizeToView(int width,int height){setSize(width, height);}
public void setDefaultCloseOperationToView(){setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
public class Handle implements ItemListener{
@Override
public void itemStateChanged(ItemEvent e) {
read();
populateData();
close();
}
}
}
有人可以建议解决该问题吗?谢谢。
最佳答案
看看下面的例子。你的有点难以理解,特别是因为我不熟悉 OpenCSV。
如果您查看 getModelFromCsvFile
,它的功能与您的 read()
方法几乎相同,只是我返回一个 DefaultTableModel
并使用拆分。您可以使用自己的方法实现。您只需使用分隔符在打开的 csv 中设置它即可。我不知道如何使用 open csv 设置分隔符,但我确信如果您知道 api,那么这是一件微不足道的事情
如果您查看getDelimiterComboBox
,我会使用 ActionListener 创建组合框。当组合框中的值发生变化时,我调用 getModelFromCsvFile
,然后为表设置一个新模型。
它应该很容易遵循,但这是您想要遵循的基本想法。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class ReadFileDemo {
private String defaultFile = "D:\\Book.txt";
private File currentFile = new File(defaultFile);
private JTable table;
public ReadFileDemo() {
DefaultTableModel model = getModelFromCsvFile(currentFile, ";");
table = new JTable(model);
JFrame frame = new JFrame();
frame.add(new JScrollPane(table));
frame.add(getDelimiterComboBox(new String[] {";", ".", "\t"}), BorderLayout.NORTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
/**
* Similar to your read() method
*/
public DefaultTableModel getModelFromCsvFile(File file, String delimiter) {
DefaultTableModel model = null;
String line;
boolean isFirstLine = true;
try(BufferedReader reader = new BufferedReader(new FileReader(file))) {
while ((line = reader.readLine()) != null) {
String[] row = line.split(delimiter);
if (isFirstLine) {
Object[] header = getTableColumnHeaders(row.length);
model = new DefaultTableModel(header, 0);
model.addRow(row);
isFirstLine = false;
} else {
if (model != null) {
model.addRow(row);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return model;
}
public JComboBox getDelimiterComboBox(String[] delimiters) {
final JComboBox cbox = new JComboBox(delimiters);
cbox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String delimiter = cbox.getSelectedItem().toString();
DefaultTableModel model = getModelFromCsvFile(currentFile,
delimiter);
table.setModel(model);
}
});
return cbox;
}
public Object[] getTableColumnHeaders(int size) {
Object[] header = new Object[size];
for (int i = 0; i < header.length; i++) {
header[i] = i + 1;
}
return header;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ReadFileDemo();
}
});
}
}
<小时/>
更新
在 read()
方法中使用 CSVReader
。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import au.com.bytecode.opencsv.CSVReader;
public class ReadFileDemo {
private String defaultFile = "D:\\Book.txt";
private File currentFile = new File(defaultFile);
private JTable table;
private CSVReader reader;
private CharsetDecoder UTF8_CHARSET;
public ReadFileDemo() {
DefaultTableModel model = getModelFromCsvFile(currentFile, ";");
table = new JTable(model);
JFrame frame = new JFrame();
frame.add(new JScrollPane(table));
frame.add(getDelimiterComboBox(new String[] { ";", ".", "\t" }),
BorderLayout.NORTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
/**
* Similar to your read() method
*/
public DefaultTableModel getModelFromCsvFile(File file, String delimiter) {
DefaultTableModel model = null;
boolean isFirstRow = true;
try {
UTF8_CHARSET = StandardCharsets.UTF_8.newDecoder();
UTF8_CHARSET.onMalformedInput(CodingErrorAction.REPLACE);
reader = new CSVReader(new InputStreamReader(new FileInputStream(file),
UTF8_CHARSET), delimiter.charAt(0));
List<String[]> dataList = reader.readAll();
for (String[] row: dataList) {
if (isFirstRow) {
model = new DefaultTableModel(getTableColumnHeaders(row.length), 0);
model.addRow(row);
isFirstRow = false;
}
else {
if (model != null) {
model.addRow(row);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return model;
}
public JComboBox getDelimiterComboBox(String[] delimiters) {
final JComboBox cbox = new JComboBox(delimiters);
cbox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String delimiter = cbox.getSelectedItem().toString();
DefaultTableModel model = getModelFromCsvFile(currentFile,
delimiter);
if (model != null) {
table.setModel(model);
}
}
});
return cbox;
}
public Object[] getTableColumnHeaders(int size) {
Object[] header = new Object[size];
for (int i = 0; i < header.length; i++) {
header[i] = i + 1;
}
return header;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ReadFileDemo();
}
});
}
}
关于java - JTable从txt文件刷新数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25349164/