具有删除功能的下拉菜单按钮。类似于QQ登录框的用户输入框

具有删除功能的下拉菜单按钮。类似于QQ登录框的用户输入框。先来看效果图:

该下拉框,具有的功能为:

1、编辑框和弹出的菜单具有图片功能。

2、在下拉菜单中选择的菜单具有放大功能。

3、编辑框具有默认图标设置功能。

4、下拉菜单项具有删除功能。(只有下拉菜单在鼠标经过时才显示删除按钮)

5、对菜单项的操作具有监听接口。(接口类:MItemListeners)

 

下面贴出程序:

MDeleteComBox(主程序)

package com.michael.wang.swing.ui;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

import java.util.List;
import java.util.*;

import javax.swing.*;
import javax.swing.plaf.basic.*;

/**
 * 具有删除功能的下拉菜单按钮。类似于QQ登录框的用户输入框
 * 
 * @Author Michael.Wang
 * @Email wqjsir@foxmail.com
 * @version 1.0 2011-5-16上午10:15:27
 **/
public class MDeleteComBox extends JComboBox {

	private static final long serialVersionUID = 1L;

	private boolean bDefaultIconShow;
	private Icon defaultIcon;
	private int maxIconSize = 24;
	private int mixIconSize = 16;
	private List<MItemListener> itemListeners = new ArrayList<MItemListener>();

	public MDeleteComBox(ComboBoxModel aModel) {
		super(aModel);
		init();
	}

	public MDeleteComBox(MDeleteComBoxEntry[] entrys) {
		super(entrys);
		init();
	}

	public MDeleteComBox(Vector<MDeleteComBoxEntry> items) {
		super(items);
		init();
	}

	void init() {
		setUI(new MDeleteComBoxUI());
		setEditor(new MDeleteComBoxEditor());
	}

	public Icon getDefaultIcon() {
		return defaultIcon;
	}

	public void setDefaultIcon(Icon defaultIcon) {
		this.defaultIcon = defaultIcon;
	}

