001package jmri.jmrit.display.layoutEditor.LayoutEditorDialogs; 002 003import java.awt.*; 004import java.awt.event.*; 005 006import javax.annotation.Nonnull; 007import javax.swing.*; 008 009import jmri.InvokeOnGuiThread; 010import jmri.jmrit.display.layoutEditor.LayoutEditor; 011import jmri.util.JmriJFrame; 012import jmri.util.swing.JmriJOptionPane; 013 014/** 015 * Layout Editor Dialogs implements some dialogs for the Layout Editor 016 * 017 * @author George Warner Copyright (c) 2019 018 */ 019public class ScaleTrackDiagramDialog { 020 021 // operational instance variables shared between tools 022 private LayoutEditor layoutEditor = null; 023 024 // constructor method 025 public ScaleTrackDiagramDialog(@Nonnull LayoutEditor thePanel) { 026 layoutEditor = thePanel; 027 } 028 029 /*===============================*\ 030 |* Dialog box to enter scale / *| 031 |* translate track diagram info *| 032 \*===============================*/ 033 //operational variables for scale/translate track diagram pane 034 private JmriJFrame scaleTrackDiagramFrame = null; 035 private boolean scaleTrackDiagramOpen = false; 036 private final JTextField xFactorField = new JTextField(6); 037 private final JTextField yFactorField = new JTextField(6); 038 private final JTextField xTranslateField = new JTextField(6); 039 private final JTextField yTranslateField = new JTextField(6); 040 private JButton scaleTrackDiagramDone; 041 private JButton scaleTrackDiagramCancel; 042 043 //display dialog for scaling the track diagram 044 @InvokeOnGuiThread 045 public void scaleTrackDiagram() { 046 if (scaleTrackDiagramOpen) { 047 scaleTrackDiagramFrame.setVisible(true); 048 return; 049 } 050 051 // Initialize if needed 052 if (scaleTrackDiagramFrame == null) { 053 scaleTrackDiagramFrame = new JmriJFrame(Bundle.getMessage("ScaleTrackDiagram")); 054 scaleTrackDiagramFrame.addHelpMenu("package.jmri.jmrit.display.ScaleTrackDiagram", true); 055 scaleTrackDiagramFrame.setLocation(70, 30); 056 Container theContentPane = scaleTrackDiagramFrame.getContentPane(); 057 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.PAGE_AXIS)); 058 059 // setup x translate 060 JPanel panel31 = new JPanel(); 061 panel31.setLayout(new FlowLayout()); 062 JLabel xTranslateLabel = new JLabel(Bundle.getMessage("XTranslateLabel")); 063 panel31.add(xTranslateLabel); 064 xTranslateLabel.setLabelFor(xTranslateField); 065 panel31.add(xTranslateField); 066 xTranslateField.setToolTipText(Bundle.getMessage("XTranslateHint")); 067 theContentPane.add(panel31); 068 069 //setup y translate 070 JPanel panel32 = new JPanel(); 071 panel32.setLayout(new FlowLayout()); 072 JLabel yTranslateLabel = new JLabel(Bundle.getMessage("YTranslateLabel")); 073 panel32.add(yTranslateLabel); 074 yTranslateLabel.setLabelFor(yTranslateField); 075 panel32.add(yTranslateField); 076 yTranslateField.setToolTipText(Bundle.getMessage("YTranslateHint")); 077 theContentPane.add(panel32); 078 079 //setup information message 1 080 JPanel panel33 = new JPanel(); 081 panel33.setLayout(new FlowLayout()); 082 JLabel message1Label = new JLabel(Bundle.getMessage("Message1Label")); 083 panel33.add(message1Label); 084 theContentPane.add(panel33); 085 086 //setup x factor 087 JPanel panel21 = new JPanel(); 088 panel21.setLayout(new FlowLayout()); 089 JLabel xFactorLabel = new JLabel(Bundle.getMessage("XFactorLabel")); 090 panel21.add(xFactorLabel); 091 xFactorLabel.setLabelFor(xFactorField); 092 panel21.add(xFactorField); 093 xFactorField.setToolTipText(Bundle.getMessage("FactorHint")); 094 theContentPane.add(panel21); 095 096 //setup y factor 097 JPanel panel22 = new JPanel(); 098 panel22.setLayout(new FlowLayout()); 099 JLabel yFactorLabel = new JLabel(Bundle.getMessage("YFactorLabel")); 100 panel22.add(yFactorLabel); 101 yFactorLabel.setLabelFor(yFactorField); 102 panel22.add(yFactorField); 103 yFactorField.setToolTipText(Bundle.getMessage("FactorHint")); 104 theContentPane.add(panel22); 105 106 //setup information message 2 107 JPanel panel23 = new JPanel(); 108 panel23.setLayout(new FlowLayout()); 109 JLabel message2Label = new JLabel(Bundle.getMessage("Message2Label")); 110 panel23.add(message2Label); 111 theContentPane.add(panel23); 112 113 //set up Done and Cancel buttons 114 JPanel panel5 = new JPanel(); 115 panel5.setLayout(new FlowLayout()); 116 panel5.add(scaleTrackDiagramDone = new JButton(Bundle.getMessage("ScaleTranslate"))); 117 scaleTrackDiagramDone.addActionListener(this::scaleTrackDiagramDonePressed); 118 scaleTrackDiagramDone.setToolTipText(Bundle.getMessage("ScaleTranslateHint")); 119 120 panel5.add(scaleTrackDiagramCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 121 scaleTrackDiagramCancel.addActionListener(this::scaleTrackDiagramCancelPressed); 122 scaleTrackDiagramCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 123 theContentPane.add(panel5); 124 125 //make this button the default button (return or enter activates) 126 JRootPane rootPane = SwingUtilities.getRootPane(scaleTrackDiagramDone); 127 rootPane.setDefaultButton(scaleTrackDiagramDone); 128 } 129 130 // Set up for Entry of Scale and Translation 131 xFactorField.setText("1.0"); 132 yFactorField.setText("1.0"); 133 xTranslateField.setText("0"); 134 yTranslateField.setText("0"); 135 scaleTrackDiagramFrame.addWindowListener(new WindowAdapter() { 136 @Override 137 public void windowClosing(WindowEvent event) { 138 scaleTrackDiagramCancelPressed(null); 139 } 140 }); 141 scaleTrackDiagramFrame.pack(); 142 scaleTrackDiagramFrame.setVisible(true); 143 scaleTrackDiagramOpen = true; 144 } 145 146 private void scaleTrackDiagramDonePressed(@Nonnull ActionEvent event) { 147 boolean changeFlag = false; 148 boolean translateError = false; 149 float xTranslation, yTranslation, xFactor, yFactor; 150 151 // get x translation 152 String newText = xTranslateField.getText().trim(); 153 try { 154 xTranslation = Float.parseFloat(newText); 155 } catch (NumberFormatException e) { 156 showEntryErrorDialog(scaleTrackDiagramFrame, e); 157 return; 158 } 159 160 // get y translation 161 newText = yTranslateField.getText().trim(); 162 try { 163 yTranslation = Float.parseFloat(newText); 164 } catch (NumberFormatException e) { 165 showEntryErrorDialog(scaleTrackDiagramFrame, e); 166 return; 167 } 168 169 // get x factor 170 newText = xFactorField.getText().trim(); 171 try { 172 xFactor = Float.parseFloat(newText); 173 } catch (NumberFormatException e) { 174 showEntryErrorDialog(scaleTrackDiagramFrame, e); 175 return; 176 } 177 178 // get y factor 179 newText = yFactorField.getText().trim(); 180 try { 181 yFactor = Float.parseFloat(newText); 182 } catch (NumberFormatException e) { 183 showEntryErrorDialog(scaleTrackDiagramFrame, e); 184 return; 185 } 186 187 // here when all numbers read in successfully - check for translation 188 if ((xTranslation != 0.0F) || (yTranslation != 0.0F)) { 189 //apply translation 190 if (layoutEditor.translateTrack(xTranslation, yTranslation)) { 191 changeFlag = true; 192 } else { 193 log.error("Error translating track diagram"); 194 translateError = true; 195 } 196 } 197 198 if (!translateError && ((xFactor != 1.0) || (yFactor != 1.0))) { 199 //apply scale change 200 if (layoutEditor.scaleTrack(xFactor, yFactor)) { 201 changeFlag = true; 202 } else { 203 log.error("Error scaling track diagram"); 204 } 205 } 206 layoutEditor.clearSelectionGroups(); 207 208 scaleTrackDiagramCancelPressed(null); 209 210 if (changeFlag) { 211 layoutEditor.redrawPanel(); 212 layoutEditor.setDirty(); 213 } 214 } 215 216 private void scaleTrackDiagramCancelPressed(ActionEvent event) { 217 scaleTrackDiagramOpen = false; 218 scaleTrackDiagramFrame.setVisible(false); 219 scaleTrackDiagramFrame.dispose(); 220 scaleTrackDiagramFrame = null; 221 } 222 223 /** 224 * showEntryErrorDialog(Component parentComponent, NumberFormatException e) 225 * 226 * @param parentComponent determines the <code>Frame</code> in which the 227 * dialog is displayed; if <code>null</code>, or if 228 * the <code>parentComponent</code> has no 229 * <code>Frame</code>, a default <code>Frame</code> 230 * is used 231 * @param e Exception thrown to indicate that the application 232 * has attempted to convert a string to one of the 233 * numeric types, but that the string does not have 234 * the appropriate format. 235 */ 236 private void showEntryErrorDialog(Component parentComponent, NumberFormatException e) { 237 JmriJOptionPane.showMessageDialog(parentComponent, 238 String.format("%s: %s %s", Bundle.getMessage("EntryError"), 239 e, Bundle.getMessage("TryAgain")), 240 Bundle.getMessage("ErrorTitle"), 241 JmriJOptionPane.ERROR_MESSAGE); 242 } 243 244 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger( 245 ScaleTrackDiagramDialog.class); 246}