首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Swing 省市二級聯動下拉框:Map 資料結構與 JComboBox 事件驅動完整實戰

     編輯:Java 程式設計入門

專案概述

本範例構建一個 Swing 表單介面,包含「省/直轄市」與「市/縣」兩個 JComboBox,實現經典的二級聯動效果:選擇省份後,城市下拉框即時更新為該省份對應的城市列表。資料結構採用 LinkedHashMap<String, String[]> 保持省份順序,UI 採用 DefaultComboBoxModel 動態綁定資料。

資料層:省市映射表

CityMap 類別靜態初始化全國 34 個省級行政區及其轄下城市:

public class CityMap {
    public static Map<String, String[]> model = new LinkedHashMap<>();
    static {
        model.put("北京", new String[]{"北京"});
        model.put("上海", new String[]{"上海"});
        model.put("廣東", new String[]{"廣州","深圳","佛山","東莞", ...});
        // ... 其餘省份
    }
}
使用 LinkedHashMap 保證遍歷順序與插入順序一致,下拉框顯示順序穩定。

UI 層:主視窗與元件佈局

MainFrame 繼承 JFrame,採用絕對佈局 (null layout) 配合 BackgroundPanel 繪製背景圖:

public class MainFrame extends JFrame {
    private JComboBox<String> comboBox;      // 省份
    private JComboBox<String> cityComboBox;  // 城市
    ...
}

核心邏輯方法

1. 獲取省份陣列

public Object[] getProvince() {
    Set<String> set = CityMap.model.keySet();
    return set.toArray(); // 直接轉 Object[] 供 DefaultComboBoxModel 使用
}

2. 根據省份獲取城市陣列

public String[] getCity(String province) {
    return CityMap.model.get(province);
}

3. 省份變更事件處理

comboBox.addItemListener(e -> {
    if (e.getStateChange() == ItemEvent.SELECTED) {
        String province = (String) comboBox.getSelectedItem();
        cityComboBox.removeAllItems();
        cityComboBox.setModel(new DefaultComboBoxModel<>(getCity(province)));
    }
});

輔助類別

  • BackgroundPanel:繼承 JPanel,重寫 paintComponent() 繪製拉伸背景圖。
  • SwingResourceManager:資源快取管理器,支援從 Classpath、檔案系統載入圖片/圖示並快取。

執行效果

省市聯動效果圖

介面包含:姓名、性別、省市聯動、詳細地址、Email、儲存/重置按鈕,模擬真實註冊表單場景。

技術亮點與最佳實踐

維度做法優勢
資料結構LinkedHashMap<String, String[]>有序、查找 O(1)、記憶體緊湊
模型驅動DefaultComboBoxModel分離資料與視圖,支援動態替換
事件處理ItemListener + SELECTED 狀態過濾避免雙重觸發(DESELECTED + SELECTED)
資源管理SwingResourceManager 快取避免重複載入圖片,提升效能
背景繪製自定義 JPanel + paintComponent輕量級背景,不干擾子元件佈局

常見坑點與改進

  • ItemListener 雙重觸發:必須判斷 e.getStateChange() == ItemEvent.SELECTED,否則邏輯執行兩次。
  • null 省份防護:getCity() 應檢查 province != null,否則 map.get(null) 回傳 null 導致 NPE。
  • 絕對佈局維護難:建議遷移至 GridBagLayout、MigLayout 或 TableLayout 實現響應式佈局。
  • 資料外部化:省市資料應放入 JSON/Properties/資料庫,支援熱更新與多語系。
  • 編碼問題:原始碼中文若非 UTF-8 儲存,編譯後會亂碼,建議統一 UTF-8 或使用 native2ascii 轉義。

擴充方向

  1. 三級聯動:省 → 市 → 區/縣(資料結構改為 Map<String, Map<String, String[]>>)。
  2. 搜尋建議:輸入拼音/首字母過濾下拉選項(AutoCompleteDecorator 或自定義 ComboBoxModel)。
  3. 資料驗證:提交前檢查必填欄位、Email 格式、手機號碼等。
  4. 持久化:整合 JDBC/JPA 將表單資料寫入資料庫。

總結

本範例以 Map + JComboBox + ItemListener 實現經典省市二級聯動,程式碼結構清晰、資料與 UI 分離、事件處理規範。掌握此模式,可輕鬆應用於「國家-城市」、「分類-子分類」、「品牌-車系」等各類層級聯動場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved