简体   繁体   中英

Updating a BeanTableModel with new Data - Java

I've a BeanTableModel that extends a RowTableModel . And a XTableColumnModel that extends DefaultTableColumnModel . Both Models came from this site: BeanTableModel and RowTableModel source

I can create the table and display data. I can update the table with new data but I CAN NOT update the table with new data from a different class.

Eg, I've a Names.class and I send a List<Names> to the table to print and it does so as expected. When I try to update the table with a different List<Names> it does update as well but when I try to update the table with a list of Dogs it will not update, in this case if I send a List<Dogs> it does not update the table and this is the main question here, how can I update the table with different class objects?!

Here is a brief runnable I've creating to replicate this error:

NOTE: It seems I can't post all the code in here due to the char limit on the post due to the BeanTableModel, RowTableModel and XTableColumnModel being quite big classes. Therefore I've left a link to my dropbox account where you can download all the source files for this short runnable jar.

Main class:

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

Design class:

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 class

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 Class

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

Dog Class:

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

Then you just need to add the BeanTableModel, RowTableModel and XTableColumnModel that you can find in the link above. Or you can download all the code above from the following dropbox link: All the necessary code - 14KB file size

So, if you run the code you'll see 3 JButtons , if you click on the "Create Table!" button it does work fine, the table is created. If you click on the "Edit with person!" it will edit the table with a different List<Person> and it will work fine. But when you click "Edit with dog!" it will try to edit the table this time with a List<Dog> and not updating the list. It is generated an exception. Here is the exception output:

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)

Again I apologise for this quite big code but I'm really stuck in here and I need help to figure out what is wrong.

-------------------------- EDIT ---------------------------------

Here is the updateTable() method code:

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

which calls this on RowTableModel Class:

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

---------------------------- EDIT 2 ------------------------------

Here is my 'new' class 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();
    }
}

Now there is no Exception when editWithDogButtton is pressed but nothing happens with the JTable . I think it may be due to a new table being created or hidden or something but I'm not sure...

A BeanTableModel can only contain objects of one type.

You created the TableModel to hold Person objects, so you can't just add a Dog object to the model.

If you are trying to remove all the Person object in the model and replace them with Dog objects, then you would need to create a completely new BeanTableModel for the Dog class.

Edit:

You create a new model with code like the following:

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

Then in your case because you are using XTableColumnModel you may need to do extra work, I'm not sure how it works.

Also, I'm not sure why you created an updateTable() method in your TablePanel class. The RowTableModel has methods that allows you to dynamically add data to the model. There was no need to add you own updateTable() method to the BeanTableModel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM