001package jmri.jmrit.display.layoutEditor.LayoutEditorDialogs; 002 003import java.awt.Container; 004import java.awt.FlowLayout; 005import java.awt.event.ActionEvent; 006 007import javax.annotation.Nonnull; 008import javax.swing.*; 009 010import jmri.*; 011import jmri.NamedBean.DisplayOptions; 012import jmri.jmrit.display.layoutEditor.*; 013import jmri.swing.NamedBeanComboBox; 014import jmri.util.JmriJFrame; 015import jmri.util.swing.JmriJOptionPane; 016 017/** 018 * MVC Editor component for TrackSegment objects. 019 * 020 * @author Bob Jacobsen Copyright (c) 2020 021 * 022 */ 023public class TrackSegmentEditor extends LayoutTrackEditor { 024 025 /** 026 * constructor method. 027 * @param layoutEditor main layout editor. 028 */ 029 public TrackSegmentEditor(@Nonnull LayoutEditor layoutEditor) { 030 super(layoutEditor); 031 } 032 033 // ********** Members and methods from LayoutTrackEditors 034 // ********** specific to TrackSegment 035 036 // variables for Edit Track Segment pane 037 private TrackSegmentView trackSegmentView; 038 private TrackSegment trackSegment; 039 040 private JmriJFrame editTrackSegmentFrame = null; 041 private final JComboBox<String> editTrackSegmentMainlineComboBox = new JComboBox<>(); 042 private final JComboBox<String> editTrackSegmentDashedComboBox = new JComboBox<>(); 043 private final JCheckBox editTrackSegmentHiddenCheckBox = new JCheckBox(Bundle.getMessage("HideTrack")); // NOI18N 044 private final NamedBeanComboBox<Block> editTrackSegmentBlockNameComboBox = new NamedBeanComboBox<>( 045 InstanceManager.getDefault(BlockManager.class), null, DisplayOptions.DISPLAYNAME); 046 private final JTextField editTrackSegmentArcTextField = new JTextField(5); 047 private JButton editTrackSegmentSegmentEditBlockButton; 048 049 private int editTrackSegmentMainlineTrackIndex; 050 private int editTrackSegmentSideTrackIndex; 051 private int editTrackSegmentDashedIndex; 052 private int editTrackSegmentSolidIndex; 053 private boolean editTrackSegmentOpen = false; 054 private boolean editTrackSegmentNeedsRedraw = false; 055 056 057 /** 058 * Edit a Track Segment. 059 */ 060 @InvokeOnGuiThread 061 @Override 062 public void editLayoutTrack(@Nonnull LayoutTrackView layoutTrackView) { 063 if ( layoutTrackView instanceof TrackSegmentView ) { 064 this.trackSegmentView = (TrackSegmentView) layoutTrackView; 065 this.trackSegment = this.trackSegmentView.getTrackSegment(); 066 } else { 067 log.error("editLayoutTrack received type {} content {}", 068 layoutTrackView.getClass(), layoutTrackView, 069 new Exception("traceback")); 070 } 071 sensorList.clear(); 072 073 if (editTrackSegmentOpen) { 074 editTrackSegmentFrame.setVisible(true); 075 } else if (editTrackSegmentFrame == null) { // Initialize if needed 076 editTrackSegmentFrame = new JmriJFrame(Bundle.getMessage("EditTrackSegment"), false, true); // key moved to DisplayBundle to be found by CircuitBuilder.java // NOI18N 077 editTrackSegmentFrame.addHelpMenu("package.jmri.jmrit.display.EditTrackSegment", true); // NOI18N 078 editTrackSegmentFrame.setLocation(50, 30); 079 Container contentPane = editTrackSegmentFrame.getContentPane(); 080 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 081 082 // add dashed choice 083 JPanel panel31 = new JPanel(); 084 panel31.setLayout(new FlowLayout()); 085 editTrackSegmentDashedComboBox.removeAllItems(); 086 editTrackSegmentDashedComboBox.addItem(Bundle.getMessage("Solid")); // NOI18N 087 editTrackSegmentSolidIndex = 0; 088 editTrackSegmentDashedComboBox.addItem(Bundle.getMessage("Dashed")); // NOI18N 089 editTrackSegmentDashedIndex = 1; 090 editTrackSegmentDashedComboBox.setToolTipText(Bundle.getMessage("DashedToolTip")); // NOI18N 091 JLabel label31a = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("Style"))); 092 panel31.add(label31a); 093 label31a.setLabelFor(editTrackSegmentDashedComboBox); 094 panel31.add(editTrackSegmentDashedComboBox); 095 contentPane.add(panel31); 096 097 // add mainline choice 098 JPanel panel32 = new JPanel(); 099 panel32.setLayout(new FlowLayout()); 100 101 editTrackSegmentMainlineComboBox.removeAllItems(); 102 editTrackSegmentMainlineComboBox.addItem(Bundle.getMessage("Mainline")); // NOI18N 103 editTrackSegmentMainlineTrackIndex = 0; 104 editTrackSegmentMainlineComboBox.addItem(Bundle.getMessage("NotMainline")); // NOI18N 105 editTrackSegmentSideTrackIndex = 1; 106 editTrackSegmentMainlineComboBox.setToolTipText(Bundle.getMessage("MainlineToolTip")); // NOI18N 107 editTrackSegmentMainlineComboBox.setName(Bundle.getMessage("Mainline")); 108 panel32.add(editTrackSegmentMainlineComboBox); 109 contentPane.add(panel32); 110 111 // add hidden choice 112 JPanel panel33 = new JPanel(); 113 panel33.setLayout(new FlowLayout()); 114 editTrackSegmentHiddenCheckBox.setToolTipText(Bundle.getMessage("HiddenToolTip")); // NOI18N 115 panel33.add(editTrackSegmentHiddenCheckBox); 116 contentPane.add(panel33); 117 118 // setup block name 119 JPanel panel2 = new JPanel(); 120 panel2.setLayout(new FlowLayout()); 121 JLabel blockNameLabel = new JLabel(Bundle.getMessage("BlockID")); // NOI18N 122 panel2.add(blockNameLabel); 123 blockNameLabel.setLabelFor(editTrackSegmentBlockNameComboBox); 124 LayoutEditor.setupComboBox(editTrackSegmentBlockNameComboBox, false, true, true); 125 editTrackSegmentBlockNameComboBox.setToolTipText(Bundle.getMessage("EditBlockNameHint")); // NOI18N 126 127 panel2.add(editTrackSegmentBlockNameComboBox); 128 129 contentPane.add(panel2); 130 131 JPanel panel20 = new JPanel(); 132 panel20.setLayout(new FlowLayout()); 133 JLabel arcLabel = new JLabel(Bundle.getMessage("SetArcAngle")); // NOI18N 134 panel20.add(arcLabel); 135 arcLabel.setLabelFor(editTrackSegmentArcTextField); 136 panel20.add(editTrackSegmentArcTextField); 137 editTrackSegmentArcTextField.setToolTipText(Bundle.getMessage("SetArcAngleHint")); // NOI18N 138 contentPane.add(panel20); 139 140 // set up Edit Block, Done and Cancel buttons 141 JPanel panel5 = new JPanel(); 142 panel5.setLayout(new FlowLayout()); 143 144 // Edit Block 145 panel5.add(editTrackSegmentSegmentEditBlockButton = new JButton(Bundle.getMessage("EditBlock", ""))); // NOI18N 146 editTrackSegmentSegmentEditBlockButton.addActionListener(this::editTrackSegmentEditBlockPressed); 147 editTrackSegmentSegmentEditBlockButton.setToolTipText(Bundle.getMessage("EditBlockHint", "")); // empty value for block 1 // NOI18N 148 149 addDoneCancelButtons(panel5, editTrackSegmentFrame.getRootPane(), 150 this::editTracksegmentDonePressed, this::editTrackSegmentCancelPressed); 151 contentPane.add(panel5); 152 } 153 // Set up for Edit 154 if (trackSegment.isMainline()) { 155 editTrackSegmentMainlineComboBox.setSelectedIndex(editTrackSegmentMainlineTrackIndex); 156 } else { 157 editTrackSegmentMainlineComboBox.setSelectedIndex(editTrackSegmentSideTrackIndex); 158 } 159 if (trackSegmentView.isDashed()) { 160 editTrackSegmentDashedComboBox.setSelectedIndex(editTrackSegmentDashedIndex); 161 } else { 162 editTrackSegmentDashedComboBox.setSelectedIndex(editTrackSegmentSolidIndex); 163 } 164 editTrackSegmentHiddenCheckBox.setSelected(trackSegmentView.isHidden()); 165 Block block = InstanceManager.getDefault(BlockManager.class).getBlock(trackSegment.getBlockName()); 166 editTrackSegmentBlockNameComboBox.getEditor().setItem(block); // Select the item via the editor, empty text field if null 167 editTrackSegmentBlockNameComboBox.setEnabled(!hasNxSensorPairs(trackSegment.getLayoutBlock())); 168 169 if (trackSegmentView.isArc() && trackSegmentView.isCircle()) { 170 editTrackSegmentArcTextField.setText("" + trackSegmentView.getAngle()); 171 editTrackSegmentArcTextField.setEnabled(true); 172 } else { 173 editTrackSegmentArcTextField.setEnabled(false); 174 } 175 176 editTrackSegmentFrame.addWindowListener(new java.awt.event.WindowAdapter() { 177 @Override 178 public void windowClosing(java.awt.event.WindowEvent e) { 179 editTrackSegmentCancelPressed(null); 180 } 181 }); 182 editTrackSegmentFrame.pack(); 183 editTrackSegmentFrame.setVisible(true); 184 editTrackSegmentOpen = true; 185 186 showSensorMessage(); 187 } // editTrackSegment 188 189 @InvokeOnGuiThread 190 private void editTrackSegmentEditBlockPressed(ActionEvent a) { 191 // check if a block name has been entered 192 String newName = editTrackSegmentBlockNameComboBox.getSelectedItemDisplayName(); 193 if (newName == null) { 194 newName = ""; 195 } 196 if ((trackSegment.getBlockName().isEmpty()) 197 || !trackSegment.getBlockName().equals(newName)) { 198 // get new block, or null if block has been removed 199 trackSegment.setLayoutBlock(layoutEditor.provideLayoutBlock(newName)); 200 editTrackSegmentNeedsRedraw = true; 201 layoutEditor.getLEAuxTools().setBlockConnectivityChanged(); 202 trackSegment.updateBlockInfo(); 203 } 204 // check if a block exists to edit 205 if (trackSegment.getLayoutBlock() == null) { 206 JmriJOptionPane.showMessageDialog(editTrackSegmentFrame, 207 Bundle.getMessage("Error1"), // NOI18N 208 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); // NOI18N 209 return; 210 } 211 trackSegment.getLayoutBlock().editLayoutBlock(editTrackSegmentFrame); 212 layoutEditor.setDirty(); 213 editTrackSegmentNeedsRedraw = true; 214 } 215 216 @InvokeOnGuiThread 217 private void editTracksegmentDonePressed(ActionEvent a) { 218 // set dashed 219 boolean oldDashed = trackSegmentView.isDashed(); 220 trackSegmentView.setDashed(editTrackSegmentDashedComboBox.getSelectedIndex() == editTrackSegmentDashedIndex); 221 222 // set mainline 223 boolean oldMainline = trackSegment.isMainline(); 224 trackSegment.setMainline(editTrackSegmentMainlineComboBox.getSelectedIndex() == editTrackSegmentMainlineTrackIndex); 225 226 // set hidden 227 boolean oldHidden = trackSegmentView.isHidden(); 228 trackSegmentView.setHidden(editTrackSegmentHiddenCheckBox.isSelected()); 229 230 if (trackSegmentView.isArc()) { 231 try { 232 double newAngle = Double.parseDouble(editTrackSegmentArcTextField.getText()); 233 trackSegmentView.setAngle(newAngle); 234 editTrackSegmentNeedsRedraw = true; 235 } catch (NumberFormatException e) { 236 editTrackSegmentArcTextField.setText("" + trackSegmentView.getAngle()); 237 } 238 } 239 // check if anything changed 240 if ((oldDashed != trackSegmentView.isDashed()) 241 || (oldMainline != trackSegment.isMainline()) 242 || (oldHidden != trackSegmentView.isHidden())) { 243 editTrackSegmentNeedsRedraw = true; 244 } 245 // check if Block changed 246 String newName = editTrackSegmentBlockNameComboBox.getSelectedItemDisplayName(); 247 if (newName == null) { 248 newName = ""; 249 } 250 if ((trackSegment.getBlockName().isEmpty()) 251 || !trackSegment.getBlockName().equals(newName)) { 252 // get new block, or null if block has been removed 253 trackSegment.setLayoutBlock(layoutEditor.provideLayoutBlock(newName)); 254 editTrackSegmentNeedsRedraw = true; 255 layoutEditor.getLEAuxTools().setBlockConnectivityChanged(); 256 trackSegment.updateBlockInfo(); 257 } 258 editTrackSegmentOpen = false; 259 260 editTrackSegmentFrame.setVisible(false); 261 editTrackSegmentFrame.dispose(); 262 editTrackSegmentFrame = null; 263 264 if (editTrackSegmentNeedsRedraw) { 265 layoutEditor.redrawPanel(); 266 editTrackSegmentNeedsRedraw = false; 267 } 268 layoutEditor.setDirty(); 269 } 270 271 @InvokeOnGuiThread 272 private void editTrackSegmentCancelPressed(ActionEvent a) { 273 editTrackSegmentOpen = false; 274 editTrackSegmentFrame.setVisible(false); 275 editTrackSegmentFrame.dispose(); 276 editTrackSegmentFrame = null; 277 if (editTrackSegmentNeedsRedraw) { 278 layoutEditor.setDirty(); 279 layoutEditor.redrawPanel(); 280 editTrackSegmentNeedsRedraw = false; 281 } 282 } 283 284 285 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrackSegmentEditor.class); 286}