001package jmri.jmrit.display.layoutEditor.LayoutEditorDialogs;
002
003import java.awt.Component;
004import java.awt.Container;
005import java.awt.FlowLayout;
006import java.awt.event.ActionEvent;
007import java.awt.event.WindowAdapter;
008import java.awt.event.WindowEvent;
009import java.text.MessageFormat;
010import javax.annotation.Nonnull;
011import javax.swing.*;
012import jmri.InstanceManager;
013import jmri.InvokeOnGuiThread;
014import jmri.Reporter;
015import jmri.ReporterManager;
016import jmri.jmrit.display.layoutEditor.LayoutEditor;
017import jmri.util.JmriJFrame;
018import org.slf4j.Logger;
019import org.slf4j.LoggerFactory;
020
021/**
022 * Layout Editor Dialogs implements some dialogs for the Layout Editor
023 *
024 * @author George Warner Copyright (c) 2019
025 */
026public class EnterReporterDialog {
027
028    // operational instance variables shared between tools
029    private LayoutEditor layoutEditor = null;
030
031    // constructor method
032    public EnterReporterDialog(@Nonnull LayoutEditor thePanel) {
033        layoutEditor = thePanel;
034    }
035
036    /*=======================================*\
037    |* Dialog box to enter new reporter info *|
038    \*=======================================*/
039    //operational variables for enter reporter pane
040    private transient JmriJFrame enterReporterFrame = null;
041    private boolean reporterOpen = false;
042    private final transient JTextField xPositionField = new JTextField(6);
043    private final transient JTextField yPositionField = new JTextField(6);
044    private final transient JTextField reporterNameField = new JTextField(6);
045    private transient JButton reporterDone;
046    private transient JButton reporterCancel;
047
048    //display dialog for entering Reporters
049    @InvokeOnGuiThread
050    public void enterReporter(int defaultX, int defaultY) {
051        if (reporterOpen) {
052            enterReporterFrame.setVisible(true);
053            return;
054        }
055
056        //Initialize if needed
057        if (enterReporterFrame == null) {
058            enterReporterFrame = new JmriJFrame(Bundle.getMessage("AddReporter"));
059
060//enterReporterFrame.addHelpMenu("package.jmri.jmrit.display.AddReporterLabel", true);
061            enterReporterFrame.setLocation(70, 30);
062            Container theContentPane = enterReporterFrame.getContentPane();
063            theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.PAGE_AXIS));
064
065            //setup reporter entry
066            JPanel panel2 = new JPanel();
067            panel2.setLayout(new FlowLayout());
068            JLabel reporterLabel = new JLabel(Bundle.getMessage("ReporterName"));
069            panel2.add(reporterLabel);
070            reporterLabel.setLabelFor(reporterNameField);
071            panel2.add(reporterNameField);
072            reporterNameField.setToolTipText(Bundle.getMessage("ReporterNameHint"));
073            theContentPane.add(panel2);
074
075            //setup coordinates entry
076            JPanel panel3 = new JPanel();
077            panel3.setLayout(new FlowLayout());
078
079            JLabel xCoordLabel = new JLabel(Bundle.getMessage("ReporterLocationX"));
080            panel3.add(xCoordLabel);
081            xCoordLabel.setLabelFor(xPositionField);
082            panel3.add(xPositionField);
083            xPositionField.setToolTipText(Bundle.getMessage("ReporterLocationXHint"));
084
085            JLabel yCoordLabel = new JLabel(Bundle.getMessage("ReporterLocationY"));
086            panel3.add(yCoordLabel);
087            yCoordLabel.setLabelFor(yPositionField);
088            panel3.add(yPositionField);
089            yPositionField.setToolTipText(Bundle.getMessage("ReporterLocationYHint"));
090
091            theContentPane.add(panel3);
092
093            //set up Add and Cancel buttons
094            JPanel panel5 = new JPanel();
095            panel5.setLayout(new FlowLayout());
096            panel5.add(reporterDone = new JButton(Bundle.getMessage("AddNewLabel")));
097            reporterDone.addActionListener(this::reporterDonePressed);
098            reporterDone.setToolTipText(Bundle.getMessage("ReporterDoneHint"));
099
100            //Cancel
101            panel5.add(reporterCancel = new JButton(Bundle.getMessage("ButtonCancel")));
102            reporterCancel.addActionListener((ActionEvent event) -> reporterCancelPressed());
103            reporterCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel")));
104            theContentPane.add(panel5);
105
106            //make this button the default button (return or enter activates)
107            JRootPane rootPane = SwingUtilities.getRootPane(reporterDone);
108            rootPane.setDefaultButton(reporterDone);
109        }
110
111        //Set up for Entry of Reporter Icon
112        xPositionField.setText(Integer.toString(defaultX));
113        yPositionField.setText(Integer.toString(defaultY));
114        enterReporterFrame.addWindowListener(new WindowAdapter() {
115            @Override
116            public void windowClosing(WindowEvent event) {
117                reporterCancelPressed();
118            }
119        });
120        enterReporterFrame.pack();
121        enterReporterFrame.setVisible(true);
122        reporterOpen = true;
123    }
124
125    private void reporterDonePressed(@Nonnull ActionEvent event) {
126        //get x coordinate
127        String newX = "";
128        int xx = 0;
129
130        newX = xPositionField.getText().trim();
131        try {
132            xx = Integer.parseInt(newX);
133        } catch (NumberFormatException e) {
134            showEntryErrorDialog(enterReporterFrame, e);
135            return;
136        }
137
138        if ((xx <= 0) || (xx > layoutEditor.gContext.getLayoutWidth())) {
139            log.error("invalid x: {}, LayoutWidth: {}", xx, layoutEditor.gContext.getLayoutWidth());
140            JOptionPane.showMessageDialog(enterReporterFrame,
141                    MessageFormat.format(Bundle.getMessage("Error2a"), String.format(" %s ", xx)),
142                    Bundle.getMessage("ErrorTitle"),
143                    JOptionPane.ERROR_MESSAGE);
144
145            return;
146        }
147
148        // get y coordinate
149        String newY = "";
150        int yy = 0;
151        newY = yPositionField.getText().trim();
152        try {
153            yy = Integer.parseInt(newY);
154        } catch (NumberFormatException e) {
155            showEntryErrorDialog(enterReporterFrame, e);
156            return;
157        }
158
159        if ((yy <= 0) || (yy > layoutEditor.gContext.getLayoutHeight())) {
160            log.error("invalid y: {}, LayoutWidth: {}", yy, layoutEditor.gContext.getLayoutHeight());
161            JOptionPane.showMessageDialog(enterReporterFrame,
162                    MessageFormat.format(Bundle.getMessage("Error2a"), String.format(" %s ", yy)),
163                    Bundle.getMessage("ErrorTitle"),
164                    JOptionPane.ERROR_MESSAGE);
165
166            return;
167        }
168
169        // get reporter name
170        Reporter reporter = null;
171        String rName = reporterNameField.getText();
172
173        if (InstanceManager.getNullableDefault(ReporterManager.class) != null) {
174            try {
175                reporter = InstanceManager.getDefault(ReporterManager.class).provideReporter(rName);
176            } catch (IllegalArgumentException e) {
177                JOptionPane.showMessageDialog(enterReporterFrame,
178                        MessageFormat.format(Bundle.getMessage("Error18"), rName), Bundle.getMessage("ErrorTitle"),
179                        JOptionPane.ERROR_MESSAGE);
180                return;
181            }
182        } else {
183            JOptionPane.showMessageDialog(enterReporterFrame,
184                    Bundle.getMessage("Error17"), Bundle.getMessage("ErrorTitle"),
185                    JOptionPane.ERROR_MESSAGE);
186
187            return;
188        }
189
190        //add the reporter icon
191        layoutEditor.addReporter(reporter, xx, yy);
192
193        reporterCancelPressed();
194    }
195
196    private void reporterCancelPressed() {
197        reporterOpen = false;
198        enterReporterFrame.setVisible(false);
199        enterReporterFrame.dispose();
200        enterReporterFrame = null;
201        layoutEditor.redrawPanel();
202    }
203
204    /**
205     * showEntryErrorDialog(Component parentComponent, NumberFormatException e)
206     *
207     * @param parentComponent determines the <code>Frame</code> in which the
208     *                        dialog is displayed; if <code>null</code>, or if
209     *                        the <code>parentComponent</code> has no
210     *                        <code>Frame</code>, a default <code>Frame</code>
211     *                        is used
212     * @param e               Exception thrown to indicate that the application
213     *                        has attempted to convert a string to one of the
214     *                        numeric types, but that the string does not have
215     *                        the appropriate format.
216     */
217    private void showEntryErrorDialog(Component parentComponent, NumberFormatException e) {
218        JOptionPane.showMessageDialog(parentComponent,
219                String.format("%s: %s %s", Bundle.getMessage("EntryError"),
220                        e, Bundle.getMessage("TryAgain")),
221                Bundle.getMessage("ErrorTitle"),
222                JOptionPane.ERROR_MESSAGE);
223    }
224
225    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(
226            EnterReporterDialog.class);
227}