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