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.BlockTableAction; 011import jmri.jmrit.beantable.block.BlockCurvatureJComboBox; 012import jmri.jmrit.display.layoutEditor.LayoutBlock; 013import jmri.jmrit.display.layoutEditor.LayoutBlockManager; 014import jmri.swing.NamedBeanComboBox; 015import jmri.util.swing.JComboBoxUtil; 016 017/** 018 * Provides an edit panel for a Block object. 019 * Note that LayoutBlockEditAction extends this class, so please check 020 * this still functions as expected when making changes here. 021 * 022 * @author Kevin Dickerson Copyright (C) 2011 023 */ 024public class BlockEditAction extends BeanEditAction<Block> { 025 026 static final java.util.Vector<String> speedList = new java.util.Vector<>(); 027 028 @Override 029 public String helpTarget() { 030 return "package.jmri.jmrit.beantable.BlockEdit"; 031 } // NOI18N 032 033 @Override 034 protected void initPanels() { 035 super.initPanels(); 036 sensor(); 037 reporterDetails(); 038 physicalDetails(); 039 } 040 041 @Override 042 public Block getByUserName(String name) { 043 return InstanceManager.getDefault(BlockManager.class).getByUserName(name); 044 } 045 046 private NamedBeanComboBox<Reporter> reporterComboBox; 047 private final JCheckBox useCurrent = new JCheckBox(); 048 049 private final JSpinner lengthSpinner = new JSpinner(); // 2 digit decimal format field, initialized later as instance 050 private final BlockCurvatureJComboBox curvatureField = new BlockCurvatureJComboBox(); 051 private final JCheckBox permissiveField = new JCheckBox(); 052 private final JCheckBox ghostField = new JCheckBox(); 053 private JComboBox<String> speedField; 054 055 private final JRadioButton inch = new JRadioButton(Bundle.getMessage("LengthInches")); 056 private final JRadioButton cm = new JRadioButton(Bundle.getMessage("LengthCentimeters")); 057 058 protected boolean metricUi = InstanceManager.getDefault(UserPreferencesManager.class) 059 .getSimplePreferenceState(BlockTableAction.BLOCK_METRIC_PREF); 060 061 BeanItemPanel reporterDetails() { 062 BeanItemPanel reporter = new BeanItemPanel(); 063 reporter.setName(Bundle.getMessage("BeanNameReporter")); 064 065 reporterComboBox = new NamedBeanComboBox<>(InstanceManager.getDefault( 066 ReporterManager.class), bean.getReporter(), DisplayOptions.DISPLAYNAME); 067 reporterComboBox.setAllowNull(true); 068 JComboBoxUtil.setupComboBoxMaxRows(reporterComboBox); 069 070 reporter.addItem(new BeanEditItem(reporterComboBox, 071 Bundle.getMessage("BeanNameReporter"), Bundle.getMessage("BlockReporterText"))); 072 073 reporterComboBox.addActionListener( e -> 074 useCurrent.setEnabled(reporterComboBox.getSelectedItem() != null)); 075 076 reporter.addItem(new BeanEditItem(useCurrent, 077 Bundle.getMessage("BlockReporterCurrent"), Bundle.getMessage("BlockUseCurrentText"))); 078 079 reporter.setResetItem(new AbstractAction() { 080 @Override 081 public void actionPerformed(ActionEvent e) { 082 reporterComboBox.setSelectedItem(bean.getReporter()); 083 useCurrent.setSelected(bean.isReportingCurrent()); 084 useCurrent.setEnabled(bean.getReporter()!=null); 085 } 086 }); 087 088 reporter.setSaveItem(new AbstractAction() { 089 @Override 090 public void actionPerformed(ActionEvent e) { 091 bean.setReporter(reporterComboBox.getSelectedItem()); 092 bean.setReportingCurrent(useCurrent.isSelected()); 093 } 094 }); 095 bei.add(reporter); 096 if (InstanceManager.getNullableDefault(ReporterManager.class) == null) { 097 setEnabled(false); 098 } 099 return reporter; 100 } 101 102 BeanItemPanel physicalDetails() { 103 104 String defaultBlockSpeedText = Bundle.getMessage("UseGlobal", "Global") 105 + " " + InstanceManager.getDefault(BlockManager.class).getDefaultSpeed(); 106 speedList.add(defaultBlockSpeedText); 107 java.util.Vector<String> _speedMap = InstanceManager.getDefault(SignalSpeedMap.class).getValidSpeedNames(); 108 for (int i = 0; i < _speedMap.size(); i++) { 109 if (!speedList.contains(_speedMap.get(i))) { 110 speedList.add(_speedMap.get(i)); 111 } 112 } 113 BeanItemPanel basic = new BeanItemPanel(); 114 basic.setName(Bundle.getMessage("BlockPhysicalProperties")); 115 116 basic.addItem(new BeanEditItem(null, null, Bundle.getMessage("BlockPropertiesText"))); 117 lengthSpinner.setModel( new SpinnerNumberModel( 118 Float.valueOf(0f), Float.valueOf(0f), Float.valueOf(1000f), Float.valueOf(0.01f))); 119 lengthSpinner.setEditor(new JSpinner.NumberEditor(lengthSpinner, "###0.00")); 120 lengthSpinner.setPreferredSize(new JTextField(8).getPreferredSize()); 121 122 ButtonGroup rg = new ButtonGroup(); 123 rg.add(inch); 124 rg.add(cm); 125 126 JPanel p = new JPanel(); 127 p.add(inch); 128 p.add(cm); 129 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 130 inch.setSelected(!metricUi); 131 cm.setSelected(metricUi); 132 inch.addActionListener( e -> updateLength()); 133 cm.addActionListener( e -> updateLength()); 134 135 basic.addItem(new BeanEditItem(lengthSpinner, 136 Bundle.getMessage("BlockLengthColName"), Bundle.getMessage("BlockLengthText") )); 137 basic.addItem(new BeanEditItem(p, 138 Bundle.getMessage("BlockLengthUnits"), Bundle.getMessage("BlockLengthUnitsText"))); 139 basic.addItem(new BeanEditItem(curvatureField, Bundle.getMessage("BlockCurveColName"), "")); 140 speedField = new JComboBox<>(speedList); 141 JComboBoxUtil.setupComboBoxMaxRows(speedField); 142 basic.addItem(new BeanEditItem(speedField, 143 Bundle.getMessage("BlockSpeedColName"), Bundle.getMessage("BlockMaxSpeedText"))); 144 basic.addItem(new BeanEditItem(permissiveField, 145 Bundle.getMessage("BlockPermColName"), Bundle.getMessage("BlockPermissiveText"))); 146 147 permissiveField.setSelected(bean.getPermissiveWorking()); 148 149 basic.addItem(new BeanEditItem(ghostField, 150 Bundle.getMessage("BlockGhostColName"), Bundle.getMessage("BlockGhostText"))); 151 ghostField.setSelected(bean.getIsGhost()); 152 153 basic.setSaveItem(new AbstractAction() { 154 @Override 155 public void actionPerformed(ActionEvent e) { 156 bean.setCurvature(curvatureField.getCurvature()); 157 String speed = (String) speedField.getSelectedItem(); 158 try { 159 bean.setBlockSpeed(speed); 160 } catch (JmriException ex) { 161 jmri.util.swing.JmriJOptionPane.showMessageDialog(f, ex.getMessage() + "\n" + speed); 162 return; 163 } 164 if (!speedList.contains(speed) && !speed.contains("Global")) { 165 speedList.add(speed); 166 } 167 float len = (Float) lengthSpinner.getValue(); 168 bean.setLength( metricUi ? len * 10.0f : len * 25.4f); 169 bean.setPermissiveWorking(permissiveField.isSelected()); 170 bean.setIsGhost(ghostField.isSelected()); 171 } 172 }); 173 basic.setResetItem(new AbstractAction() { 174 @Override 175 public void actionPerformed(ActionEvent e) { 176 curvatureField.setCurvature(bean.getCurvature()); 177 String speed = bean.getBlockSpeed(); 178 if (!speedList.contains(speed)) { 179 speedList.add(speed); 180 } 181 speedField.setEditable(true); 182 speedField.setSelectedItem(speed); 183 updateLength(); 184 permissiveField.setSelected(bean.getPermissiveWorking()); 185 ghostField.setSelected(bean.getIsGhost()); 186 } 187 }); 188 bei.add(basic); 189 return basic; 190 } 191 192 private void updateLength() { 193 metricUi = cm.isSelected(); 194 lengthSpinner.setValue(metricUi ? bean.getLengthCm() : bean.getLengthIn()); 195 } 196 197 private NamedBeanComboBox<Sensor> sensorComboBox; 198 199 BeanItemPanel sensor() { 200 201 BeanItemPanel basic = new BeanItemPanel(); 202 basic.setName(Bundle.getMessage("BeanNameSensor")); 203 204 sensorComboBox = new NamedBeanComboBox<>( 205 InstanceManager.sensorManagerInstance(), bean.getSensor(), DisplayOptions.DISPLAYNAME); 206 sensorComboBox.setAllowNull(true); 207 JComboBoxUtil.setupComboBoxMaxRows(sensorComboBox); 208 basic.addItem(new BeanEditItem(sensorComboBox, 209 Bundle.getMessage("BeanNameSensor"), Bundle.getMessage("BlockAssignSensorText"))); 210 211 final SensorDebounceEditAction debounce = new SensorDebounceEditAction(); 212 //debounce.setBean(bean); 213 debounce.sensorDebounce(basic); 214 215 sensorComboBox.addActionListener((ActionEvent e) -> { 216 debounce.setBean(sensorComboBox.getSelectedItem()); 217 debounce.resetDebounceItems(e); 218 }); 219 220 basic.setSaveItem(new AbstractAction() { 221 @Override 222 public void actionPerformed(ActionEvent e) { 223 LayoutBlock lBlk = InstanceManager.getDefault(LayoutBlockManager.class).getLayoutBlock(bean); 224 // If the block is related to a layoutblock then set the 225 // sensor details there and allow that to propagate the changes down. 226 if (lBlk != null) { 227 lBlk.validateSensor(sensorComboBox.getSelectedItemDisplayName(), null); 228 } else { 229 bean.setSensor(sensorComboBox.getSelectedItemDisplayName()); 230 } 231 debounce.saveDebounceItems(e); 232 } 233 }); 234 basic.setResetItem(new AbstractAction() { 235 @Override 236 public void actionPerformed(ActionEvent e) { 237 //From basic details 238 sensorComboBox.setSelectedItem(bean.getSensor()); 239 debounce.setBean(bean.getSensor()); 240 debounce.resetDebounceItems(e); 241 } 242 }); 243 244 bei.add(basic); 245 return basic; 246 } 247 248 // private final static Logger log = LoggerFactory.getLogger(BlockEditAction.class); 249 250}