javax.swing.JList 是 Swing 中展示物件列表的核心組件。本文系統講解靜態初始化、動態數據模型、多選模式、滾動條集成、選中事件監聽等全方位用法。
String[] days = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
JList<String> list = new JList<>(days); // 僅展示,運行時不可增刪改
DefaultListModel<String> model = new DefaultListModel<>();
JList<String> list = new JList<>(model);
// 增
model.addElement("新項目");
model.add(0, "插入首位");
// 刪
model.remove(0); // 按索引刪除
model.removeElement("值"); // 按值刪除
model.clear(); // 清空
// 改
model.set(0, "修改後");
// 查
String val = model.get(0);
int size = model.getSize();
核心原則:JList 負責視圖渲染與選中狀態,ListModel 負責數據存儲與變更通知,嚴格分離關注點。
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // 默認模式
// 獲取選中值 (推薦 Java 8+)
List<String> selected = list.getSelectedValuesList(); // 返回不可變列表
// 獲取選中索引
int[] indices = list.getSelectedIndices();
// 程式化選中
list.setSelectedIndex(0); // 單選
list.setSelectedIndices(new int[]{0,2,4}); // 多選
list.addListSelectionListener(e -> {
// 關鍵:過濾「調整中」事件,避免拖拽選擇時重複觸發
if (e.getValueIsAdjusting()) return;
List<String> selected = list.getSelectedValuesList();
selected.forEach(System.out::println);
});
getValueIsAdjusting() 詳解:
true:選擇範圍正在擴展中 (如拖拽鼠標、按住 Shift 點擊)false:選擇最終確定if (e.getValueIsAdjusting()) return; 只在最終確定時處理JList 不自帶滾動條,必須包裝在 JScrollPane 中:
JScrollPane scrollPane = new JScrollPane(list); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setPreferredSize(new Dimension(200, 200));
list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList> list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof User) {
User u = (User) value;
label.setText(u.getName() + " (" + u.getEmail() + ")");
label.setIcon(u.isOnline() ? onlineIcon : offlineIcon);
}
return label;
}
});
public class JListDemo extends JFrame {
private DefaultListModel<String> model = new DefaultListModel<>();
private JList<String> list = new JList<>(model);
private JTextArea logArea = new JTextArea(10, 30);
public JListDemo() {
// 初始化數據
Stream.of("Apple", "Banana", "Cherry", "Date").forEach(model::addElement);
// 事件監聽
list.addListSelectionListener(e -> {
if (e.getValueIsAdjusting()) return;
logArea.append("選中: " + list.getSelectedValuesList() + "\n");
});
// 按鈕操作
JButton btnAdd = new JButton("添加");
btnAdd.addActionListener(e -> model.addElement("Item-" + (model.getSize()+1)));
JButton btnDel = new JButton("刪除選中");
btnDel.addActionListener(e -> {
List<String> selected = list.getSelectedValuesList();
selected.forEach(model::removeElement);
});
// 佈局
setLayout(new BorderLayout());
add(new JScrollPane(list), BorderLayout.WEST);
add(new JScrollPane(logArea), BorderLayout.CENTER);
JPanel btnPanel = new JPanel();
btnPanel.add(btnAdd); btnPanel.add(btnDel);
add(btnPanel, BorderLayout.SOUTH);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack(); setLocationRelativeTo(null); setVisible(true);
}
public static void main(String[] args) { SwingUtilities.invokeLater(JListDemo::new); }
}