import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListSelectionModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.ComboPopup; /** * 多选ComboBox * * @author tang * * @param <E> */ @SuppressWarnings({ "serial", "rawtypes", "unchecked" }) public class MultiSelectComboBox<E> extends CustomComboBox<E> { public static void main(String[] args) { UIManager.put("ScrollBarUI", com.sun.java.swing.plaf.windows.WindowsScrollBarUI.class.getName());// 设置滚动条样式为window风格的滚动条样式 final JFrame frame = new JFrame(); frame.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 500); frame.setLocationRelativeTo(null); final MultiSelectComboBox<String> comboBox = new MultiSelectComboBox<>(new String[] { "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6" }); comboBox.setPreferredSize(new Dimension(150, 26)); comboBox.setForegroundAndToPopup(Color.YELLOW); comboBox.setBorder(BorderFactory.createLineBorder(Color.GREEN)); comboBox.setPopupBorder(BorderFactory.createLineBorder(Color.RED)); comboBox.setPopupBackground(Color.DARK_GRAY); comboBox.setSelectionBackground(Color.BLUE); comboBox.setSelectionForeground(Color.RED); comboBox.addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { } @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { System.out.println("选择的值:"+comboBox.getSelectedItemsString()); } @Override public void popupMenuCanceled(PopupMenuEvent e) { } }); frame.add(comboBox); frame.setVisible(true); } protected Set<Integer> selectedIndexs = new HashSet<>(); protected String spliceRegex = ","; public MultiSelectComboBox(Vector<E> vector) { super(new DefaultComboBoxModel(vector)); init(); } public MultiSelectComboBox() { super(); init(); } public MultiSelectComboBox(ComboBoxModel<E> aModel) { super(aModel); init(); } public MultiSelectComboBox(E[] items) { super(items); init(); } private void init() { setUI(new MultiSelectComboBoxUI()); setRenderer(new MultiSelectComboBoxRenderer()); setSelectionBackground(getBackground()); setSelectionForeground(getForeground()); synchAllToPopup(); setSelectionModeIsMulti(true); } @Override public void updateUI() { setUI(new MultiSelectComboBoxUI()); setSelectionBackground(selectionBackground); setSelectionForeground(selectionForeground); setPopupBackground(popupBackground); setPopupForeground(popupForeground); setPopupBorder(popupBorder); ListCellRenderer<?> renderer = getRenderer(); if (renderer instanceof Component) { SwingUtilities.updateComponentTreeUI((Component) renderer); } } /** * 设置true为多选模式,false为单选模式 * * @param isMulti * 是否多选 */ public void setSelectionModeIsMulti(boolean isMulti) { if (isMulti) { getPopup().getList().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); } else { getPopup().getList().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } } /** * 返回true为多选模式,false为单选模式 * * @return */ public boolean getSelectionModeIsMulti() { return getPopup().getList().getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION; } /** * 添加Popup事件 */ public void addPopupMenuListener(PopupMenuListener l) { getPopup().addPopupMenuListener(l); } @Override public void setSelectedItem(Object anObject) { super.setSelectedItem(anObject); if (anObject == null) { clearSelectedIndexs(); } else { boolean found = false; for (int i = 0; i < dataModel.getSize(); i++) { E element = dataModel.getElementAt(i); if (anObject.equals(element)) { found = true; addSelectedIndex(i); break; } } if (!found) { clearSelectedIndexs(); } } } public boolean addSelectedIndex(Integer index) { return selectedIndexs.add(index); } public boolean isSelected(Integer index) { return selectedIndexs.contains(index); } public boolean removeSelectedIndex(Integer index) { return selectedIndexs.remove(index); } public void clearSelectedIndexs() { selectedIndexs.clear(); } /** * 获得选择项的索引 * * @return */ public Set<Integer> getSelectedIndexs() { return selectedIndexs; } /** * 获得已经排序后的选择项的索引 * * @return */ public List<Integer> getSelectedSortedIndexs() { List<Integer> list = new ArrayList<>(getSelectedIndexs()); Collections.sort(list); return list; } /** * 获取选择的值 * * @return */ public List<E> getSelectedItems() { List<E> list = new ArrayList<>(); for (Integer index : getSelectedSortedIndexs()) { list.add(getModel().getElementAt(index)); } return list; } /** * 返回选择的值,用','拼接的字符串 * * @return */ public String getSelectedItemsString() { List<String> list = new ArrayList<>(); for (Integer index : getSelectedSortedIndexs()) { E elementAt = getModel().getElementAt(index); list.add(elementAt == null ? "" : elementAt.toString()); } return spliceCollectionValue(list, spliceRegex); } public String getSpliceRegex() { return spliceRegex; } public void setSpliceRegex(String spliceRegex) { this.spliceRegex = spliceRegex; } /** * 用指定字符串将一个字符串数组拼接成一个字符串 */ public static String spliceArrayValue(Object[] strs, String regex) { if (strs == null || strs.length == 0) { return ""; } StringBuffer buffer = new StringBuffer(); for (Object temp : strs) { if (temp == null) { temp = ""; } buffer.append(temp); buffer.append(regex); } int lastRegexIndex = buffer.lastIndexOf(regex); if (lastRegexIndex >= 0) { buffer.delete(lastRegexIndex, buffer.length());// 删除最后一个"," } return buffer.toString(); } /** * 用指定字符串将一个字符串集合拼接成一个字符串 */ public static String spliceCollectionValue(Collection strs, String regex) { if (strs == null || strs.isEmpty()) { return ""; } return spliceArrayValue(strs.toArray(new Object[strs.size()]), regex); } public static class MultiSelectComboBoxUI extends CustomComboBoxUI { protected JLabel currentValueComponent = new JLabel(); /** * Paints the currently selected item. */ @Override public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) { currentValueComponent.setText(((MultiSelectComboBox) comboBox).getSelectedItemsString()); currentValueComponent.setBackground(comboBox.getBackground());// 清除渲染器原来设置的背景色,将渲染器的背景设置成ComboBox的背景色 currentValueComponent.setForeground(comboBox.getForeground());// 清除渲染器原来设置的前景色,将渲染器的前景设置成ComboBox的前景色 currentValueComponent.setFont(comboBox.getFont()); currentValueComponent.setOpaque(comboBox.isOpaque()); if (comboBox.getRenderer() instanceof JComponent) { JComponent r = (JComponent) comboBox.getRenderer(); currentValueComponent.setBorder(r.getBorder()); } int x = bounds.x, y = bounds.y, w = bounds.width, h = bounds.height; if (padding != null) { x = bounds.x + padding.left; y = bounds.y + padding.top; w = bounds.width - (padding.left + padding.right); h = bounds.height - (padding.top + padding.bottom); } currentValuePane.paintComponent(g, currentValueComponent, comboBox, x, y, w, h, false); } @Override protected ListCellRenderer<?> createRenderer() { return new MultiSelectComboBoxRenderer(); } @Override protected ComboPopup createPopup() { return new MultiSelectComboBoxPopup(comboBox); } public class MultiSelectComboBoxPopup extends BasicComboPopup { public MultiSelectComboBoxPopup(JComboBox<?> cBox) { super(cBox); } @Override protected JList createList() { return new CustomList<>(comboBox.getModel()); } @Override protected MouseListener createListMouseListener() { return new MouseAdapter() { public void mousePressed(MouseEvent anEvent) { int index = list.getSelectedIndex(); MultiSelectComboBox<?> multiComboBox = (MultiSelectComboBox<?>) comboBox; if (list.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) { if (multiComboBox.isSelected(index)) { multiComboBox.removeSelectedIndex(index); } else { multiComboBox.addSelectedIndex(index); } } else { if (!multiComboBox.isSelected(index)) { multiComboBox.clearSelectedIndexs(); multiComboBox.addSelectedIndex(index); } } updateListBoxSelectionForEvent(anEvent, false); comboBox.repaint(); list.repaint(); } public void mouseReleased(MouseEvent anEvent) { if (!(list.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)) { comboBox.setPopupVisible(false); } } }; } @Override protected void configureList() { super.configureList(); list.setSelectionModel(new DefaultListSelectionModel() { public boolean isSelectedIndex(int index) { return ((MultiSelectComboBox<?>) comboBox).isSelected(index); } }); } } } public static class MultiSelectComboBoxRenderer extends JCheckBox implements ListCellRenderer<Object>, Serializable { private Border rendererBorder = BorderFactory.createEmptyBorder(0, 1, 0, 0); public MultiSelectComboBoxRenderer() { setOpaque(true); setBorder(rendererBorder); // 如果觉得默认的CheckBox图标不好看可以直接设置: // setIcon(defaultIcon); // setSelectedIcon(selectedIcon) // setPressedIcon(pressedIcon) // setRolloverEnabled(true); // setRolloverIcon(rolloverIcon) // setRolloverSelectedIcon(rolloverSelectedIcon) } @Override public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setComponentOrientation(list.getComponentOrientation()); if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } setEnabled(list.isEnabled()); setSelected(isSelected); setText(value == null ? "" : value.toString()); setFont(list.getFont()); return this; } public Border getRendererBorder() { return rendererBorder; } public void setRendererBorder(Border rendererBorder) { this.rendererBorder = rendererBorder; setBorder(rendererBorder); } } }
相关推荐
在标题"JComboBox下拉框多选"中提到的场景,就是将`JComboBox`与`JCheckBox`相结合,以实现用户可以从下拉列表中选择多个选项的功能。 以下是一个详细的解释: 1. **JComboBox的基本使用**: `JComboBox`是Java ...
在Swing中,多选下拉框通常由JComboBox类实现,但默认的JComboBox只支持单选。为了实现多选功能,我们需要扩展JComboBox或者使用第三方库,如JList或JTable与弹出面板组合。 本主题涉及的知识点主要包括以下几个...
要实现多选下拉框功能,我们需要自定义组件或者使用第三方库来扩展`JComboBox`的功能。 ### 一、自定义多选下拉框 自定义多选下拉框通常涉及以下几个关键步骤: 1. **创建自定义模型**:你需要创建一个自定义的`...
在Java Swing中,`JComboBox`和`JList`是两种常用的用户界面组件,用于创建交互式的下拉列表和多选列表。在这个“文件浏览器组件”中,它们被巧妙地结合在一起,为用户提供了一个功能丰富的文件浏览和选择的界面。这...
在多选场景下,我们通常不直接使用JComboBox,因为它默认只支持单选。但是,我们可以借助JList和JScrollPane来实现多选功能。 为了创建这样一个多选下拉框,我们可以这样做: 1. **自定义模型**: 创建一个自定义的...
`JComboBox`提供了一个可扩展的列表,用户可以从中选择一个或多个选项,而`JCheckBox`则允许用户在一组选项中进行多选。将这两者结合起来,我们可以创建一个具有复选功能的下拉菜单,这种设计在用户界面中非常实用,...
在Java界面开发中,"下拉多选计算和"是一个常见的功能需求,它涉及到Java Swing库中的JComboBox组件,以及事件处理和数据处理等技术。JComboBox是一个允许用户从一组预定义选项中选择一个或多个项目的控件。在这个...
这个程序很可能是用Swing库中的JComboBox或JList组件来创建的,因为它们可以支持多选功能。 首先,JComboBox是一个下拉列表控件,可以通过添加适配器(如DefaultComboBoxModel)来存储和显示选项。在多选模式下,...
不同于选择框(通常指`JComboBox`),`JList` 支持多种选择模式,使得用户能够灵活地进行单选或多选操作。本文将详细介绍如何通过`JList` 实现不同类型的多选功能,并提供一个具体的实例来演示这些概念。 #### 三种...
为了实现多选,我们需要创建一个自定义的JComboBox子类,并添加额外的逻辑来处理多选行为。 在"phaGUILib"中,我们可以预期这个组件可能包含了以下特性: 1. **多选功能**:通过扩展JComboBox,实现一个能够同时...
在这个场景中,我们关注的是一个自定义的下拉菜单与复选框功能的实现,这通常用于提供多选选项给用户。这个功能使得用户能够在文本框中通过点击触发一个下拉菜单,然后在菜单中选择多个复选框选项,这些选项会自动...
- JList支持单选或多选模式,通过setSelectionMode()来设置。 - 通过addListSelectionListener()可以监听用户的选择变化。 4. JColorChooser(颜色选择器): - JColorChooser提供了一个用户友好的界面,让用户...
在Java Swing库中,`JComboBox`是一种常用的组件,它允许用户从一组预先定义的选项中选择一个。本文将深入探讨`checkCombox`的概念,以及如何在Swing应用程序中实现和操作它。我们将结合提供的标签"源码"和"工具"来...
如果你看到文件名`TestChoiceGroup.java`,这可能与Java ME(Micro Edition)有关,`ChoiceGroup`是Java ME中用于创建多选或单选选项的组件。在Java ME环境中,创建`ChoiceGroup`的步骤如下: 1. 导入必要的库: ``...
通过以上步骤,我们可以创建一个既实用又灵活的`MyCheckComboBox`组件,它将JComboBox的便利性和JCheckBox的多选特性结合在一起,为Java Swing应用提供了更多的功能选择。在实际开发中,这样的自定义组件可以大大...
这个PPT教案主要讲解了如何使用Java Swing库来创建具有选择性组件的用户界面,包括组合框(JComboBox)、列表框(JList)、单选按钮(JRadioButton)和复选框(JCheckBox),并涉及到了选择事件的处理。 首先,任务...
- **JComboBox**: 用于创建下拉列表,用户可以从预设的选项中选择一个。 - **JCheckBox**: 用于实现复选框,用户可以多选,可以选择多个选项。 - **JRadioButton**: 用于创建单选按钮,用户只能选择一个选项。 -...
JCheckBox用于提供多选选项。用户可以勾选或取消勾选,以表示他们对某个特性或选项的选择。可以将复选框添加到JPanel或直接与JMenuItem结合使用。 5. **单选按钮(JRadioButton)**: JRadioButton是单选按钮,...
本篇文章将详细介绍如何设计和使用这些组件,特别是`JList`和`JComboBox`。 首先,让我们讨论`JList`。`JList`是一个显示一系列项目的组件,用户可以通过单击或双击来选择一个或多个项。它提供了多种方式来处理用户...
JCheckBox 允许用户在多个选项中进行多选。 ```java JCheckBox checkBox1 = new JCheckBox("复选项1"); JCheckBox checkBox2 = new JCheckBox("复选项2"); ``` 使用 ItemListener 或 ChangeListener 监听选中/...