Как получить данные JTable в виде массива - PullRequest
0 голосов
/ 22 января 2011

Я заполнил JTable через DefaultTableModel конструктором (Object[][] data, String[] headers).Пользователи могут редактировать таблицу, и я хочу иметь возможность загружать новые данные обратно в массив (Object[][]).Обратите внимание, что я предпочел бы не просто обновлять массив по крупицам, но иметь возможность просто полностью загрузить новый массив из таблицы.Как это можно сделать?

Ответы [ 5 ]

22 голосов
/ 22 января 2011

Вернемся к этому, подумав, что вам не нужно ничего настраивать - TableModel - это интерфейс, в котором есть все 3 вызова метода, которые вам нужны. :)

Сводка: получите модель для таблицы, проверьте ее класс и приведите ее к соответствующему классу (Abstract или Default TableModel) и используйте ее методы для загрузки вновь созданного массива. Какой-то psuedoCode:

public Object[][] getTableData (JTable table) {
    DefaultTableModel dtm = (DefaultTableModel) table.getModel();
    int nRow = dtm.getRowCount(), nCol = dtm.getColumnCount();
    Object[][] tableData = new Object[nRow][nCol];
    for (int i = 0 ; i < nRow ; i++)
        for (int j = 0 ; j < nCol ; j++)
            tableData[i][j] = dtm.getValueAt(i,j);
    return tableData;
}

Ваши заголовки не должны были изменить пользовательские изменения. Надеюсь, это поможет. С уважением, - М.С.

2 голосов
/ 21 июля 2015

Я хотел бы предложить небольшое улучшение ответа Манидипа Сенгупты. Вместо того, чтобы приводить table.getModel () к соответствующему классу, лучше просто работать с TableModel. Это также делает код более пригодным для повторного использования (не имеет значения, с какой реализацией TableModel фактически выполняется).

public Object[][] getTableData (JTable table) {
    TableModel dtm = table.getModel();
    int nRow = dtm.getRowCount(), nCol = dtm.getColumnCount();
    Object[][] tableData = new Object[nRow][nCol];
    for (int i = 0 ; i < nRow ; i++)
        for (int j = 0 ; j < nCol ; j++)
            tableData[i][j] = dtm.getValueAt(i,j);
    return tableData;
}
1 голос
/ 22 января 2011

Я заполнил JTable через DefaultTableModel с помощью (Object [] [] data, String [] заголовки)

DefaultTableModel - это динамическая модель, которая означает строки истолбцы могут быть добавлены динамически.Массивы не являются динамическими, поэтому при создании DefaultTableModel с использованием массивов данные из массивов копируются в вектор векторов.

Я хочу иметь возможность загружать новые данные обратно в массив (Object [] []).Я бы предпочел не просто обновлять массив побитно

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

Или, поскольку DefaultTableModel использует Вектор Векторов для хранения данных, вы можете использовать метод getDataVector () для доступа к данным.Затем вы получаете каждую строку из Vector и вызываете метод List.toArray () в строке Vector перед добавлением ее в свой массив.

В любом случае вам потребуется выполнить цикл по Векторам в модели.

Если вы хотите использовать 2D-массив в качестве хранилища для TableModel, вам нужно будет создать пользовательский TableModel, который использует предоставленный массив для хранения данных.После реализации всех необходимых методов интерфейса TableModel вам потребуется предоставить метод getTableDataArray () для возврата ссылки на массив.

0 голосов
/ 22 января 2011

С готовой реализацией JTable вы не можете.Когда вы инициализируете JTable с помощью Object[][] rowData, этот rowData используется анонимным экземпляром AbstractTableModel, но он недоступен как таковой извне.

public JTable(final Object[][] rowData, final Object[] columnNames) {
    this(new AbstractTableModel() {
        public String getColumnName(int column) { return columnNames[column].toString(); }
        public int getRowCount() { return rowData.length; }
        public int getColumnCount() { return columnNames.length; }
        public Object getValueAt(int row, int col) { return rowData[row][col]; }
        public boolean isCellEditable(int row, int column) { return true; }
        public void setValueAt(Object value, int row, int col) {
            rowData[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    });
}

Можно рассмотреть возможность создания подкласса как JTable, так и AbstractTableModel и «перезаписать» этоконструктор в JTable для создания вашей собственной реализации TableModel, которая будет хранить эту ссылку Object [] [] и возвращать ее с Object[][] getRowData().Или просто сохраните rowData как поле в самом подклассе JTable после вызова super(...) в этом конструкторе - если вы действительно не заботитесь о MVC.

Но вам нужно убедиться, что послетаблица редактируется, исходная модель сохраняется и не заменяется новым объектом модели (конечно, другого типа) с setModel.Если это так, то, чего вы хотите, достичь невозможно - вам нужно будет пройти через все ячейки.

0 голосов
/ 22 января 2011

Не с существующей моделью таблицы по умолчанию. Как правило, вам следует использовать табличную модель по умолчанию. Вы должны реализовать свою собственную модель таблицы (MyTableModel). Вы можете реализовать TableModel или расширить AbstractTableModel. Я предлагаю последнее, так как оно предоставляет несколько полезных методов. Есть 2 способа добиться того, что вы делаете

  1. введите ваши новые данные в новый экземпляр MyTableModel и вызовите JTable.setModel().
  2. Второй способ - создать метод в вызове MyTableModel, например, replaceData(T[][] data). Удерживайте ссылку на модель, которую таблица отображает в данный момент. Всякий раз, когда вы хотите заменить данные, звоните replaceData(). Предполагая, что вы расширяете AbstractTableModel, затем позвоните fireTableChanged(), чтобы уведомить таблицу.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...