Где должно быть определение моих необязательных методов DefaultTableModel?

Я использую этот 3 класс для показа данных из базы данных в JTable,

public class TableContent {

private final Vector<String> headers;
private final Vector<Vector<String>> content;

public TableContent(final Vector<String> headers, final Vector<Vector<String>> content) {
this.headers = headers;
this.content = content;
  }

public Vector<String> headers() {
return headers;
}

public Vector<Vector<String>> content() {
return content;
}

А также:

public class TableData {

public TableContent getData() {
Vector<String> headers = new Vector<String>();
Vector<Vector<String>> content = new Vector<Vector<String>>();

try {
    Connection conn = DriverManager.getConnection("");
    Statement statement = conn.createStatement();
    ResultSet rs = statement.executeQuery("Select * from table");

    headers = buildHeaders(rs);
    content = buildContent(rs);

} catch (SQLException e) {
    e.printStackTrace();
}

return new TableContent(headers, content);
 }

private Vector<String> buildHeaders(final ResultSet rs) throws SQLException {
Vector<String> headers = new Vector<String>();

int col = rs.getMetaData().getColumnCount();
for (int i = 1; i <= col; i++) {
    headers.add(rs.getMetaData().getColumnName(i));
    }
return headers;
}

private Vector<Vector<String>> buildContent(final ResultSet rs) throws SQLException {
Vector<Vector<String>> content = new Vector<Vector<String>>();

while (rs.next()) {
    int col = rs.getMetaData().getColumnCount();
    Vector<String> newRow = new Vector<String>(col);

    for (int i = 1; i <= col; i++) {
        newRow.add(rs.getString(i));
    }
    content.add(newRow);
 }
return content;
  }
 }
}

А также:

public class TableGUI extends JFrame {
// Create GUI and Show table
 }

Раньше я добавлял свои методы в расширенный класс DefaultTableModel. Теперь, как я могу определить эти методы и где это делать?

Обновить:

Например, я тестирую этот метод:

