class FirstColumnTableModel extends AbstractTableModel{ protected Obj ect[][] data = {
{"Текст", Color.black, new Boolean(true)},
{"Фон", new Color(130, 56, 187), new Boolean(true)},
{"Рамка", new Color(200, 45, 125), new Boolean(false)},
};
protected String[] colNames = {"Элемент", "Цвет", "Выбрать"};
public FirstColumnTableModel(){ super(); }
// Определяем обязательные методы
public int getRowCount(){ return data.length; }
public int getColumnCount(){ return data[0].length; }
public Object getValueAt(int row, int col){ return data[row][col]; }
// Запрещаем заполнять ячейки первого столбца public void setValueAt(Object value, int row, int col){ if (col != 0) data[row][col] = value;
// Сообщаем, что первый столбец нельзя редактировать public boolean isCellEditable(int row, int col){ return col != 0;
}
// Для визуализации содержимого ячеек графическим // компонентом определяем класс ячеек столбца public Class getColumnClass(int col){ return data[0][col].getClass();
}
// Для показа имен в строке заголовков public String getColumnName(int col){ return colNames[col];
}
}
Как видно из рис. 13.1, объект класса Boolean показан В таблице компонентом JCheckBox. Это результат действия метода getColumnClass (). На рис. 13.2 тот же объект изображен в стандартном виде. Но объект класса Color по-прежнему показан строкой — результатом действия метода toString ( ).
Рис. 13.1. Таблица со сложными объектами |
Класс DefaultTableModel кроме реализации методов интерфейса TableModel добавляет несколько конструкторов и полезных методов работы с моделью данных. Он создает редактируемую модель ячеек таблицы. Для хранения данных он создает вектор строк класса Vector, хранящий строки опять-таки в виде вектора. Получившийся вектор векторов хранится в
Конструктор по умолчанию DefaultTableModel () создает объект с нулевым количеством строк и столбцов.
Конструктор DefaultTableModel (int rowCount, int colCount) создает модель данных с заданным числом строк и столбцов. В ячейках этой модели — пустые ссылки null.
Конструкторы
DefaultTableModel(Vector data, Vector colNames);
DefaultTableModel(Object[][] data, Object[] colNames);
сразу же заполняют модель данными.
Еще два конструктора
DefaultTableModel(Vector colNames, int rowCount);
DefaultTableModel(Obj ect[] colNames, int rowNames);
задают модель с поименованными столбцами и пустыми строками.
Методы класса DefaultTableModel, как и положено модели данных, добавляют в конец модели строки методами addRow() и столбцы методами addColumn (), вставляют строку в указанное место методами insertRow( ). Аргументы этих методов могут быть типа Object или Vector.
Модель позволяет заполнить ячейки объектами методом
setValueAt(Object value, int row, int column);
Многочисленные методы getXxx () предоставляют сведения о модели.
В модели можно переставить строки методом
moveRow(int start, int end, int to);
Первые два аргумента — start и end — задают диапазон переставляемых строк, последний аргумент to — новый индекс строки, имевшей до перестановки индекс start.
Наконец, методы setDataVector() позволяют вообще заменить все содержимое модели, т. е. содержимое поля dataVector.
При создании модели ячеек таблицы часто бывает удобнее расширить класс DefaultTableModel, а не абстрактный класс AbstractTableModel. В листинге 13.3 показан пример такого расширения — модель заполняется сведениями о файлах, полученными из каталога, имя которого указывается в командной строке.
Листинг 13.3. Заполнение модели ячеек таблицы данными из каталога
import javax.swing.*; import javax.swing.table.*; import java.io.*; import java.util.*;
public class FileTable extends JFrame{
public FileTable(File dir){ super(" Таблица файлов");
JTable table = new JTable(new FileTableModel(dir));
add(new JScrollPane(table)); setSize(600, 400); setVisible(true);
setDefaultCloseOperation(EXIT ON CLOSE);
}
public static void main(String[] args){
File dir = args.length > 0 ? new File(args[0]) : new File(System.getProperty("user.home"));
new FileTable(dir);
}
}
class FileTableModel extends DefaultTableModel{
protected File dir; protected String[] fName;
protected String[] colName = new String[]{ "Имя", "Размер", "Дата и время",
"Каталог", "Для чтения", "Для записи"
};
protected Class[] colClass = new Class[]{ String.class, Long.class, Date.class, Boolean.class, Boolean.class, Boolean.class
};
public FileTableModel(File dir){ super(dir.list().length, 6); this.dir = dir; fName = dir.list();
}
public String getColumnName(int col){ return colName[col]; } public Class getColumnClass(int col){ return colClass[col]; }
public Object getValueAt(int row, int col){
File f = new File(dir, fName[row]); switch(col){
case 0: return fName[row];
case 1: return new Long(f.length());
case 2: return new Date(f.lastModified());
case 3: return f.isDirectory() ?
Boolean.TRUE : Boolean.FALSE; case 4: return f.canRead() ?
Boolean.TRUE : Boolean.FALSE; case 5: return f.canWrite() ?