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 /** 083 * Gets the number of checkboxes(+1) that can fix in one row see 084 * OperationsFrame.MIN_CHECKBOXES and OperationsFrame.MAX_CHECKBOXES 085 * 086 * @return the number of checkboxes, minimum is 5 (6 checkboxes) 087 */ 088 protected int getNumberOfCheckboxesPerLine() { 089 return this.getContentPane().getNumberOfCheckboxesPerLine(this.getPreferredSize()); 090 } 091 092 protected void addButtonAction(JButton b) { 093 b.addActionListener(this::buttonActionPerformed); 094 } 095 096 protected void buttonActionPerformed(ActionEvent ae) { 097 this.getContentPane().buttonActionPerformed(ae); 098 } 099 100 protected void addRadioButtonAction(JRadioButton b) { 101 b.addActionListener(this::radioButtonActionPerformed); 102 } 103 104 protected void radioButtonActionPerformed(ActionEvent ae) { 105 this.getContentPane().radioButtonActionPerformed(ae); 106 } 107 108 protected void addCheckBoxAction(JCheckBox b) { 109 b.addActionListener(this::checkBoxActionPerformed); 110 } 111 112 protected void checkBoxActionPerformed(ActionEvent ae) { 113 this.getContentPane().checkBoxActionPerformed(ae); 114 } 115 116 protected void addSpinnerChangeListerner(JSpinner s) { 117 s.addChangeListener(this::spinnerChangeEvent); 118 } 119 120 protected void spinnerChangeEvent(ChangeEvent ae) { 121 this.getContentPane().spinnerChangeEvent(ae); 122 } 123 124 protected void addComboBoxAction(JComboBox<?> b) { 125 b.addActionListener(this::comboBoxActionPerformed); 126 } 127 128 protected void comboBoxActionPerformed(ActionEvent ae) { 129 this.getContentPane().comboBoxActionPerformed(ae); 130 } 131 132 protected void selectNextItemComboBox(JComboBox<?> b) { 133 this.getContentPane().selectNextItemComboBox(b); 134 } 135 136 /** 137 * Will modify the character column width of a TextArea box to 90% of a 138 * panels width. ScrollPane is set to 95% of panel width. 139 * 140 * @param scrollPane the pane containing the textArea 141 * @param textArea the textArea to adjust 142 */ 143 protected void adjustTextAreaColumnWidth(JScrollPane scrollPane, JTextArea textArea) { 144 this.getContentPane().adjustTextAreaColumnWidth(scrollPane, textArea, this.getPreferredSize()); 145 } 146 147 protected void adjustTextAreaColumnWidth(JScrollPane scrollPane, JTextArea textArea, Dimension size) { 148 this.getContentPane().adjustTextAreaColumnWidth(scrollPane, textArea, size); 149 } 150 151 /** 152 * Load the table width, position, and sorting status from the user 153 * preferences file. 154 * 155 * @param table The table to be adjusted. 156 * 157 */ 158 public void loadTableDetails(JTable table) { 159 this.getContentPane().loadTableDetails(table); 160 } 161 162 protected void clearTableSort(JTable table) { 163 this.getContentPane().clearTableSort(table); 164 } 165 166 /** 167 * Code at frame level to clear modified flag 168 */ 169 protected synchronized void createShutDownTask() { 170 InstanceManager.getDefault(OperationsManager.class) 171 .setShutDownTask(new SwingShutDownTask("Operations Train Window Check", // NOI18N 172 Bundle.getMessage("PromptQuitWindowNotWritten"), Bundle.getMessage("PromptSaveQuit"), this) { 173 @Override 174 public boolean checkPromptNeeded() { 175 setModifiedFlag(false); // allow only one popup requesting save operation files 176 if (Setup.isAutoSaveEnabled()) { 177 storeValues(); 178 return true; 179 } 180 return !OperationsXml.areFilesDirty(); 181 } 182 183 @Override 184 public void didPrompt() { 185 storeValues(); 186 } 187 }); 188 } 189 190 @Override 191 protected void storeValues() { 192 this.getContentPane().storeValues(); 193 } 194 195 @Override 196 public void dispose() { 197 this.getContentPane().dispose(); 198 super.dispose(); 199 } 200 201 /* 202 * Kludge fix for horizontal scrollbar encroaching buttons at bottom of a scrollable window. 203 */ 204 protected void addHorizontalScrollBarKludgeFix(JScrollPane pane, JPanel panel) { 205 this.getContentPane().addHorizontalScrollBarKludgeFix(pane, panel); 206 } 207 208 /** 209 * {@inheritDoc} 210 * <p> 211 * This implementation only accepts the content pane if it is an 212 * {@link OperationsPanel}. 213 * 214 * @throws java.lang.IllegalArgumentException if the content pane is not an 215 * OperationsPanel 216 */ 217 @Override 218 public void setContentPane(Container contentPane) { 219 if (contentPane instanceof OperationsPanel) { 220 super.setContentPane(contentPane); 221 } else { 222 throw new IllegalArgumentException("OperationsFrames can only use an OperationsPanel as the contentPane"); 223 } 224 } 225 226 /** 227 * {@inheritDoc} 228 * <p> 229 * This implementation only returns the content pane if it is an 230 * {@link OperationsPanel}. 231 * 232 * @throws java.lang.IllegalArgumentException if the content pane is not an 233 * OperationsPanel 234 */ 235 @Override 236 public OperationsPanel getContentPane() { 237 Container c = super.getContentPane(); 238 if (c instanceof OperationsPanel) { 239 return (OperationsPanel) c; 240 } 241 throw new IllegalArgumentException("OperationsFrames can only use an OperationsPanel as the contentPane"); 242 } 243}