JTable Comment actualiser le modèle de table après l'insertion, supprimer ou mettre à jour les données.

89

C'est ma jTable

private JTable getJTable() {
    String[] colName = { "Name", "Email", "Contact No. 1", "Contact No. 2",
            "Group", "" };
    if (jTable == null) {
        jTable = new JTable() {
            public boolean isCellEditable(int nRow, int nCol) {
                return false;
            }
        };
    }
    DefaultTableModel contactTableModel = (DefaultTableModel) jTable
            .getModel();
    contactTableModel.setColumnIdentifiers(colName);
    jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    return jTable;
}

J'appellerai cette méthode pour récupérer les données de la base de données et les mettre dans un modèle de table

public void setUpTableData() {
    DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();
    ArrayList<Contact> list = new ArrayList<Contact>();
    if (!con.equals(""))
        list = sql.getContactListsByGroup(con);
    else
        list = sql.getContactLists();
    for (int i = 0; i < list.size(); i++) {
        String[] data = new String[7];

            data[0] = list.get(i).getName();
            data[1] = list.get(i).getEmail();
            data[2] = list.get(i).getPhone1();
            data[3] = list.get(i).getPhone2();
            data[4] = list.get(i).getGroup();
            data[5] = list.get(i).getId();

        tableModel.addRow(data);
    }
    jTable.setModel(tableModel);
}

Actuellement, j'utilisais cette méthode pour actualiser la table après avoir mis à jour les données de la table. Je vais d'abord débarrasser la table

DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();
tableModel.setRowCount(0);

puis restructurez à nouveau le modèle de table pour qu'il actualise le jTable. Mais je pensais qu'il y avait des meilleures pratiques ou une meilleure façon de le faire?

user236501
la source

Réponses:

119

Si vous souhaitez vous informer des JTablemodifications de vos données, utilisez
tableModel.fireTableDataChanged()

De la documentation :

Avertit tous les écouteurs que toutes les valeurs de cellule des lignes de la table peuvent avoir changé. Le nombre de lignes peut également avoir changé et le JTable doit redessiner le tableau à partir de zéro. La structure de la table (comme dans l'ordre des colonnes) est supposée être la même.

Peter Lang
la source
voulez-vous dire que j'appelle cette tableModel.fireTableDataChanged () à chaque fois que je fais la mise à jour?
user236501
3
@ newbie123: Si vous n'insérez que de nouvelles lignes, vous pouvez utiliser à la place fireTableRowsInserted . En revanche, l'implémentation de DefaultTableModel.addRowdevrait déjà gérer ça ... Votre table n'est-elle pas rafraîchie par addRow?
Peter Lang
4
Utiliser setValueAt, DefaultTableModeldéclenche l'événement.
Peter Lang
18
Il faut noter cependant que l'appel doit être effectué sur casté javax.swing.table.AbstractTableModel, car l'interface TableModeln'a pas la méthode mentionnée ci-dessus
Milan Aleksić
@PeterLang voir ma question s'il vous plaît: stackoverflow.com/questions/18282753/…
Sajad
20

Le moyen le plus rapide pour votre cas est:

    jTable.repaint(); // Repaint all the component (all Cells).

La manière optimisée quand une ou plusieurs cellules changent:

    ((AbstractTableModel) jTable.getModel()).fireTableCellUpdated(x, 0); // Repaint one cell.
Daniel De León
la source
1
En fait, j'ai trouvé que jTable.invalidate () était la méthode qui a forcé un redessiner.
Kevin Qiu
Bien, mais la méthode validate fait partie du processus de mise en page et a également un impact sur les parents du conteneur. Donc, si vous avez besoin de refaire la mise en page, utilisez-la. docs.oracle.com/javase/7/docs/api/java/awt/…
Daniel De León
7

essaye ça

public void setUpTableData() {
    DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();

    /**
    * additional code.
    **/
    tableModel.setRowCount(0);
    /**/
    ArrayList<Contact> list = new ArrayList<Contact>();
    if (!con.equals(""))
        list = sql.getContactListsByGroup(con);
    else
        list = sql.getContactLists();
    for (int i = 0; i < list.size(); i++) {
        String[] data = new String[7];

        data[0] = list.get(i).getName();
        data[1] = list.get(i).getEmail();
        data[2] = list.get(i).getPhone1();
        data[3] = list.get(i).getPhone2();
        data[4] = list.get(i).getGroup();
        data[5] = list.get(i).getId();

        tableModel.addRow(data);
    }
    jTable.setModel(tableModel);
    /**
    * additional code.
    **/
    tableModel.fireTableDataChanged();
    /**/
}
Achille
la source
2
Vous n'avez pas besoin du jTable.setModel (tableModel) à la fin car vous avez déjà le modèle de Table au début.
David George
2
DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.fireTableDataChanged(); // notifies the JTable that the model has changed
Sumit Singh
la source
3
non, pas ... DefaultTableModel a implémenté cet événement, et mis en œuvre correctement ...
mKorbel
1

Ne serait-il pas préférable de l'utiliser java.util.Observableet java.util.Observercela entraînera une mise à jour du tableau?

à M
la source
6
pas, bien sûr, ne faites pas cela, pourquoi a simulé l'option intégrée de JTable et sortie d'EDT
mKorbel
-4

Je l'ai fait comme ça dans ma Jtable, son autorefreshing après 300 ms;

DefaultTableModel tableModel = new DefaultTableModel(){
public boolean isCellEditable(int nRow, int nCol) {
                return false;
            }
};
JTable table = new JTable();

Timer t = new Timer(300, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                addColumns();
                remakeData(set);
                table.setModel(model);
            }
        });
        t.start();

private void addColumns() {
        model.setColumnCount(0);
        model.addColumn("NAME");
            model.addColumn("EMAIL");} 

 private void remakeData(CollectionType< Objects > name) {
    model.setRowCount(0);
    for (CollectionType Objects : name){
    String n = Object.getName();
    String e = Object.getEmail();
    model.insertRow(model.getRowCount(),new Object[] { n,e });
    }}

Je doute que cela fasse du bien avec un grand nombre d'objets comme plus de 500, le seul autre moyen est d'implémenter TableModelListener dans votre classe, mais je n'ai pas compris comment bien l'utiliser. regardez http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

nkvnkv
la source