001package jmri.jmrit.progsupport; 002 003import java.awt.event.ActionEvent; 004import java.awt.event.ActionListener; 005import java.beans.PropertyChangeListener; 006import java.util.ArrayList; 007import java.util.List; 008import java.util.Vector; 009import javax.swing.BoxLayout; 010import javax.swing.DefaultComboBoxModel; 011import javax.swing.JComboBox; 012import javax.swing.JLabel; 013 014import jmri.*; 015import org.slf4j.Logger; 016import org.slf4j.LoggerFactory; 017 018/** 019 * Provide a JPanel with a JComboBox to configure the service mode (Global) programmer. 020 * <p> 021 * The using code should get a configured programmer with {@link #getProgrammer()}. 022 * <p> 023 * A ProgModePane may "share" between one of these and a ProgOpsModePane, which 024 * means that there might be _none_ of these buttons selected. When that 025 * happens, the mode of the underlying programmer is left unchanged and no 026 * message is propagated. 027 * <p> 028 * Note that you should call the dispose() method when you're really done, so 029 * that a ProgModePane object can disconnect its listeners. 030 * 031 * <hr> 032 * This file is part of JMRI. 033 * <p> 034 * JMRI is free software; you can redistribute it and/or modify it under the 035 * terms of version 2 of the GNU General Public License as published by the Free 036 * Software Foundation. See the "COPYING" file for a copy of this license. 037 * <p> 038 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 039 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 040 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 041 * 042 * @author Bob Jacobsen Copyright (C) 2001 043 */ 044public class ProgServiceModeComboBox extends ProgModeSelector implements PropertyChangeListener, ActionListener { 045 046 // GUI member declarations 047 JLabel progLabel = new JLabel(Bundle.getMessage("ProgrammerLabel")); 048 JComboBox<GlobalProgrammerManager> progBox; 049 JComboBox<ProgrammingMode> modeBox; 050 ArrayList<Integer> modes = new ArrayList<Integer>(); 051 052 /** 053 * Get the configured programmer 054 */ 055 @Override 056 public Programmer getProgrammer() { 057 if (progBox == null) { 058 log.trace("getProgrammer returns null with no progBox"); 059 return null; 060 } 061 GlobalProgrammerManager pm = (GlobalProgrammerManager) progBox.getSelectedItem(); 062 if (pm == null) { 063 log.trace("getProgrammer returns null with no selection"); 064 return null; 065 } 066 log.trace("getProgrammer returns {}", pm.getGlobalProgrammer()); 067 return pm.getGlobalProgrammer(); 068 } 069 070 /** 071 * Are any of the modes selected? 072 * 073 * @return true 074 */ 075 @Override 076 public boolean isSelected() { 077 return true; 078 } 079 080 public ProgServiceModeComboBox() { 081 this(BoxLayout.X_AXIS); 082 } 083 084 /** 085 * Get the list of Global ProgrammingManagers. 086 * 087 * @return empty list if none 088 */ 089 protected final List<GlobalProgrammerManager> getMgrList() { 090 var list = InstanceManager.getList(jmri.GlobalProgrammerManager.class); 091 log.trace("gtMgrList returns {}", list.size()); 092 return list; 093 } 094 095 public ProgServiceModeComboBox(int direction) { 096 log.trace("ctor starts"); 097 modeBox = new JComboBox<ProgrammingMode>(); 098 modeBox.addActionListener(this); 099 100 // general GUI config 101 setLayout(new BoxLayout(this, direction)); 102 103 // create the programmer display combo box 104 progBox = new JComboBox<>(); 105 Vector<GlobalProgrammerManager> v = new Vector<>(); 106 for (GlobalProgrammerManager pm : getMgrList()) { 107 Programmer globProg = null; 108 if (pm != null) { 109 globProg = pm.getGlobalProgrammer(); 110 } 111 if (globProg != null) { 112 v.add(pm); 113 log.debug("ProgServiceModeComboBox added programmer {} as item {}", 114 (pm != null ? pm.getClass() : "null"), pm); 115 // listen for changes 116 globProg.addPropertyChangeListener(this); 117 } 118 } 119 120 add(progLabel); 121 add(progBox = new JComboBox<>(v)); 122 progBox.getAccessibleContext().setAccessibleName(Bundle.getMessage("ProgrammerLabel")); 123 124 // if only one, don't show is confusing to user, so show combo with just 1 choice) 125 progBox.setSelectedItem(InstanceManager.getDefault(jmri.GlobalProgrammerManager.class)); // set default 126 progBox.addActionListener(new ActionListener() { 127 @Override 128 public void actionPerformed(ActionEvent e) { 129 // new programmer selection 130 programmerSelected(); 131 } 132 }); 133 log.trace("progBox loadeded with {}", progBox.getItemCount()); 134 135 // install mode selection items in GUI 136 add(new JLabel(Bundle.getMessage("ProgrammingModeLabel"))); 137 add(modeBox); 138 modeBox.getAccessibleContext().setAccessibleName(Bundle.getMessage("ProgrammingModeLabel")); 139 140 // and execute the setup for 1st time 141 programmerSelected(); 142 log.trace("ctor ends"); 143 } 144 145 /** 146 * Reload the interface with the new programming modes 147 */ 148 void programmerSelected() { 149 DefaultComboBoxModel<ProgrammingMode> model = new DefaultComboBoxModel<>(); 150 Programmer p = getProgrammer(); 151 if (p != null) { 152 for (ProgrammingMode mode : p.getSupportedModes()) { 153 model.addElement(mode); 154 } 155 } 156 log.trace("programmerSelected setting modes"); 157 modeBox.setModel(model); 158 ProgrammingMode mode = (p != null) ? p.getMode() : null; 159 log.trace("programmerSelected set mode {}", mode); 160 modeBox.setSelectedItem(mode); 161 } 162 163 /** 164 * Listen to modeBox for mode changes 165 */ 166 @Override 167 public void actionPerformed(java.awt.event.ActionEvent e) { 168 // convey change to programmer 169 log.debug("Selected mode: {}", modeBox.getSelectedItem()); 170 if (modeBox.getSelectedItem() != null) { 171 getProgrammer().setMode((ProgrammingMode) modeBox.getSelectedItem()); 172 } 173 } 174 175 /** 176 * Listen to programmer for mode changes 177 */ 178 @Override 179 public void propertyChange(java.beans.PropertyChangeEvent e) { 180 if ("Mode".equals(e.getPropertyName()) && getProgrammer().equals(e.getSource())) { 181 // mode changed in programmer, change GUI here if needed 182 if (isSelected()) { // if we're not holding a current mode, don't update 183 modeBox.setSelectedItem(e.getNewValue()); 184 } 185 } 186 } 187 188 // no longer needed, disconnect if still connected 189 @Override 190 public void dispose() { 191 } 192 private final static Logger log = LoggerFactory.getLogger(ProgServiceModeComboBox.class); 193}