summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ComboBox.java
blob: 2dddd48edcfb0462d6099297fc6606c7074907a6 (plain) (tree)















































                                                                                         
                                                  



                                                                                                     
                                                                      


                                                      

                                                                   














                                                                                                                        

                                                                                                       


















                                                                                                                                      






















                                                                                                     
                         
                                                                                                                



                 
package org.openslx.dozmod.gui.control;

import java.awt.Component;
import java.util.Comparator;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

@SuppressWarnings("serial")
public class ComboBox<T> extends JComboBox<T> {

	public static abstract class ComboBoxRenderer<T> {
		public abstract String renderItem(T item);

		public String getEmptyText() {
			return null;
		}
	}

	private final Comparator<T> equalityComparator;
	private final ComboBoxRenderer<T> itemRenderer;
	private final ComboBox<T> me = this;
	private boolean replacedRenderer = false;

	public ComboBox(ComboBoxRenderer<T> renderer) {
		this(null, renderer);
	}

	public ComboBox(Comparator<T> equalityComparator, ComboBoxRenderer<T> renderer) {
		super();
		this.itemRenderer = renderer;
		this.equalityComparator = equalityComparator;
	}

	/**
	 * This version of {@link JComboBox#setSelectedItem(Object)} will use the
	 * comparator given when constructing the ComboBox to determine if an entry
	 * should be selected.
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void setSelectedItem(Object anObject) {
		if (anObject != null && equalityComparator != null) {
			ComboBoxModel<T> model = getModel();
			Object localObject = null;
			try {
				for (int i = 0; i < model.getSize(); ++i) {
					T element = model.getElementAt(i);
					if (equalityComparator.compare((T) anObject, element) == 0) {
						localObject = element;
						break;
					}
				}
				super.setSelectedItem(localObject);
				return;
			} catch (ClassCastException e) {
				// Bummer, fall through
			}
		}
		super.setSelectedItem(anObject);
	}

	@Override
	public void updateUI() {
		super.updateUI();
		if (!replacedRenderer) {
			replacedRenderer = true;
			final ListCellRenderer<? super T> oldRenderer = super.getRenderer();
			if (oldRenderer instanceof JLabel) {
				// The default JComboBox renderer always seems to be a subclass of JLabel, which is nice
				((JLabel) oldRenderer).putClientProperty("html.disable", Boolean.TRUE);
				((JLabel) oldRenderer).putClientProperty("html", null);
				super.setRenderer(new ListCellRenderer<T>() {
					@Override
					public Component getListCellRendererComponent(JList<? extends T> list, T value,
							int index, boolean isSelected, boolean cellHasFocus) {
						String text;
						if (me.getModel().getSize() == 0) {
							text = itemRenderer.getEmptyText();
						} else {
							text = itemRenderer.renderItem(value);
						}
						Component comp = oldRenderer.getListCellRendererComponent(list, null, index,
								isSelected, cellHasFocus);
						comp.setEnabled(me.isEnabled());
						((JLabel) comp).setText(text);
						return comp;
					}
				});
			} else {
				// Fallback, in case there's any platform, L&F, runtime environment or whatnot where it's not a JLabel
				super.setRenderer(new FallbackCellRenderer());
			}
		}
	}

	private class FallbackCellRenderer extends DefaultListCellRenderer {
		public FallbackCellRenderer() {
			putClientProperty("html.disable", Boolean.TRUE);
			putClientProperty("html", null);
		}

		@SuppressWarnings("unchecked")
		@Override
		public Component getListCellRendererComponent(JList<?> list, Object value, int index,
				boolean isSelected, boolean cellHasFocus) {
			if (me.getModel().getSize() == 0) {
				value = itemRenderer.getEmptyText();
			} else {
				try {
					value = itemRenderer.renderItem((T) value);
				} catch (ClassCastException e) {
					// Should never happen; do nothing, retain original value
				}
			}
			return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
		}
	}

}