我创建了一个简单的GUI,其中包括一个JTable。此表可以保存&通过适当的对象流加载。
在这一点上,Save函数正在按预期工作,当在保存目录中查找时,我可以看到表对象存储在一个文件中。
但是,当我尝试从文件加载表时,GUI从不显示加载的表。actionlistener函数被调用,因为我有一个system.out"Data loaded",但表从不显示更新的数据。
我试过调用repaint(),但没有成功。对于任何能揭露我可能做错了什么的人,我将不胜感激。
看一些代码
import javax.swing.*;
import java.awt.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.imageio.*;
import java.io.*;
import java.awt.image.BufferedImage;
import java.util.*;
import javax.swing.table.*;
import java.awt.event.*;
public class Save3 extends JFrame implements ActionListener{
public int PADDING = 10;
public JMenuItem menuNew;
public JMenuItem menuOpen;
public JMenuItem menuSave;
public JMenuItem menuExit;
public JPanel container;
public DefaultTableModel model;
public JScrollPane scrollPane;
public JTable table;
public FileInputStream fis;
public ObjectInputStream in;
public FileOutputStream fos;
public ObjectOutputStream out;
public String filename;
public Save3(){
fis = null;
in = null;
fos = null;
out = null;
filename = "test.ref";
initGUI();
}
public void initGUI(){
setTitle("WIM Reference Data Comparison Tool");
setSize(500, 400);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// Menu Bar and Menu Items setup
JMenuBar menuBar;
JMenu menu;
JMenuItem menuItem;
menuBar = new JMenuBar();
menu = new JMenu("Menu");
menuBar.add(menu);
menuNew = new JMenuItem("New");
menuOpen = new JMenuItem("Open");
menuSave = new JMenuItem("Save");
menuExit = new JMenuItem("Exit");
menuNew.addActionListener(this);
menuOpen.addActionListener(this);
menuSave.addActionListener(this);
menuExit.addActionListener(this);
menu.add(menuNew);
menu.add(menuOpen);
menu.add(menuSave);
menu.add(menuExit);
setJMenuBar(menuBar);
container = new JPanel(new BorderLayout());
String[] columnNames = {"", "MotorBike", " Car"};
Object[][] data = { {"Vehicle Summary", new Integer(100), new Integer(200)}, // Header 1: Green
{"Axle Numbers", new Integer(100), new Integer(200)},
{"Axle Code", new Integer(100), new Integer(200)},
{"Axle Distances (cm)", new Integer(100), new Integer(200)},
{"Vehicle Speed (km/h)", new Integer(100), new Integer(200)},
{"Gross Weight", new Integer(100), new Integer(200)},
{"Axle Weight 1", new Integer(100), new Integer(200)},
{"Axle Weight 2", new Integer(100), new Integer(200)},
};
model = new DefaultTableModel(data, columnNames);
table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
scrollPane = new JScrollPane(table);
container.add(scrollPane, BorderLayout.CENTER);
add(container);
}
public void setPanel(JTable table){
scrollPane.remove(table);
container.remove(scrollPane);
scrollPane = new JScrollPane(table);
container.add(scrollPane, BorderLayout.CENTER);
repaint();
}
public void actionPerformed(ActionEvent e){
System.out.println("Clicked item!");
// NEW
if(e.getSource() == menuNew){
System.out.println("New File");
}
// SAVE
if(e.getSource() == menuSave){
System.out.println("Save!");
try{
model.fireTableDataChanged();
table = new JTable(model);
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(table);
}catch(IOException e3){
e3.printStackTrace();
}
}
if(e.getSource() == menuOpen){
System.out.println("Open!");
JTable table = new JTable();
try{
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
table = new JTable();
table = (JTable) in.readObject();
in.close();
setPanel(table);
System.out.println("data loaded");
}catch(IOException e1){
e1.printStackTrace();
}catch(ClassNotFoundException e2){
e2.printStackTrace();
}
}
if(e.getSource() == menuExit){
System.out.println("Exit!");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
Save3 ex = new Save3();
ex.setVisible(true);
}
});
}
}
您的新表没有添加到任何位置,因此不会显示。试试这样的东西:
public void actionPerformed(ActionEvent e){
JTable oldTable = table;
// your stuff, loading the table from file
thePanelHoldingYourTable.remove(oldTable);
thePanelHoldingYourTable.add(table);
// if there are other components in that panel, make sure, your table is in the right spot
// maybe refresh your layout by using invalidate()
}
EDIT:好的,并不建议序列化表,最好只保存表模型。这是您编辑的SSCCE(感谢kleopatra的帮助):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Save3 extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
public int PADDING = 10;
public JMenuItem menuNew;
public JMenuItem menuOpen;
public JMenuItem menuSave;
public JMenuItem menuExit;
public JPanel container;
public DefaultTableModel model;
public JScrollPane scrollPane;
public JTable table;
public FileInputStream fis;
public ObjectInputStream in;
public FileOutputStream fos;
public ObjectOutputStream out;
public String filename;
String[] columnNames = {"", "MotorBike", " Car"};
Object[][] data = { {"Vehicle Summary", new Integer(100), new Integer(200)}, // Header 1: Green
{"Axle Numbers", new Integer(100), new Integer(200)}, {"Axle Code", new Integer(100), new Integer(200)}, {"Axle Distances (cm)", new Integer(100), new Integer(200)}, {"Vehicle Speed (km/h)", new Integer(100), new Integer(200)}, {"Gross Weight", new Integer(100), new Integer(200)}, {"Axle Weight 1", new Integer(100), new Integer(200)}, {"Axle Weight 2", new Integer(100), new Integer(200)},};
public Save3() {
fis = null;
in = null;
fos = null;
out = null;
filename = "test.ref";
initGUI();
}
public void initGUI() {
setTitle("WIM Reference Data Comparison Tool");
setSize(500, 400);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// Menu Bar and Menu Items setup
JMenuBar menuBar;
JMenu menu;
menuBar = new JMenuBar();
menu = new JMenu("Menu");
menuBar.add(menu);
menuNew = new JMenuItem("New");
menuOpen = new JMenuItem("Open");
menuSave = new JMenuItem("Save");
menuExit = new JMenuItem("Exit");
menuNew.addActionListener(this);
menuOpen.addActionListener(this);
menuSave.addActionListener(this);
menuExit.addActionListener(this);
menu.add(menuNew);
menu.add(menuOpen);
menu.add(menuSave);
menu.add(menuExit);
setJMenuBar(menuBar);
container = new JPanel(new BorderLayout());
model = new DefaultTableModel(data, columnNames);
table = new JTable();
table.setModel(model);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
scrollPane = new JScrollPane(table);
container.add(scrollPane, BorderLayout.CENTER);
add(container);
}
public void setModel(DefaultTableModel writeModel) {
table.setModel(writeModel);
}
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked item!");
if (e.getSource() == menuNew) {
System.out.println("New File");
} else if (e.getSource() == menuSave) {
System.out.println("Save!");
try {
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
table.clearSelection();
table.setModel(new DefaultTableModel());
out.writeObject(model);
table.setModel(model);
} catch (IOException e3) {
e3.printStackTrace();
} finally {
try {
out.close();
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
} else if (e.getSource() == menuOpen) {
System.out.println("Open!");
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
DefaultTableModel modelRead = (DefaultTableModel) in.readObject();
setModel(modelRead);
System.out.println("data loaded");
in.close();
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e2) {
e2.printStackTrace();
}
} else if (e.getSource() == menuExit) {
System.out.println("Exit!");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Save3 ex = new Save3();
ex.setVisible(true);
}
});
}
}
请注意,我使用以下三行来序列化模型:
table.setModel(new DefaultTableModel());
out.writeObject(model);
table.setModel(model);
因此,在序列化时将模型从表中分离出来。不幸的是,该模型也试图序列化其侦听器(但失败了)。这就是为什么这个步骤是必要的。保存后,模型可以再次应用于表。
-
JTable及其XxxTableModel基于向量或对象[]
-
必须按照
Vector
或Object[]
的结构将数据从FileIO
加载到XxxTableModel
-
XxxTableModel的所有更新都必须在EventDispatchThread上完成,否则任何更改都可以在屏幕上看到
在actionPerformed
代码中,导入的表(这是一个新实例)不会添加到容器中。