Unable to populate SummaryTable with results

2019-08-29 08:16发布

问题:

    private void myProfileTabStateChanged(javax.swing.event.ChangeEvent evt) {                                          
    if (myProfileTab.getSelectedComponent() == EditProfile) {
        editProfile();
    } else if (SearchAcademic == myProfileTab.getSelectedComponent()) {
        AcademicDAO aDao = new AcademicDAO();
        try {
            List<AcademicDTO> listAll = aDao.listAll(AcademicDTO.class);
            searchTable.setData(listAll);
        } catch (DBException ex) {
            Logger.getLogger(MainMenu.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}  





public class ListDataUI<T extends BaseDTO> extends javax.swing.JPanel {

    public ListDataUI() {
        this.summaryColumnsAndTheirViewNames = Collections.emptyMap();
        this.dtoSummaryFields = Collections.emptyList();
        this.summaryTableModel = new SummaryTableModel();
        initComponents();
        this.summaryTable.setModel(summaryTableModel);
        initListeners();
    }

    /**
     * Creates new form ListDataUI
     */
    public ListDataUI(LinkedHashMap<String, String> summaryColumnsAndTheirViewNames) {
        this.summaryColumnsAndTheirViewNames = summaryColumnsAndTheirViewNames;
        this.dtoSummaryFields = new ArrayList<String>(summaryColumnsAndTheirViewNames.keySet());
        this.summaryTableModel = new SummaryTableModel();
        initComponents();
        this.summaryTable.setModel(summaryTableModel);
        initListeners();
    }

    public ListDataUI(List<String> dtoSummaryFields) {
        this.summaryColumnsAndTheirViewNames = Collections.emptyMap();
        this.dtoSummaryFields = new ArrayList<String>(dtoSummaryFields);
        this.summaryTableModel = new SummaryTableModel();
        initComponents();
        this.summaryTable.setModel(summaryTableModel);
        initListeners();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        tableSp = new javax.swing.JScrollPane();
        summaryTable = new javax.swing.JTable();

        setLayout(new java.awt.BorderLayout());

        summaryTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        tableSp.setViewportView(summaryTable);

        add(tableSp, java.awt.BorderLayout.CENTER);
    }// </editor-fold>                        
    // Variables declaration - do not modify                     
    private javax.swing.JTable summaryTable;
    private javax.swing.JScrollPane tableSp;
    // End of variables declaration                   
    private List<T> data;
    private Map<String, String> summaryColumnsAndTheirViewNames;
    private List<String> dtoSummaryFields;
    private SummaryTableModel summaryTableModel;

    public List<T> getData() {
        return data;
    }

    public void removeSelectedDataRow() {
        final int selectedRow = summaryTable.getSelectedRow();
        if (selectedRow != -1) {
            final int modelIndex = summaryTable.convertRowIndexToModel(selectedRow);
            data.remove(modelIndex);
            summaryTableModel.fireTableRowsDeleted(modelIndex, modelIndex);
        }
    }

    public void setData(List<T> data) {
        this.data = data;
        summaryTableModel.fireTableDataChanged();
        if (data.size() > 0) {
            summaryTable.getSelectionModel().setSelectionInterval(0, 0);
        }
    }

I am trying to show the row data from database in the table searchTable , to which I invoke the setData() method. I set a breakpoint at the line `searchTable.setData(listAll);', listAll has all the data from database, but doesnt showup on searchTable.

回答1:

The problem is at not moment is the model of your JTable connected to your data. So your JTable and its TableModel have absolutely no knowledge of that List<T> data.

So basically you need to have a TableModel that receives your list and then fires an appropriate TableModelEvent. The TableModel should implement very few basic methods that indicate how to access the data and which data to display.

Find below a very basic example of such implementation (here it is based on a List of Person to display first name and last name). It should be pretty straightforward to adapt this to your case:

import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;

public class TestListTableModel {

    class MyTableModel extends AbstractTableModel {

        private List<Person> baseModel;

        public MyTableModel() {
            baseModel = new ArrayList<TestListTableModel.Person>();
        }

        public MyTableModel(List<Person> baseModel) {
            super();
            this.baseModel = new ArrayList<Person>(baseModel);
        }

        @Override
        public int getRowCount() {
            return baseModel.size();
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return "First Name";
            case 1:
                return "Last Name";
            }
            return null;
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 0:
                return getPersonAtIndex(rowIndex).getFirstName();
            case 1:
                return getPersonAtIndex(rowIndex).getLastName();
            }
            return null;
        }

        public Person getPersonAtIndex(int rowIndex) {
            return baseModel.get(rowIndex);
        }

        public int getIndexOfPerson(Person person) {
            return baseModel.indexOf(person);
        }

        public void addPerson(Person person) {
            baseModel.add(person);
            fireTableRowsInserted(baseModel.size() - 1, baseModel.size() - 1);
        }

        public void removePerson(Person person) {
            int removed = baseModel.indexOf(person);
            if (removed > -1) {
                baseModel.remove(removed);
                fireTableRowsDeleted(removed, removed);
            }
        }

        public void setBaseModel(List<Person> baseModel) {
            this.baseModel = baseModel;
            fireTableChanged(new TableModelEvent(this));
        }

    }

    protected void initUI() {
        List<Person> personModel = new ArrayList<TestListTableModel.Person>();
        personModel.add(new Person("John", "Smith"));
        personModel.add(new Person("Peter", "Donoghan"));
        personModel.add(new Person("Amy", "Peterson"));
        personModel.add(new Person("David", "Anderson"));
        JFrame frame = new JFrame(TestListTableModel.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MyTableModel tableModel = new MyTableModel();
        JTable table = new JTable(tableModel);
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setVisible(true);
        tableModel.setBaseModel(personModel);
    }

    public class Person {
        private final String firstName;
        private final 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 static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestListTableModel().initUI();
            }
        });
    }

}


回答2:

Firstly you should create a TableModel to your JTable. Any update on the data should be done on the table model.

Set the data to the TableModel. If each row is an Object then add objects to the TableModel list.

Then set the model to your table using setModel method. Ex: table.setModel(customModel);

P.S: Prefer DefaultTableModel where all the required methods have been implemented, than going for AbstractTableModel.