CardLayout 需手動管理卡片切換邏輯,JTabbedPane 內建分頁標籤、鍵盤導航、滾動標籤等功能,開發效率大幅提升。本文解析 Tabbed.java 範例,展示以 RTTI (執行期型別識別) 動態實例化面板的技巧。
public class Tabbed extends JPanel {
// [標籤文字, 面板 Class 物件]
static Object[][] panels = {
{ "Felix", Borders.class },
{ "The Professor", Buttons.class },
{ "Rock Bottom", ButtonGroups.class },
// ... 更多
};
static JPanel makePanel(Class c) {
String title = c.getName().substring(c.getName().lastIndexOf('.') + 1);
JPanel p = null;
try { p = (JPanel) c.newInstance(); } // RTTI 實例化
catch (Exception e) { e.printStackTrace(); }
p.setBorder(new TitledBorder(title));
return p;
}
public Tabbed() {
setLayout(new BorderLayout());
JTabbedPane tabbed = new JTabbedPane();
for (Object[] entry : panels)
tabbed.addTab((String) entry[0], makePanel((Class) entry[1]));
add(tabbed, BorderLayout.CENTER);
tabbed.setSelectedIndex(panels.length / 2); // 預設開啟中間分頁
}
}
panels 將「標籤文字」與「面板類別」解耦,新增分頁只需加一行資料,零修改邏輯代碼。Class.newInstance() (已棄用,現代用 clazz.getDeclaredConstructor().newInstance()) 依類別物件建立實例,配合 Class.getName() 取得簡單類名作為邊框標題。addTab(String title, Component comp):新增分頁,元件可為任意 JComponent。setSelectedIndex(int) / getSelectedIndex():程式控制當前分頁。JPanel 子類,確保 makePanel() 強制轉型安全。| 特性 | CardLayout | JTabbedPane |
|---|---|---|
| 使用者切換方式 | 需自行提供按鈕/選單 | 內建標籤點擊切換 |
| 標籤管理 | 無 | 自動佈局、捲動、圖示、工具提示 |
| 鍵盤無障礙 | 需自行實作 | 內建 Ctrl+Tab、左/右鍵導航 |
| 程式碼量 | 較多 (監聽器+切換邏輯) | 極少 (資料驅動即可) |
Object[][] 改為 List<TabEntry>,TabEntry 為 record 或 POJO,型別安全。ServiceLoader 或模組系統自動發現面板實作,完全解耦主程式與示範模組。JSplitPane 或 JDesktopPane 實現更複雜的多視圖工作台。JTabbedPane 是 Swing 中「開箱即用、功能完整」的典範,掌握資料驅動 + RTTI 模式,可快速構建可擴充的多視圖應用。