001package jmri.swing;
002
003import java.awt.Component;
004import java.util.ArrayList;
005import java.util.List;
006import java.util.Vector;
007
008import javax.annotation.Nonnull;
009import javax.swing.DefaultComboBoxModel;
010import javax.swing.JComboBox;
011import javax.swing.JLabel;
012import javax.swing.JList;
013import javax.swing.ListCellRenderer;
014import jmri.Manager;
015import jmri.NamedBean;
016import jmri.ProxyManager;
017
018/**
019 * A JComboBox for a set of Managers for the same type of NamedBean.
020 *
021 * @author Randall Wood
022 * @param <B> the type of NamedBean
023 */
024public class ManagerComboBox<B extends NamedBean> extends JComboBox<Manager<B>> {
025
026    public ManagerComboBox() {
027        this(new ArrayList<Manager<B>>());
028    }
029
030    public ManagerComboBox(@Nonnull List<Manager<B>> list) {
031        this(list, null);
032    }
033
034    public ManagerComboBox(@Nonnull List<Manager<B>> list, Manager<B> selection) {
035        super();
036        setRenderer(new ManagerRenderer(getRenderer()));
037        // prevent overriding method from being used
038        ManagerComboBox.this.setManagers(list, selection);
039    }
040
041    /**
042     * Set the list of managers, selecting the first manager in the list.
043     *
044     * @param list the list of managers
045     */
046    public void setManagers(@Nonnull List<Manager<B>> list) {
047        setManagers(list, null);
048    }
049
050    /**
051     * Set the list of managers, selecting the passed in manager.
052     *
053     * @param list      the list of managers
054     * @param selection the manager to select; if null, the first manager in the
055     *                  list is selected
056     */
057    public void setManagers(@Nonnull List<Manager<B>> list, Manager<B> selection) {
058        setModel(new DefaultComboBoxModel<>(new Vector<>(list)));
059        if (!list.isEmpty()) {
060            if (selection == null) {
061                setSelectedIndex(0);
062            } else {
063                setSelectedItem(selection);
064            }
065        }
066    }
067
068    /**
069     * Set the list of managers to the single passed in manager, and select it.
070     *
071     * @param manager the manager; if manager is a {@link ProxyManager}, this is
072     *                equivalent to calling {@link #setManagers(List, Manager)}
073     *                with the results of
074     *                {@link ProxyManager#getDisplayOrderManagerList()},
075     *                {@link ProxyManager#getDefaultManager()}
076     */
077    public void setManagers(@Nonnull Manager<B> manager) {
078        if (manager instanceof ProxyManager) {
079            ProxyManager<B> proxy = (ProxyManager<B>) manager;
080            setManagers(proxy.getDisplayOrderManagerList(), proxy.getDefaultManager());
081        } else {
082            List<Manager<B>> list = new ArrayList<>();
083            list.add(manager);
084            setManagers(list, manager);
085        }
086    }
087
088    /**
089     * {@inheritDoc}
090     */
091    @Override
092    public Manager<B> getSelectedItem() {
093        return getItemAt(getSelectedIndex());
094    }
095
096    private class ManagerRenderer implements ListCellRenderer<Manager<B>> {
097
098        private final ListCellRenderer<? super Manager<B>> myRenderer;
099
100        public ManagerRenderer(ListCellRenderer<? super Manager<B>> renderer) {
101            this.myRenderer = renderer;
102        }
103
104        @Override
105        public Component getListCellRendererComponent(JList<? extends Manager<B>> list, Manager<B> value, int index,
106                boolean isSelected, boolean cellHasFocus) {
107            JLabel label = (JLabel) myRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
108            if (value != null) {
109                label.setText(value.getMemo().getUserName());
110            }
111            return label;
112        }
113    }
114
115}