public class TableContent {
String dbUrl = "...";

private final Vector<String> headers;
private final Vector<Vector<String>> content;

public TableContent(final Vector<String> hdr, final Vector<Vector<String>> cnt) {
    headers = hdr;
    content = cnt;
}

public Vector<String> headers() {
    return headers;
}

public Vector<Vector<String>> content() {
    return content;
}
public void removeRow(int modelRow, Object rowID) {
    String removeQuery = "delete from table where id=?";
    Connection conn;
    PreparedStatement ps = null;
    try {
        conn = DriverManager.getConnection(...);
        ps = conn.prepareStatement(removeQuery);
        Object idValue = rowID;
        ps.setObject(1, idValue);
        if (ps.executeUpdate() == 1) {
            content.remove(modelRow);
         fireTableRowsDeleted(modelRow, modelRow);   // Error
        }
    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
}
}

Теперь здесь проблема fireTableRowsDeleted(...);!

Проблема означает, что IDE говорят, что cannot resolve methodfireTableRowsDeleted (целое, целое)`

2 ответа

Решение

Что это за 10-й вопрос по этой теме? Почему ваш опубликованный код для создания TableModel не похож на код, который я предложил в 9-й публикации? В этом примере кода я показал вам, как вернуть TableModel из метода. Вместо этого ваш код создает два вектора и пытается сохранить ссылку на эти векторы. Это НЕ способ сделать это. DefaultTableModel содержит данные, вам не нужна отдельная копия данных. Вы можете получить доступ к данным в модели с помощью метода getValueAt (..).

Как я уже говорил, у вас есть два варианта:

  1. Создайте вспомогательный класс с методами для обновления базы данных и TableModel.
  2. Расширьте DefaultTableModel, чтобы добавить эти методы.

Для вспомогательного класса вы бы определили метод как:

public void removeRow(DefaultTableModel model, int modelRow)
{
    Object rowID = model.getValueAt(modelRow, theColumn);

    // your code to delete row from database

    if (row delected successfully)
        model.removeRow(modelRow);
}

Вам не нужен rowID в качестве параметра, потому что вы можете получить данные из модели с помощью метода getValueAt(). Идея состоит в том, чтобы использовать методы DefaultTableModel для управления данными, а не изобретать велосипед. Все, что вы делаете, это добавляете код для обновления базы данных.

Если вы хотите создать CustomTableModel, расширив DefaultTableModel, то для вашего метода removeRow() не нужен DefaultTableModel в качестве параметра, и вы можете вызвать метод super.removeRow() объекта DefaultTableModel.

Я хочу добавить больше методов в мою модель стола. например, я хочу иметь возможность выбрать строку в таблице

Этот код может быть в ListSelectionListener, который добавляется в JTable, если вы хотите активировать какое-либо действие при выделении строки / столбца / ячейки. Если, с другой стороны, вы просто хотите воздействовать на выбранную в данный момент строку и / или столбец, когда происходит какое-либо другое событие, например нажатие кнопки или щелчок правой кнопкой мыши, вам даже не нужно добавлять ListSelectionListener, а лучше запросить таблицу для выбранной строки / столбца, а затем преобразовать индекс строки и / или столбца в модель, используя соответствующий convertXxxxIndexToModel(...) метод. Обязательно установите режим выбора таблицы соответствующим образом с setSelectionMode(...) согласно учебникам.

и удалите или отредактируйте его.

Код удаления начинается в любом событии, которое вы хотите использовать для запуска удаления, возможно, в классе AbstractAction, который может быть добавлен в JButton или всплывающее меню, или и то, и другое. Тогда это действие назовет deleteRow(...) метод в вашей TableModel.

Для более конкретной помощи, вы захотите показать нам свой код TableModel.


редактировать
По поводу вашего обновления. Вы заявляете:

Теперь здесь проблема в fireTableRowsDeleted(...);!

Пожалуйста, поймите, что мы можем понять только то, что вы нам сообщаете, и такое утверждение, как "проблема есть...", говорит нам почти ничего. Какие у вас проблемы? Разве это не компилируется? Если нет, пожалуйста, покажите сообщение об ошибке компилятора. Он компилируется, но выдает исключения? Если да, пожалуйста, опубликуйте полное исключение? Это заставляет ваш монитор выделять белый дым? Если это так, выключите компьютер, отсоедините его и уходите от него. Это дает вам пощечину и называет вас грязными именами? Какие?

И вы до сих пор не опубликовали код модели таблицы. т. е. не существует кода для классов, расширяющих какие-либо из TableModel, ни AbstractTableModel, ни DefaultTableModel. Код вашей модели не может работать по волшебству, и для родительских классов потребуется один из этих двух.


Редактировать 2
После прочтения ваших комментариев у меня сложилось впечатление, что вы полагаете, что ваш TableContent является вашей TableModel, и ожидаете, что он сможет компилироваться с помощью вызовов методов, таких как fireTableRowsDeleted(...) хотя ваш класс ничего не расширяет. Несколько советов:

  • Чтобы класс вел себя как TableModel, сначала он должен быть TableModel. В переводе на ООП это означает, что вы должны использовать наследование, так как этот класс должен удовлетворять критерию "is-a" объектно-ориентированного программирования.
  • Все классы TableModel должны по крайней мере расширять класс AbstractTableModel, или это не тот класс, а затем класс, который в конечном итоге расширяет его, поскольку этот класс содержит проводку, которая необходима для работы JTables с моделью.
  • Некоторые классы могут обойтись с расширением класса DefaultTableModel, который может сэкономить вам некоторую работу, поскольку вы можете легко использовать готовые методы этого класса.
  • Но чтобы расширить DefaultTableModel, вы должны поместить все данные модели в суперкласс, обычно вызывая соответствующий суперконструктор. Вы не можете иметь отдельное ядро ​​модели данных из суперкласса DefaultTableModel. Поэтому я не думаю, что это будет хорошо работать для ваших целей.
  • Вместо этого вам, вероятно, потребуется расширить AbstractTableModel, а затем написать свои собственные методы модели, стараясь запустить соответствующие методы уведомления (они начинаются с fire***(...)) всякий раз, когда вы меняете данные.
  • Другой вариант - использовать класс модели, который был создан другими, если они удовлетворяют вашим целям, например, класс модели таблицы Роба Камика, который хорошо работает с базами данных SQL, которые можно найти в его блоге.
  • Независимо от того, что вы делаете, крайне важно, чтобы вы не просто читали, но и изучали Swing JTable Tutorial, поскольку он содержит настоящий набор полезной и даже необходимой информации, которая вам понадобится. Вы можете найти этот и другие учебные пособия в Обучающем руководстве по действительно большому индексу Java.
Другие вопросы по тегам