使用表模型
前面修改了後端。現在來看看前端。GUI 應用程式顯示表中的事件,如果沒 有模型,這項任務就非常單調乏味。為了避免在討論真正的介面時分心,我們來 看看這些模型是如何工作的,這樣後面就清楚是怎麼回事了。
什麼是表模型?
如果您曾經做過程式員,我告訴您需要顯示一個表中的資訊,那麼您就知道 需要採取一系列的步驟。需要安排不同的行和列,記錄哪一行代表哪個對象,等 等。如果還希望編輯表,那麼要完成的任務清單就更長了。
問題在於這一系列活動都是固定的。如果知道應用程式中要在好幾個地方做 同樣的事情,您可能就會決定建立某種自動化過程來簡化工作。當然,毫不奇怪 別人已經這樣做了。事實上,這種模型的概念就是 Swing 的一部分,Swing 是 組成 GUI 的 Java API。
應用程式使用 AbstractTableModel 對象告訴 GUI 如何執行動作,如填充表 、響應資料的修改。該模型在建立表時設定(參見 清單 15)。
清單 15. 利用表模型
...
this.eventModel = new EventTableModel();
reloadTableModel();
final JTable eventTable = new JTable(this.eventModel);
tablePanel.add(new JScrollPane(eventTable), BorderLayout.CENTER);
...
EventTableModel 類中定義了這些行為,因此 eventTable 對象立刻知道要 做什麼。我們來看看這個類。
定義表
第一步是將該類定義為 AbstractTableModel 的子類和定義表本身的結構, 如 清單 16 所示。
清單 16. 定義表本身
import java.sql.Connection;
import java.util.Date;
import javax.swing.table.AbstractTableModel;
public class EventTableModel extends AbstractTableModel {
String[] columns = { "Title", "Description", "Reminders To" };
EventClass[] events;
public int getRowCount() {
if (events != null) {
return events.length;
}
return 0;
}
public int getColumnCount() {
return columns.length;
}
public String getColumnName(int col) {
return columns[col];
}
}
EventClass[] 數組表示表要顯示的資料。行數就是該zo數組的大小。列用 columns 數組定義。
讀寫資料
Java 代碼開始顯示表格之後,需要知道每個儲存格顯示什麼資料,如 清單 17 所示。
清單 17. 為儲存格提供資料
...
public String getColumnName(int col) {
return columns[col];
}
public Object getValueAt(int rowIndex, int columnIndex) {
if ((events != null) && (rowIndex < events.length)
&& (columnIndex < columns.length)) {
switch (columnIndex) {
case 0:
return events[rowIndex].getTitle();
case 1:
return events[rowIndex].getDescription();
case 2:
return events[rowIndex].getRemindersTo();
default:
return null;
}
} else {
return null;
}
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if ((events != null) && (rowIndex < events.length)
&& (columnIndex < columns.length)) {
switch (columnIndex) {
case 0:
events[rowIndex].setTitle(aValue.toString());
break;
case 1:
events[rowIndex].setDescription(aValue.toString());
break;
case 2:
events[rowIndex].setRemindersTo(aValue.toString());
break;
}
}
}
}
如果儲存格是可編輯的 —— 可使用行列資訊為每個儲存格設定該屬性 —— GUI 需要知道如果使用者編輯了該儲存格那麼該如何做。在這裡 GUI 為適當的 EventClass 對象設定適當的資料。