加载Java JTable:为什么它不起作用? [英] Loading Java JTable: Why does it not work?

查看:103
本文介绍了加载Java JTable:为什么它不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个包含JTable的简单GUI.该表可以保存和保存;通过适当的对象流加载.

I have created a simple GUI which includes a JTable. This table may be saved & loaded via the appropriate Object Stream.

此时,保存"功能已按预期运行,并且在保存目录中查找时,我可以看到表对象存储在文件中.

At this point the Save function is working as intended, and I can see the table object is stored in a file when looking in the save directory.

但是,当我尝试从文件中加载表时,GUI从不显示加载的表.因为我有一个system.out已加载数据",所以调用了actionlistener函数,但是该表从不显示更新的数据.

However, when I try to load the table from the file, the GUI never displays the loaded table. The actionlistener function is called, as I have a system.out "Data loaded", but the table never displays updated data.

我尝试调用repaint(),但无济于事.对于任何可以了解我可能做错事情的人,我将深表感谢.

I have tried to call repaint(), but to no avail. To anyone who can shed some light on what I may be doing wrong, I would be most grateful.

看一些代码

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);
        }
    });
}

}

推荐答案

您的新表未添加到任何地方,因此不会显示.尝试这样的事情:

Your new table is not added anywhere, so it will not show up. Try something like this:

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()
}

好的,不建议对表进行序列化,最好只保存表模型.这是您编辑的SSCCE(感谢 kleopatra 的帮助):

Ok, serializing the table is not really advised, it is better to only save the table model. Here is your edited SSCCE (thanks to kleopatra for the help):

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);
            }
        });
    }
}

请注意,我使用以下三行序列化模型:

Please notice that I use the following three lines to serialize the model:

table.setModel(new DefaultTableModel());
out.writeObject(model);
table.setModel(model);

因此在序列化时将模型从表中分离出来.不幸的是,该模型还尝试序列化其侦听器(失败).这就是为什么必须执行此步骤的原因.保存后,可以将模型再次应用于表格.

So the model is detached from the table while serializing. Unfortunately the model tries to serialize its listeners as well (which fails). That's why this step is neccessary. Once saved, the model can be applied to the table again.

这篇关于加载Java JTable:为什么它不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