JTable Verileri sildikten veya güncelledikten sonra tablo modeli nasıl yenilenir.


90

Bu benim jTable'ım

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

Veriyi veritabanından almak ve tablo modeline koymak için bu yöntemi arayacağım

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

Şu anda tablo verilerini güncelledikten sonra tabloyu yenilemek için bu yöntemi kullanıyordum. Önce masayı temizleyeceğim

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

ve sonra tablo modelini yeniden yapılandırın, böylece jTable'ı yenileyecektir. Ama bunu yapmanın en iyi uygulamaları veya daha iyi bir yolu var mı diye düşünüyordum.

Yanıtlar:


119

JTableVerilerinizdeki değişiklikleri bildirmek istiyorsanız , şunu kullanın:
tableModel.fireTableDataChanged()

Gönderen belgeler :

Tüm dinleyicilere tablonun satırlarındaki tüm hücre değerlerinin değişmiş olabileceğini bildirir. Satırların sayısı da değişmiş olabilir ve JTable tabloyu sıfırdan yeniden çizmelidir. Tablonun yapısının (sütunların sırasına göre) aynı olduğu varsayılır.


güncelleme yaparken her zaman bu tableModel.fireTableDataChanged () 'i çağırdığımı mı söylüyorsunuz?
user236501

3
@ newbie123: Yalnızca yeni satırlar eklerseniz, bunun yerine fireTableRowsInserted'ı kullanabilirsiniz . Öte yandan, uygulaması DefaultTableModel.addRowzaten bunu halletmeli ... Tablonuz yenilenmedi addRowmi?
Peter Lang

4
Kullan setValueAt, DefaultTableModelolayı başlatır.
Peter Lang

19
javax.swing.table.AbstractTableModelArayüz TableModelyukarıda belirtilen yönteme sahip olmadığından , çağrının cast üzerinde yapılması gerektiğine dikkat edilmelidir
Milan Aleksić

@PeterLang lütfen soruma bakın: stackoverflow.com/questions/18282753/…
Sajad

20

Vakanız için daha hızlı yol:

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

Bir veya birkaç hücre değiştiğinde optimize edilmiş yol:

    ((AbstractTableModel) jTable.getModel()).fireTableCellUpdated(x, 0); // Repaint one cell.

1
Aslında jTable.invalidate () yönteminin yeniden çizmeyi gerçekten zorlayan yöntem olduğunu buldum.
Kevin Qiu

Doğru, ancak doğrulama yöntemi düzen sürecinin bir parçasıdır ve kapsayıcının üst öğelerini de etkiler. Öyleyse, düzeni yeniden yapmanız gerekiyorsa, onu kullanın. docs.oracle.com/javase/7/docs/api/java/awt/…
Daniel De León

8

bunu dene

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

2
Başlangıçta Tablonun modelini zaten aldığınız için sonunda jTable.setModel'e (tableModel) ihtiyacınız yoktur.
David George

2
DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.fireTableDataChanged(); // notifies the JTable that the model has changed

3
hayır, değil ... DefaultTableModel bu olayı uyguladı ve doğru bir şekilde uyguladı ...
mKorbel

1

Kullanması daha iyi olmaz mıydı java.util.Observableve java.util.Observerbu tablonun güncellenmesine neden olur mu?


7
hayır, emin değilim, bunu yapmayın, neden
JTable'ın

-4

Jtable'ımda 300 ms sonra otomatik olarak yenilenmesini böyle yaptım;

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

500'den fazla nesne gibi çok sayıda nesnede işe yarayacağından şüpheliyim, yalnızca başka bir yol sınıfınıza TableModelListener uygulamaktır, ancak onu nasıl kullanacağımı anlamadım. http://download.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange adresine bakın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.