package com.bugu.mutilcombobox;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicArrowButton;
/**
* hi , this is my first ui component. my ui component "hello world"!!
*
* @author bugu
*
*/
public class MulitCombobox extends JComponent {
private Object[] values;
private Object[] defaultValues;
private List<ActionListener> listeners = new ArrayList<ActionListener>();
private MulitPopup popup;
private JTextField editor;
protected JButton arrowButton;
private String valueSperator;
private static final String DEFAULT_VALUE_SPERATOR = " ";
public MulitCombobox(Object[] value, Object[] defaultValue){
this(value,defaultValue,DEFAULT_VALUE_SPERATOR);
}
public MulitCombobox(Object[] value, Object[] defaultValue , String valueSperator) {
values = value;
defaultValues = defaultValue;
this.valueSperator = valueSperator;
initComponent();
}
private void initComponent() {
//暂时使用该布局,后续自己写个布局
this.setLayout(new FlowLayout());
popup =new MulitPopup(values,defaultValues);
popup.addActionListener(new PopupAction());
editor = new JTextField();
editor.setBackground(Color.WHITE);
editor.setEditable(false);
editor.setBorder(null);
editor.addMouseListener(new EditorHandler());
arrowButton = createArrowButton();
arrowButton.addMouseListener(new EditorHandler());
add(editor);
add(arrowButton);
setText() ;
}
public Object[] getSelectedValues() {
return popup.getSelectedValues();
}
public void addActionListener(ActionListener listener) {
if (!listeners.contains(listener))
listeners.add(listener);
}
public void removeActionListener(ActionListener listener) {
if (listeners.contains(listener))
listeners.remove(listener);
}
protected void fireActionPerformed(ActionEvent e) {
for (ActionListener l : listeners) {
l.actionPerformed(e);
}
}
private class PopupAction implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals(MulitPopup.CANCEL_EVENT)){
}else if(e.getActionCommand().equals(MulitPopup.COMMIT_EVENT)){
defaultValues = popup.getSelectedValues();
setText();
//把事件继续传递出去
fireActionPerformed(e);
}
togglePopup();
}
}
private void togglePopup(){
if(popup.isVisible()){
popup.setVisible(false);
}else{
popup.setDefaultValue(defaultValues);
popup.show(this, 0, getHeight());
}
}
private void setText() {
StringBuilder builder = new StringBuilder();
for(Object dv : defaultValues){
builder.append(dv);
builder.append(valueSperator);
}
editor.setText(builder.substring(0, builder.length() > 0 ? builder.length() -1 : 0).toString());
}
private class EditorHandler implements MouseListener{
@Override
public void mouseClicked(MouseEvent e) {
togglePopup();
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fillRect(0,0,getWidth(),getHeight());
}
/**
* 摘自JDK
* Creates an button which will be used as the control to show or hide
* the popup portion of the combo box.
*
* @return a button which represents the popup control
*/
protected JButton createArrowButton() {
JButton button = new BasicArrowButton(BasicArrowButton.SOUTH,
UIManager.getColor("ComboBox.buttonBackground"),
UIManager.getColor("ComboBox.buttonShadow"),
UIManager.getColor("ComboBox.buttonDarkShadow"),
UIManager.getColor("ComboBox.buttonHighlight"));
button.setName("ComboBox.arrowButton");
return button;
}
private class MulitComboboxLayout implements LayoutManager{
@Override
public void addLayoutComponent(String name, Component comp) {
// TODO Auto-generated method stub
}
@Override
public void removeLayoutComponent(Component comp) {
// TODO Auto-generated method stub
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return parent.getPreferredSize();
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return parent.getMinimumSize();
}
@Override
public void layoutContainer(Container parent) {
int w=parent.getWidth();
int h=parent.getHeight();
Insets insets=parent.getInsets();
h=h-insets.top-insets.bottom;
}
}
}
package com.bugu.mutilcombobox;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
/**
*
* @author bugu
*
*/
public class MulitPopup extends JPopupMenu {
private List<ActionListener> listeners = new ArrayList<ActionListener>();
private Object[] values;
private Object[] defaultValues;
private List<JCheckBox> checkBoxList = new ArrayList<JCheckBox>();
private JButton commitButton ;
private JButton cancelButton;
public static final String COMMIT_EVENT = "commit";
public static final String CANCEL_EVENT = "cancel";
public MulitPopup(Object[] value , Object[] defaultValue) {
super();
values = value;
defaultValues = defaultValue;
initComponent();
}
public void addActionListener(ActionListener listener) {
if (!listeners.contains(listener))
listeners.add(listener);
}
public void removeActionListener(ActionListener listener) {
if (listeners.contains(listener))
listeners.remove(listener);
}
private void initComponent() {
JPanel checkboxPane = new JPanel();
JPanel buttonPane = new JPanel();
this.setLayout(new BorderLayout());
for(Object v : values){
JCheckBox temp = new JCheckBox(v.toString() , selected(v));
checkBoxList.add(temp);
}
checkboxPane.setLayout(new GridLayout(checkBoxList.size() , 1 ,3, 3));
for(JCheckBox box : checkBoxList){
checkboxPane.add(box);
}
commitButton = new JButton("ok");
commitButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
commit();
}
});
cancelButton = new JButton("cancel");
cancelButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
cancel();
}
});
buttonPane.add(commitButton);
buttonPane.add(cancelButton);
this.add(checkboxPane , BorderLayout.CENTER);
this.add(buttonPane , BorderLayout.SOUTH);
}
private boolean selected(Object v) {
for(Object dv : defaultValues){
if( dv .equals(v) ){
return true;
}
}
return false;
}
protected void fireActionPerformed(ActionEvent e) {
for (ActionListener l : listeners) {
l.actionPerformed(e);
}
}
public Object[] getSelectedValues(){
List<Object> selectedValues = new ArrayList<Object>();
for(int i = 0 ; i < checkBoxList.size() ; i++){
if(checkBoxList.get(i).isSelected())
selectedValues.add(values[i]);
}
return selectedValues.toArray(new Object[selectedValues.size()]);
}
public void setDefaultValue(Object[] defaultValue) {
defaultValues = defaultValue;
}
public void commit(){
fireActionPerformed(new ActionEvent(this, 0, COMMIT_EVENT));
}
public void cancel(){
fireActionPerformed(new ActionEvent(this, 0, CANCEL_EVENT));
}
}
上面是源码,不多说了,是我写的第一个控件。比较菜,至于为啥写。出差的时候无聊写的,:-)。下面是demo
package com.bugu.mutilcombobox.demo;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.bugu.mutilcombobox.MulitCombobox;
public class MainFrame extends JFrame {
public MainFrame(){
init();
}
private void init() {
this.setLayout(new FlowLayout());
Object[] value = new String[]{ "1" , "2" ,"3" ,"4","5" };
Object[] defaultValue = new String[]{ "1" ,"4","5" };
final MulitCombobox mulit = new MulitCombobox(value, defaultValue);
final JTextField text = new JTextField(20);
mulit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object[] v = mulit.getSelectedValues();
StringBuilder builder = new StringBuilder();
for(Object dv : v){
builder.append(dv);
builder.append("--");
}
text.setText(builder.toString());
}
});
this.add(mulit );
this.add(text);
}
/**
* @param args
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Window main = new MainFrame();
main.setSize(400,400);
main.setVisible(true);
}
}