如何在 JMenuItem 上保存 JTable 数据点击
How to save JTable data on JMenuItem click
我已经拥有的是 JTable
和 MyTableModel
table 模型。我有一个 tableChanged()
方法,它在修改 table 单元格时将 table 数据写入 data.csv
文件。这意味着每次用户输入新数据时都会将 table 数据写入文件。相反,我希望有一个菜单项,用户可以在其中单击 'Save',然后继续执行保存到文件的代码。
@Override
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel) e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
BufferedWriter bw = null;
FileWriter fw = null;
String rivi = "";
try {
fw = new FileWriter("data.csv");
bw = new BufferedWriter(fw);
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
if (j == 69) {
rivi += model.getValueAt(i, j);
} else {
rivi += model.getValueAt(i, j) + ",";
}
}
if (i != 69) {
rivi += "\n";
}
}
bw.write(rivi);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
if (fw != null) {
fw.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
假设我理解正确,我需要的是将文件保存代码从 tableChanged()
方法移动到 actionPerformed()
方法,但我不知道如何获得 TableModelEvent e
参数来自 tableChanged()
方法并在 actionPerformed()
方法中使用它,这样我就可以通过 TableModel model = (TableModel) e.getSource()
获取 table 数据并将其保存到文件中。
@Override
public void actionPerformed(ActionEvent e) {
// File saving code here?
}
完整代码在这里:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedWriter;
import java.io.FileWriter;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import static sun.misc.ClassFileTransformer.add;
public class DesktopEsimerkki extends JPanel
implements TableModelListener, ActionListener {
protected JTable table = null;
protected TableModel model = null;
public DesktopEsimerkki() {
super(new GridLayout(1, 0));
table = new JTable(new MyTableModel());
table.setFillsViewportHeight(true);
table.getModel().addTableModelListener(this);
add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
this.model = table.getModel();
}
@Override
public void tableChanged(TableModelEvent e) {}
@Override
public void actionPerformed(ActionEvent e) {
BufferedWriter bw = null;
String rivi = "";
FileWriter fw = null;
try {
fw = new FileWriter("data.csv");
bw = new BufferedWriter(fw);
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
if (j == 69) {
rivi += model.getValueAt(i, j);
} else {
rivi += model.getValueAt(i, j) + ",";
}
}
if (i != 69) {
rivi += "\n";
}
}
System.out.println(rivi);
bw.write(rivi);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
if (fw != null) {
fw.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public JMenuBar luoValikkoPalkki() {
JMenuBar valikkopalkki = new JMenuBar();
JMenu valikko = new JMenu("File");
valikko.setMnemonic(KeyEvent.VK_F);
valikko.getAccessibleContext().setAccessibleDescription(
"File Saving MEnu");
valikkopalkki.add(valikko);
JMenuItem valikkoitem = new JMenuItem("Save", KeyEvent.VK_S);
valikkoitem.setAccelerator(KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_S, ActionEvent.CTRL_MASK));
valikko.add(valikkoitem);
valikkoitem.addActionListener(this);
return valikkopalkki;
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"Col 1", "Col 2", "Col 3"};
private Object[][] data = {{"Data 1", "Data 2", "Data 3"}};
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
@Override
public Object getValueAt(int row, int col) {
return data[row][col];
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("DesktopEsimerkki");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DesktopEsimerkki desim = new DesktopEsimerkki();
frame.setJMenuBar(desim.luoValikkoPalkki());
DesktopEsimerkki newContentPane = new DesktopEsimerkki();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
您的代码可以正常工作,您的问题更基本 -- 您创建了太多 DesktopEsimerkki
对象,一个对象的值您正在更改,另一个对象的值您正在显示。改变这个:
JFrame frame = new JFrame("DesktopEsimerkki");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// this guy creates the menu
DesktopEsimerkki desim = new DesktopEsimerkki();
frame.setJMenuBar(desim.luoValikkoPalkki());
// but this separate guy is used as the GUI
DesktopEsimerkki newContentPane = new DesktopEsimerkki();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
对此:
JFrame frame = new JFrame("DesktopEsimerkki");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// use only one instance for **both**
DesktopEsimerkki desim = new DesktopEsimerkki();
frame.setJMenuBar(desim.luoValikkoPalkki());
// DesktopEsimerkki newContentPane = new DesktopEsimerkki();
// newContentPane.setOpaque(true);
// frame.setContentPane(newContentPane);
// *********** here ***********
frame.setContentPane(desim);
只是为了笑,我创建了自己的程序来执行此操作,例如:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Formatter;
import java.util.Scanner;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
@SuppressWarnings("serial")
public class TableFun extends JPanel {
public static final String DATA_FILE_PATH = "data.csv";
private MyTableModel model = new MyTableModel();
private JTable table = new JTable(model);
private JTextField fileNameField = new JTextField(DATA_FILE_PATH, 30);
private JMenuBar menuBar;
private Action writeModelAction = new WriteModelAction(table, "Write to File", this);
private Action readModelAction = new ReadModelAction(table, "Read from File", this);
public TableFun() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JLabel("File:"));
btnPanel.add(fileNameField);
btnPanel.add(new JButton(writeModelAction));
btnPanel.add(new JButton(readModelAction));
table.getColumnModel().getColumn(0).setCellRenderer(new TimeColumnRenderer());
JScrollPane scrollpane = new JScrollPane(table);
setLayout(new BorderLayout());
add(scrollpane);
add(btnPanel, BorderLayout.PAGE_START);
}
public String getFileName() {
return fileNameField.getText();
}
public JMenuBar getMenuBar() {
if (menuBar == null) {
menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
menuBar.add(fileMenu);
fileMenu.add(new JMenuItem(readModelAction));
fileMenu.add(new JMenuItem(writeModelAction));
}
return menuBar;
}
private static void createAndShowGui() {
TableFun mainPanel = new TableFun();
JFrame frame = new JFrame("TableFun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getMenuBar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class WriteModelAction extends AbstractAction {
private ReadWriteTableData readWriteTableData;
private TableFun tableFun;
public WriteModelAction(JTable table, String name, TableFun tableFun) {
super(name);
int mnemonic = name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
readWriteTableData = new ReadWriteTableData(table);
this.tableFun = tableFun;
}
@Override
public void actionPerformed(ActionEvent e) {
File file = new File(tableFun.getFileName());
if (file.exists()) {
String message = "File " + tableFun.getFileName() + " already exists -- do you wish to overrite?";
String title = "File Already Exists";
int optionType = JOptionPane.YES_NO_OPTION;
int response = JOptionPane.showConfirmDialog(tableFun, message, title, optionType);
if (response != JOptionPane.YES_OPTION) {
return;
}
}
try {
readWriteTableData.write(file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@SuppressWarnings("serial")
class ReadModelAction extends AbstractAction {
private ReadWriteTableData readWriteTableData;
private TableFun tableFun;
public ReadModelAction(JTable table, String name, TableFun tableFun) {
super(name);
int mnemonic = name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
readWriteTableData = new ReadWriteTableData(table);
this.tableFun = tableFun;
}
@Override
public void actionPerformed(ActionEvent e) {
File file = new File(tableFun.getFileName());
if (!file.exists()) {
String message = "File " + tableFun.getFileName() + " cannot be found -- aborting read";
String title = "File Cannot Be Found";
int optionType = JOptionPane.WARNING_MESSAGE;
JOptionPane.showMessageDialog(tableFun, message, title, optionType);
return;
}
try {
readWriteTableData.read(file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
class ReadWriteTableData {
private JTable table;
public ReadWriteTableData(JTable table) {
this.table = table;
}
public void read(File file) throws FileNotFoundException {
MyTableModel tableModel = (MyTableModel) table.getModel();
tableModel.setRowCount(0);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
String[] tokens = line.split("\|");
String[] trimmedTokens = new String[tokens.length];
for (int i = 0; i < tokens.length; i++) {
String text = tokens[i];
if (text == null || text.trim().equals("null")) {
text = "";
} else {
text = text.trim();
}
trimmedTokens[i] = text;
}
tableModel.addRow(trimmedTokens);
}
}
table.setModel(tableModel);
scanner.close();
}
public void write(File file) throws IOException {
FileWriter fileWriter = new FileWriter(file);
Formatter formatter = new Formatter(fileWriter);
MyTableModel model = (MyTableModel) table.getModel();
for (int row = 0; row < model.getRowCount(); row++) {
for (int col = 0; col < model.getColumnCount(); col++) {
String value = (String) model.getValueAt(row, col);
value = value == null ? "" : value;
formatter.format("%25s ", value);
if (col != model.getColumnCount() - 1) {
formatter.format(" | ");
}
}
formatter.format("%n");
}
if (formatter != null) {
formatter.close();
}
}
}
class MyTableModel extends DefaultTableModel {
public static final String[] COLUMNS = {"Time", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
private static final int START_TIME = 8;
private static final int END_TIME = 17;
public MyTableModel() {
super(COLUMNS, 0);
for (int i = START_TIME; i < END_TIME + 1; i++) {
Object[] rowData = {String.valueOf(i), "", "", "", "", ""};
addRow(rowData);
}
}
@Override
public boolean isCellEditable(int row, int column) {
return column != 0;
}
}
class TimeColumnRenderer extends DefaultTableCellRenderer {
public TimeColumnRenderer() {
setHorizontalAlignment(SwingConstants.TRAILING);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
int time = Integer.parseInt(value.toString());
time = time > 12 ? time % 12 : time;
String timeText = String.format("%d:00", time);
return super.getTableCellRendererComponent(table, timeText, isSelected, hasFocus, row, column);
}
}
它使用管道符号 |
作为 csv 分隔符,因此典型的文本文件可能如下所示:
8 | | judy | | |
9 | John | | Bill | | Frank
10 | | Hello | | Goodbye |
11 | Donald duck | Frank Nitti | Al Capone | Johnson |
12 | | | | | ss
13 | | | | |
14 | Bill Clinton | Donald Trump | Hello | Fresh |
15 | | What the | heck | | Yes
16 | | | | |
17 | Here | we | are | |
我已经拥有的是 JTable
和 MyTableModel
table 模型。我有一个 tableChanged()
方法,它在修改 table 单元格时将 table 数据写入 data.csv
文件。这意味着每次用户输入新数据时都会将 table 数据写入文件。相反,我希望有一个菜单项,用户可以在其中单击 'Save',然后继续执行保存到文件的代码。
@Override
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel) e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
BufferedWriter bw = null;
FileWriter fw = null;
String rivi = "";
try {
fw = new FileWriter("data.csv");
bw = new BufferedWriter(fw);
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
if (j == 69) {
rivi += model.getValueAt(i, j);
} else {
rivi += model.getValueAt(i, j) + ",";
}
}
if (i != 69) {
rivi += "\n";
}
}
bw.write(rivi);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
if (fw != null) {
fw.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
假设我理解正确,我需要的是将文件保存代码从 tableChanged()
方法移动到 actionPerformed()
方法,但我不知道如何获得 TableModelEvent e
参数来自 tableChanged()
方法并在 actionPerformed()
方法中使用它,这样我就可以通过 TableModel model = (TableModel) e.getSource()
获取 table 数据并将其保存到文件中。
@Override
public void actionPerformed(ActionEvent e) {
// File saving code here?
}
完整代码在这里:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedWriter;
import java.io.FileWriter;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import static sun.misc.ClassFileTransformer.add;
public class DesktopEsimerkki extends JPanel
implements TableModelListener, ActionListener {
protected JTable table = null;
protected TableModel model = null;
public DesktopEsimerkki() {
super(new GridLayout(1, 0));
table = new JTable(new MyTableModel());
table.setFillsViewportHeight(true);
table.getModel().addTableModelListener(this);
add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
this.model = table.getModel();
}
@Override
public void tableChanged(TableModelEvent e) {}
@Override
public void actionPerformed(ActionEvent e) {
BufferedWriter bw = null;
String rivi = "";
FileWriter fw = null;
try {
fw = new FileWriter("data.csv");
bw = new BufferedWriter(fw);
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
if (j == 69) {
rivi += model.getValueAt(i, j);
} else {
rivi += model.getValueAt(i, j) + ",";
}
}
if (i != 69) {
rivi += "\n";
}
}
System.out.println(rivi);
bw.write(rivi);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
if (fw != null) {
fw.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public JMenuBar luoValikkoPalkki() {
JMenuBar valikkopalkki = new JMenuBar();
JMenu valikko = new JMenu("File");
valikko.setMnemonic(KeyEvent.VK_F);
valikko.getAccessibleContext().setAccessibleDescription(
"File Saving MEnu");
valikkopalkki.add(valikko);
JMenuItem valikkoitem = new JMenuItem("Save", KeyEvent.VK_S);
valikkoitem.setAccelerator(KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_S, ActionEvent.CTRL_MASK));
valikko.add(valikkoitem);
valikkoitem.addActionListener(this);
return valikkopalkki;
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"Col 1", "Col 2", "Col 3"};
private Object[][] data = {{"Data 1", "Data 2", "Data 3"}};
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
@Override
public Object getValueAt(int row, int col) {
return data[row][col];
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("DesktopEsimerkki");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DesktopEsimerkki desim = new DesktopEsimerkki();
frame.setJMenuBar(desim.luoValikkoPalkki());
DesktopEsimerkki newContentPane = new DesktopEsimerkki();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
您的代码可以正常工作,您的问题更基本 -- 您创建了太多 DesktopEsimerkki
对象,一个对象的值您正在更改,另一个对象的值您正在显示。改变这个:
JFrame frame = new JFrame("DesktopEsimerkki");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// this guy creates the menu
DesktopEsimerkki desim = new DesktopEsimerkki();
frame.setJMenuBar(desim.luoValikkoPalkki());
// but this separate guy is used as the GUI
DesktopEsimerkki newContentPane = new DesktopEsimerkki();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
对此:
JFrame frame = new JFrame("DesktopEsimerkki");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// use only one instance for **both**
DesktopEsimerkki desim = new DesktopEsimerkki();
frame.setJMenuBar(desim.luoValikkoPalkki());
// DesktopEsimerkki newContentPane = new DesktopEsimerkki();
// newContentPane.setOpaque(true);
// frame.setContentPane(newContentPane);
// *********** here ***********
frame.setContentPane(desim);
只是为了笑,我创建了自己的程序来执行此操作,例如:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Formatter;
import java.util.Scanner;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
@SuppressWarnings("serial")
public class TableFun extends JPanel {
public static final String DATA_FILE_PATH = "data.csv";
private MyTableModel model = new MyTableModel();
private JTable table = new JTable(model);
private JTextField fileNameField = new JTextField(DATA_FILE_PATH, 30);
private JMenuBar menuBar;
private Action writeModelAction = new WriteModelAction(table, "Write to File", this);
private Action readModelAction = new ReadModelAction(table, "Read from File", this);
public TableFun() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JLabel("File:"));
btnPanel.add(fileNameField);
btnPanel.add(new JButton(writeModelAction));
btnPanel.add(new JButton(readModelAction));
table.getColumnModel().getColumn(0).setCellRenderer(new TimeColumnRenderer());
JScrollPane scrollpane = new JScrollPane(table);
setLayout(new BorderLayout());
add(scrollpane);
add(btnPanel, BorderLayout.PAGE_START);
}
public String getFileName() {
return fileNameField.getText();
}
public JMenuBar getMenuBar() {
if (menuBar == null) {
menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
menuBar.add(fileMenu);
fileMenu.add(new JMenuItem(readModelAction));
fileMenu.add(new JMenuItem(writeModelAction));
}
return menuBar;
}
private static void createAndShowGui() {
TableFun mainPanel = new TableFun();
JFrame frame = new JFrame("TableFun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getMenuBar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class WriteModelAction extends AbstractAction {
private ReadWriteTableData readWriteTableData;
private TableFun tableFun;
public WriteModelAction(JTable table, String name, TableFun tableFun) {
super(name);
int mnemonic = name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
readWriteTableData = new ReadWriteTableData(table);
this.tableFun = tableFun;
}
@Override
public void actionPerformed(ActionEvent e) {
File file = new File(tableFun.getFileName());
if (file.exists()) {
String message = "File " + tableFun.getFileName() + " already exists -- do you wish to overrite?";
String title = "File Already Exists";
int optionType = JOptionPane.YES_NO_OPTION;
int response = JOptionPane.showConfirmDialog(tableFun, message, title, optionType);
if (response != JOptionPane.YES_OPTION) {
return;
}
}
try {
readWriteTableData.write(file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@SuppressWarnings("serial")
class ReadModelAction extends AbstractAction {
private ReadWriteTableData readWriteTableData;
private TableFun tableFun;
public ReadModelAction(JTable table, String name, TableFun tableFun) {
super(name);
int mnemonic = name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
readWriteTableData = new ReadWriteTableData(table);
this.tableFun = tableFun;
}
@Override
public void actionPerformed(ActionEvent e) {
File file = new File(tableFun.getFileName());
if (!file.exists()) {
String message = "File " + tableFun.getFileName() + " cannot be found -- aborting read";
String title = "File Cannot Be Found";
int optionType = JOptionPane.WARNING_MESSAGE;
JOptionPane.showMessageDialog(tableFun, message, title, optionType);
return;
}
try {
readWriteTableData.read(file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
class ReadWriteTableData {
private JTable table;
public ReadWriteTableData(JTable table) {
this.table = table;
}
public void read(File file) throws FileNotFoundException {
MyTableModel tableModel = (MyTableModel) table.getModel();
tableModel.setRowCount(0);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
String[] tokens = line.split("\|");
String[] trimmedTokens = new String[tokens.length];
for (int i = 0; i < tokens.length; i++) {
String text = tokens[i];
if (text == null || text.trim().equals("null")) {
text = "";
} else {
text = text.trim();
}
trimmedTokens[i] = text;
}
tableModel.addRow(trimmedTokens);
}
}
table.setModel(tableModel);
scanner.close();
}
public void write(File file) throws IOException {
FileWriter fileWriter = new FileWriter(file);
Formatter formatter = new Formatter(fileWriter);
MyTableModel model = (MyTableModel) table.getModel();
for (int row = 0; row < model.getRowCount(); row++) {
for (int col = 0; col < model.getColumnCount(); col++) {
String value = (String) model.getValueAt(row, col);
value = value == null ? "" : value;
formatter.format("%25s ", value);
if (col != model.getColumnCount() - 1) {
formatter.format(" | ");
}
}
formatter.format("%n");
}
if (formatter != null) {
formatter.close();
}
}
}
class MyTableModel extends DefaultTableModel {
public static final String[] COLUMNS = {"Time", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
private static final int START_TIME = 8;
private static final int END_TIME = 17;
public MyTableModel() {
super(COLUMNS, 0);
for (int i = START_TIME; i < END_TIME + 1; i++) {
Object[] rowData = {String.valueOf(i), "", "", "", "", ""};
addRow(rowData);
}
}
@Override
public boolean isCellEditable(int row, int column) {
return column != 0;
}
}
class TimeColumnRenderer extends DefaultTableCellRenderer {
public TimeColumnRenderer() {
setHorizontalAlignment(SwingConstants.TRAILING);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
int time = Integer.parseInt(value.toString());
time = time > 12 ? time % 12 : time;
String timeText = String.format("%d:00", time);
return super.getTableCellRendererComponent(table, timeText, isSelected, hasFocus, row, column);
}
}
它使用管道符号 |
作为 csv 分隔符,因此典型的文本文件可能如下所示:
8 | | judy | | |
9 | John | | Bill | | Frank
10 | | Hello | | Goodbye |
11 | Donald duck | Frank Nitti | Al Capone | Johnson |
12 | | | | | ss
13 | | | | |
14 | Bill Clinton | Donald Trump | Hello | Fresh |
15 | | What the | heck | | Yes
16 | | | | |
17 | Here | we | are | |