	/**
	 * 调整图片大小。该方法为一个工具类中的方法。这里直接copy过来
	 * 
	 * @param icon
	 * @param maxSize
	 * @return
	 */
	public static ImageIcon resizeImageIcon(ImageIcon icon, int maxSize) {
		Image orgImage = icon.getImage();
		Image newImage = orgImage;
		if (icon.getIconHeight() > maxSize && icon.getIconWidth() > maxSize) {
			// 缩小图像,使其高或宽为maxSize
			if (icon.getIconHeight() > icon.getIconWidth()) {
				newImage = newImage.getScaledInstance(maxSize, -1,
						Image.SCALE_SMOOTH);
			} else {
				newImage = newImage.getScaledInstance(-1, maxSize,
						Image.SCALE_SMOOTH);
			}

		}

		// 等待Image载入完成。
		while (!Toolkit.getDefaultToolkit()
				.prepareImage(newImage, -1, -1, null)) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}

		}
		;
		int width = newImage.getWidth(null);
		int height = newImage.getHeight(null);
		if (height > maxSize || width > maxSize) {
			width = width > maxSize ? maxSize : width;
			height = height > maxSize ? maxSize : height;
			// 对图像进行裁剪,使其高和宽一致
			CropImageFilter cropFilter = new CropImageFilter(0, 0, width,
					height);
			newImage = Toolkit.getDefaultToolkit().createImage(
					new FilteredImageSource(newImage.getSource(), cropFilter));
		}

		if (newImage != orgImage) {
			// 如果image发生改变,则重新生成icon
			icon = new ImageIcon(newImage);
		}
		return icon;
	}

	public boolean isBDefaultIconShow() {
		return bDefaultIconShow;
	}

	public void setBDefaultIconShow(boolean defaultIconShow) {
		bDefaultIconShow = defaultIconShow;
	}

	public void addMItemListener(MItemListener listener) {
		itemListeners.add(listener);
	}

	public void removeMItemListener(MItemListener listener) {
		itemListeners.remove(listener);
	}

	protected void fireMItemSelected(MDeleteComBoxEntry entry) {
		for (MItemListener _listener : itemListeners) {
			_listener.itemSelected(entry);
		}
	}

	protected void fireMItemDeleted(MDeleteComBoxEntry entry) {
		for (MItemListener _listener : itemListeners) {
			_listener.itemDeleted(entry);
		}
	}

	class MDeleteComBoxUI extends BasicComboBoxUI {
		@Override
		protected ListCellRenderer createRenderer() {
			return new ComboBoxListCellRender();
		}

		@Override
		protected ComboPopup createPopup() {
			return new MDeleteComBoxPopup(comboBox);
		}
	}

	private class ComboBoxListCellRender extends DefaultListCellRenderer {
		private static final long serialVersionUID = 1L;

		public ComboBoxListCellRender() {

		}

		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			this.setText(value == null ? "" : value.toString());
			return this;
		}
	}

	class MDeleteComBoxEditor implements ComboBoxEditor {
		final protected JTextField editor;
		protected JPanel editorPanel;
		protected JLabel lbIcon;
		protected Object objItem;

		public MDeleteComBoxEditor() {
			editor = new JTextField("");
			editorPanel = new JPanel();
			lbIcon = new JLabel();

			editorPanel.setBackground(Color.white);

			editor.setBorder(null);

			editorPanel.setLayout(new BorderLayout(2, 2));
			editorPanel.add(lbIcon, BorderLayout.WEST);
			editorPanel.add(editor, BorderLayout.CENTER);
		}

		public void addActionListener(ActionListener l) {
			listenerList.add(ActionListener.class, l);
		}

		public Component getEditorComponent() {
			return editorPanel;
		}

		public Object getItem() {
			return objItem;
		}

		public void removeActionListener(ActionListener l) {
			listenerList.remove(ActionListener.class, l);
		}

		public void selectAll() {
			// Ignore
		}

		public void setItem(Object newValue) {
			objItem = newValue;
			if (newValue != null) {
				MDeleteComBoxEntry _entry = (MDeleteComBoxEntry) newValue;
				editor.setText(_entry.getText());
				lbIcon.setIcon(_entry.getIcon());
			} else {
				editor.setText(null);
				lbIcon.setIcon(null);
			}
		}

	}

	private class MDeleteComBoxPopup extends BasicComboPopup {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		protected Color selectedBackground;
		protected Color selectedForeground;
		protected Color background;
		protected Color foreground;

		private JPanel panelList;
		private Map<MDeleteComBoxEntry, JComponent> values;

		private Dimension maxDimension = new Dimension(-1, 40);
		private Dimension mixDimension = new Dimension(-1, 25);

		public MDeleteComBoxPopup(JComboBox comboBox) {
			super(comboBox);
			comboBox.setMaximumRowCount(5);
			background = UIManager.getColor("ComboBox.background");
			foreground = UIManager.getColor("ComboBox.foreground");
			selectedBackground = UIManager
					.getColor("ComboBox.selectionBackground");
			selectedForeground = UIManager
					.getColor("ComboBox.selectionForeground");
			initializePopup();
		}

		private void initializePopup() {
			setLayout(new BorderLayout());
			panelList = new JPanel();
			panelList.setLayout(new GridBagLayout());
			values = new HashMap<MDeleteComBoxEntry, JComponent>();
			values.clear();
			DefaultComboBoxModel _model = (DefaultComboBoxModel) comboBox
					.getModel();
			int size = _model == null ? 0 : _model.getSize();
			this.removeAll();
			for (int i = 0; i < size; i++) {
				MDeleteComBoxEntry _entry = (MDeleteComBoxEntry) _model
						.getElementAt(i);

				JPanel _panelItem = new JPanel(new GridBagLayout());
				_panelItem.setBackground(Color.white);
				_panelItem.setPreferredSize(mixDimension);

				JLabel _lbIcon = new JLabel(_entry.getIcon());
				_lbIcon.setHorizontalAlignment(JLabel.LEFT);
				_lbIcon.setText(_entry.getText());
				values.put(_entry, _panelItem);
				_lbIcon.setFont(new Font(Font.DIALOG, Font.PLAIN, 13));

				JLabel _lbDel = new JLabel("x");
				_lbDel.setHorizontalTextPosition(JLabel.CENTER);
				_lbDel.setHorizontalAlignment(JLabel.CENTER);
				_lbDel.setPreferredSize(new Dimension(15, 15));
				_lbDel.setVisible(false);

				_panelItem.add(_lbIcon, new GridBagConstraints(0, 0, 1, 1, 1,
						1, GridBagConstraints.WEST, GridBagConstraints.BOTH,
						new Insets(0, 0, 0, 0), 0, 0));
				_panelItem.add(_lbDel, new GridBagConstraints(1, 0, 1, 1, 0, 0,
						GridBagConstraints.CENTER, GridBagConstraints.NONE,
						new Insets(5, 5, 5, 10), 0, 0));

				ItemMoseListener _itemMoseListener = new ItemMoseListener(
						_entry, _panelItem, _lbDel);
				_panelItem.addMouseListener(_itemMoseListener);
				_panelItem.addMouseMotionListener(_itemMoseListener);
				panelList.add(_panelItem, new GridBagConstraints(0, i, 1, 1, 1,
						1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
						new Insets(0, 0, 0, 0), 0, 0));
			}

			if (size == 0 && isBDefaultIconShow() && getDefaultIcon() != null) {
				MDeleteComBoxEntry _entry = new MDeleteComBoxEntry(
						getDefaultIcon(), "");
				_model.insertElementAt(_entry, 0);
				_model.setSelectedItem(_entry);
			}
			JScrollPane _scrollPane = new JScrollPane(panelList);
			_scrollPane.setBorder(null);
			add(_scrollPane, BorderLayout.CENTER);

		}

		@Override
		public Dimension getPreferredSize() {
			Dimension _dimension = super.getPreferredSize();
			_dimension.width = comboBox.getWidth();
			if (values.size() > 1) {
				_dimension.height = (int) (panelList.getPreferredSize()
						.getHeight() + 10);
			}
			return _dimension;
		}

		@Override
		protected void firePopupMenuWillBecomeVisible() {
			DefaultComboBoxModel _model = (DefaultComboBoxModel) comboBox
					.getModel();
			MDeleteComBoxEntry _entry = (MDeleteComBoxEntry) _model
					.getSelectedItem();
			if (_entry != null) {
				JComponent _comp = values.get(_entry);
				if (_comp != null && _comp instanceof JPanel) {
					updateSelectItem((JPanel) _comp, true);
				}
			}
			super.firePopupMenuWillBecomeVisible();
		}

		private void updateSelectItem(JPanel panel, boolean select) {
			Component _comp;
			if (select) {
				panel.setBackground(selectedBackground);
				panel.setPreferredSize(maxDimension);
				for (int i = 0; i < panel.getComponentCount(); i++) {
					_comp = panel.getComponent(i);
					_comp.setFont(new Font(Font.DIALOG, Font.PLAIN, 18));
					_comp.setForeground(selectedForeground);
					if (_comp instanceof JLabel) {
						JLabel _label = (JLabel) _comp;
						if ("x".equals(_label.getText())) {
							_label.setVisible(true);
						} else if (_label.getIcon() != null) {
							resizeImageIcon((ImageIcon) _label.getIcon(),
									maxIconSize);
						}
					}
				}
			} else {
				panel.setBackground(Color.white);
				panel.setPreferredSize(mixDimension);
				for (int i = 0; i < panel.getComponentCount(); i++) {
					_comp = panel.getComponent(i);
					_comp.setFont(new Font(Font.DIALOG, Font.PLAIN, 13));
					_comp.setForeground(Color.black);
					if (_comp instanceof JLabel) {
						JLabel _label = (JLabel) _comp;
						if ("x".equals(_label.getText())) {
							_label.setVisible(false);
						} else if (_label.getIcon() != null) {
							resizeImageIcon((ImageIcon) _label.getIcon(),
									mixIconSize);
						}
					}
				}
			}
			panel.updateUI();

		}

		private class ItemMoseListener extends MouseAdapter {

			private MDeleteComBoxEntry entry;
			private JPanel panel;
			private JLabel lbDel;

			public ItemMoseListener(MDeleteComBoxEntry entry, JPanel panel,
					JLabel lbDel) {
				this.entry = entry;
				this.panel = panel;
				this.lbDel = lbDel;
			}

			@Override
			public void mouseClicked(MouseEvent e) {
				DefaultComboBoxModel _model = (DefaultComboBoxModel) comboBox
						.getModel();
				if (e.getPoint().getX() > lbDel.getX()
						&& e.getPoint().getX() < (lbDel.getX() + lbDel
								.getWidth())) {
					_model.removeElement(entry);
					fireMItemDeleted(entry);
					initializePopup();
				} else {
					_model.setSelectedItem(entry);
					fireMItemSelected(entry);
				}

				MDeleteComBoxPopup.this.hide();

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				DefaultComboBoxModel _model = (DefaultComboBoxModel) comboBox
						.getModel();
				MDeleteComBoxEntry _entry = (MDeleteComBoxEntry) _model
						.getSelectedItem();
				JComponent _comp = values.get(_entry);
				if (_comp != null && _comp instanceof JPanel) {
					updateSelectItem((JPanel) _comp, false);
				}
				updateSelectItem(panel, true);
			}

			@Override
			public void mouseExited(MouseEvent e) {
				updateSelectItem(panel, false);
			}

			@Override
			public void mouseMoved(MouseEvent e) {
				if (e.getPoint().getX() > lbDel.getX()
						&& e.getPoint().getX() < (lbDel.getX() + lbDel
								.getWidth())) {
					lbDel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1,
							Color.gray));
				} else {
					lbDel
							.setBorder(BorderFactory.createEmptyBorder(1, 1, 1,
									1));
				}
				panel.updateUI();

			}

		}
	}

	
	/***
	 * 测试代码
	 * @param args
	 */
	public static void main(String[] args) {

		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager
							.getSystemLookAndFeelClassName());
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (UnsupportedLookAndFeelException e) {
					e.printStackTrace();
				}
				JFrame _frame = new JFrame();
				Icon _icon1 = new ImageIcon("./images/user1.png");
				Icon _icon2 = new ImageIcon("./images/user2.png");
				Icon _icon3 = new ImageIcon("./images/user3.png");

				MDeleteComBoxEntry[] items = new MDeleteComBoxEntry[] {
						new MDeleteComBoxEntry(_icon1, "Wang"),
						new MDeleteComBoxEntry(_icon2, "Zhang"),
						new MDeleteComBoxEntry(_icon3, "Zhong") };
				MDeleteComBox _comBox = new MDeleteComBox(items);
				_comBox.setPreferredSize(new Dimension(150, 25));
				_comBox.setEditable(true);
				_comBox.setDefaultIcon(_icon1);
				_comBox.setBDefaultIconShow(true);
				_comBox.addMItemListener(new MItemListener() {
					@Override
					public void itemDeleted(MDeleteComBoxEntry entry) {
						System.out.println("entry deleted:" + entry.getText());
					}

					@Override
					public void itemSelected(MDeleteComBoxEntry entry) {
						System.out.println("entry selected:" + entry.getText());
					}

				});
				JPanel _panel = new JPanel();
				_panel.add(_comBox);

				_frame.add(_panel);
				_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				_frame.setSize(new Dimension(400, 300));
				_frame.setVisible(true);
			}

		});
	}
}


 

