Темы и jtable

У меня проблема с jtable.

У меня есть несколько потоков, и каждый из них должен добавить строку в jTable, но таблица остается пустой. Я'Работая с NetBeans, графика полностью отделена от логики. Может кто-то помочь мне, пожалуйста?

это код, который я использую для добавления строки

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) {
    }
 Maxim Shoustin15 нояб. 2012 г., 23:38
У вас есть проблема (таблица остается пустой), пожалуйста, предоставьте нам фрагменты вашего кода, чтобы мы могли помочь вам
 mKorbel16 нояб. 2012 г., 08:16
@mav для лучшей помощи, скорее отправьтеSSCCEс жестко закодированными значениями для потоков, короткими, запускаемыми, компилируемыми, иначе все здесь может быть только выстрелом в темноту

Ответы на вопрос(6)

JTableважно удалить любойtableModelListener перед обновлением модели. Я видел это наблюдение сmodel.addColumn() а такжеtable.moveColumn(), Убедитесь, что вы добавилиtableModelListener после любых изменений, внесенных в модель.

потоков, отличных от потока диспетчеризации событий AWT, используйте

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

вы знаете, что Swing не является потокобезопасным (за редким исключением). Вы должны позаботиться об этом в своем коде.

 MadProgrammer16 нояб. 2012 г., 00:20
Тот'больше комментариев
 Addict16 нояб. 2012 г., 00:23
Дон»у меня нет разрешения начать комментировать :)
public class TM extends AbstractTableModel {
final Listids;

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);
 mKorbel16 нояб. 2012 г., 17:24
дон»читаю правильно, мой плохой
 rimas16 нояб. 2012 г., 17:21
Пожалуйста, прокрутите код немного вниз и найдите метод addRow (int id). В небольшом примере я разместил в моей таблице только один столбец, и я использовал очень простое хранилище (список). Вызывая метод addRow, вы можете вставить новую строку в модель и обновить таблицу потокобезопасным способом.
 mKorbel16 нояб. 2012 г., 16:45
and each of them have to add a row to the jTableпожалуйста где есть методы дляaddRow, Есть толькоgetXxx методы, пожалуйста, чтобы удалить этот ответ

Дон»изменить пользовательский интерфейс из любого потока, кроме потока диспетчеризации событий

Во-первых, убедитесь, что ваши обновления звонки синхронизируются, используяSwingUtilities#invokeLater или если обновление имеет решающее значение для пути кодаSwingUtilities#invokeAndWait

При добавлении строк в модель таблицы вы несете ответственность за запуск событий обновления, необходимых для уведомления представления об изменении модели.

Если ты'используяDefaultTableModel тогда это будет сделано для вас, если выиспользуяAbstractTableModel или вы владеетеTableModel тогда вам нужно будет сделать это самостоятельно.

Самый простой способ - написать реализацию, которая выходит изAbstractTableModel и позвонитьAbstractTableModel#fireTableRowsInserted(int, int) из вашего метода добавления, это скажетJTable что модель добавила строки и заставит таблицу обновляться сама по себе.

Дон»обмануть, используяfireTableRowsInserted как правило, быстрее, чем с помощьюfireTableDataChanged при добавлении строк в модель таблицы, поскольку вся таблица неТ нужно перекрасить. Если ты'мы значительно изменили таблицу (добавили / удалили / обновили много строк), затемfireTableDataChanged будет быстрее, чем серия отдельных вставок / удаленных / обновленных вызовов.

Посмотри наКак использовать таблицы а такжеПараллелизм в Swing для дополнительной информации

ОБНОВЛЕНО

Похоже, что я, возможно, не прояснил себя. Модель отвечает за пожарные события. Это означает, что в вашем методе add вы должны вызыватьfireTableRowsInserted, Вы должны воздерживаться от вызова этих методов из внешнего источника.

 MadProgrammer16 нояб. 2012 г., 00:31
@SteveKuo Точно, "модель» отвечает за отправку событий. Когда OP вызывает там метод add, они должны вызывать соответствующийfireTableXxx от с в этом методе. Извините, если я несделать это ясно
 Steve Kuo16 нояб. 2012 г., 20:39
Если вы посмотрите наDefaultTableModel исходный код, он запускает событие change при вызове addRow, insertRow и т. д. Я хочу сказать, что хорошо написанная табличная модель должна автоматически инициировать события изменения, когда ее состояние изменилось. Клиент, модифицирующий модель таблицы, не должен вручную запускать события изменения.
 Steve Kuo16 нояб. 2012 г., 00:26
Я бы сказал, что табличная модель отвечает за запуск событий обновления. Единственная причинаAbstractTableModel Есть методы общественного огня для делегирования.
 MadProgrammer16 нояб. 2012 г., 20:57
@ SteveKuo, и мы согласны с вами. Другая проблема, которую следует учитывать, заключается в том, что Swing небезопасен для потоков, поэтому даже если ваша модель делает то, что должна, если вызывающая сторона не выполняет контракт EDT, вы 'все еще будут проблемы;)
 mKorbel16 нояб. 2012 г., 08:14
@Steve Kuo такие же проблемы с DefaultTableModel, в случае, если вы 'измененное значение модели из EDT

как вы добавляете строки? Надеюсь, используя модель, верно? После добавления новой строки вы должны вызвать модельs метод fireTableDataChanged /не лучший вариант/ или fireTableRowsInserted /лучше/ И не забудьте сделать это с помощью SwingUtilities.invokeLater, чтобы избежать проблем Swing

 mav16 нояб. 2012 г., 13:59
да с table.setModel (новый DefaultTableModel (data, columnName));
 rimas16 нояб. 2012 г., 16:17
Более правильным будет создать собственную модель таблицы, которая расширяет DefaultTableModel, а затем установить ее для вашей таблицы. См пример ниже

Ваш ответ на вопрос