加载Java JTable:为什么它不起作用



我创建了一个简单的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基于向量或对象[]

  • 必须按照VectorObject[] 的结构将数据从FileIO加载到XxxTableModel

  • XxxTableModel的所有更新都必须在EventDispatchThread上完成,否则任何更改都可以在屏幕上看到

actionPerformed代码中,导入的表(这是一个新实例)不会添加到容器中。

相关内容

  • 没有找到相关文章

最新更新