001package jmri.jmrit.roster.swing;
002
003import java.beans.PropertyChangeEvent;
004import java.util.ArrayList;
005import java.util.Collections;
006import java.util.Locale;
007import javax.swing.JComboBox;
008
009import jmri.jmrit.roster.Roster;
010import jmri.jmrit.roster.rostergroup.RosterGroupSelector;
011
012/**
013 * A JComboBox of Roster Groups.
014 *
015 * @author Randall Wood Copyright (C) 2011, 2014
016 * @see jmri.jmrit.roster.Roster
017 */
018public class RosterGroupComboBox extends JComboBox<String> implements RosterGroupSelector {
019
020    private Roster _roster;
021    private boolean allEntriesEnabled = false;
022
023    /**
024     * Create a RosterGroupComboBox with an arbitrary Roster instead of the
025     * default Roster instance.
026     *
027     * @param roster the Roster to show the groups of
028     */
029    // needed for unit tests
030    public RosterGroupComboBox(Roster roster) {
031        this(roster, roster.getDefaultRosterGroup());
032    }
033
034    /**
035     * Create a RosterGroupComboBox with an arbitrary selection.
036     *
037     * @param selection the initial roster group selection
038     */
039    public RosterGroupComboBox(String selection) {
040        this(Roster.getDefault(), selection);
041    }
042
043    /**
044     * Create a RosterGroupComboBox with arbitrary selection and Roster.
045     *
046     * @param roster    the Roster to show the groups of
047     * @param selection the initial roster group selection
048     */
049    public RosterGroupComboBox(Roster roster, String selection) {
050        super();
051        _roster = roster;
052        update(selection);
053        roster.addPropertyChangeListener((PropertyChangeEvent pce) -> {
054            if (pce.getPropertyName().equals("RosterGroupAdded")) {
055                update();
056            } else if (pce.getPropertyName().equals("RosterGroupRemoved")
057                    || pce.getPropertyName().equals("RosterGroupRenamed")) {
058                if (getSelectedItem().equals(pce.getOldValue())) {
059                    update((String) pce.getNewValue());
060                } else {
061                    update();
062                }
063            }
064        });
065        setEditable(false);
066    }
067
068    /**
069     * Create a RosterGroupComboBox with the default Roster instance and the
070     * default roster group.
071     */
072    public RosterGroupComboBox() {
073        this(Roster.getDefault(), Roster.getDefault().getDefaultRosterGroup());
074    }
075
076    /**
077     * Update the combo box and reselect the current selection.
078     */
079    public final void update() {
080        update(this.getSelectedItem());
081    }
082
083    /**
084     * Update the combo box and select given String.
085     * @param selection the selection to update to; null or empty means 1st item if present
086     */
087    public final void update(String selection) {
088        removeAllItems();
089        ArrayList<String> l = _roster.getRosterGroupList();
090        Collections.sort(l);
091        l.forEach((g) -> {
092            addItem(g);
093        });
094        if (allEntriesEnabled) {
095            insertItemAt(Roster.allEntries(Locale.getDefault()), 0);
096            if (selection == null) {
097                selection = Roster.ALLENTRIES;
098            }
099            this.setToolTipText(null);
100        } else {
101            if (this.getItemCount() == 0) {
102                // this.addItem(Bundle.getMessage("RosterGroupComboBoxNoGroups"));
103                this.setToolTipText(Bundle.getMessage("RosterGroupComboBoxNoGroupsToolTip"));
104                return;
105            } else {
106                this.setToolTipText(null);
107            }
108        }
109
110        if (this.getItemCount() == 1) {
111            this.setSelectedIndex(0);
112            this.setEnabled(false);
113        } else {
114            this.setEnabled(true);
115            if (selection != null && !selection.isEmpty()) {
116                setSelectedItem(selection);
117            } else {
118                this.setSelectedIndex(0);
119            }
120        }
121    }
122
123    @Override
124    public String getSelectedRosterGroup() {
125        if (getSelectedItem() == null) {
126            return null;
127        } else if (getSelectedItem().equals(Roster.ALLENTRIES)
128                || getSelectedItem().equals(Roster.allEntries(Locale.getDefault()))) {
129            return null;
130        } else {
131            return getSelectedItem();
132        }
133    }
134
135    /**
136     * @return the allEntriesEnabled
137     */
138    public boolean isAllEntriesEnabled() {
139        return allEntriesEnabled;
140    }
141
142    /**
143     * Setting this true will display the "All Groups" item in 
144     * addition to the defined groups.  Default is false.
145     * @param allEntriesEnabled the allEntriesEnabled to set
146     */
147    public void setAllEntriesEnabled(boolean allEntriesEnabled) {
148        this.allEntriesEnabled = allEntriesEnabled;
149        this.update();
150    }
151
152    @Override
153    public String getSelectedItem() {
154
155        Object item = super.getSelectedItem();
156        return item != null ? item.toString() : null;
157    }
158}