package com.onaro.util.jfc.mixedvalue;
import static com.onaro.util.jfc.mixedvalue.MixedValueConstants.MIXED_VALUE;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import org.apache.commons.lang3.StringUtils;
/**
* An extension to {@link JComboBox} allowing for a special "mixed" valued. Used when editing multiple values which are
* not the same, though the user can set all of them to the same value selected from the list.
*
* Once the user clics on the field, the mixed mode, if set, is reset and the value clears and a value is selected.
*/
public class MixedComboBox extends JComboBox {
private static final long serialVersionUID = 1L;
/**
* Tells if the current value is this special "mixed".
*/
private boolean mixed;
/**
* Font to use for the special "mixed" value.
*/
private Font italicFont;
/**
* Standard font to use for any value but the special "mixed" value.
*/
private Font plainFont;
/**
* Initializes this mixed-value combo-box field. Records the default fonts. Registers the listeners that will
* clear the "mixed mode" once the user clicks on the field.
* @param items the values from which the user can select
*/
public MixedComboBox(final Object items[]) {
this(new DefaultComboBoxModel(items));
}
/**
* Initializes this mixed-value combo-box field. Records the default fonts. Registers the listeners that will
* clear the "mixed mode" once the user clicks on the field.
* @param aModel the model for this combo-box
*/
public MixedComboBox(ComboBoxModel aModel) {
super(aModel);
italicFont = getFont().deriveFont(Font.ITALIC);
plainFont = getFont().deriveFont(Font.PLAIN);
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (getSelectedIndex() >= 0) {
setMixed(false);
}
}
});
}
public void reset() {
// set the current selected item.
selectedItemReminder = dataModel.getSelectedItem();
}
/**
* Sets the mixed mode of this field. When set to true, the field will show "mixed" in italic, blue font.
* @param mixed true if the field should enter the "mixed mode"
*/
public void setMixed(boolean mixed) {
if (this.mixed != mixed) {
this.mixed = mixed;
if (mixed) setSelectedIndex(-1);
}
}
/**
* Tells if the field is currently in "mixed mode".
* @return true if the field is in "mixed mode"
*/
public boolean isMixed() {
return mixed;
}
protected boolean isDontCare(Object value){
return value == null;
}
/**
* Override the original method to guarantee enough space for all values.
* @return
*/
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.setSize(size.getWidth()+10,size.getHeight());
return size;
}
public void setRenderer(ListCellRenderer renderer) {
super.setRenderer(new MixedCellRenderer(renderer));
}
private class MixedCellRenderer implements ListCellRenderer {
ListCellRenderer encapsulatedRenderer;
public MixedCellRenderer(ListCellRenderer encapsulatedRenderer) {
this.encapsulatedRenderer = encapsulatedRenderer;
}
public Component getListCellRendererComponent(JList> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
/**
* Render "DONT_CARE" as blank.
*/
if (isDontCare(value)) value = StringUtils.EMPTY;
/**
* Render "MIXED" as blue italic
*/
if(isMixed() && index < 0) {
list.setForeground(UIManager.getColor("mixedValue.color")); //$NON-NLS-1$
list.setFont(italicFont);
value = MIXED_VALUE;
}else{
list.setForeground(Color.BLACK);
list.setFont(plainFont);
}
return encapsulatedRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
}
}