Использование модели таблицы в EDT, созданной SwingWorker

У меня есть Swingworker для создания модели таблицы для обновления jTable при запуске программы. Но я не знаю, как я могу вызвать эту модель из EDT и применить эту модель к моей jtable?

Вот мой код Swingworker;

public class FillTable extends SwingWorker<DefaultTableModel, DefaultTableModel> {
    private final DefaultTableModel model;
    public FillTable(DefaultTableModel model) {
     this.model = model;
    }

   @Override
 protected DefaultTableModel doInBackground() throws Exception {
        ResultSet rsaccounts;
        Statement stmt;
        String queryaccounts = "select NAME from acc (nolock)\n" + "order by Name";

        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        String connectionUrl = "jdbc:sqlserver://192.100.100.23;" + "databaseName=Dbacc;" + "user=" + "sa" + ";" + "password=" + "sapassword!" + ";"; 
        Connection con = DriverManager.getConnection(connectionUrl);
        stmt = con.createStatement();
        rsaccounts = stmt.executeQuery(queryaccounts);
        ResultSetMetaData rsmd = rsaccounts.getMetaData();


        Vector<String> columnNames = new Vector<String>();
        columnNames.add(rsmd.getColumnName(1)); 
        System.out.println(columnNames);
        int columnCount = rsmd.getColumnCount();

        Vector<Vector<Object>> data = new Vector<Vector<Object>>();

       while (rsaccounts.next()) {
            Vector<Object> vector = new Vector<Object>();
            for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
            vector.add(rsaccounts.getObject(columnIndex));
            }
            data.add(vector);
       }

        rsaccounts.close();
        stmt.close();
        model = new DefaultTableModel(data, columnNames);
        return model;
    }


  protected void done() {
    try {
        TableModel model = get();
    } catch (InterruptedException | ExecutionException ex) {
        ex.printStackTrace();
    }
  }

}

Ниже метод возвращает ошибку; Исключение в потоке «AWT-EventQueue-0» java.lang.IllegalArgumentException: невозможно установить нулевую TableModel

private DefaultTableModel model1;

FillTable fff = new FillTable(model1);
        fff.execute();
        model1 = fff.model;

        jTable3.setModel(model1);

person Black White    schedule 22.02.2014    source источник
comment
Вы также могли бы просто попросить меня более подробно объяснить мой ответ, когда я ответил на ваш предыдущий пост, что вы должны обновить свою таблицу из done(), которая работает в EDT. Вы даже не проголосовали за мой ответ, который привлек ваше внимание к этой проблеме.   -  person sbrattla    schedule 22.02.2014


Ответы (1)


Когда вы выполняете что-то вроде

FillTable fff = new FillTable(model1);
fff.execute();
model1 = fff.model;
jTable3.setModel(model1);

тогда строка model1 = fff.model, скорее всего, будет выполнена до завершения работы SwingWorker. Вызов execute приведет к тому, что работа будет выполнена в фоновом режиме, а следующие строки будут выполнены независимо от того, завершена ли работа уже или нет.

Общий подход может заключаться в использовании модели в вашем методе done(), примерно следующим образом:

protected void done() {
    try {
        TableModel model = get();

        jTable3.setModel(model); // Use it here!

    } catch (InterruptedException | ExecutionException ex) {
        ex.printStackTrace();
    }
}

(Для этого вам нужно будет передать ссылку jTable3 на ваш SwingWorker, то есть передать ее конструктору и сохранить как поле в SwingWorker).

Могут быть более элегантные решения, но, судя по предоставленному коду, это, по крайней мере, кажется причиной ошибки и возможным решением.

person Marco13    schedule 22.02.2014
comment
Спасибо за решение. Это работает. Но мне интересно; Могу ли я использовать созданную модель таблицы из EDT не в Swingworker? - person Black White; 22.02.2014
comment
Вопрос мне не ясен. TableModel создается в doInBackground, и метод done() вызывается (в EDT), когда создание TableModel завершено. - person Marco13; 22.02.2014
comment
О, мой ответ: метод done() вызывается (в EDT), спасибо. - person Black White; 22.02.2014
comment
+1. Я удалил свой ответ, потому что ваш уже охватывает то, что я сказал. Отличная работа! - person dic19; 22.02.2014
comment
@ dic19 Не уверен, что это было необходимо. То, что вы сказали, тоже верно. Но чтобы избежать путаницы, я удалил (теперь недействительную) ссылку из своего ответа. - person Marco13; 22.02.2014
comment
@dic19 Спасибо, что напомнили мне о важной линейной модели = new DefaultTableModel(data, columnNames); Также я отредактировал свой вопрос сейчас. - person Black White; 22.02.2014