001package jmri.jmrit.picker;
002
003import java.util.*;
004
005import javax.annotation.CheckForNull;
006import javax.annotation.CheckReturnValue;
007import javax.annotation.Nonnull;
008import javax.swing.JTable;
009import javax.swing.ListSelectionModel;
010import javax.swing.SortOrder;
011import javax.swing.table.TableColumn;
012import javax.swing.table.TableColumnModel;
013import javax.swing.table.TableRowSorter;
014
015import jmri.*;
016import jmri.jmrit.beantable.BeanTableDataModel;
017import jmri.jmrit.entryexit.*;
018import jmri.jmrit.logix.*;
019import jmri.jmrit.logixng.GlobalVariable;
020import jmri.jmrit.logixng.GlobalVariableManager;
021import jmri.swing.RowSorterUtil;
022import jmri.util.*;
023import jmri.util.swing.XTableColumnModel;
024
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027
028/**
029 * Abstract class to make pick lists for NamedBeans; Table model for pick lists
030 * in IconAdder
031 * <p>
032 * Concrete pick list class for many beans are include at the end of this file.
033 * This class also has instantiation methods serve as a factory for those
034 * classes.
035 * <p>
036 * Note: Extensions of this class must call init() after instantiation.
037 *
038 * <hr>
039 * This file is part of JMRI.
040 * <p>
041 * JMRI is free software; you can redistribute it and/or modify it under the
042 * terms of version 2 of the GNU General Public License as published by the Free
043 * Software Foundation. See the "COPYING" file for a copy of this license.
044 * <p>
045 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
046 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
047 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
048 *
049 * @param <E> the supported type of NamedBean
050 * @author Pete Cressman Copyright (C) 2009, 2010
051 */
052public abstract class PickListModel<E extends NamedBean> extends BeanTableDataModel<E> {
053
054    protected ArrayList<E> _pickList;
055    protected String _name;
056    private JTable _table;       // table using this model
057    protected TableRowSorter<PickListModel<E>> _sorter;
058
059    public static final int SNAME_COLUMN = 0;
060    public static final int UNAME_COLUMN = 1;
061    public static final int POSITION_COL = 2;
062    public static final ResourceBundle rb = ResourceBundle.getBundle("jmri.jmrit.beantable.BeanTableBundle");
063
064    static HashMap<String, Integer> _listMap = new HashMap<String, Integer>();
065
066    static public int getNumInstances(@Nonnull String type) {
067        Integer num = _listMap.get(type.toLowerCase());
068        log.debug("getNumInstances of {} num={}", type, num);
069        if (num != null) {
070            return num;
071        }
072        return 0;
073    }
074
075    /**
076     * Default constructor makes a table sorted by System Name.
077     */
078    public PickListModel() {
079        super();
080    }
081
082    /**
083     * If table has been sorted table row no longer is the same as array index.
084     *
085     * @param index row of table
086     * @return bean at index or null if index is out of range
087     */
088    @CheckForNull
089    public E getBeanAt(int index) {
090        if (index >= _pickList.size()) {
091            return null;
092        }
093        return _pickList.get(index);
094    }
095
096    public int getIndexOf(@Nonnull E bean) {
097        for (int i = 0; i < _pickList.size(); i++) {
098            if (_pickList.get(i).equals(bean)) {
099                return i;
100            }
101        }
102        return -1;
103    }
104
105    /**
106     * This method is overridden if only a limited set of the beans should be retrieved.
107     * @return the list of beans
108     */
109    @Nonnull
110    public List<E> getBeanList() {
111        return _pickList;
112    }
113
114    /**
115     * override BeanTableDataModel only lists SystemName
116     */
117    @Override
118    protected synchronized void updateNameList() {
119        makePickList();
120    }
121
122    @CheckReturnValue
123    @Nonnull
124    protected SortedSet<E> getNamedBeanSet() {
125        return getManager().getNamedBeanSet();
126    }
127
128    private void makePickList() {
129        // Don't know who is added or deleted so remove all name change listeners
130        if (_pickList != null) {
131            for (E e : _pickList) {
132                e.removePropertyChangeListener(this);
133            }
134        }
135        TreeSet<E> ts = new TreeSet<>(new NamedBeanComparator<>());
136        ts.addAll(getNamedBeanSet());
137
138        _pickList = new ArrayList<>(getNamedBeanSet().size());
139
140        _pickList.addAll(ts);
141        // add name change listeners
142        for (E e : _pickList) {
143            e.addPropertyChangeListener(this);
144        }
145        log.debug("_pickList has {} beans", _pickList.size());
146    }
147
148    /** {@inheritDoc} */
149    @Override
150    @CheckForNull
151    public E getBySystemName(@Nonnull String name) {
152        return getManager().getBySystemName(name);
153    }
154
155    /** {@inheritDoc} */
156    @Override
157    @CheckForNull
158    protected E getByUserName(@Nonnull String name) {
159        return getManager().getByUserName(name);
160    }
161
162    /** {@inheritDoc} */
163    @Override
164    @Nonnull
165    abstract public Manager<E> getManager();
166
167    /**
168     * Return bean with name given in parameter. Create if needed and possible.
169     *
170     * @param name the System name for the Bean.
171     * @return the Bean or null if not made.
172     * @throws IllegalArgumentException with reason why Bean cannot be created.
173     */
174    @CheckForNull
175    abstract public E addBean(@Nonnull String name) throws IllegalArgumentException;
176
177    @CheckForNull
178    abstract public E addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException;
179
180    /**
181     * Check if beans can be added by this model.
182     *
183     * @return true if model can create beans; false otherwise
184     */
185    abstract public boolean canAddBean();
186
187    // these BeanTableDataModel abstract methods not needed
188    /** {@inheritDoc} */
189    @Override
190    protected String getMasterClassName() {
191        return "PickListModel";
192    }
193
194    /** {@inheritDoc} */
195    @Override
196    public void clickOn(E t) {
197    }
198
199    /** {@inheritDoc} */
200    @Override
201    public Class<?> getColumnClass(int c) {
202        return String.class;
203    }
204
205    /** {@inheritDoc} */
206    @Override
207    public int getColumnCount() {
208        return 2;
209    }
210
211    /** {@inheritDoc} */
212    @Override
213    public String getColumnName(int c) {
214        if (c == SNAME_COLUMN) {
215            return Bundle.getMessage("ColumnSystemName");
216        } else if (c == UNAME_COLUMN) {
217            return Bundle.getMessage("ColumnUserName");
218        }
219        return "";
220    }
221
222    /** {@inheritDoc} */
223    @Override
224    public boolean isCellEditable(int r, int c) {
225        return false;
226    }
227
228    /** {@inheritDoc} */
229    @Override
230    public int getRowCount() {
231        return _pickList.size();
232    }
233
234    /** {@inheritDoc} */
235    @Override
236    public Object getValueAt(int r, int c) {
237        // some error checking
238        if (r >= _pickList.size()) {
239            log.debug("row is greater than picklist size");
240            return null;
241        }
242        if (c == SNAME_COLUMN) {
243            return _pickList.get(r).getSystemName();
244        } else if (c == UNAME_COLUMN) {
245            return _pickList.get(r).getUserName();
246        }
247        return null;
248    }
249
250    /** {@inheritDoc} */
251    @Override
252    public void setValueAt(Object type, int r, int c) {
253    }
254
255    // these BeanTableDataModel abstract methods not needed
256    /** {@inheritDoc} */
257    @Override
258    public String getValue(String systemName) {
259        return systemName;
260    }
261
262    public String getName() {
263        return _name;
264    }
265
266    /** {@inheritDoc} */
267    @Override
268    protected String getBeanType() {
269        return _name;
270    }
271
272    /**
273     * Handle additions and deletions in the table and changes to beans within
274     * the table.
275     *
276     * @param e the change
277     */
278    @Override
279    public void propertyChange(java.beans.PropertyChangeEvent e) {
280        if (e.getPropertyName().equals("length")) {
281            // a NamedBean added or deleted
282            makePickList();
283            fireTableDataChanged();
284        }
285        if (e.getSource() instanceof NamedBean) {
286            NamedBean bean = (NamedBean) e.getSource();
287            for (int i = 0; i < _pickList.size(); i++) {
288                if (bean.equals(_pickList.get(i))) {
289                    fireTableRowsUpdated(i, i);
290                    break;
291                }
292            }
293        }
294        if (log.isDebugEnabled()) {
295            log.debug("propertyChange of \"{}\" for {}", e.getPropertyName(), e.getSource().toString());
296        }
297    }
298
299    /**
300     * Make pick table, DND enabled.
301     * @return the table
302     */
303    public JTable makePickTable() {
304        _sorter = new TableRowSorter<>(this);
305        _table = new JTable(this) {
306            /**
307             * Overridden to prevent empty cells from being selected
308             */
309            @Override
310            public void changeSelection(int row, int col, boolean toggle, boolean extend) {
311                if (super.getValueAt(row, col) != null) {
312                    super.changeSelection(row, col, toggle, extend);
313                }
314            }
315        };
316        _sorter.setComparator(SNAME_COLUMN, new jmri.util.AlphanumComparator());
317        _sorter.setComparator(UNAME_COLUMN, new jmri.util.AlphanumComparator());
318        RowSorterUtil.setSortOrder(_sorter, SNAME_COLUMN, SortOrder.ASCENDING);
319        _table.setRowSorter(_sorter);
320
321        _table.setRowSelectionAllowed(true);
322        _table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
323        _table.setPreferredScrollableViewportSize(new java.awt.Dimension(250, _table.getRowHeight() * 7));
324        _table.setDragEnabled(true);
325        _table.setTransferHandler(new DnDTableExportHandler());
326
327        _table.getTableHeader().setReorderingAllowed(true);
328        _table.setColumnModel(new XTableColumnModel());
329        _table.createDefaultColumnsFromModel();
330        TableColumnModel columnModel = _table.getColumnModel();
331
332        TableColumn sNameColumnT = columnModel.getColumn(SNAME_COLUMN);
333        sNameColumnT.setResizable(true);
334        sNameColumnT.setMinWidth(50);
335        //sNameColumnT.setMaxWidth(200);
336
337        TableColumn uNameColumnT = columnModel.getColumn(UNAME_COLUMN);
338        uNameColumnT.setResizable(true);
339        uNameColumnT.setMinWidth(100);
340        //uNameColumnT.setMaxWidth(300);
341
342        addMouseListenerToHeader(_table);
343        _table.setAutoCreateColumnsFromModel(false);
344
345        return _table;
346    }
347
348    public void makeSorter(@Nonnull JTable table) {
349        _sorter = new TableRowSorter<>(this);
350        _sorter.setComparator(SNAME_COLUMN, new jmri.util.AlphanumComparator());
351        _sorter.setComparator(UNAME_COLUMN, new jmri.util.AlphanumComparator());
352        RowSorterUtil.setSortOrder(_sorter, SNAME_COLUMN, SortOrder.ASCENDING);
353        table.setRowSorter(_sorter);
354    }
355
356    @Nonnull
357    public JTable getTable() {
358        return _table;
359    }
360
361    /** {@inheritDoc} */
362    @Override
363    public void dispose() {
364        getManager().removePropertyChangeListener(this);
365    }
366
367    @Nonnull
368    public static PickListModel<Turnout> turnoutPickModelInstance() {
369        Integer num = _listMap.get("turnout");
370        if (num != null) {
371            _listMap.put("turnout", num + 1);
372        } else {
373            _listMap.put("turnout", 1);
374        }
375        return new TurnoutPickModel();
376    }
377
378    @Nonnull
379    public static PickListModel<Sensor> sensorPickModelInstance() {
380        Integer num = _listMap.get("sensor");
381        if (num != null) {
382            _listMap.put("sensor", num + 1);
383        } else {
384            _listMap.put("sensor", 1);
385        }
386        return new SensorPickModel();
387    }
388
389    @Nonnull
390    public static PickListModel<Sensor> multiSensorPickModelInstance() {
391        Integer num = _listMap.get("multisensor");
392        if (num != null) {
393            _listMap.put("multisensor", num + 1);
394        } else {
395            _listMap.put("multisensor", 1);
396        }
397        return new MultiSensorPickModel();
398    }
399
400    @Nonnull
401    public static PickListModel<SignalHead> signalHeadPickModelInstance() {
402        Integer num = _listMap.get("signalhead");
403        if (num != null) {
404            _listMap.put("signalhead", num + 1);
405        } else {
406            _listMap.put("signalhead", 1);
407        }
408        return new SignalHeadPickModel();
409    }
410
411    @Nonnull
412    public static PickListModel<SignalMast> signalMastPickModelInstance() {
413        Integer num = _listMap.get("signalmast");
414        if (num != null) {
415            _listMap.put("signalmast", num + 1);
416        } else {
417            _listMap.put("signalmast", 1);
418        }
419        return new SignalMastPickModel();
420    }
421
422    @Nonnull
423    public static PickListModel<Memory> memoryPickModelInstance() {
424        Integer num = _listMap.get("memory");
425        if (num != null) {
426            _listMap.put("memory", num + 1);
427        } else {
428            _listMap.put("memory", 1);
429        }
430        return new MemoryPickModel();
431    }
432
433    @Nonnull
434    public static PickListModel<GlobalVariable> globalVariablePickModelInstance() {
435        Integer num = _listMap.get("globalVariable");
436        if (num != null) {
437            _listMap.put("globalVariable", num + 1);
438        } else {
439            _listMap.put("globalVariable", 1);
440        }
441        return new GlobalVariablePickModel();
442    }
443
444    @Nonnull
445    public static PickListModel<Block> blockPickModelInstance() {
446        Integer num = _listMap.get("block");
447        if (num != null) {
448            _listMap.put("block", num + 1);
449        } else {
450            _listMap.put("block", 1);
451        }
452        return new BlockPickModel();
453    }
454
455    @Nonnull
456    public static PickListModel<Reporter> reporterPickModelInstance() {
457        Integer num = _listMap.get("reporter");
458        if (num != null) {
459            _listMap.put("reporter", num + 1);
460        } else {
461            _listMap.put("reporter", 1);
462        }
463        return new ReporterPickModel();
464    }
465
466    @Nonnull
467    public static PickListModel<Light> lightPickModelInstance() {
468        Integer num = _listMap.get("light");
469        if (num != null) {
470            _listMap.put("light", num + 1);
471        } else {
472            _listMap.put("light", 1);
473        }
474        return new LightPickModel();
475    }
476
477    @Nonnull
478    public static PickListModel<OBlock> oBlockPickModelInstance() {
479        Integer num = _listMap.get("oBlock");
480        if (num != null) {
481            _listMap.put("oBlock", num + 1);
482        } else {
483            _listMap.put("oBlock", 1);
484        }
485        return new OBlockPickModel();
486    }
487
488    @Nonnull
489    public static PickListModel<Warrant> warrantPickModelInstance() {
490        Integer num = _listMap.get("warrant");
491        if (num != null) {
492            _listMap.put("warrant", num + 1);
493        } else {
494            _listMap.put("warrant", 1);
495        }
496        return new WarrantPickModel();
497    }
498
499    @Nonnull
500    public static PickListModel<DestinationPoints> entryExitPickModelInstance() {
501        Integer num = _listMap.get("entryExit");
502        if (num != null) {
503            _listMap.put("entryExit", num + 1);
504        } else {
505            _listMap.put("entryExit", 1);
506        }
507        return new EntryExitPickModel();
508    }
509
510    public static PickListModel<Logix> logixPickModelInstance() {
511        Integer num = _listMap.get("logix");
512        if (num != null) {
513            _listMap.put("logix", num + 1);
514        } else {
515            _listMap.put("logix", 1);
516        }
517        return new LogixPickModel();
518    }
519
520    @Nonnull
521    public static PickListModel<Audio> audioPickModelInstance() {
522        Integer num = _listMap.get("audio");
523        if (num != null) {
524            _listMap.put("audio", num + 1);
525        } else {
526            _listMap.put("audio", 1);
527        }
528        return new AudioPickModel();
529    }
530
531    private final static Logger log = LoggerFactory.getLogger(PickListModel.class);
532
533    static class TurnoutPickModel extends PickListModel<Turnout> {
534
535        TurnoutManager manager = InstanceManager.turnoutManagerInstance();
536
537        TurnoutPickModel() {
538            _name = rb.getString("TitleTurnoutTable");
539        }
540
541        /** {@inheritDoc} */
542        @Override
543        @Nonnull
544        public Manager<Turnout> getManager() {
545            manager = InstanceManager.turnoutManagerInstance();
546            return manager;
547        }
548
549        /** {@inheritDoc} */
550        @Override
551        public Turnout addBean(@Nonnull String name) throws IllegalArgumentException {
552            return manager.provideTurnout(name);
553        }
554
555        /** {@inheritDoc} */
556        @Override
557        public Turnout addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
558            return manager.newTurnout(sysName, userName);
559        }
560
561        /** {@inheritDoc} */
562        @Override
563        public boolean canAddBean() {
564            return true;
565        }
566    }
567
568    static class SensorPickModel extends PickListModel<Sensor> {
569
570        SensorManager manager = InstanceManager.getDefault(SensorManager.class);
571
572        SensorPickModel() {
573            _name = rb.getString("TitleSensorTable");
574        }
575
576        /** {@inheritDoc} */
577        @Override
578        @Nonnull
579        public Manager<Sensor> getManager() {
580            manager = InstanceManager.sensorManagerInstance();
581            return manager;
582        }
583
584        /** {@inheritDoc} */
585        @Override
586        public Sensor addBean(@Nonnull String name) throws IllegalArgumentException {
587            return manager.provideSensor(name);
588        }
589
590        /** {@inheritDoc} */
591        @Override
592        public Sensor addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
593            return manager.newSensor(sysName, userName);
594        }
595
596        /** {@inheritDoc} */
597        @Override
598        public boolean canAddBean() {
599            return true;
600        }
601    }
602
603    static class MultiSensorPickModel extends SensorPickModel {
604
605        private final HashMap<Integer, String> _position = new HashMap<>();
606
607        MultiSensorPickModel() {
608            super();
609        }
610
611        /** {@inheritDoc} */
612        @Override
613        public Object getValueAt(int r, int c) {
614            if (c == POSITION_COL) {
615                return _position.get(r);
616            }
617            return super.getValueAt(r, c);
618        }
619
620        /** {@inheritDoc} */
621        @Override
622        public void setValueAt(Object type, int r, int c) {
623            if (c == POSITION_COL) {
624                _position.put(r, (String) type);
625            }
626        }
627    }
628
629    static class SignalHeadPickModel extends PickListModel<SignalHead> {
630
631        SignalHeadManager manager = InstanceManager.getDefault(SignalHeadManager.class);
632
633        SignalHeadPickModel() {
634            _name = rb.getString("TitleSignalTable");
635        }
636
637        /** {@inheritDoc} */
638        @Override
639        @Nonnull
640        public Manager<SignalHead> getManager() {
641            manager = InstanceManager.getDefault(SignalHeadManager.class);
642            return manager;
643        }
644
645        /** {@inheritDoc} */
646        @Override
647        public SignalHead addBean(@Nonnull String name) {
648            return manager.getSignalHead(name);
649        }
650
651        /** {@inheritDoc} */
652        @Override
653        public SignalHead addBean(@Nonnull String sysName, String userName) {
654            SignalHead sh = manager.getSignalHead(userName);
655            if (sh == null) {
656                sh = manager.getSignalHead(sysName);
657            }
658            return sh;
659        }
660
661        /** {@inheritDoc} */
662        @Override
663        public boolean canAddBean() {
664            return false;
665        }
666    }
667
668    static class SignalMastPickModel extends PickListModel<SignalMast> {
669
670        SignalMastManager manager = InstanceManager.getDefault(SignalMastManager.class);
671
672        SignalMastPickModel() {
673            _name = rb.getString("TitleSignalMastTable");
674        }
675
676        /** {@inheritDoc} */
677        @Override
678        @Nonnull
679        public Manager<SignalMast> getManager() {
680            manager = InstanceManager.getDefault(SignalMastManager.class);
681            return manager;
682        }
683
684        /** {@inheritDoc} */
685        @Override
686        public SignalMast addBean(@Nonnull String name) throws IllegalArgumentException {
687            return manager.provideSignalMast(name);
688        }
689
690        /** {@inheritDoc} */
691        @Override
692        public SignalMast addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
693            SignalMast sm = manager.getSignalMast(userName);
694            if (sm == null) {
695                sm = manager.provideSignalMast(sysName);
696            }
697            return sm;
698        }
699
700        /** {@inheritDoc} */
701        @Override
702        public boolean canAddBean() {
703            return false;
704        }
705    }
706
707    static class MemoryPickModel extends PickListModel<Memory> {
708
709        MemoryManager manager = InstanceManager.memoryManagerInstance();
710
711        MemoryPickModel() {
712            _name = rb.getString("TitleMemoryTable");
713        }
714
715        /** {@inheritDoc} */
716        @Override
717        @Nonnull
718        public Manager<Memory> getManager() {
719            manager = InstanceManager.memoryManagerInstance();
720            return manager;
721        }
722
723        /** {@inheritDoc} */
724        @Override
725        public Memory addBean(@Nonnull String name) throws IllegalArgumentException {
726            return manager.provideMemory(name);
727        }
728
729        /** {@inheritDoc} */
730        @Override
731        public Memory addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
732            return manager.newMemory(sysName, userName);
733        }
734
735        /** {@inheritDoc} */
736        @Override
737        public boolean canAddBean() {
738            return true;
739        }
740    }
741
742    static class GlobalVariablePickModel extends PickListModel<GlobalVariable> {
743
744        GlobalVariableManager manager = InstanceManager.getDefault(GlobalVariableManager.class);
745
746        GlobalVariablePickModel() {
747            _name = rb.getString("TitleLogixNGGlobalVariablesTable");
748        }
749
750        /** {@inheritDoc} */
751        @Override
752        @Nonnull
753        public Manager<GlobalVariable> getManager() {
754            manager = InstanceManager.getDefault(GlobalVariableManager.class);
755            return manager;
756        }
757
758        /** {@inheritDoc} */
759        @Override
760        public GlobalVariable addBean(@Nonnull String name) throws IllegalArgumentException {
761            throw new UnsupportedOperationException("Not supported");
762        }
763
764        /** {@inheritDoc} */
765        @Override
766        public GlobalVariable addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
767            throw new UnsupportedOperationException("Not supported");
768        }
769
770        /** {@inheritDoc} */
771        @Override
772        public boolean canAddBean() {
773            return false;
774        }
775    }
776
777    static class BlockPickModel extends PickListModel<Block> {
778
779        BlockManager manager = InstanceManager.getDefault(BlockManager.class);
780
781        BlockPickModel() {
782            _name = rb.getString("TitleBlockTable");
783        }
784
785        /** {@inheritDoc} */
786        @Override
787        @Nonnull
788        public Manager<Block> getManager() {
789            manager = InstanceManager.getDefault(BlockManager.class);
790            return manager;
791        }
792
793        /** {@inheritDoc} */
794        @Override
795        public Block addBean(@Nonnull String name) throws IllegalArgumentException {
796            return manager.provideBlock(name);
797        }
798
799        /** {@inheritDoc} */
800        @Override
801        public Block addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
802            return manager.createNewBlock(sysName, userName);
803        }
804
805        /** {@inheritDoc} */
806        @Override
807        public boolean canAddBean() {
808            return true;
809        }
810    }
811
812    static class ReporterPickModel extends PickListModel<Reporter> {
813
814        ReporterManager manager = InstanceManager.getDefault(ReporterManager.class);
815
816        ReporterPickModel() {
817            _name = rb.getString("TitleReporterTable");
818        }
819
820        /** {@inheritDoc} */
821        @Override
822        @Nonnull
823        public Manager<Reporter> getManager() {
824            manager = InstanceManager.getDefault(ReporterManager.class);
825            return manager;
826        }
827
828        /** {@inheritDoc} */
829        @Override
830        public Reporter addBean(@Nonnull String name) throws IllegalArgumentException {
831            return manager.provideReporter(name);
832        }
833
834        /** {@inheritDoc} */
835        @Override
836        public Reporter addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
837            return manager.newReporter(sysName, userName);
838        }
839
840        /** {@inheritDoc} */
841        @Override
842        public boolean canAddBean() {
843            return true;
844        }
845    }
846
847    static class LightPickModel extends PickListModel<Light> {
848
849        LightManager manager = InstanceManager.lightManagerInstance();
850
851        LightPickModel() {
852            _name = rb.getString("TitleLightTable");
853        }
854
855        /** {@inheritDoc} */
856        @Override
857        @Nonnull
858        public Manager<Light> getManager() {
859            manager = InstanceManager.lightManagerInstance();
860            return manager;
861        }
862
863        /** {@inheritDoc} */
864        @Override
865        public Light addBean(@Nonnull String name) throws IllegalArgumentException {
866            return manager.provideLight(name);
867        }
868
869        /** {@inheritDoc} */
870        @Override
871        public Light addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
872            return manager.newLight(sysName, userName);
873        }
874
875        /** {@inheritDoc} */
876        @Override
877        public boolean canAddBean() {
878            return true;
879        }
880    }
881
882    static class OBlockPickModel extends PickListModel<OBlock> {
883
884        OBlockManager manager = InstanceManager.getDefault(OBlockManager.class);
885
886        OBlockPickModel() {
887            _name = rb.getString("TitleBlockTable");
888        }
889
890        /** {@inheritDoc} */
891        @Override
892        @Nonnull
893        public Manager<OBlock> getManager() {
894            manager = InstanceManager.getDefault(OBlockManager.class);
895            return manager;
896        }
897
898        /** {@inheritDoc} */
899        @Override
900        public OBlock addBean(@Nonnull String name) throws IllegalArgumentException {
901            return manager.provideOBlock(name);
902        }
903
904        /** {@inheritDoc} */
905        @Override
906        public OBlock addBean(@Nonnull String sysName, String userName) {
907            return manager.createNewOBlock(sysName, userName);
908        }
909
910        /** {@inheritDoc} */
911        @Override
912        public boolean canAddBean() {
913            return true;
914        }
915    }
916
917    static class WarrantPickModel extends PickListModel<Warrant> {
918
919        WarrantManager manager = InstanceManager.getDefault(WarrantManager.class);
920
921        WarrantPickModel() {
922            _name = rb.getString("TitleWarrantTable");
923        }
924
925        /** {@inheritDoc} */
926        @Override
927        @Nonnull
928        public Manager<Warrant> getManager() {
929            manager = InstanceManager.getDefault(WarrantManager.class);
930            return manager;
931        }
932
933        /** {@inheritDoc} */
934        @Override
935        public Warrant addBean(@Nonnull String name) throws IllegalArgumentException {
936            return manager.provideWarrant(name);
937        }
938
939        /** {@inheritDoc} */
940        @Override
941        public Warrant addBean(@Nonnull String sysName, String userName) {
942            return manager.createNewWarrant(sysName, userName, false, 0);
943        }
944
945        /** {@inheritDoc} */
946        @Override
947        public boolean canAddBean() {
948            return false;
949        }
950    }
951
952    static class EntryExitPickModel extends PickListModel<DestinationPoints> {
953
954        EntryExitPairs manager = InstanceManager.getDefault(EntryExitPairs.class);
955
956        EntryExitPickModel() {
957            _name = rb.getString("TitleEntryExitTable");
958        }
959
960        /** {@inheritDoc} */
961        @Override
962        @Nonnull
963        public Manager<DestinationPoints> getManager() {
964            manager = InstanceManager.getDefault(EntryExitPairs.class);
965            return manager;
966        }
967
968        /** {@inheritDoc} */
969        @Override
970        public DestinationPoints addBean(@Nonnull String name) {
971            return null;
972        }
973
974        /** {@inheritDoc} */
975        @Override
976        public DestinationPoints addBean(@Nonnull String sysName, String userName) {
977            return null;
978        }
979
980        /** {@inheritDoc} */
981        @Override
982        public boolean canAddBean() {
983            return false;
984        }
985
986        /** {@inheritDoc} */
987        @Override
988        public String getColumnName(int c) {
989            if (c == SNAME_COLUMN) {
990                return "Unique Id";
991            } else if (c == UNAME_COLUMN) {
992                return Bundle.getMessage("ColumnUserName");
993            }
994            return "";
995        }
996    }
997
998    static class LogixPickModel extends PickListModel<Logix> {
999
1000        LogixManager manager;
1001
1002        LogixPickModel() {
1003           _name = rb.getString("TitleLogixTable");
1004        }
1005
1006        /** {@inheritDoc} */
1007        @Override
1008        @Nonnull
1009        public Manager<Logix> getManager() {
1010            manager = InstanceManager.getDefault(LogixManager.class);
1011            return manager;
1012        }
1013
1014        /** {@inheritDoc} */
1015        @Override
1016        public Logix addBean(@Nonnull String name) {
1017            return null;
1018        }
1019
1020        /** {@inheritDoc} */
1021        @Override
1022        public Logix addBean(@Nonnull String sysName, String userName) {
1023            return null;
1024        }
1025
1026        /** {@inheritDoc} */
1027        @Override
1028        public boolean canAddBean() {
1029            return false;
1030        }
1031    }
1032
1033    static class AudioPickModel extends PickListModel<Audio> {
1034
1035        AudioManager manager = InstanceManager.getDefault(AudioManager.class);
1036
1037        AudioPickModel() {
1038            _name = rb.getString("TitleAudioTable");
1039        }
1040
1041        /** {@inheritDoc} */
1042        @Override
1043        @Nonnull
1044        public Manager<Audio> getManager() {
1045            manager = InstanceManager.getDefault(AudioManager.class);
1046            return manager;
1047        }
1048
1049        @CheckReturnValue
1050        @Nonnull
1051        @Override
1052        protected SortedSet<Audio> getNamedBeanSet() {
1053            java.util.function.Predicate<Audio> filter = (bean) -> { return bean.getSubType() == Audio.SOURCE; };
1054            TreeSet<Audio> namedBeanSet = new TreeSet<>(new NamedBeanComparator<>());
1055            namedBeanSet.addAll(manager.getNamedBeanSet().stream().filter(filter)
1056                            .collect(java.util.stream.Collectors.toSet()));
1057            return Collections.unmodifiableSortedSet(namedBeanSet);
1058        }
1059
1060        /** {@inheritDoc} */
1061        @Override
1062        public Audio addBean(@Nonnull String name) throws IllegalArgumentException {
1063            try {
1064                return manager.provideAudio(name);
1065            } catch (AudioException e) {
1066                throw new IllegalArgumentException(e);
1067            }
1068        }
1069
1070        /** {@inheritDoc} */
1071        @Override
1072        public Audio addBean(@Nonnull String sysName, String userName) throws IllegalArgumentException {
1073            try {
1074                return manager.newAudio(sysName, userName);
1075            } catch (AudioException e) {
1076                throw new IllegalArgumentException(e);
1077            }
1078        }
1079
1080        /** {@inheritDoc} */
1081        @Override
1082        public boolean canAddBean() {
1083            return true;
1084        }
1085    }
1086
1087}