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