将 CSV 文件加载到 JTable 中
Load CSV File into JTable
我的代码:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import javax.swing.JTable;
import java.io.*;
import java.util.*;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Font;
import java.io.*;
import java.util.*;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Font;
public class students extends JFrame {
private JPanel contentPane;
private JTable table;
private DefaultTableModel m;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
students frame = new students();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public students() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1280, 740);
contentPane = new JPanel();
contentPane.setBackground(new Color(24,24,24));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
studentTable();
System.out.println("students();");
}
public void studentTable() {
try {
System.out.println("studentTable();");
String datafile = "data.txt";
FileReader fin = new FileReader(datafile);
DefaultTableModel m = createTableModel(fin, null);
JPanel panel = new JPanel();
panel.setBackground(new Color(35,35,35));
panel.setBounds(240, 163, 800, 360);
contentPane.add(panel);
panel.setLayout(null);
table = new JTable(m);
table.setBounds(0, 0, 800, 360);
table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
table.getTableHeader().setOpaque(false);
table.setBackground(new Color(35, 35, 35));
table.getTableHeader().setBackground(new Color(35,35,35));
table.setForeground(new Color(255,255,255));
table.getTableHeader().setForeground(new Color(255,255,255));
table.setRowHeight(25);
table.setFocusable(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.setRowHeight(25);
table.setSelectionBackground(new Color(32, 32, 32));
table.setShowVerticalLines(false);
table.getTableHeader().setReorderingAllowed(false);
FileWriter out = new FileWriter("data.csv");
defaultTableModelToStream(m, out);
out.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void defaultTableModelToStream(DefaultTableModel dtm,
Writer out) throws IOException {
System.out.println("defaultTableModelToStream();");
final String LINE_SEP = System.getProperty("line.separator");
int numCols = dtm.getColumnCount();
int numRows = dtm.getRowCount();
// Write headers
String sep = "";
for (int i = 0; i < numCols; i++) {
out.write(sep);
out.write(dtm.getColumnName(i));
sep = ",";
}
out.write(LINE_SEP);
for (int r = 0; r < numRows; r++) {
sep = "";
for (int c = 0; c < numCols; c++) {
out.write(sep);
out.write(dtm.getValueAt(r, c).toString());
sep = ",";
}
out.write(LINE_SEP);
}
}
public static DefaultTableModel createTableModel(Reader in,
Vector<Object> headers) {
System.out.println("DefaultTableModel();");
DefaultTableModel model = null;
Scanner s = null;
try {
Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
s = new Scanner(in);
while (s.hasNextLine()) {
rows.add(new Vector<Object>(Arrays.asList(s.nextLine()
.split("\s*,\s*",
-1))));
}
if (headers == null) {
headers = rows.remove(0);
model = new DefaultTableModel(rows, headers);
} else {
model = new DefaultTableModel(rows, headers);
}
return model;
} finally {
s.close();
}
}
}
发生了什么:
table 不加载也不加载 'data.txt'。
执行顺序是:
并且控制台中没有显示崩溃或错误。
找到文本文件。
应该发生什么
JTable 应该位于 JPanel 上,数据从文本文件中提取并加载。
我尝试自己修复它,但没有成功。也许有人会有解决方案。谢谢!
简短的回答是,你永远不会将 JTable
添加到任何东西中
长答案,好吧,要复杂得多。
null
布局(像素完美布局)在现代 UI 开发中是一种幻觉,许多因素决定和维护组件的大小和关系,让您浪费时间重新发明什么已经很容易地供您使用。
相反,花时间阅读和学习 how to use layout managers。
你的students
class做的工作太多了(而且读起来也很费劲),应该专注于做好一件事情,即展示table 的数据。也没有理由从 JFrame
扩展,您没有向 class 添加任何新功能,只是让它比需要的更复杂。相反,从一个简单的容器 class 开始,例如 JPanel
,例如...
public class StudentsPane extends JPanel {
private JTable table;
private DefaultTableModel m;
public StudentsPane(TableModel model) {
setLayout(new BorderLayout());
setBackground(new Color(24, 24, 24));
setBorder(new EmptyBorder(50, 50, 50, 50));
table = new JTable(model);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
table.getTableHeader().setOpaque(false);
table.setBackground(new Color(35, 35, 35));
table.getTableHeader().setBackground(new Color(35, 35, 35));
table.setForeground(new Color(255, 255, 255));
table.getTableHeader().setForeground(new Color(255, 255, 255));
table.setFocusable(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.setRowHeight(25);
table.setSelectionBackground(new Color(32, 32, 32));
table.setShowVerticalLines(false);
table.getTableHeader().setReorderingAllowed(false);
add(new JScrollPane(table));
}
}
现在,面板不关心数据来自哪里,只关心显示提供的模型。
将数据的 loading/saving 与它自己的 class 分开(查看 Single Responsibility Principle for the reasons why) and make sure that you are managing your resources correctly, see The try-with-resources Statement 以了解有关如何实现的更多详细信息,例如...
public class StudentsManager {
public static TableModel loadFrom(File file) throws IOException {
return loadFrom(file, null);
}
public static TableModel loadFrom(File file, Vector<Object> headers) throws IOException {
try (Reader is = new FileReader(file)) {
return loadFrom(is, headers);
}
}
public static TableModel loadFrom(Reader is) {
return loadFrom(is, null);
}
public static TableModel loadFrom(Reader reader, Vector<Object> headers) {
DefaultTableModel model = null;
Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
Scanner s = new Scanner(reader);
while (s.hasNextLine()) {
rows.add(new Vector<Object>(Arrays.asList(s.nextLine().split("\s*,\s*"))));
}
if (headers == null) {
headers = rows.remove(0);
}
model = new DefaultTableModel(rows, headers);
return model;
}
public static void writeTo(DefaultTableModel dtm, File file) throws IOException {
try (Writer writer = new FileWriter(file)) {
writeTo(dtm, writer);
}
}
public static void writeTo(DefaultTableModel dtm, Writer out) throws IOException {
final String LINE_SEP = System.getProperty("line.separator");
int numCols = dtm.getColumnCount();
int numRows = dtm.getRowCount();
StringJoiner joiner = new StringJoiner(",");
for (int i = 0; i < numCols; i++) {
joiner.add(dtm.getColumnName(i));
}
out.write(joiner.toString());
out.write(LINE_SEP);
for (int r = 0; r < numRows; r++) {
joiner = new StringJoiner(",");
for (int c = 0; c < numCols; c++) {
joiner.add(dtm.getValueAt(r, c).toString());
}
out.write(joiner.toString());
out.write(LINE_SEP);
}
}
}
准备就绪后,只需加载数据并显示面板...
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
TableModel model = StudentsManager.loadFrom(new File("data.txt"));
JFrame frame = new JFrame();
frame.add(new StudentsPane(model));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
可运行示例...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import javax.swing.JPanel;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
TableModel model = StudentsManager.loadFrom(new File("data.txt"));
JFrame frame = new JFrame();
frame.add(new StudentsPane(model));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class StudentsManager {
public static TableModel loadFrom(File file) throws IOException {
return loadFrom(file, null);
}
public static TableModel loadFrom(File file, Vector<Object> headers) throws IOException {
try (Reader is = new FileReader(file)) {
return loadFrom(is, headers);
}
}
public static TableModel loadFrom(Reader is) {
return loadFrom(is, null);
}
public static TableModel loadFrom(Reader reader, Vector<Object> headers) {
DefaultTableModel model = null;
Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
Scanner s = new Scanner(reader);
while (s.hasNextLine()) {
rows.add(new Vector<Object>(Arrays.asList(s.nextLine().split("\s*,\s*"))));
}
if (headers == null) {
headers = rows.remove(0);
}
model = new DefaultTableModel(rows, headers);
return model;
}
public static void writeTo(DefaultTableModel dtm, File file) throws IOException {
try (Writer writer = new FileWriter(file)) {
writeTo(dtm, writer);
}
}
public static void writeTo(DefaultTableModel dtm, Writer out) throws IOException {
final String LINE_SEP = System.getProperty("line.separator");
int numCols = dtm.getColumnCount();
int numRows = dtm.getRowCount();
StringJoiner joiner = new StringJoiner(",");
for (int i = 0; i < numCols; i++) {
joiner.add(dtm.getColumnName(i));
}
out.write(joiner.toString());
out.write(LINE_SEP);
for (int r = 0; r < numRows; r++) {
joiner = new StringJoiner(",");
for (int c = 0; c < numCols; c++) {
joiner.add(dtm.getValueAt(r, c).toString());
}
out.write(joiner.toString());
out.write(LINE_SEP);
}
}
}
public class StudentsPane extends JPanel {
private JTable table;
private DefaultTableModel m;
public StudentsPane(TableModel model) {
setLayout(new BorderLayout());
setBackground(new Color(24, 24, 24));
setBorder(new EmptyBorder(50, 50, 50, 50));
table = new JTable(model);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
table.getTableHeader().setOpaque(false);
table.setBackground(new Color(35, 35, 35));
table.getTableHeader().setBackground(new Color(35, 35, 35));
table.setForeground(new Color(255, 255, 255));
table.getTableHeader().setForeground(new Color(255, 255, 255));
table.setFocusable(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.setRowHeight(25);
table.setSelectionBackground(new Color(32, 32, 32));
table.setShowVerticalLines(false);
table.getTableHeader().setReorderingAllowed(false);
add(new JScrollPane(table));
}
}
}
我的代码:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import javax.swing.JTable;
import java.io.*;
import java.util.*;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Font;
import java.io.*;
import java.util.*;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Font;
public class students extends JFrame {
private JPanel contentPane;
private JTable table;
private DefaultTableModel m;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
students frame = new students();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public students() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1280, 740);
contentPane = new JPanel();
contentPane.setBackground(new Color(24,24,24));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
studentTable();
System.out.println("students();");
}
public void studentTable() {
try {
System.out.println("studentTable();");
String datafile = "data.txt";
FileReader fin = new FileReader(datafile);
DefaultTableModel m = createTableModel(fin, null);
JPanel panel = new JPanel();
panel.setBackground(new Color(35,35,35));
panel.setBounds(240, 163, 800, 360);
contentPane.add(panel);
panel.setLayout(null);
table = new JTable(m);
table.setBounds(0, 0, 800, 360);
table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
table.getTableHeader().setOpaque(false);
table.setBackground(new Color(35, 35, 35));
table.getTableHeader().setBackground(new Color(35,35,35));
table.setForeground(new Color(255,255,255));
table.getTableHeader().setForeground(new Color(255,255,255));
table.setRowHeight(25);
table.setFocusable(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.setRowHeight(25);
table.setSelectionBackground(new Color(32, 32, 32));
table.setShowVerticalLines(false);
table.getTableHeader().setReorderingAllowed(false);
FileWriter out = new FileWriter("data.csv");
defaultTableModelToStream(m, out);
out.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void defaultTableModelToStream(DefaultTableModel dtm,
Writer out) throws IOException {
System.out.println("defaultTableModelToStream();");
final String LINE_SEP = System.getProperty("line.separator");
int numCols = dtm.getColumnCount();
int numRows = dtm.getRowCount();
// Write headers
String sep = "";
for (int i = 0; i < numCols; i++) {
out.write(sep);
out.write(dtm.getColumnName(i));
sep = ",";
}
out.write(LINE_SEP);
for (int r = 0; r < numRows; r++) {
sep = "";
for (int c = 0; c < numCols; c++) {
out.write(sep);
out.write(dtm.getValueAt(r, c).toString());
sep = ",";
}
out.write(LINE_SEP);
}
}
public static DefaultTableModel createTableModel(Reader in,
Vector<Object> headers) {
System.out.println("DefaultTableModel();");
DefaultTableModel model = null;
Scanner s = null;
try {
Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
s = new Scanner(in);
while (s.hasNextLine()) {
rows.add(new Vector<Object>(Arrays.asList(s.nextLine()
.split("\s*,\s*",
-1))));
}
if (headers == null) {
headers = rows.remove(0);
model = new DefaultTableModel(rows, headers);
} else {
model = new DefaultTableModel(rows, headers);
}
return model;
} finally {
s.close();
}
}
}
发生了什么: table 不加载也不加载 'data.txt'。 执行顺序是: 并且控制台中没有显示崩溃或错误。 找到文本文件。
应该发生什么 JTable 应该位于 JPanel 上,数据从文本文件中提取并加载。
我尝试自己修复它,但没有成功。也许有人会有解决方案。谢谢!
简短的回答是,你永远不会将 JTable
添加到任何东西中
长答案,好吧,要复杂得多。
null
布局(像素完美布局)在现代 UI 开发中是一种幻觉,许多因素决定和维护组件的大小和关系,让您浪费时间重新发明什么已经很容易地供您使用。
相反,花时间阅读和学习 how to use layout managers。
你的students
class做的工作太多了(而且读起来也很费劲),应该专注于做好一件事情,即展示table 的数据。也没有理由从 JFrame
扩展,您没有向 class 添加任何新功能,只是让它比需要的更复杂。相反,从一个简单的容器 class 开始,例如 JPanel
,例如...
public class StudentsPane extends JPanel {
private JTable table;
private DefaultTableModel m;
public StudentsPane(TableModel model) {
setLayout(new BorderLayout());
setBackground(new Color(24, 24, 24));
setBorder(new EmptyBorder(50, 50, 50, 50));
table = new JTable(model);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
table.getTableHeader().setOpaque(false);
table.setBackground(new Color(35, 35, 35));
table.getTableHeader().setBackground(new Color(35, 35, 35));
table.setForeground(new Color(255, 255, 255));
table.getTableHeader().setForeground(new Color(255, 255, 255));
table.setFocusable(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.setRowHeight(25);
table.setSelectionBackground(new Color(32, 32, 32));
table.setShowVerticalLines(false);
table.getTableHeader().setReorderingAllowed(false);
add(new JScrollPane(table));
}
}
现在,面板不关心数据来自哪里,只关心显示提供的模型。
将数据的 loading/saving 与它自己的 class 分开(查看 Single Responsibility Principle for the reasons why) and make sure that you are managing your resources correctly, see The try-with-resources Statement 以了解有关如何实现的更多详细信息,例如...
public class StudentsManager {
public static TableModel loadFrom(File file) throws IOException {
return loadFrom(file, null);
}
public static TableModel loadFrom(File file, Vector<Object> headers) throws IOException {
try (Reader is = new FileReader(file)) {
return loadFrom(is, headers);
}
}
public static TableModel loadFrom(Reader is) {
return loadFrom(is, null);
}
public static TableModel loadFrom(Reader reader, Vector<Object> headers) {
DefaultTableModel model = null;
Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
Scanner s = new Scanner(reader);
while (s.hasNextLine()) {
rows.add(new Vector<Object>(Arrays.asList(s.nextLine().split("\s*,\s*"))));
}
if (headers == null) {
headers = rows.remove(0);
}
model = new DefaultTableModel(rows, headers);
return model;
}
public static void writeTo(DefaultTableModel dtm, File file) throws IOException {
try (Writer writer = new FileWriter(file)) {
writeTo(dtm, writer);
}
}
public static void writeTo(DefaultTableModel dtm, Writer out) throws IOException {
final String LINE_SEP = System.getProperty("line.separator");
int numCols = dtm.getColumnCount();
int numRows = dtm.getRowCount();
StringJoiner joiner = new StringJoiner(",");
for (int i = 0; i < numCols; i++) {
joiner.add(dtm.getColumnName(i));
}
out.write(joiner.toString());
out.write(LINE_SEP);
for (int r = 0; r < numRows; r++) {
joiner = new StringJoiner(",");
for (int c = 0; c < numCols; c++) {
joiner.add(dtm.getValueAt(r, c).toString());
}
out.write(joiner.toString());
out.write(LINE_SEP);
}
}
}
准备就绪后,只需加载数据并显示面板...
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
TableModel model = StudentsManager.loadFrom(new File("data.txt"));
JFrame frame = new JFrame();
frame.add(new StudentsPane(model));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
可运行示例...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import javax.swing.JPanel;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
TableModel model = StudentsManager.loadFrom(new File("data.txt"));
JFrame frame = new JFrame();
frame.add(new StudentsPane(model));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class StudentsManager {
public static TableModel loadFrom(File file) throws IOException {
return loadFrom(file, null);
}
public static TableModel loadFrom(File file, Vector<Object> headers) throws IOException {
try (Reader is = new FileReader(file)) {
return loadFrom(is, headers);
}
}
public static TableModel loadFrom(Reader is) {
return loadFrom(is, null);
}
public static TableModel loadFrom(Reader reader, Vector<Object> headers) {
DefaultTableModel model = null;
Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
Scanner s = new Scanner(reader);
while (s.hasNextLine()) {
rows.add(new Vector<Object>(Arrays.asList(s.nextLine().split("\s*,\s*"))));
}
if (headers == null) {
headers = rows.remove(0);
}
model = new DefaultTableModel(rows, headers);
return model;
}
public static void writeTo(DefaultTableModel dtm, File file) throws IOException {
try (Writer writer = new FileWriter(file)) {
writeTo(dtm, writer);
}
}
public static void writeTo(DefaultTableModel dtm, Writer out) throws IOException {
final String LINE_SEP = System.getProperty("line.separator");
int numCols = dtm.getColumnCount();
int numRows = dtm.getRowCount();
StringJoiner joiner = new StringJoiner(",");
for (int i = 0; i < numCols; i++) {
joiner.add(dtm.getColumnName(i));
}
out.write(joiner.toString());
out.write(LINE_SEP);
for (int r = 0; r < numRows; r++) {
joiner = new StringJoiner(",");
for (int c = 0; c < numCols; c++) {
joiner.add(dtm.getValueAt(r, c).toString());
}
out.write(joiner.toString());
out.write(LINE_SEP);
}
}
}
public class StudentsPane extends JPanel {
private JTable table;
private DefaultTableModel m;
public StudentsPane(TableModel model) {
setLayout(new BorderLayout());
setBackground(new Color(24, 24, 24));
setBorder(new EmptyBorder(50, 50, 50, 50));
table = new JTable(model);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
table.getTableHeader().setOpaque(false);
table.setBackground(new Color(35, 35, 35));
table.getTableHeader().setBackground(new Color(35, 35, 35));
table.setForeground(new Color(255, 255, 255));
table.getTableHeader().setForeground(new Color(255, 255, 255));
table.setFocusable(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.setRowHeight(25);
table.setSelectionBackground(new Color(32, 32, 32));
table.setShowVerticalLines(false);
table.getTableHeader().setReorderingAllowed(false);
add(new JScrollPane(table));
}
}
}