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 this.setOpaque(false); 103 104 // create the programmer display combo box 105 progBox = new JComboBox<>(); 106 Vector<GlobalProgrammerManager> v = new Vector<>(); 107 for (GlobalProgrammerManager pm : getMgrList()) { 108 Programmer globProg = null; 109 if (pm != null) { 110 globProg = pm.getGlobalProgrammer(); 111 } 112 if (globProg != null) { 113 v.add(pm); 114 log.debug("ProgServiceModeComboBox added programmer {} as item {}", 115 (pm != null ? pm.getClass() : "null"), pm); 116 // listen for changes 117 globProg.addPropertyChangeListener(this); 118 } 119 } 120 121 add(progLabel); 122 add(progBox = new JComboBox<>(v)); 123 progBox.getAccessibleContext().setAccessibleName(Bundle.getMessage("ProgrammerLabel")); 124 125 // if only one, don't show is confusing to user, so show combo with just 1 choice) 126 progBox.setSelectedItem(InstanceManager.getDefault(jmri.GlobalProgrammerManager.class)); // set default 127 progBox.addActionListener(new ActionListener() { 128 @Override 129 public void actionPerformed(ActionEvent e) { 130 // new programmer selection 131 programmerSelected(); 132 } 133 }); 134 log.trace("progBox loadeded with {}", progBox.getItemCount()); 135 136 // install mode selection items in GUI 137 add(new JLabel(Bundle.getMessage("ProgrammingModeLabel"))); 138 add(modeBox); 139 modeBox.getAccessibleContext().setAccessibleName(Bundle.getMessage("ProgrammingModeLabel")); 140 141 // and execute the setup for 1st time 142 programmerSelected(); 143 log.trace("ctor ends"); 144 } 145 146 /** 147 * Reload the interface with the new programming modes 148 */ 149 void programmerSelected() { 150 DefaultComboBoxModel<ProgrammingMode> model = new DefaultComboBoxModel<>(); 151 Programmer p = getProgrammer(); 152 if (p != null) { 153 for (ProgrammingMode mode : p.getSupportedModes()) { 154 model.addElement(mode); 155 } 156 } 157 log.trace("programmerSelected setting modes"); 158 modeBox.setModel(model); 159 ProgrammingMode mode = (p != null) ? p.getMode() : null; 160 log.trace("programmerSelected set mode {}", mode); 161 modeBox.setSelectedItem(mode); 162 } 163 164 /** 165 * Listen to modeBox for mode changes 166 */ 167 @Override 168 public void actionPerformed(java.awt.event.ActionEvent e) { 169 // convey change to programmer 170 log.debug("Selected mode: {}", modeBox.getSelectedItem()); 171 if (modeBox.getSelectedItem() != null) { 172 getProgrammer().setMode((ProgrammingMode) modeBox.getSelectedItem()); 173 } 174 } 175 176 /** 177 * Listen to programmer for mode changes 178 */ 179 @Override 180 public void propertyChange(java.beans.PropertyChangeEvent e) { 181 if ("Mode".equals(e.getPropertyName()) && getProgrammer().equals(e.getSource())) { 182 // mode changed in programmer, change GUI here if needed 183 if (isSelected()) { // if we're not holding a current mode, don't update 184 modeBox.setSelectedItem(e.getNewValue()); 185 } 186 } 187 } 188 189 // no longer needed, disconnect if still connected 190 @Override 191 public void dispose() { 192 } 193 private static final Logger log = LoggerFactory.getLogger(ProgServiceModeComboBox.class); 194}