/* * Copyright (C) 2009 Quadduc <quadduc@gmail.com> * * This file is part of LateralGM. * LateralGM is free software and comes with ABSOLUTELY NO WARRANTY. * See LICENSE for details. */ package org.lateralgm.ui.swing.propertylink; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Map; import javax.swing.JComboBox; import org.lateralgm.util.PropertyLink; import org.lateralgm.util.PropertyMap; import org.lateralgm.util.PropertyMap.PropertyUpdateEvent; public class ComboBoxLink<K extends Enum<K>, V> extends PropertyLink<K,V> implements ActionListener { public final JComboBox<?> box; private final ComboBoxConversion<V> conv; public static interface ComboBoxConversion<T> { /** * Converts a JComboBox selectable item into its backend equivalent. */ public T convertItem(int index, Object o); } public static interface ComboBoxSelectable<V> { public void select(JComboBox<?> b, V o); } public static class DefaultComboBoxConversion<V> implements ComboBoxConversion<V>, ComboBoxSelectable<V> { @SuppressWarnings("unchecked") public V convertItem(int ind, Object o) { return (V) o; } public void select(JComboBox<?> b, V o) { b.setSelectedItem(o); } } public static class IndexComboBoxConversion implements ComboBoxConversion<Integer>, ComboBoxSelectable<Integer> { public Integer convertItem(int ind, Object o) { return ind; } public void select(JComboBox<?> b, Integer o) { b.setSelectedIndex(o); } } public static class KeyComboBoxConversion<V> implements ComboBoxConversion<V>, ComboBoxSelectable<V> { private final V[] items; private final Map<?,Integer> map; public KeyComboBoxConversion(V[] items) { this.items = items; this.map = null; } public KeyComboBoxConversion(V[] items, Map<?,Integer> map) { this.items = items; this.map = map; } public V convertItem(int ind, Object o) { return (V) items[ind]; } public void select(JComboBox<?> b, V o) { if (map != null) { b.setSelectedIndex(map.get(o)); return; } for (int i = 0; i < items.length; i++) { if (items[i].equals(o)) { b.setSelectedIndex(i); return; } } } } public ComboBoxLink(JComboBox<?> b, PropertyMap<K> m, K k, ComboBoxConversion<V> conv) { super(m,k); box = b; this.conv = conv == null ? new DefaultComboBoxConversion<V>() : conv; reset(); box.addActionListener(this); } protected void setComponent(V i) { setConvertedSelection(i); } /** * Searches for and selects the selectable item that converts to this backend object. * To make this method more efficient, your ComboBoxConversion should also implement * ComboBoxSelectable */ public void setConvertedSelection(V o) { if (conv instanceof ComboBoxSelectable) { ((ComboBoxSelectable<V>) conv).select(box,o); return; } if (o == null) return; for (int i = 0; i < box.getItemCount(); i++) { V it = conv.convertItem(i,box.getItemAt(i)); if (o.equals(it)) { box.setSelectedIndex(i); return; } } } public V getConvertedSelection() { return conv.convertItem(box.getSelectedIndex(),box.getSelectedItem()); } @Override public void remove() { super.remove(); box.removeActionListener(this); } @Override public void updated(PropertyUpdateEvent<K> e) { editComponentIfChanged(getConvertedSelection()); } public void actionPerformed(ActionEvent e) { Object i = getConvertedSelection(); if (i.equals(map.get(key))) return; editProperty(i); } }