文档章节

Swing之下拉框

思想永无止境
 思想永无止境
发布于 2016/11/04 11:58
字数 2412
阅读 11
收藏 1

转载请注明原创地址: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
博文 257
码字总数 292814
作品 0
昌平
程序员
私信 提问
JComboBox 弹出下拉框的问题

Swing的JComboBox 用了2层JPanel 第二层上添加了一个JComboBox,在Frame的Size比较大的时候下拉框无法弹出。 缩小Size之后下拉框才能弹出。 如图: 红色方框是用一个JPanel 里装一个 Lable ...

chally
2011/12/24
891
4
java下拉列表框

用Swing控件,及不同的事件处理接口,设计一个超市收银系统界面。要求在一个JComboBox(下拉框)中有5个商品名称选项,当选中其中一项时,在文本区中会显示这个商品的详细信息,同时在文本框...

runningerror
2017/12/08
2.7K
2
Java学习笔记之Swing(三)

Java学习笔记之Swing(三) Swing中的常用控件 你将学到: 了解如何创建文本框和文本框的实际应用; 了解如何创建复选框和复选框的实际应用; 了解如何创建单选按钮和单选按钮的实际应用; ...

FelixSmile
2016/09/22
51
0
swing组件JcomboBox与文本框 JTextField 互相联动

@easonwang 你好,想跟你请教个问题: /** * This method initializes jComboBox * ComboBox会员 * @return javax.swing.JComboBox */ private JComboBox getCmbMem() { if (cmbMem == null)......

破梦的选择
2014/01/19
1.5K
1
企业客户GUI界面开发选择、尝试和困惑

这段时间,和兄弟们使用ZK捣弄出的界面,70个左右的表,每个要增删改查,还需要关联,包括报表,权限控制XX等功能,我感觉如果不用zk,估计做不出来这么快;当然还有很多问题(后面说),先看...

铂金小鬼
2010/11/30
1.9K
17

没有更多内容

加载失败,请刷新页面

加载更多

Spring AOP-06-切入点类型

切入点是匹配连接点的拦截规则。之前使用的是注解@Pointcut,该注解是AspectJ中的。除了这个注解之外,Spring也提供了其他一些切入点类型: • 静态方法切入点StaticMethodMatcherPointcut •...

moon888
昨天
90
0
Class Loaders in Java

1. Introduction to Class Loaders Class loaders are responsible for loading Java classes during runtime dynamically to the JVM (Java Virtual Machine). Also, they are part of the ......

Ciet
昨天
68
0
以Lazada为例,看电商系统架构演进

什么是Lazada? Lazada 2012年成立于新加坡,是东南亚第一电商,2016年阿里投资10亿美金,2017年完成对lazada的收购。 业务模式上Lazada更偏重自营,类似于亚马逊,自建仓储和为商家提供服务...

春哥大魔王的博客
昨天
60
0
【自用】 Flutter Timer 简单用法

dart: void _startTime() async { _timer = Timer(Duration(seconds: sec), () { fun(xxx,yyy,zzz); }); } @override void dispose() { _timer.cancel()......

Tensor丨思悟
昨天
65
0
计算机实现原理专题--自动化(六)

目前实现的加减法器可以扩充到更高位宽的数值范围,不仅可以实现连续n个数的相加减,还可以实现其中几个数的相加减,并保存相应的结果。但是还不能应对某些场景,例如需要复用中间的临时结果...

FAT_mt
昨天
58
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部