001package jmri.jmrit.consisttool;
002
003import java.io.IOException;
004import java.util.ArrayList;
005
006import javax.swing.JComboBox;
007
008import jmri.*;
009
010import org.jdom2.JDOMException;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014
015/**
016 *  
017 * A JComboBox with JMRI consists
018 * Entries can be a String or a DccLocoAddress 
019 * 
020 * @author Lionel Jeanson Copyright (c) 2023
021 * 
022 */
023public class ConsistComboBox extends JComboBox<Object> implements ConsistListListener {
024    ConsistManager consistManager = InstanceManager.getDefault(ConsistManager.class);    
025    private static boolean consistMgrInitFromXmlFile = false;
026    private boolean isUpdatingList = false;
027        
028    public ConsistComboBox() {
029        super();        
030        init();
031    }    
032
033    private void init() {
034        setToolTipText(Bundle.getMessage("ConsistAddressBoxToolTip"));
035        initConsistList();
036        setSelectedIndex(0);
037        setRenderer(new ConsistListCellRenderer());
038        consistManager.addConsistListListener(this);
039        if (!consistMgrInitFromXmlFile) {
040            try {
041                new ConsistFile().readFile();
042                consistMgrInitFromXmlFile =true;
043            } catch (IOException | JDOMException e) {
044                log.warn("error reading consist file: {}", e.getMessage());
045            }
046            consistMgrInitFromXmlFile =true;
047        }
048    }
049            
050    public void dispose() {
051        consistManager.removeConsistListListener(this);        
052    }
053
054    private void initConsistList() {
055        if (isUpdatingList) {
056            return;
057        }
058        isUpdatingList = true;
059        Object selectedItem = getSelectedItem();
060        int selectedIndex = getSelectedIndex();
061        ArrayList<LocoAddress> existingConsists = consistManager.getConsistList();
062        removeAllItems();
063        if (!existingConsists.isEmpty()) {
064            java.util.Collections.sort(existingConsists, new jmri.util.LocoAddressComparator()); // sort the consist list.            
065            existingConsists.forEach(consist -> addItem(consist));
066            setEnabled(true);
067        } else {
068            setEnabled(false);
069        }
070        insertItemAt(Bundle.getMessage("NoConsistSelected"), 0);
071        if (selectedIndex > getItemCount() || (selectedItem != getItemAt(selectedIndex)) ) {
072            setSelectedIndex(0);            
073        } else {
074            setSelectedIndex(selectedIndex);
075        }
076        isUpdatingList = false;
077    }
078    
079    /**
080     * Limit action firing to user actions
081     */
082    @Override
083    protected void fireActionEvent() {
084        if (! isUpdatingList ) {
085            super.fireActionEvent();
086        }
087    }
088
089    @Override
090    public void notifyConsistListChanged() {
091        initConsistList();
092    }
093
094    private static final Logger log = LoggerFactory.getLogger(ConsistComboBox.class);
095}