简体   繁体   English

使用新数据更新BeanTableModel - Java

[英]Updating a BeanTableModel with new Data - Java

I've a BeanTableModel that extends a RowTableModel . 我有一个BeanTableModel是延伸的RowTableModel And a XTableColumnModel that extends DefaultTableColumnModel . 以及扩展DefaultTableColumnModelXTableColumnModel Both Models came from this site: BeanTableModel and RowTableModel source 这两个模型都来自这个站点: BeanTableModel和RowTableModel源

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

Here is a brief runnable I've creating to replicate this error: 这是一个简短的runnable我创建复制此错误:

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. 注意:由于BeanTableModel,RowTableModel和XTableColumnModel是相当大的类,因为帖子上的char限制,我似乎无法在此处发布所有代码。 Therefore I've left a link to my dropbox account where you can download all the source files for this short runnable jar. 因此,我留下了一个指向我的Dropbox帐户的链接,您可以在其中下载这个短的可运行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 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 Class 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);
    }
}

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. 然后你只需要添加你可以在上面的链接中找到的BeanTableModel,RowTableModel和XTableColumnModel。 Or you can download all the code above from the following dropbox link: All the necessary code - 14KB file size 或者您可以从以下保管箱链接下载上面的所有代码: 所有必需的代码 - 14KB文件大小

So, if you run the code you'll see 3 JButtons , if you click on the "Create Table!" 因此,如果您运行代码,您将看到3个JButtons ,如果您单击“创建表!” 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. 它将使用不同的List<Person>编辑表,它将正常工作。 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. 它将尝试使用List<Dog>编辑表,而不是更新列表。 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: 这是updateTable()方法代码:

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

which calls this on RowTableModel Class: 在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();
    }

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

Here is my 'new' class LeftPanel: 这是我的“新”类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 . 现在按下editWithDogButtton时没有异常,但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. BeanTableModel只能包含一种类型的对象。

You created the TableModel to hold Person objects, so you can't just add a Dog object to the model. 您创建了TableModel来保存Person对象,因此您不能只将Dog对象添加到模型中。

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. 如果您尝试删除模型中的所有Person对象并将其替换为Dog对象,那么您需要为Dog类创建一个全新的BeanTableModel。

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. 然后在你的情况下,因为你正在使用XTableColumnModel,你可能需要做额外的工作,我不知道它是如何工作的。

Also, I'm not sure why you created an updateTable() method in your TablePanel class. 另外,我不确定为什么在TablePanel类中创建了TablePanel updateTable()方法。 The RowTableModel has methods that allows you to dynamically add data to the model. RowTableModel具有允许您向模型动态添加数据的方法。 There was no need to add you own updateTable() method to the BeanTableModel. 没有必要将自己的updateTable()方法添加到BeanTableModel。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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