Swing 採用委託佈局模式:容器持有 LayoutManager,組件添加時附帶約束對象,佈局管理器負責計算組件位置與大小。核心優勢:跨平台一致性、容器尺寸變化自適應、國際化文本長度自適應。劣勢:精確像素級控制困難,複雜界面需嵌套多層面板組合。
JFrame (BorderLayout)
├── NORTH: JPanel (FlowLayout-LEFT) // 查詢條件區:Label + TextField + Button
├── CENTER: JScrollPane (JTable) // 數據展示區:自帶滾動條、列寬自適應
└── SOUTH: JPanel (FlowLayout-HGAP30) // 操作按鈕區:新增/刪除/修改 (等間距)
public class MainFrame extends JFrame {
public MainFrame() {
// 1. 根容器 BorderLayout
getContentPane().setLayout(new BorderLayout());
// 2. 北部查詢面板
JPanel northPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 10));
northPanel.setBackground(Color.RED); // 調試可視化
JLabel label = new JLabel("請輸入查詢條件");
label.setPreferredSize(new Dimension(100, 16));
JTextField textField = new JTextField();
textField.setPreferredSize(new Dimension(140, 22));
JButton queryBtn = new JButton("查詢");
queryBtn.addActionListener(e -> loadTableData());
northPanel.add(label);
northPanel.add(textField);
northPanel.add(queryBtn);
// 3. 中部數據表格 (自帶滾動)
JTable table = new JTable();
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // 開啟水平滾動
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.getViewport().add(table);
// 4. 南部操作按鈕面板
JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 30, 5));
southPanel.setBackground(Color.ORANGE);
JButton addBtn = new JButton("新增");
JButton delBtn = new JButton("刪除");
JButton editBtn = new JButton("修改");
southPanel.add(addBtn);
southPanel.add(delBtn);
southPanel.add(editBtn);
// 5. 組裝
add(northPanel, BorderLayout.NORTH);
add(scrollPane, BorderLayout.CENTER);
add(southPanel, BorderLayout.SOUTH);
// 6. 窗口屬性
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 350);
setLocationRelativeTo(null); // 居中顯示
setVisible(true);
}
private void loadTableData() {
// 模擬 30 列 × 100 行數據
Vector cols = new Vector<>();
for (int i = 1; i <= 30; i++) cols.add("列" + i);
Vector> rows = new Vector<>();
for (int r = 1; r <= 100; r++) {
Vector
| 管理器 | 適用場景 | 關鍵約束/屬性 | 典型組合 |
|---|---|---|---|
| BorderLayout | 主窗口/面板宏觀五區劃分 | NORTH/SOUTH/EAST/WEST/CENTER (唯一) | 根容器、分割面板 |
| FlowLayout | 按鈕組、工具欄、標簽+輸入框行 | Alignment (LEFT/CENTER/RIGHT)、Hgap/Vgap | 嵌套在 BorderLayout 區域內 |
| GridLayout | 計算器鍵盤、表單網格、等分區域 | rows/cols/hgap/vgap (強制等寬高) | 表單面板、屬性表 |
| GridBagLayout | 複雜表單、報表設計器、精確對齊 | GridBagConstraints (gridx/y, weightx/y, fill, anchor, insets, ipadx/y) | 最強大但最複雜,建議 GUI 建模工具生成 |
| BoxLayout | 垂直/水平堆疊、工具欄、側邊欄 | X_AXIS/Y_AXIS、glue/strut/rigidArea | 替代 GridBag 簡單場景 |
| CardLayout | 向導對話框、Tab 切換、狀態視圖切換 | first/next/previous/last/show(name) | JTabbedPane 內部實現 |
| SpringLayout | GUI 建模器內部、組件間彈簧約束 | Spring/Constraint (邊緣關係) | 極少手寫 |
| GroupLayout | Matisse (NetBeans GUI Builder) 專用 | SequentialGroup/ParallelGroup、Gap、Baseline 對齊 | IDE 可視化設計產出 |
| MigLayout (第三方) | 現代 Swing/JavaFX 通用、字符串約束 DSL | "wrap", "span", "grow", "push", "align", "size" | 強烈推薦手寫代碼首選 |
setPreferredSize() 是佈局管理器計算的關鍵依據,而非 setSize()table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF) + JScrollPaneSwingUtilities.invokeLater()setBorder(BorderFactory.createTitledBorder("Name")) 可視化邊界setLayout(null) + setBounds() 破壞自適應,僅用於極特殊場景 (圖形編輯器、遊戲)miglayout-swing,單字符串約束搞定 90% 複雜界面,語法可讀、可維護、跨平台完美$$$setupUI$$$()、支持 GridLayoutManager (類 GridBag)建議:先手寫掌握原理,再用工具提效。MigLayout 讓手寫代碼重獲生產力,複雜項目首選 IntelliJ GUI Designer + MigLayout 混合模式。