使用新数据更新BeanTableModel - Java

时间:2013-11-24 01:05:24

标签: java swing jtable

我的BeanTableModel扩展了RowTableModel。并XTableColumnModel延伸DefaultTableColumnModel。这两个模型都来自这个网站:BeanTableModel and RowTableModel source

我可以创建表格并显示数据。我可以使用新数据更新表格,但我不能使用来自其他类别的新数据更新表格。

例如,我有一个Names.class,我向表格发送List<Names>进行打印,并按预期进行。当我尝试使用不同的List<Names>更新表时,它也会更新,但当我尝试使用Dogs列表更新表时,它将不会更新,在这种情况下,如果我发送List<Dogs>它不更新表,这是主要问题,如何用不同的类对象更新表?!

这是一个简短的runnable我正在创建以复制此错误:

注意:由于BeanTableModel,RowTableModel和XTableColumnModel是相当大的类,由于帖子上的char限制,我似乎无法在此处发布所有代码。因此,我留下了一个指向我的Dropbox帐户的链接,您可以在其中下载这个短版可运行jar的所有源文件。

主要课程:

import javax.swing.SwingUtilities;

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Design();                
            }
        });
    }
}

设计类:

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;

public class Design extends JFrame {

    private LeftPanel leftPanel;
    private TablePanel tablePanel;

    public Design() {
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setVisible(true);
        setMinimumSize(new Dimension(600, 400));

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new BorderLayout());

        leftPanel = new LeftPanel();
        tablePanel = TablePanel.getInstance();

        add(leftPanel, BorderLayout.NORTH);
        add(tablePanel, BorderLayout.SOUTH);
    }
}

LeftPanel类

public class LeftPanel extends JPanel {

    private JButton startButton;
    private JButton editWithDogButtton;
    private JButton editWithPerson;
    private TablePanel tablePanel;

    public LeftPanel() {
        initComponents();
        tablePanel = TablePanel.getInstance();

    }

    public void initComponents() {
        startButton = new JButton("Create table!");
        editWithDogButtton = new JButton("Edit with dog!");
        editWithPerson = new JButton("Edit with person!");

        setLayout(new GridBagLayout());

        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        add(startButton, constraints);

        constraints.gridx = 1;
        constraints.gridy = 0;
        add(editWithDogButtton, constraints);

        constraints.gridx = 1;
        constraints.gridx = 2;
        add(editWithPerson, constraints);

        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<Person> listPerson = new ArrayList<>();
                listPerson.add(new Person("John", "Spencer"));
                listPerson.add(new Person("Mike", "Strada"));
                listPerson.add(new Person("Johan", "Anderson"));

                ArrayList<String> columnLabels = new ArrayList<>();
                columnLabels.add("First name");
                columnLabels.add("Last name");

                tablePanel.createTable(Person.class, listPerson, true, true, columnLabels);
            }
        });

        editWithDogButtton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<Dog> listDog = new ArrayList<>();
                listDog.add(new Dog("Bob", "German Sheppard"));
                listDog.add(new Dog("Laika", "Bulldog"));

                ArrayList<String> columnLabels = new ArrayList<>();
                columnLabels.add("Dog's Name");
                columnLabels.add("Race");

                tablePanel.updateTable(listDog, columnLabels); // It doesn't work...!
            }
        });

        editWithPerson.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<Person> listPerson2 = new ArrayList<>();
                listPerson2.add(new Person("Jessica", "Carlton"));
                listPerson2.add(new Person("Sthephanie", "Oujur"));
                listPerson2.add(new Person("Angela", "Parker"));

                ArrayList<String> columnLabels = new ArrayList<>();
                columnLabels.add("First Name");
                columnLabels.add("Last Name");

                tablePanel.updateTable(listPerson2, columnLabels); // It works!
            }
        });
    }

    public void createTable(Class c, List data) {
        JTable table;
        BeanTableModel beanTableModel;
        XTableColumnModel columnModel;

        beanTableModel = new BeanTableModel(c, data);
        columnModel = new XTableColumnModel();
        table = new JTable(beanTableModel);
        table.setColumnModel(columnModel);
        table.createDefaultColumnsFromModel();

    }
}

TablePanel类

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.table.TableColumn;


public class TablePanel extends JPanel {

    private JTable table;
    private JFileChooser fileChooser;
    private BeanTableModel beanTableModel;
    private XTableColumnModel columnModel;
    private Class c;
    private Class classAncestor;
    private List dataList;
    private static TablePanel instance;

