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