Threads and jtable

橙三吉。 提交于 2019-12-02 16:30:58

问题


I have a problem with jtable.

I have a number of threads and each of them have to add a row to the jTable, but the table remains empty. I'm working with netbeans, the graphics are totally separate from the logic. Can someone help me, please?


this is the code that i use for adding a row

MainGui.java

public void addToTable(String from, String to, int request, int response, String timeElapsed) {
    Object [][] temp = new Object [data.length + 1][5];

    for (int i = 0; i < data.length; i++) {
        for (int j = 0; j < 5; j++) {
            temp[i][j] = data[i][j];
        }
    }

    temp[data.length][0] = from;
    temp[data.length][1] = to;
    temp[data.length][2] = request;
    temp[data.length][3] = response;
    temp[data.length][4] = timeElapsed;

    data = temp;
    table.setModel(new DefaultTableModel(data, columnName));
}

MyThread.java

public void run() {
    try {
        MainGui mg = new MainGui();
        mg.addtotable("null", "null", 0, 0, "null");
    } catch (Exception e) {
    }

回答1:


The first rule of Swing - Don't modify the UI from any Thread other then the Event Dispatching Thread

First, make sure your updates calls are synchronized, using SwingUtilities#invokeLater or if the update is critical to the code path SwingUtilities#invokeAndWait

When adding rows to the table model, you are responsible for firing the update events required to notify the view that the model has changed.

If you're using a DefaultTableModel then this will be done for you, if you're using an AbstractTableModel or you own TableModel then you will need to do this yourself.

The easiest way is to write an implementation that extends from AbstractTableModel and call AbstractTableModel#fireTableRowsInserted(int, int) from within your add method, this will tell the JTable that the model has added rows and will cause the table to update itself accordiningly.

Don't be fooled, using fireTableRowsInserted is generally faster then using fireTableDataChanged when adding rows to a table model as the whole table doesn't need to be repainted. If you've significantly changed the table (added/removed/updated lots of rows), then fireTableDataChanged would be quicker than a series individual insert/deleted/updated calls.

Have a look at How to Use Tables and Concurrency in Swing for more information

UPDATED

As it appears as I may not have made myself clear. The model is responsible for fire the events. That means, that within your add method, you should be calling fireTableRowsInserted. You should refrain from calling these methods from an external source.




回答2:


Swing is not thread-safe. If you need to modify Swing components from Threads other than the AWT event dispatch thread, use

SwingUtilities.invokeLater(new Runnable(){public void run() {
 // your code
}});



回答3:


public class TM extends AbstractTableModel {
final List<Integer>ids;

public TM() {
    ids = new ArrayList();
}

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

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

@Override
public String getColumnName(int column) {
    if(column == 0) {
        return "ID";
    } else {
        return "UNDEF";
    }
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    if(columnIndex == 0) {
        return ids.get(rowIndex);
    } else {
        return "NaN";
    }
}

public void addId(final int id) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            insertNewRow(id);
        }
    });
}

private void insertNewRow(int id) {
    ids.add(id);
    int rowIndex = ids.size();
    fireTableRowsInserted(rowIndex, rowIndex);
}

}

//Somewhere in your code
TM myModel = new TM();
myTable = new JTable(myModel);


//Somewhere from thread:
myModel.addId(123);

//Somewhere from another thread:
myModel.addInd(455);



回答4:


Could you please clarify how you adding rows? Hopefully using model, right? Once new row added you have to call model's method fireTableDataChanged/not the best option/ or fireTableRowsInserted/better/ And dont forget to do it using SwingUtilities.invokeLater to avoid problems Swing




回答5:


Also when trying to update a model of JTable, its important to remove any tableModelListener before updating the model. I saw this observation with model.addColumn() and table.moveColumn(). Make sure you add the tableModelListener after whatever changes gets made to the model.




回答6:


I hope you know that Swing is not thread safe(with few exceptions) . You need to take care of that in your code.



来源:https://stackoverflow.com/questions/13407418/threads-and-jtable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!