    public synchronized static TablePanel getInstance()
    {
        if(instance == null)
        {
            instance = new TablePanel();
        }

        return instance;
    }

    private TablePanel() {
//        fileChooser = new JFileChooser();
    }

    public void setTable(JTable table) {
        this.table = table;
    }

    public void setBeanTableModel(BeanTableModel beanTableModel) {
        this.beanTableModel = beanTableModel;
    }

    public void setColumnModel(XTableColumnModel columnModel) {
        this.columnModel = columnModel;
    }

    public void setC(Class c) {
        this.c = c;
    }

    public void setData(List data) {
        this.dataList = data;
    }

    public List getDataList() {
        return dataList;
    }

    public void createTable(Class c, List data, boolean toolBarUp,
            boolean toolBarBottom, ArrayList<String> labelsCheckBox) {

        beanTableModel = new BeanTableModel(c, data);
        columnModel = new XTableColumnModel();
        table = new JTable(beanTableModel);
        table.setColumnModel(columnModel);
        table.createDefaultColumnsFromModel();

        if (toolBarUp == true) {
            final JToolBar toolBarTop = new JToolBar();

            JButton reset = new JButton("Reset");

            reset.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    for (Component c : toolBarTop.getComponents()) {
                        if (c instanceof JCheckBox) {
                            JCheckBox checkBox = (JCheckBox) c;
                            checkBox.setSelected(false);
                            columnModel.setAllColumnsVisible();
                        }
                    }
                    int numberOfColumn = columnModel.getColumnCount();

                    for (int aux = 0; aux < numberOfColumn; aux++) {
                        int num = columnModel.getColumnCount();
                        TableColumn column = columnModel.getColumnByModelIndex(aux);
                        columnModel.setColumnVisible(column, true);
                    }
                }
            });

            toolBarTop.add(reset);

            // Create a JCheckBox for each column
            for (int i = 0; i < labelsCheckBox.size(); i++) {
                final int index = i;
                toolBarTop.add(new JCheckBox(new AbstractAction(labelsCheckBox.get(i)) {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        TableColumn column = columnModel.getColumnByModelIndex(index);
                        boolean visible = columnModel.isColumnVisible(column);
                        columnModel.setColumnVisible(column, !visible);
                    }
                }));
            }

            setLayout(new BorderLayout());
            add(toolBarTop, BorderLayout.NORTH);
            add(new JScrollPane(table), BorderLayout.CENTER);
            revalidate();
            repaint();
        }

        if (toolBarBottom == true) {
            final JToolBar toolBarDown = new JToolBar();

            toolBarDown.add(new JButton(new AbstractAction("Save Table") {
                @Override
                public void actionPerformed(ActionEvent e) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            }));
            add(toolBarDown, BorderLayout.SOUTH);
        }
    }

    public void fireTableDataChanged() {
        table.setModel(beanTableModel);
        table.revalidate();
        table.repaint();
    }

    public void updateTable(List l, List<String> columnNames) {
        beanTableModel.updateTable(l, columnNames);
    }
}

狗类:

public class Dog {

    private String name;
    private String race;

    public Dog(String name, String race)
    {
        this.name = name;
        this.race = race;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public String getName() {
        return name;
    }

    public String getRace() {
        return race;
    }     
}

PErson Class

public class Person {

    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

然后你只需要添加你可以在上面的链接中找到的BeanTableModel,RowTableModel和XTableColumnModel。或者,您可以从以下保管箱链接下载上述所有代码:All the necessary code - 14KB文件大小

因此,如果您运行代码,您将看到3 JButtons,如果您单击“创建表格!”按钮它确实工作正常,表创建。 如果您点击“与人一起编辑!”它将使用不同的List<Person>编辑表格,它将正常工作。但是当你点击“用狗编辑!”时它会尝试使用List<Dog>编辑表格,而不是更新列表。它产生了一个例外。 这是异常输出:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: java.lang.ClassCastException@6a22778a
    at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at MainPackage.BeanTableModel.getValueAt(BeanTableModel.java:229)
    at javax.swing.JTable.getValueAt(JTable.java:2720)
    at javax.swing.JTable.prepareRenderer(JTable.java:5718)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
    at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
    at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
    at javax.swing.JComponent.paintComponent(JComponent.java:778)
    at javax.swing.JComponent.paint(JComponent.java:1054)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)
    at javax.swing.JComponent.paint(JComponent.java:1063)
    at javax.swing.JViewport.paint(JViewport.java:731)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)
    at javax.swing.JComponent.paint(JComponent.java:1063)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1482)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1413)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1206)
    at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:770)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677)
    at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:682)
    at java.awt.EventQueue$3.run(EventQueue.java:680)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

