package org.rr.jeborker.gui.cell;
import static org.rr.commons.utils.StringUtil.EMPTY;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import org.rr.commons.collection.CompoundList;
import org.rr.commons.utils.ListUtils;
import org.rr.commons.utils.StringUtil;
import org.rr.commons.utils.UtilConstants;
import com.l2fprod.common.beans.editor.AbstractPropertyEditor;
public class MultiListPropertyEditor extends AbstractPropertyEditor {
private static final String noChanges = "<" + Bundle.getString("ComboBoxPropertyEditor.noChanges") + ">";
private static final String clear = "<" + Bundle.getString("ComboBoxPropertyEditor.clear") + ">";
private Object oldValue;
private Icon[] icons;
private boolean editorInputChanged = false;
private boolean selectionChanged = false;
public MultiListPropertyEditor() {
editor = new JComboBox() {
public void setSelectedItem(Object anObject) {
oldValue = getSelectedItem();
super.setSelectedItem(anObject);
}
};
final JComboBox combo = (JComboBox) editor;
combo.setEditable(true);
((JTextField)combo.getEditor().getEditorComponent()).setBorder(new EmptyBorder(new Insets(0, 3, 0, 0)));
combo.getEditor().getEditorComponent().addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
String text = ((JTextField)combo.getEditor().getEditorComponent()).getText();
if(noChanges.equals(text) || clear.equals(text) || text == null) {
((JTextField)combo.getEditor().getEditorComponent()).setText(EMPTY);
}
}
});
combo.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
editorInputChanged = true;
if (e.getKeyChar() == '\n' || e.getKeyChar() == '\t') {
MultiListPropertyEditor.this.firePropertyChange(oldValue, combo.getSelectedItem());
}
}
});
combo.setRenderer(new Renderer());
combo.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
MultiListPropertyEditor.this.firePropertyChange(oldValue, combo.getSelectedItem());
selectionChanged = true;
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
selectionChanged = true;
}
});
combo.setSelectedIndex(-1);
}
public Object getValue() {
int selectedIndex = ((JComboBox) editor).getSelectedIndex();
Object result;
if(selectedIndex == -1) {
//editor value
result = ((JTextField)((JComboBox) editor).getEditor().getEditorComponent()).getText();
} else if(!editorInputChanged && selectedIndex == 0) {
//no change
result = null;
} else if(!(editorInputChanged || selectionChanged) && selectedIndex == 1) {
//no change
result = null;
} else if((editorInputChanged || selectionChanged) && selectedIndex == 1) {
//clear
result = EMPTY;
} else {
result = ((JTextField)((JComboBox) editor).getEditor().getEditorComponent()).getText();
}
return result;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void setValue(Object value) {
List viewList = new ArrayList(Arrays.asList(new Object[((List) value).size()]));
Collections.copy(viewList, ((List) value));
//the first one is the value which is stored to all selected ebooks.
Object selectedValue = viewList.remove(0);
viewList = ListUtils.distinct(viewList, UtilConstants.COMPARE_TEXT);
viewList.remove(EMPTY);
viewList.remove(null);
viewList = new CompoundList(Arrays.asList(new Object[] {noChanges, clear}), viewList);
Object[] values = viewList.toArray(new Object[viewList.size()]);
this.setAvailableValues(values);
if(selectedValue == null) {
((JComboBox) editor).setSelectedIndex(0);
} else if(StringUtil.toString(selectedValue).isEmpty()) {
((JComboBox) editor).setSelectedIndex(1);
} else {
((JComboBox) editor).setSelectedItem(selectedValue);
}
}
public void setAvailableValues(Object[] values) {
((JComboBox) editor).setModel(new DefaultComboBoxModel(values));
}
public void setAvailableIcons(Icon[] icons) {
this.icons = icons;
}
private class Renderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (icons != null && index >= 0 && component instanceof JLabel) {
((JLabel) component).setIcon(icons[index]);
}
return component;
}
}
}