Swing之下拉框

转载请注明原创地址:http://blog.csdn.net/u012643122/article/details/39081017

Swing中的下拉框JComboBox又丑又不能设置弹出的下拉菜单的样式,而且还不支持复选、多选,所以要想设置弹出的下拉菜单的样式或需要多选下拉框可以选择使用以下这两个下拉框:

一、单选ComboBox

以下代码非常完整,copy可以直接运行。
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.io.Serializable;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;

/**
 * 自定义下拉框
 * <p>
 * 
 * @author tang
 */
@SuppressWarnings({ "rawtypes", "unchecked", "serial" })
public class CustomComboBox<E> extends JComboBox<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 CustomComboBox<String> comboBox = new CustomComboBox<>(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.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (ItemEvent.SELECTED == e.getStateChange()) {
					System.out.println("选择的值:" + comboBox.getSelectedItem());
				}
			}
		});

		frame.add(comboBox);

		frame.setVisible(true);
	}

	protected Icon arrowIcon;

	protected Color selectionBackground;
	protected Color selectionForeground;
	protected Color popupBackground;
	protected Color popupForeground;
	protected Border popupBorder;

	public CustomComboBox() {
		init();
	}

	public CustomComboBox(ComboBoxModel<E> aModel) {
		super(aModel);
		init();
	}

	public CustomComboBox(E[] items) {
		super(items);
		init();
	}

	public CustomComboBox(Vector<E> items) {
		super(items);
		init();
	}

	public CustomComboBox(Icon arrowIcon) {
		this.arrowIcon = arrowIcon;
		init();
	}

	private void init() {

		setUI(new CustomComboBoxUI());
		setOpaque(true);
		setForeground(Color.decode("#9a9a9a"));
		setBackground(Color.WHITE);
		Border lineBorder = BorderFactory.createLineBorder(Color.decode("#c5c7c8"));
		setBorder(lineBorder);
		setFont(new Font(Font.DIALOG, Font.PLAIN, 16));
		setPopupForeground(getForeground());
		setPopupBackground(getBackground());
		setSelectionBackground(Color.LIGHT_GRAY);
		// getPopup().setOpaque(true);
		// getPopup().setBackground(popupBackground);
		setPopupBorder(lineBorder);
		setRenderer(new CustomComboBoxRenderer());
	}

	@Override
	public synchronized void addMouseListener(MouseListener l) {
		super.addMouseListener(l);
		if (getArrowButton() != null) {
			getArrowButton().addMouseListener(l);
		}
	}

	public void setSelectionBackground(Color selectionBackground) {
		this.selectionBackground = selectionBackground;
		getPopup().getList().setSelectionBackground(selectionBackground);
	}

	public void setSelectionForeground(Color selectionForeground) {
		this.selectionForeground = selectionForeground;
		getPopup().getList().setSelectionForeground(selectionForeground);
	}

	public void setPopupBackground(Color popupBackground) {
		this.popupBackground = popupBackground;
		getPopup().getList().setBackground(popupBackground);
	}

	public void setPopupForeground(Color popupForeground) {
		this.popupForeground = popupForeground;
		getPopup().getList().setForeground(popupForeground);
	}

	public void setPopupBorder(Border popupBorder) {
		this.popupBorder = popupBorder;
		getPopup().setBorder(popupBorder);
	}

	@Override
	public void setUI(ComboBoxUI ui) {
		if (ui instanceof CustomComboBoxUI) {
			super.setUI(ui);
		} else {
			super.setUI(new CustomComboBoxUI());
		}
	}

	@Override
	public void updateUI() {

		setUI(new CustomComboBoxUI());

		setSelectionBackground(selectionBackground);
		setSelectionForeground(selectionForeground);
		setPopupBackground(popupBackground);
		setPopupForeground(popupForeground);
		setPopupBorder(popupBorder);

		ListCellRenderer<?> renderer = getRenderer();
		if (renderer instanceof Component) {
			SwingUtilities.updateComponentTreeUI((Component) renderer);
		}
	}

	/**
	 * 如果想将ComboBox的Background和Foreground与弹出的Popup的Background和Foreground保持一致则可以调用此方法
	 */
	public void synchGroundToPopup() {
		setPopupBackground(getBackground());
		setPopupForeground(getForeground());
	}

	/**
	 * 如果想将ComboBox的Background和Foreground和Border与弹出的Popup的Background和Foreground和Border保持一致则可以调用此方法
	 */
	public void synchAllToPopup() {
		setPopupBackground(getBackground());
		setPopupForeground(getForeground());
		setPopupBorder(getBorder());
	}

	/**
	 * 设置ComboBox的Background和Popup的Background
	 * 
	 * @param color
	 */
	public void setBackgroundAndToPopup(Color color) {
		setBackground(color);
		setPopupBackground(color);
	}

	/**
	 * 设置ComboBox的Foreground和Popup的Foreground
	 * 
	 * @param color
	 */
	public void setForegroundAndToPopup(Color color) {
		setForeground(color);
		setPopupForeground(color);
	}

	/**
	 * 设置ComboBox的Border和Popup的Border
	 * 
	 * @param border
	 */
	public void setBorderAndToPopup(Border border) {
		setBorder(border);
		setPopupBorder(border);
	}

	public Icon getArrowIcon() {
		if (arrowIcon == null) {
			arrowIcon = new ArrowIcon(16, 10, 10, 10, Color.decode("#707070"), SwingConstants.BOTTOM);
		}
		return arrowIcon;
	}

	public BasicComboPopup getPopup() {
		return ((CustomComboBoxUI) getUI()).getPopup();
	}

	public JButton getArrowButton() {
		return ((CustomComboBoxUI) getUI()).getArrowButton();
	}

	public static boolean isMenuShortcutKeyDown(InputEvent event) {
		return (event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
	}

	public static class CustomList<E> extends JList<E> {

		public CustomList() {
			super();
		}

		public CustomList(E[] listData) {
			super(listData);
		}

		public CustomList(ListModel<E> dataModel) {
			super(dataModel);
		}

		public CustomList(Vector<? extends E> listData) {
			super(listData);
		}

		@Override
		public void processMouseEvent(MouseEvent e) {
			if (isMenuShortcutKeyDown(e)) {
				// Fix for 4234053. Filter out the Control Key from the list.
				// ie., don't allow CTRL key deselection.
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				e = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(), e.getX(), e.getY(),
						e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), MouseEvent.NOBUTTON);
			}
			super.processMouseEvent(e);
		}
	}

	public static class CustomComboBoxUI extends MetalComboBoxUI {

		@Override
		protected JButton createArrowButton() {
			final CustomComboBox box = (CustomComboBox) comboBox;
			Icon arrowIcon = box.getArrowIcon();
			JButton button = new JButton(arrowIcon);
			button.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
			button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
			button.setHorizontalTextPosition(SwingConstants.CENTER);
			button.setVerticalTextPosition(SwingConstants.CENTER);
			button.setRolloverEnabled(true);
			button.setFocusPainted(false);
			button.setOpaque(false);
			button.setContentAreaFilled(false);
			button.setBorderPainted(false);
			button.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
			if (arrowIcon != null) {
				button.setPressedIcon(new MoveIcon(arrowIcon, 0, 1));
			}
			button.setName("ComboBox.arrowButton");
			return button;
		}

		/**
		 * Paints the currently selected item.
		 */
		@Override
		public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) {
			Component c = comboBox.getRenderer().getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, hasFocus && !isPopupVisible(comboBox),
					false);
			c.setBackground(comboBox.getBackground());// 清除渲染器原来设置的背景色,将渲染器的背景设置成ComboBox的背景色
			c.setForeground(comboBox.getForeground());// 清除渲染器原来设置的前景色,将渲染器的前景设置成ComboBox的前景色
			if (c instanceof JComponent) {
				JComponent jc = (JComponent) c;
				jc.setOpaque(comboBox.isOpaque());
			}

			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, c, comboBox, x, y, w, h, c instanceof JPanel);
		}

		/**
		 * Paints the background of the currently selected item.
		 */
		@Override
		public void paintCurrentValueBackground(Graphics g, Rectangle bounds, boolean hasFocus) {
			Color t = g.getColor();
			g.setColor(comboBox.getBackground());
			g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
			g.setColor(t);
		}

		public BasicComboPopup getPopup() {
			return (BasicComboPopup) popup;
		}

		public JButton getArrowButton() {
			return arrowButton;
		}
	}

	public static class CustomComboBoxRenderer extends DefaultListCellRenderer implements ListCellRenderer<Object>, Serializable {

		private Border rendererBorder = BorderFactory.createEmptyBorder(0, 5, 0, 5);

		public CustomComboBoxRenderer() {
			setBorder(rendererBorder);
		}

		@Override
		public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
			setBorder(rendererBorder);
			return this;
		}

		public Border getRendererBorder() {
			return rendererBorder;
		}

		public void setRendererBorder(Border rendererBorder) {
			this.rendererBorder = rendererBorder;
		}
	}

	/**
	 * 箭头Icon
	 * 
	 * @author tang
	 */
	public static class ArrowIcon implements Icon {

		protected int iconWidth;
		protected int iconHeight;
		protected int triangleWidth;
		protected int triangleHeight;
		protected Color triangleColor;
		protected int direction;
		protected Polygon triangle = new Polygon();

		public ArrowIcon(int width, int height, Color arrowColor, int direction) {
			this(width, height, width, height, arrowColor, direction);
		}

		public ArrowIcon(int iconWidth, int iconHeight, int triangleWidth, int triangleHeight, Color triangleColor, int direction) {
			this.iconWidth = iconWidth;
			this.iconHeight = iconHeight;
			this.triangleWidth = triangleWidth;
			this.triangleHeight = triangleHeight;
			this.triangleColor = triangleColor;
			this.direction = direction;

			createTriangle();
		}

		protected void createTriangle() {
			int x = (iconWidth - triangleWidth) / 2;
			int y = (iconHeight - triangleHeight) / 2;

			if (direction == SwingConstants.TOP) {// 箭头向上
				triangle.addPoint(triangleWidth / 2 + x, y);
				triangle.addPoint(triangleWidth + x, triangleHeight + y);
				triangle.addPoint(x, triangleHeight + y);
			} else if (direction == SwingConstants.BOTTOM) {// 箭头向下
				triangle.addPoint(x, y);
				triangle.addPoint(triangleWidth + x, y);
				triangle.addPoint(triangleWidth / 2 + x, triangleHeight + y);
			} else if (direction == SwingConstants.LEFT) {
				triangle.addPoint(x, triangleHeight / 2 + y);
				triangle.addPoint(triangleWidth + x, y);
				triangle.addPoint(triangleWidth + x, triangleHeight + y);
			} else if (direction == SwingConstants.RIGHT) {
				triangle.addPoint(x, y);
				triangle.addPoint(triangleWidth + x, triangleHeight / 2 + y);
				triangle.addPoint(x, triangleHeight + y);
			}
		}

		@Override
		public void paintIcon(Component c, Graphics g, int x, int y) {
			Graphics2D g2 = (Graphics2D) g;
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setColor(triangleColor);
			AffineTransform af = new AffineTransform();
			af.translate(x, y);
			Shape shape = af.createTransformedShape(triangle);
			g2.fill(shape);
		}

		@Override
		public int getIconWidth() {
			return iconWidth;
		}

		@Override
		public int getIconHeight() {
			return iconHeight;
		}
	}

	/**
	 * 将原Icon位置移动的Icon
	 * 
	 * @author PC
	 * 
	 */
	public static class MoveIcon implements Icon {
		Icon icon;
		int moveX;
		int moveY;

		public MoveIcon(Icon icon, int moveX, int moveY) {
			this.icon = icon;
			this.moveX = moveX;
			this.moveY = moveY;
		}

		@Override
		public void paintIcon(Component c, Graphics g, int x, int y) {
			icon.paintIcon(c, g, x + moveX, y + moveY);
		}

		@Override
		public int getIconWidth() {
			return icon.getIconWidth();
		}

		@Override
		public int getIconHeight() {
			return icon.getIconHeight();
		}
	}
}

运行结果:



二、可多选ComboBox

以下代码非常完整,copy可以直接运行。
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);
		}
	}
}
运行结果:



  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值