在 Eclipse SWT/JFace 開發中,TableViewer 需要 ITableLabelProvider 來提供每欄的文字與圖示。傳統寫法需針對每種資料類型撰寫 if-else 判斷欄位,缺乏彈性。本文展示如何利用 Java 反射機制,動態根據欄位索引讀取物件的公開欄位值,實現通用的 Label Provider。
import java.lang.reflect.Field;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.swt.graphics.Image;
/**
* 通用 TableViewer Label Provider,利用反射動態獲取欄位值
*/
public class TableViewerLabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null; // 本例不提供圖示
}
public String getColumnText(Object element, int columnIndex) {
Class> clazz = element.getClass();
Field[] fields = clazz.getFields(); // 僅取得 public fields
try {
return fields[columnIndex].get(element).toString();
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
return "";
}
// 以下為 IBaseLabelProvider 介面方法,本例不需邏輯
public void addListener(ILabelProviderListener listener) {}
public void dispose() {}
public boolean isLabelProperty(Object element, String property) { return false; }
public void removeListener(ILabelProviderListener listener) {}
}
使用方式:
// 原本寫法需針對每個屬性撰寫條件判斷 // if (columnIndex == 0) return p.getId().toString(); // if (columnIndex == 1) return p.getName(); // ... // 現在只需確保資料物件的欄位順序與表格欄位一致,且欄位為 public TableViewer viewer = new TableViewer(parent, SWT.FULL_SELECTION); viewer.setLabelProvider(new TableViewerLabelProvider()); viewer.setContentProvider(ArrayContentProvider.getInstance()); viewer.setInput(dataList);
優點:
注意:
public 欄位;若需存取私有欄位,可改用 getDeclaredFields() 並設定 setAccessible(true)。