001package jmri.jmrit.beantable.beanedit; 002 003import java.awt.event.ActionEvent; 004 005import javax.swing.*; 006 007import jmri.*; 008import jmri.NamedBean.DisplayOptions; 009import jmri.implementation.SignalSpeedMap; 010import jmri.jmrit.beantable.block.BlockCurvatureJComboBox; 011import jmri.jmrit.beantable.oblock.TableFrames; 012import jmri.jmrit.logix.OBlock; 013import jmri.jmrit.logix.OBlockManager; 014import jmri.swing.NamedBeanComboBox; 015import jmri.util.swing.JComboBoxUtil; 016 017/** 018 * Provides a tabbed beanedit panel for an OBlock object. 019 * 020 * @author Kevin Dickerson Copyright (C) 2011 021 * @author Egbert Broerse Copyright (C) 2020 022 */ 023public class OBlockEditAction extends BeanEditAction<OBlock> { 024 025 static final java.util.Vector<String> speedList = new java.util.Vector<>(); 026 private String tabName = Bundle.getMessage("BeanNameOBlock"); 027 NamedBeanComboBox<Reporter> reporterComboBox; 028 JCheckBox useCurrent = new JCheckBox(); 029 TableFrames.BlockPathJPanel blockPathPanel; 030 NamedBeanComboBox<Sensor> sensorComboBox; 031 NamedBeanComboBox<Sensor> errorSensorComboBox; 032 033 public OBlockEditAction(ActionEvent ae) { 034 super(); 035 if (ae != null) { 036 tabName = ae.getActionCommand(); 037 } 038 } 039 040 @Override 041 public String helpTarget() { 042 return "package.jmri.jmrit.beantable.OBlockTable"; 043 } // NOI18N 044 045 public void setTablePanel(TableFrames.BlockPathJPanel panel){ 046 blockPathPanel = panel; 047 } 048 049 @Override 050 protected void initPanels() { 051 super.initPanels(); 052 sensor(); 053 paths(); 054 reporterDetails(); 055 physicalDetails(); 056 } 057 058 @Override 059 public OBlock getByUserName(String name) { 060 return InstanceManager.getDefault(OBlockManager.class).getByUserName(name); 061 } 062 063 BeanItemPanel sensor() { 064 BeanItemPanel basic = new BeanItemPanel(); 065 basic.setName(Bundle.getMessage("BeanNameSensors")); 066 067 sensorComboBox = new NamedBeanComboBox<>(InstanceManager.sensorManagerInstance(), bean.getSensor(), DisplayOptions.DISPLAYNAME); 068 sensorComboBox.setAllowNull(true); 069 JComboBoxUtil.setupComboBoxMaxRows(sensorComboBox); 070 basic.addItem(new BeanEditItem(sensorComboBox, Bundle.getMessage("BeanNameSensor"), Bundle.getMessage("BlockAssignSensorText"))); 071 072 errorSensorComboBox = new NamedBeanComboBox<>(InstanceManager.sensorManagerInstance(), bean.getSensor(), DisplayOptions.DISPLAYNAME); 073 errorSensorComboBox.setAllowNull(true); 074 JComboBoxUtil.setupComboBoxMaxRows(errorSensorComboBox); 075 basic.addItem(new BeanEditItem(errorSensorComboBox, Bundle.getMessage("ErrorSensorCol"), Bundle.getMessage("BlockAssignErrorSensorText"))); 076 077 final SensorDebounceEditAction debounce = new SensorDebounceEditAction(); 078 debounce.sensorDebounce(basic); 079 080 sensorComboBox.addActionListener(e -> { 081 debounce.setBean(sensorComboBox.getSelectedItem()); 082 debounce.resetDebounceItems(e); 083 }); 084 basic.setSaveItem(new AbstractAction() { 085 @Override 086 public void actionPerformed(ActionEvent e) { 087 if (sensorComboBox.getSelectedItem() == null) { 088 bean.setSensor(null); 089 } else { 090 bean.setSensor(sensorComboBox.getSelectedItem().getDisplayName()); 091 } 092 if (errorSensorComboBox.getSelectedItem() == null) { 093 bean.setErrorSensor(null); 094 } else { 095 bean.setErrorSensor(errorSensorComboBox.getSelectedItem().getDisplayName()); 096 } 097 } 098 }); 099 basic.setResetItem(new AbstractAction() { 100 @Override 101 public void actionPerformed(ActionEvent e) { 102 //From basic details 103 sensorComboBox.setSelectedItem(bean.getSensor()); 104 errorSensorComboBox.setSelectedItem(bean.getErrorSensor()); 105 debounce.setBean(bean.getSensor()); 106 debounce.resetDebounceItems(e); 107 } 108 }); 109 110 bei.add(basic); 111 return basic; 112 } 113 114 BeanItemPanel paths() { 115 BeanItemPanel paths = new BeanItemPanel(); 116 String name = Bundle.getMessage("TitlePaths"); 117 paths.setName(name); 118 119 paths.addItem(new BeanEditItem(blockPathPanel, Bundle.getMessage("PathTableLabel", bean.getDisplayName()), null)); 120 // includes Add Path button 121 122 paths.setResetItem(new AbstractAction() { 123 @Override 124 public void actionPerformed(ActionEvent e) { 125 //clear the table? 126 } 127 }); 128 129 bei.add(paths); 130 if (InstanceManager.getNullableDefault(OBlockManager.class) == null) { 131 setEnabled(false); 132 } 133 if (name.equals(tabName)) { 134 setSelectedComponent(paths); 135 } 136 return paths; 137 } 138 139 BeanItemPanel reporterDetails() { 140 BeanItemPanel reporter = new BeanItemPanel(); 141 reporter.setName(Bundle.getMessage("BeanNameReporter")); 142 143 reporterComboBox = new NamedBeanComboBox<>(InstanceManager.getDefault(ReporterManager.class), bean.getReporter(), DisplayOptions.DISPLAYNAME); 144 reporterComboBox.setAllowNull(true); 145 JComboBoxUtil.setupComboBoxMaxRows(reporterComboBox); 146 147 reporter.addItem(new BeanEditItem(reporterComboBox, Bundle.getMessage("BeanNameReporter"), Bundle.getMessage("BlockReporterText"))); 148 149 reporterComboBox.addActionListener(e -> useCurrent.setEnabled(reporterComboBox.getSelectedItem() != null)); 150 151 reporter.addItem(new BeanEditItem(useCurrent, Bundle.getMessage("BlockReporterCurrent"), Bundle.getMessage("BlockUseCurrentText"))); 152 153 reporter.setResetItem(new AbstractAction() { 154 @Override 155 public void actionPerformed(ActionEvent e) { 156 reporterComboBox.setSelectedItem(bean.getReporter()); 157 useCurrent.setSelected(bean.isReportingCurrent()); 158 useCurrent.setEnabled(bean.getReporter()!=null); 159 } 160 }); 161 162 reporter.setSaveItem(new AbstractAction() { 163 @Override 164 public void actionPerformed(ActionEvent e) { 165 bean.setReporter(reporterComboBox.getSelectedItem()); 166 bean.setReportingCurrent(useCurrent.isSelected()); 167 } 168 }); 169 bei.add(reporter); 170 if (InstanceManager.getNullableDefault(ReporterManager.class) == null) { 171 setEnabled(false); 172 } 173 return reporter; 174 } 175 176 JSpinner lengthSpinner = new JSpinner(); // 2 digit decimal format field, initialized later as instance 177 private final BlockCurvatureJComboBox curvatureField = new BlockCurvatureJComboBox(); 178 JCheckBox permissiveField = new JCheckBox(); 179 JComboBox<String> speedField; 180 181 JRadioButton inch = new JRadioButton(Bundle.getMessage("LengthInches")); 182 JRadioButton cm = new JRadioButton(Bundle.getMessage("LengthCentimeters")); 183 184 String defaultBlockSpeedText; 185 186 BeanItemPanel physicalDetails() { 187 defaultBlockSpeedText = (Bundle.getMessage("UseGlobal", "Global") + " " + InstanceManager.getDefault(BlockManager.class).getDefaultSpeed()); 188 speedList.add(defaultBlockSpeedText); 189 java.util.Vector<String> _speedMap = InstanceManager.getDefault(SignalSpeedMap.class).getValidSpeedNames(); 190 for (String s : _speedMap) { 191 if (!speedList.contains(s)) { 192 speedList.add(s); 193 } 194 } 195 BeanItemPanel basic = new BeanItemPanel(); 196 basic.setName(Bundle.getMessage("BlockPhysicalProperties")); 197 198 basic.addItem(new BeanEditItem(null, null, Bundle.getMessage("BlockPropertiesText"))); 199 lengthSpinner.setModel( 200 new SpinnerNumberModel(Float.valueOf(0f), Float.valueOf(0f), Float.valueOf(1000f), Float.valueOf(0.01f))); 201 lengthSpinner.setEditor(new JSpinner.NumberEditor(lengthSpinner, "###0.00")); 202 lengthSpinner.setPreferredSize(new JTextField(8).getPreferredSize()); 203 lengthSpinner.setValue(0f); // reset from possible previous use 204 basic.addItem(new BeanEditItem(lengthSpinner, Bundle.getMessage("BlockLengthColName"), Bundle.getMessage("BlockLengthText"))); 205 206 ButtonGroup rg = new ButtonGroup(); 207 rg.add(inch); 208 rg.add(cm); 209 210 JPanel p = new JPanel(); 211 p.add(inch); 212 p.add(cm); 213 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 214 inch.setSelected(true); 215 216 inch.addActionListener(e -> { 217 cm.setSelected(!inch.isSelected()); 218 updateLength(); 219 }); 220 cm.addActionListener(e -> { 221 inch.setSelected(!cm.isSelected()); 222 updateLength(); 223 }); 224 225 speedField = new JComboBox<>(speedList); 226 JComboBoxUtil.setupComboBoxMaxRows(speedField); 227 basic.addItem(new BeanEditItem(p, Bundle.getMessage("BlockLengthUnits"), Bundle.getMessage("BlockLengthUnitsText"))); 228 basic.addItem(new BeanEditItem(curvatureField, Bundle.getMessage("BlockCurveColName"), "")); 229 basic.addItem(new BeanEditItem(speedField, Bundle.getMessage("BlockSpeedColName"), Bundle.getMessage("BlockMaxSpeedText"))); 230 basic.addItem(new BeanEditItem(permissiveField, Bundle.getMessage("BlockPermColName"), Bundle.getMessage("BlockPermissiveText"))); 231 232 permissiveField.setSelected(bean.getPermissiveWorking()); 233 234 basic.setSaveItem(new AbstractAction() { 235 @Override 236 public void actionPerformed(ActionEvent e) { 237 bean.setCurvature(curvatureField.getCurvature()); 238 239 String speed = (String) speedField.getSelectedItem(); 240 try { 241 bean.setBlockSpeed(speed); 242 } catch (JmriException ex) { 243 jmri.util.swing.JmriJOptionPane.showMessageDialog(f, ex.getMessage() + "\n" + speed); 244 return; 245 } 246 if (speed != null && !speedList.contains(speed) && !speed.contains("Global")) { 247 speedList.add(speed); 248 } 249 float len = (Float) lengthSpinner.getValue(); 250 bean.setLength( inch.isSelected() ? (len * 25.4f) : (len * 10.0f) ); 251 bean.setPermissiveWorking(permissiveField.isSelected()); 252 } 253 }); 254 basic.setResetItem(new AbstractAction() { 255 @Override 256 public void actionPerformed(ActionEvent e) { 257 lengthSpinner.setValue(bean.getLengthMm()); 258 259 curvatureField.setCurvature(bean.getCurvature()); 260 261 String speed = bean.getBlockSpeed(); 262 if (!speedList.contains(speed)) { 263 speedList.add(speed); 264 } 265 266 speedField.setEditable(true); 267 speedField.setSelectedItem(speed); 268 updateLength(); 269 permissiveField.setSelected(bean.getPermissiveWorking()); 270 } 271 }); 272 bei.add(basic); 273 return basic; 274 } 275 276 private void updateLength() { 277 lengthSpinner.setValue(inch.isSelected() ? bean.getLengthIn() : bean.getLengthCm()); 278 } 279 280 // private final static Logger log = LoggerFactory.getLogger(OBlockEditAction.class); 281 282}