Воссоздание JTable при обновлении содержимого

У меня есть приложение, которое использует в нем JTable. когда я добавляю что-то в базу данных, оно попадает в базу данных, но я не могу каким-то образом воссоздать JTable. Я пытался перекрасить(); метод, который создает мою таблицу, я пробовал Revalidate(); но тоже безуспешно

Я даже пытался вспомнить метод, но и это не помогло.

Действие выполняется следующим образом:

    @Override
public void actionPerformed(ActionEvent e) {

    if(e.getSource() == add) {
        model.insertValue(toDo.getText());
        model.getValue();
        view.createTable();
        toDo.setText("");
    }
}

и метод, который создает JTable

    public void createTable() {

    JTable table = new JTable();

    DefaultTableModel tableModel = new DefaultTableModel(new Object[][]{},new String[]{"To do","Date added", "Modify"});

    table.setSize(450, 600);


    table.setModel(tableModel);
    JScrollPane scrlPan=new JScrollPane(table);

    for(int i = 0; i < model.getId().size(); i++) {

        tableModel.addRow(new Object[]{
                model.getItem().get(i), 
                model.getDate().get(i), 
                model.getId().get(i)
                });
    }

    add(scrlPan);
    add(table.getTableHeader(), BorderLayout.NORTH);
    add(table, BorderLayout.CENTER);
}

любые идеи о том, как решить эту проблему?


person Reshad    schedule 09.01.2013    source источник
comment
Добавление тегов не требует затрат и помогает классифицировать просмотр и поиск, поэтому попробуйте выбрать более одного тега.   -  person Andrew Thompson    schedule 09.01.2013
comment
1) Создайте таблицу при запуске и при необходимости настройте модель. 2) Чтобы быстрее получить помощь, опубликуйте SSCCE.   -  person Andrew Thompson    schedule 09.01.2013


Ответы (3)


  • не изобретайте велосипед, найдите ResultSetTableModel (few code workarounds) или TableFromDatabase сделал @camickr

  • am обходной путь: EDT sensitive, JTables содержимое ждет, пока ResultSet не вернет все строки, Swing GUI замораживает или не несет ответственности за Key & Mouse events до тех пор, пока не будет выполнено долгое и сложное Object (JDBC), эта логика может подойти для небольших ResultSets из small DB tables, без открытия и закрытия Connection to Database , иначе придется использовать SwingWorker и Batch logics (например, обновление XxxTableModel with 20rows)

person mKorbel    schedule 09.01.2013

Следующий код, полученный непосредственно из вашего, работает у меня без проблем:

    JTable table = new JTable();
    final DefaultTableModel model = new DefaultTableModel(
            new Object[][] {}, new String[] { "To do", "Date added",
                    "Modify" });
    table.setModel(model);

    JFrame f = new JFrame();
    f.getContentPane().add(table);

    JButton b = new JButton("More ..");
    f.getContentPane().add(b, BorderLayout.NORTH);
    b.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < 2; i++) {
                model.addRow(new Object[] { "A" + i, "B" + i, "C" + i });
            }
        }
    });
    f.setSize(400, 400);
    f.setVisible(true);
    b.doClick();

Просто проверьте, что вы делаете по-другому. И последнее, что я могу подозревать - возможно, вы устанавливаете новые значения непосредственно из потока, отличного от Swing. Используйте SwingUtilities.invokeLater для установки значений.

Модели, производные от AbstractTableModel, должны вызывать унаследованный метод fireTableCellUpdated в вашей модели. Есть также больше триггеров для запуска прослушивателей изменения содержимого, которые JTable регистрирует, чтобы он мог обновлять себя при изменении модели. Используйте то, что подходит для вашего случая. Альтернативный способ, который может быть полезен для полного изменения содержимого, — это создать и установить полностью новую TableModel. Но в вашем случае это может быть неактуально, поскольку вы используете DefaultTableModel: эта функция уже реализована, ей не нужны repaint(), revalidate(), fireTableXYZ. Он должен делать все сам, как только вы установите новый контент.

person Audrius Meskauskas    schedule 09.01.2013
comment
В какой части моей модели мне нужно использовать функцию fireTableCellUpdated? потому что моя Модель ничего не знает о JTable, все это, на мой взгляд. Модель знает только обработку базы данных и отправку в представление. - person Reshad; 09.01.2013
comment
Хм... если вы хотите вызвать fireXX из кода вне tableModel - это нет-нет: сама модель должна уведомить своих слушателей. Лучше всего делать это внутри пользовательской реализации tableModel :-) - person kleopatra; 09.01.2013
comment
Ваша модель достаточно знает о своей таблице, поскольку она является производной от AbstractTableModel и имеет унаследованный код. Самое главное, он наследует addTableModelListener, который вызывается JTable, когда вы устанавливаете для него модель. Просто вызовите свою модель: myModel.fireTableCellUpdated(); . - person Audrius Meskauskas; 09.01.2013
comment
@AudriusMeškauskas ах, подождите, я неправильно понял .. мой плохой! но что мне делать с параметрами, которые я должен указать в myModel.fireTableCellUpdate();? потому что он не может быть пустым: S предлагает использовать eclipse fireTableChanged(); для этого не требуются параметры, но при его использовании на самом деле ничего не происходит. - person Reshad; 09.01.2013
comment
Если вы не уверены, где и что изменилось, или, может быть, изменилось все, может быть проще воссоздать и установить полностью новую модель. - person Audrius Meskauskas; 09.01.2013
comment
вот что я сделал, я сделал эту защищенную таблицу DefaultTableModel tableModel; и я называю это view.tableModel.fireTableStructureChanged(); в моем действии выполнено, но до сих пор никаких изменений. - person Reshad; 09.01.2013
comment
@Reshad никогда не вызывайте fireTableXxx для DefaultTableModel, этот уведомитель реализован и правильно - person mKorbel; 09.01.2013
comment
хм, так что в принципе мне ничего не нужно делать? (кстати, это тоже не работает) - person Reshad; 11.01.2013

Сделайте tableModel полем класса и обновляйте его, когда вам нужно. Не пересоздавайте объект table.

person Andremoniy    schedule 09.01.2013
comment
я пробовал это .. но не работал. Я думаю, что я реализовал это неправильно. не могли бы вы привести пример? - person Reshad; 09.01.2013
comment
@Reshad попробуйте tableModel.fireTableDataChanged() после смены модели. Также посмотрите на это: stackoverflow.com/questions/3179136/ - person Andremoniy; 09.01.2013
comment
нет, никогда не вызывайте какие-либо методы fireXX из кода, внешнего по отношению к модели - model несет ответственность за уведомление своих слушателей об изменении - person kleopatra; 09.01.2013
comment
@kleopatra, почему вы сказали никогда не вызывать какие-либо методы fireXX из кода, внешнего по отношению к модели? Как вы можете это объяснить? Кроме того, я предоставил ссылку на вопрос и его ответ с самым высоким рейтингом. Вы будете спорить с этими экспертами? - person Andremoniy; 09.01.2013
comment
OP использует DefaultTableModel, поэтому нет необходимости явно вызывать метод fireXX. Сама DefaultTableModel делает это при изменении данных таблицы. Насколько я знаю, что бы вы ни делали с данными таблицы, это нужно делать с tableModel. Таким образом, ваша табличная модель должна вызывать методы fireXX всякий раз, когда она обновляется. Думаю, именно поэтому клеопатра так сказала. - person Amarnath; 09.01.2013