在Java Swing中,JList
通常用于显示一系列的元素,而JComboBox
则是一个下拉列表框,允许用户从预定义的选项中选择一个。如果你想在JList
中使用JComboBox
作为元素,可以通过自定义渲染器和编辑器来实现。
以下是一个简单的示例,展示了如何在JList
中使用JComboBox
:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
public class JListWithComboBoxExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("JList with JComboBox Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
// 创建数据模型
DefaultListModel<ListItem> listModel = new DefaultListModel<>();
listModel.addElement(new ListItem("Option 1", new String[]{"SubOption 1", "SubOption 2"}));
listModel.addElement(new ListItem("Option 2", new String[]{"SubOption 3", "SubOption 4"}));
// 创建JList
JList<ListItem> list = new JList<>(listModel);
list.setCellRenderer(new ComboBoxRenderer());
list.setCellEditor(new ComboBoxEditor(list));
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
ListItem selectedItem = list.getSelectedValue();
System.out.println("Selected: " + selectedItem.getText());
}
}
});
// 添加到frame
frame.add(new JScrollPane(list), BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
// 自定义列表项类
static class ListItem {
private String text;
private String[] subOptions;
public ListItem(String text, String[] subOptions) {
this.text = text;
this.subOptions = subOptions;
}
public String getText() {
return text;
}
public String[] getSubOptions() {
return subOptions;
}
}
// 自定义渲染器
static class ComboBoxRenderer implements ListCellRenderer<ListItem> {
@Override
public Component getListCellRendererComponent(JList<? extends ListItem> list, ListItem value, int index, boolean isSelected, boolean cellHasFocus) {
JComboBox<String> comboBox = new JComboBox<>(value.getSubOptions());
comboBox.setEditable(false);
comboBox.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
comboBox.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
comboBox.setBorder(new EmptyBorder(2, 5, 2, 5));
return comboBox;
}
}
// 自定义编辑器
static class ComboBoxEditor implements ListCellEditor<ListItem> {
private JList<ListItem> list;
private JComboBox<String> comboBox;
public ComboBoxEditor(JList<ListItem> list) {
this.list = list;
}
@Override
public Component getTableCellEditorComponent(JTable table, ListItem value, boolean isSelected, int row, int column) {
comboBox = new JComboBox<>(value.getSubOptions());
comboBox.addActionListener(e -> {
String selectedValue = (String) comboBox.getSelectedItem();
list.getModel().getElementAt(list.getSelectedIndex()).setText(selectedValue);
});
return comboBox;
}
@Override
public Object getCellEditorValue() {
return comboBox.getSelectedItem();
}
@Override
public boolean isCellEditable(EventObject anEvent) {
return true;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
@Override
public boolean stopCellEditing() {
return true;
}
@Override
public void cancelCellEditing() {
}
}
}
DefaultListModel
来存储列表项,每个列表项包含一个文本和一个子选项数组。ComboBoxRenderer
类实现了ListCellRenderer
接口,用于在JList
中显示JComboBox
。ComboBoxEditor
类实现了ListCellEditor
接口,用于在编辑模式下显示JComboBox
,并在用户选择子选项时更新列表项的文本。ListSelectionListener
来监听列表项的选择变化,并输出选中的文本。这种组合可以用于需要在一个列表中显示多个选项,并且每个选项下有多个子选项的场景。例如,一个配置界面,其中每个配置项有多个可选值。
通过这种方式,你可以在JList
中使用JComboBox
作为元素,提供更丰富的用户交互体验。
领取专属 10元无门槛券
手把手带您无忧上云