MDeleteComBoxEntry(菜单项)

 

package com.michael.wang.swing.ui;

import javax.swing.Icon;

/**
 *菜单项类s
 * @Author Michael.Wang
 * @Email wqjsir@foxmail.com
 * @version 1.0 2011-5-16下午07:27:05
 **/
public class MDeleteComBoxEntry {

	private Icon icon;
	private String text;

	public MDeleteComBoxEntry(String text){
		this.text = text;
	}
	
	public MDeleteComBoxEntry(Icon icon,String text){
		this.icon = icon;
		this.text = text;
	}

	public Icon getIcon() {
		return icon;
	}

	public void setIcon(Icon icon) {
		this.icon = icon;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
	
	@Override
	public String toString(){
		return text;
	}
	
}


菜单项监视接口类:

MItemListener

package com.michael.wang.swing.ui;

/**
 *菜单项监视接口类
 * @Author Michael.Wang
 * @Email wqjsir@foxmail.com
 * @version 1.0 2011-5-17上午09:45:02
 **/
public interface MItemListener {
	
	/**
	 * 菜单项被删除
	 * @param entry
	 */
	public void itemDeleted(MDeleteComBoxEntry entry);
	
	/**
	 * 菜单项选中
	 * @param entry
	 */
	public void itemSelected(MDeleteComBoxEntry entry);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值