001package jmri.jmrit.operations;
002
003import java.awt.*;
004import java.awt.event.ActionEvent;
005
006import javax.swing.*;
007import javax.swing.event.ChangeEvent;
008
009import jmri.InstanceManager;
010import jmri.implementation.swing.SwingShutDownTask;
011import jmri.jmrit.operations.setup.Control;
012import jmri.jmrit.operations.setup.Setup;
013import jmri.util.JmriJFrame;
014
015/**
016 * Frame for operations
017 *
018 * @author Dan Boudreau Copyright (C) 2008, 2012
019 */
020public class OperationsFrame extends JmriJFrame {
021
022    public static final String NEW_LINE = "\n"; // NOI18N
023    public static final String NONE = ""; // NOI18N
024
025    public OperationsFrame(String s) {
026        this(s, new OperationsPanel());
027    }
028
029    public OperationsFrame() {
030        this(new OperationsPanel());
031    }
032
033    public OperationsFrame(OperationsPanel p) {
034        super();
035        this.setContentPane(p);
036        this.setEscapeKeyClosesWindow(true);
037    }
038
039    public OperationsFrame(String s, OperationsPanel p) {
040        super(s);
041        this.setContentPane(p);
042        this.setEscapeKeyClosesWindow(true);
043    }
044
045    @Override
046    public void initComponents() {
047        // default method does nothing, but fail to call super.initComponents,
048        // so that Exception does not need to be caught
049    }
050
051    public void initMinimumSize() {
052        initMinimumSize(new Dimension(Control.panelWidth500, Control.panelHeight250));
053    }
054
055    public void initMinimumSize(Dimension dimension) {
056        setMinimumSize(dimension);
057        pack();
058        setVisible(true);
059    }
060
061    protected void addItem(JComponent c, int x, int y) {
062        this.getContentPane().addItem(c, x, y);
063    }
064
065    protected void addItem(JPanel p, JComponent c, int x, int y) {
066        this.getContentPane().addItem(p, c, x, y);
067    }
068
069    protected void addItemLeft(JPanel p, JComponent c, int x, int y) {
070        this.getContentPane().addItemLeft(p, c, x, y);
071    }
072
073    protected void addItemTop(JPanel p, JComponent c, int x, int y) {
074        this.getContentPane().addItemTop(p, c, x, y);
075    }
076
077    protected void addItemWidth(JPanel p, JComponent c, int width, int x, int y) {
078        this.getContentPane().addItemWidth(p, c, width, x, y);
079    }
080    
081    protected JPanel getColorChooserPanel(String text, JColorChooser chooser) {
082        return this.getContentPane().getColorChooserPanel(text, chooser);
083    }
084
085    protected JPanel getColorChooserPanel(String text, JColorChooser chooser, JCheckBox checkBox) {
086        return this.getContentPane().getColorChooserPanel(text, chooser, checkBox);
087    }
088    
089    protected JPanel getColorChooserPanel(String title, Color color, JColorChooser chooser, JCheckBox checkBox) {
090        return this.getContentPane().getColorChooserPanel(title, color, chooser, checkBox);
091    }
092
093    /**
094     * Gets the number of checkboxes(+1) that can fix in one row see
095     * OperationsFrame.MIN_CHECKBOXES and OperationsFrame.MAX_CHECKBOXES
096     *
097     * @return the number of checkboxes, minimum is 5 (6 checkboxes)
098     */
099    protected int getNumberOfCheckboxesPerLine() {
100        return this.getContentPane().getNumberOfCheckboxesPerLine(this.getPreferredSize());
101    }
102
103    protected void addButtonAction(JButton b) {
104        b.addActionListener(this::buttonActionPerformed);
105    }
106
107    protected void buttonActionPerformed(ActionEvent ae) {
108        this.getContentPane().buttonActionPerformed(ae);
109    }
110
111    protected void addRadioButtonAction(JRadioButton b) {
112        b.addActionListener(this::radioButtonActionPerformed);
113    }
114
115    protected void radioButtonActionPerformed(ActionEvent ae) {
116        this.getContentPane().radioButtonActionPerformed(ae);
117    }
118
119    protected void addCheckBoxAction(JCheckBox b) {
120        b.addActionListener(this::checkBoxActionPerformed);
121    }
122
123    protected void checkBoxActionPerformed(ActionEvent ae) {
124        this.getContentPane().checkBoxActionPerformed(ae);
125    }
126
127    protected void addSpinnerChangeListerner(JSpinner s) {
128        s.addChangeListener(this::spinnerChangeEvent);
129    }
130
131    protected void spinnerChangeEvent(ChangeEvent ae) {
132        this.getContentPane().spinnerChangeEvent(ae);
133    }
134
135    protected void addComboBoxAction(JComboBox<?> b) {
136        b.addActionListener(this::comboBoxActionPerformed);
137    }
138
139    protected void comboBoxActionPerformed(ActionEvent ae) {
140        this.getContentPane().comboBoxActionPerformed(ae);
141    }
142
143    protected void selectNextItemComboBox(JComboBox<?> b) {
144        this.getContentPane().selectNextItemComboBox(b);
145    }
146
147    /**
148     * Will modify the character column width of a TextArea box to 90% of a
149     * panels width. ScrollPane is set to 95% of panel width.
150     *
151     * @param scrollPane the pane containing the textArea
152     * @param textArea   the textArea to adjust
153     */
154    protected void adjustTextAreaColumnWidth(JScrollPane scrollPane, JTextArea textArea) {
155        this.getContentPane().adjustTextAreaColumnWidth(scrollPane, textArea, this.getPreferredSize());
156    }
157    
158    protected void adjustTextAreaColumnWidth(JScrollPane scrollPane, JTextArea textArea, Dimension size) {
159        this.getContentPane().adjustTextAreaColumnWidth(scrollPane, textArea, size);
160    }
161
162    /**
163     * Load the table width, position, and sorting status from the user
164     * preferences file.
165     *
166     * @param table The table to be adjusted.
167     *
168     */
169    public void loadTableDetails(JTable table) {
170        this.getContentPane().loadTableDetails(table);
171    }
172
173    protected void clearTableSort(JTable table) {
174        this.getContentPane().clearTableSort(table);
175    }
176
177    /**
178     * Checks at shutdown if operations files need to be saved
179     */
180    protected synchronized void createShutDownTask() {
181        InstanceManager.getDefault(OperationsManager.class)
182                .setShutDownTask(new SwingShutDownTask("Operations Train Window Check", // NOI18N
183                        Bundle.getMessage("PromptQuitWindowNotWritten"), Bundle.getMessage("PromptSaveQuit"), this) {
184                    @Override
185                    public boolean checkPromptNeeded() {
186                        setModifiedFlag(false);
187                        if (Setup.isAutoSaveEnabled()) {
188                            storeValues();
189                            return true; // no prompt needed
190                        }
191                        return !OperationsXml.areFilesDirty();
192                    }
193
194                    @Override
195                    public void didPrompt() {
196                        storeValues();
197                    }
198                });
199    }
200    
201    @Override
202    protected void storeValues() {
203        this.getContentPane().storeValues();
204    }
205
206    @Override
207    public void dispose() {
208        this.getContentPane().dispose();
209        super.dispose();
210    }
211
212    /*
213     * Kludge fix for horizontal scrollbar encroaching buttons at bottom of a scrollable window.
214     */
215    protected void addHorizontalScrollBarKludgeFix(JScrollPane pane, JPanel panel) {
216        this.getContentPane().addHorizontalScrollBarKludgeFix(pane, panel);
217    }
218
219    /**
220     * {@inheritDoc}
221     * <p>
222     * This implementation only accepts the content pane if it is an
223     * {@link OperationsPanel}.
224     *
225     * @throws java.lang.IllegalArgumentException if the content pane is not an
226     *                                            OperationsPanel
227     */
228    @Override
229    public void setContentPane(Container contentPane) {
230        if (contentPane instanceof OperationsPanel) {
231            super.setContentPane(contentPane);
232        } else {
233            throw new IllegalArgumentException("OperationsFrames can only use an OperationsPanel as the contentPane");
234        }
235    }
236
237    /**
238     * {@inheritDoc}
239     * <p>
240     * This implementation only returns the content pane if it is an
241     * {@link OperationsPanel}.
242     *
243     * @throws java.lang.IllegalArgumentException if the content pane is not an
244     *                                            OperationsPanel
245     */
246    @Override
247    public OperationsPanel getContentPane() {
248        Container c = super.getContentPane();
249        if (c instanceof OperationsPanel) {
250            return (OperationsPanel) c;
251        }
252        throw new IllegalArgumentException("OperationsFrames can only use an OperationsPanel as the contentPane");
253    }
254}