我再次为这个相当大的代码道歉,但我真的被困在这里,我需要帮助才能找出问题所在。

--------------------------编辑----------------- ----------------

这是updateTable()方法代码:

public void updateTable(List l, List<String> columnNames)
    {
        super.setDataAndColumnNames(l, columnNames);
    }

在RowTableModel类上调用它:

protected void setDataAndColumnNames(List<T> modelData, List<String> columnNames) {
        this.modelData = modelData;
        this.columnNames = columnNames;
        columnClasses = new Class[getColumnCount()];
        isColumnEditable = new Boolean[getColumnCount()];
        fireTableStructureChanged();
    }

----------------------------编辑2 -------------- ----------------

这是我的'新'类LeftPanel:

public class LeftPanel extends JPanel {

    private JButton startButton;
    private JButton editWithDogButtton;
    private JButton editWithPerson;
    private TablePanel tablePanel;
    private JTable table;
    private BeanTableModel beanTableModel;
    private XTableColumnModel columnModel;

    public LeftPanel() {
        initComponents();
        tablePanel = TablePanel.getInstance();
        table = new JTable();
        columnModel = new XTableColumnModel();
    }

    public void initComponents() {
        startButton = new JButton("Create table!");
        editWithDogButtton = new JButton("Edit with dog!");
        editWithPerson = new JButton("Edit with person!");

        setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        add(startButton, constraints);

        constraints.gridx = 1;
        constraints.gridy = 0;
        add(editWithDogButtton, constraints);

        constraints.gridx = 1;
        constraints.gridx = 2;
        add(editWithPerson, constraints);

        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<Person> listPerson = new ArrayList<>();
                listPerson.add(new Person("John", "Spencer"));
                listPerson.add(new Person("Mike", "Strada"));
                listPerson.add(new Person("Johan", "Anderson"));

                ArrayList<String> columnLabels = new ArrayList<>();
                columnLabels.add("First name");
                columnLabels.add("Last name");

                tablePanel.createTable(Person.class, listPerson, true, true, columnLabels);
            }
        });

        editWithDogButtton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<Dog> listDog = new ArrayList<>();
                listDog.add(new Dog("Bob", "German Sheppard"));
                listDog.add(new Dog("Laika", "Bulldog"));

                ArrayList<String> columnLabels = new ArrayList<>();
                columnLabels.add("Dog's Name");
                columnLabels.add("Race");

                // Note to this code below 
                BeanTableModel<Dog> dogModel = new BeanTableModel<>(Dog.class);
                dogModel.insertRows(0, listDog);
                table.setModel(dogModel);
                table.setColumnModel(columnModel);
                table.createDefaultColumnsFromModel();
            }
        });

        editWithPerson.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<Person> listPerson2 = new ArrayList<>();
                listPerson2.add(new Person("Jessica", "Carlton"));
                listPerson2.add(new Person("Sthephanie", "Oujur"));
                listPerson2.add(new Person("Angela", "Parker"));

                ArrayList<String> columnLabels = new ArrayList<>();
                columnLabels.add("First Name2");
                columnLabels.add("Last Name2");

                tablePanel.updateTable(listPerson2, columnLabels); // It works!
            }
        });
    }

    public void createTable(Class c, List data) {
        beanTableModel = new BeanTableModel(c, data);
        table.setModel(beanTableModel);
        table.setColumnModel(columnModel);
        table.createDefaultColumnsFromModel();
    }
}

现在按下editWithDogButtton时没有异常,但JTable没有任何异常。我认为这可能是由于创建或隐藏了一个新表或某些东西,但我不确定......

1 个答案:

答案 0 :(得分:2)

BeanTableModel只能包含一种类型的对象。

您创建了TableModel来保存Person个对象,因此您无法向模型中添加Dog个对象。

如果您尝试删除模型中的所有Person对象并将其替换为Dog对象,则需要为Dog类创建一个全新的BeanTableModel。

编辑:

使用以下代码创建新模型:

BeanTableModel<Dog> dogModel = new BeanTableModel<Dog>(Dog.class);
dogModel.insertRows(...);
table.setModel( dogModel );

然后在你的情况下,因为你正在使用XTableColumnModel,你可能需要做额外的工作,我不知道它是如何工作的。

另外,我不确定您在updateTable()课程中创建TablePanel方法的原因。 RowTableModel具有允许您向模型动态添加数据的方法。没有必要将自己的updateTable()方法添加到BeanTableModel。