001package jmri.jmrit.beantable; 002 003import java.awt.Frame; 004import java.awt.GridBagLayout; 005import java.awt.event.ActionEvent; 006import java.text.MessageFormat; 007import java.util.*; 008 009import javax.swing.*; 010import javax.swing.event.ChangeEvent; 011 012import jmri.*; 013import jmri.jmrit.operations.OperationsFrame; 014import jmri.jmrit.operations.OperationsPanel; 015import jmri.util.PhysicalLocation; 016import jmri.util.PhysicalLocationPanel; 017import jmri.util.swing.JmriJOptionPane; 018 019/** 020 * Swing action to create a SetPhysicalLocation dialog. 021 * 022 * @author Bob Jacobsen Copyright (C) 2001 023 * @author Daniel Boudreau Copyright (C) 2010 024 * @author Mark Underwood Copyright (C) 2011 025 */ 026public class SetPhysicalLocationAction extends AbstractAction { 027 028 Reporter _reporter; 029 030 static ResourceBundle rb = ResourceBundle.getBundle("jmri.jmrit.beantable.JmritBeantablePhysicalLocationBundle"); 031 032 /** 033 * Constructor. 034 * 035 * @param s title of the action 036 * @param reporter {@link Reporter} to use 037 */ 038 public SetPhysicalLocationAction(String s, Reporter reporter) { 039 super(s); 040 _reporter = reporter; 041 } 042 043 SetPhysicalLocationFrame f = null; 044 045 /** 046 * Action method. 047 * 048 * @param e the associated {@link ActionEvent} that triggered this action 049 */ 050 @Override 051 public void actionPerformed(ActionEvent e) { 052 // create a copy route frame 053 if (f == null || !f.isVisible()) { 054 f = new SetPhysicalLocationFrame(_reporter); 055 f.setVisible(true); 056 } 057 f.setExtendedState(Frame.NORMAL); 058 } 059 060 /** 061 * Frame for setting train physical location coordinates for a Reporter. 062 * 063 * @author Bob Jacobsen Copyright (C) 2001 064 * @author Daniel Boudreau Copyright (C) 2010 065 * @author Mark Underwood Copyright (C) 2011 066 * 067 */ 068 private static class SetPhysicalLocationFrame extends OperationsFrame { 069 070 /** 071 * Frame Constructor. 072 * @param reporter reporter 073 */ 074 public SetPhysicalLocationFrame(Reporter reporter) { 075 super(rb.getString("MenuSetPhysicalLocation"), new SetPhysicalLocationPanel(reporter)); 076 077 // add help menu to window 078 addHelpMenu("package.jmri.jmrit.operations.Operations_SetTrainIconCoordinates", true); // fix this later 079 080 super.pack(); 081 } 082 } 083 084 private static class SetPhysicalLocationPanel extends OperationsPanel { 085 086 Reporter _reporter; 087 088 String emptyReporterString = "(No Reporters)"; 089 090 List<Reporter> _reporterList = new ArrayList<>(); 091 092 // labels 093 // text field 094 // check boxes 095 // major buttons 096 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 097 JButton closeButton = new JButton(Bundle.getMessage("ButtonClose")); 098 099 // combo boxes 100 JComboBox<String> reporterBox = getReporterComboBox(); 101 102 // Spinners 103 PhysicalLocationPanel physicalLocation; 104 105 public SetPhysicalLocationPanel(Reporter l) { 106 107 // Store the location (null if called from the list view) 108 _reporter = l; 109 110 // general GUI config 111 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 112 113 // set tool tips 114 saveButton.setToolTipText(rb.getString("TipSaveButton")); 115 closeButton.setToolTipText(rb.getString("TipCloseButton")); 116 117 // Set up the panels 118 JPanel pLocation = new JPanel(); 119 pLocation.setBorder(BorderFactory.createTitledBorder(rb.getString("ReporterName"))); 120 pLocation.setToolTipText(rb.getString("TipSelectReporter")); 121 pLocation.add(reporterBox); 122 123 physicalLocation = new PhysicalLocationPanel(rb.getString("PhysicalLocation")); 124 physicalLocation.setToolTipText(rb.getString("TipPhysicalLocation")); 125 physicalLocation.setVisible(true); 126 127 JPanel pControl = new JPanel(); 128 pControl.setLayout(new GridBagLayout()); 129 pControl.setBorder(BorderFactory.createTitledBorder("")); 130 addItem(pControl, saveButton, 1, 0); 131 addItem(pControl, closeButton, 2, 0); 132 133 add(pLocation); 134 add(physicalLocation); 135 add(pControl); 136 137 // setup buttons 138 saveButton.addActionListener(this::saveButtonActionPerformed); 139 closeButton.addActionListener(this::closeButtonActionPerformed); 140 141 // setup combo box 142 addComboBoxAction(reporterBox); 143 reporterBox.setSelectedIndex(0); 144 145 if (_reporter != null) { 146 reporterBox.setSelectedItem(_reporter); 147 } 148 149 setVisible(true); 150 } 151 152 /** 153 * Construct the combo box with the list of available Reporters. 154 */ 155 protected JComboBox<String> getReporterComboBox() { 156 ReporterManager mgr = InstanceManager.getDefault(jmri.ReporterManager.class); 157 List<String> displayList = new ArrayList<>(); 158 for (Reporter r : mgr.getNamedBeanSet()) { 159 if (r != null) { 160 _reporterList.add(r); 161 displayList.add(r.getDisplayName()); 162 } 163 } 164 if (displayList.isEmpty()) { 165 displayList.add(emptyReporterString); 166 saveButton.setEnabled(false); 167 } 168 String[] sa = new String[displayList.size()]; 169 displayList.toArray(sa); 170 JComboBox<String> retv = new JComboBox<>(sa); 171 return (retv); 172 173 } 174 175 /** 176 * Close button action. 177 */ 178 public void closeButtonActionPerformed(@SuppressWarnings("javadoc") ActionEvent ae) { 179 JmriJOptionPane.showMessageDialog(this, 180 rb.getString("CloseButtonSaveWarning"), 181 rb.getString("CloseButtonSaveWarningTitle"), 182 JmriJOptionPane.WARNING_MESSAGE); 183 dispose(); 184 } 185 186 /** 187 * Save button action -> save this Reporter's location. 188 */ 189 public void saveButtonActionPerformed(@SuppressWarnings("javadoc") ActionEvent ae) { 190 // check to see if a location has been selected 191 if (reporterBox.getSelectedItem() == null 192 || reporterBox.getSelectedItem().equals("")) { 193 JmriJOptionPane.showMessageDialog(this, 194 rb.getString("SelectLocationToEdit"), 195 rb.getString("NoLocationSelected"), 196 JmriJOptionPane.ERROR_MESSAGE); 197 return; 198 } 199 Reporter l = getReporterFromList(); 200 if (l == null) { 201 return; 202 } 203 int value = JmriJOptionPane.showConfirmDialog(null, MessageFormat.format(rb.getString("UpdatePhysicalLocation"), 204 new Object[]{l.getDisplayName()}), rb.getString("SaveLocation?"), JmriJOptionPane.YES_NO_OPTION); 205 if (value == JmriJOptionPane.YES_OPTION) { 206 saveSpinnerValues(l); 207 } 208 } 209 210 /** 211 * Get a Reporter from its name in the combo box. 212 */ 213 private Reporter getReporterFromList() { 214 String s = (String) reporterBox.getSelectedItem(); 215 // Since we don't have "getByDisplayName()" we need to do this in two steps 216 Reporter r = InstanceManager.getDefault(jmri.ReporterManager.class).getByDisplayName(s); 217 return (r); 218 } 219 220 /** 221 * Combo box action. 222 */ 223 @Override 224 public void comboBoxActionPerformed(ActionEvent ae) { 225 if (reporterBox.getSelectedItem() != null) { 226 if (reporterBox.getSelectedItem().equals("") || reporterBox.getSelectedItem().equals(emptyReporterString)) { 227 resetSpinners(); 228 } else { 229 Reporter l = getReporterFromList(); 230 loadSpinners(l); 231 } 232 } 233 } 234 235 /** 236 * Spinner change event. 237 */ 238 @Override 239 public void spinnerChangeEvent(ChangeEvent ae) { 240 if (ae.getSource() == physicalLocation) { 241 Reporter l = getReporterFromList(); 242 if (l != null) { 243 PhysicalLocation.setBeanPhysicalLocation(physicalLocation.getValue(), l); 244 } 245 } 246 } 247 248 /** 249 * Reset spinners to zero. 250 */ 251 private void resetSpinners() { 252 // Reset spinners to zero. 253 physicalLocation.setValue(new PhysicalLocation()); 254 } 255 256 /** 257 * Load spinners from an existing Reporter 258 */ 259 private void loadSpinners(Reporter r) { 260 log.debug("Load spinners Reporter location {}", r.getSystemName()); 261 physicalLocation.setValue(PhysicalLocation.getBeanPhysicalLocation(r)); 262 } 263 264 // Unused. Carried over from SetTrainIconPosition or whatever it was 265 // called... 266 /* 267 * private void spinnersEnable(boolean enable){ 268 * physicalLocation.setEnabled(enable); } 269 */ 270 /** 271 * Write spinner values to a Reporter. 272 */ 273 private void saveSpinnerValues(Reporter r) { 274 log.debug("Save train icons coordinates for location {}", r.getSystemName()); 275 PhysicalLocation.setBeanPhysicalLocation(physicalLocation.getValue(), r); 276 } 277 278 } 279 280 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SetPhysicalLocationAction.class); 281 282}