001 package view;
002
003 import controller.IEnvAdapter;
004 import sysModel.ICmdFactory;
005 import sysModel.ISecurityAdapter;
006 import sysModel.env.AEnvFactory;
007 import sysModel.env.AGlobalEnv;
008
009 import javax.swing.*;
010 import java.awt.*;
011 import java.awt.event.ActionEvent;
012 import java.awt.event.ActionListener;
013 import java.lang.reflect.Constructor;
014
015 /**
016 * Dialog to create new environment.
017 *
018 * @author Mathias Ricken
019 */
020 public class CreateEnvDialog {
021 /**
022 * Environment factory to be used for creating the environment. This acts both as the factory and as the GUI panel
023 * with the environment settings.
024 */
025 private AEnvFactory _envFactory;
026
027 /**
028 * Combobox containing the different choices for the environment.
029 */
030 private JComboBox _envChooser;
031
032 /**
033 * Environment dialog. This component contains everything else.
034 */
035 private JDialog _dialog;
036
037 /**
038 * Array of buttons on the dialog.
039 */
040 private JButton[] _optButtons;
041
042 /**
043 * Constant to access the create button in _optButtons.
044 */
045 private static final int CREATE_BUTTON = 0;
046
047 /**
048 * Constant to access the cancel button in _optButtons.
049 */
050 private static final int CANCEL_BUTTON = 1;
051
052 /**
053 * Panel for the environment options. Contains the environment factory.
054 */
055 private JPanel _optionsPanel;
056
057 /**
058 * Adpapter to the model for dealing with environments.
059 */
060 private IEnvAdapter _envAdapter;
061
062 /**
063 * Creates a new CreateEnvDialog and all its controls.
064 *
065 * @param parent parent frame for the dialog
066 * @param ea environment adapter
067 */
068 public CreateEnvDialog(JFrame parent, IEnvAdapter ea) {
069 _envAdapter = ea;
070 _dialog = new JDialog(parent, "Create new environment", true);
071 _dialog.setContentPane(makeOptionsPanel());
072 _dialog.pack();
073 _dialog.setResizable(false);
074 }
075
076
077 /**
078 * Show the modal dialog that allows the user to create a new environment. If the dialog is dismissed by clicking
079 * the "OK" button, a new environment is created to the user's specification and returned. If "Cancel" is chosen or
080 * there is an error constructing the environment, <code>null</code> is returned.
081 *
082 * @return the newly created Environment or <code>null</code>
083 */
084 public AEnvFactory showDialog() {
085 _envChooser.setSelectedIndex(0);
086 envChosen();
087
088 // center dialog in middle of parent frame
089 Component parent = _dialog.getParent();
090 _dialog.setLocation(parent.getX() + parent.getWidth() / 2 - _dialog.getSize().width / 2,
091 parent.getY() + parent.getHeight() / 2 - _dialog.getSize().height / 2);
092 _dialog.setVisible(true); // Modal dialog will block until setVisible(false), see ok/cancel methods
093
094 return _envFactory;
095 }
096
097 /**
098 * Remove environment settings from dialog.
099 */
100 private void removeEnvSettings() {
101 if (null != _envFactory) {
102 _optionsPanel.remove(_envFactory);
103 _envFactory = null;
104 }
105 }
106
107 /**
108 * Add environment factory to dialog.
109 *
110 * @param factory factory to add
111 */
112 private void addEnvSettings(AEnvFactory factory) {
113 _envFactory = factory;
114 _optionsPanel.add(_envFactory);
115 }
116
117 /**
118 * Callback when user selects new environment class choice from combo box.
119 */
120 private void envChosen() {
121 IEnvChoice envChoice = (IEnvChoice)_envChooser.getSelectedItem();
122 envChoice.select();
123 _dialog.pack();
124 _dialog.getContentPane().validate(); // force immediate validation
125 }
126
127 /**
128 * Callback when user clicks cancel button.
129 */
130 private void cancelClicked() {
131 _dialog.setVisible(false);
132 removeEnvSettings();
133 }
134
135 /**
136 * Callback when user clicks ok button.
137 */
138 private void okClicked() {
139 _dialog.setVisible(false);
140 }
141
142 /**
143 * Build options dialog.
144 *
145 * @return options pane
146 */
147 private JOptionPane makeOptionsPanel() {
148 JPanel myControls = new JPanel();
149 myControls.setLayout(new BoxLayout(myControls, BoxLayout.Y_AXIS));
150
151 JLabel lab;
152 myControls.add(lab = new JLabel("Choose environment type: "));
153 lab.setAlignmentX(Component.CENTER_ALIGNMENT);
154
155 _envChooser = new JComboBox();
156
157 // add environments
158 String[] envClassNames = _envAdapter.getEnvironmentClassNames();
159 Class[] parameterTypes = new Class[]{ICmdFactory.class, ISecurityAdapter.class};
160 Object[] initArgs = new Object[]{_envAdapter.getCmdFactory(), _envAdapter.getSecurityAdapter()};
161 for(int i = 0; i < envClassNames.length; i++) {
162 try {
163 Class envClass = Class.forName(envClassNames[i]);
164 Constructor envCtor = envClass.getConstructor(parameterTypes);
165 AGlobalEnv env = (AGlobalEnv)envCtor.newInstance(initArgs);
166 AEnvFactory factory = env.makeEnvFactory();
167
168 ConcreteEnvChoice choice = new ConcreteEnvChoice(this, factory);
169 _envChooser.addItem(choice);
170 }
171 catch(Exception e) {
172 System.err.println(e);
173 }
174 }
175
176 // add "Add..." choice
177 _envChooser.addItem(new AddEnvChoice(this));
178
179 _envChooser.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
180 _envChooser.addActionListener(new ActionListener() {
181 public void actionPerformed(ActionEvent evt) {
182 envChosen();
183 }
184 });
185 myControls.add(_envChooser);
186
187 _optionsPanel = new JPanel();
188 myControls.add(_optionsPanel);
189
190 JOptionPane optPane = new JOptionPane(myControls, JOptionPane.QUESTION_MESSAGE);
191 _optButtons = new JButton[]{new JButton("Create"), new JButton("Cancel")};
192 optPane.setOptions(_optButtons);
193 optPane.setInitialValue(_optButtons[CREATE_BUTTON]);
194 _optButtons[CREATE_BUTTON].addActionListener(new ActionListener() {
195 public void actionPerformed(ActionEvent e) {
196 okClicked();
197 }
198 });
199 _optButtons[CANCEL_BUTTON].addActionListener(new ActionListener() {
200 public void actionPerformed(ActionEvent e) {
201 cancelClicked();
202 }
203 });
204
205 return optPane;
206 }
207
208 /**
209 * Nested interface for environment choices.
210 */
211 private interface IEnvChoice {
212 /**
213 * Select this interface.
214 */
215 public void select();
216 }
217
218 /**
219 * Nested class for choosing an environment.
220 */
221 private static class ConcreteEnvChoice implements IEnvChoice {
222 /**
223 * CreateEnvDialog used.
224 */
225 private CreateEnvDialog _envDialog;
226 /**
227 * Environment settings.
228 */
229 private AEnvFactory _envFactory;
230
231 /**
232 * Make a new concrete environment choice.
233 *
234 * @param envDialog the create environment dialog
235 * @param factory environment factory
236 */
237 public ConcreteEnvChoice(CreateEnvDialog envDialog, AEnvFactory factory) {
238 _envDialog = envDialog;
239 _envFactory = factory;
240 }
241
242 /**
243 * Select this choice.
244 */
245 public void select() {
246 _envDialog._optButtons[CREATE_BUTTON].setEnabled(true);
247 _envDialog.removeEnvSettings();
248 _envDialog.addEnvSettings(_envFactory);
249 }
250
251 /**
252 * Return string representation.
253 *
254 * @return string representation
255 */
256 public String toString() {
257 return _envFactory.toString();
258 }
259 }
260
261 /**
262 * Nested class for adding an environment.
263 */
264 private class AddEnvChoice implements IEnvChoice {
265 /**
266 * CreateEnvDialog used.
267 */
268 private CreateEnvDialog _envDialog;
269
270 /**
271 * Make a new add environment choice.
272 *
273 * @param envDialog the create environment dialog
274 */
275 public AddEnvChoice(CreateEnvDialog envDialog) {
276 _envDialog = envDialog;
277 }
278
279 public void select() {
280 _envDialog._optButtons[CREATE_BUTTON].setEnabled(false);
281 _envDialog.removeEnvSettings();
282
283 String className = (new InputStringDialog(_envDialog._dialog, "Add environment class")).showDialog();
284 if (className==null) { return; }
285 try {
286 Class envClass = Class.forName(className);
287 Constructor envCtor = envClass.getConstructor(new Class[]{ICmdFactory.class, ISecurityAdapter.class});
288 AGlobalEnv env = (AGlobalEnv)envCtor.newInstance(
289 new Object[]{_envAdapter.getCmdFactory(), _envAdapter.getSecurityAdapter()});
290 AEnvFactory envFactory = env.makeEnvFactory();
291
292 ConcreteEnvChoice choice = new ConcreteEnvChoice(_envDialog, envFactory);
293 _envDialog._envChooser.insertItemAt(choice, _envDialog._envChooser.getItemCount() - 1);
294 _envDialog._envChooser.setSelectedItem(choice);
295 choice.select();
296 }
297 catch(Exception e) {
298 System.err.println(e);
299 _envDialog._envChooser.setSelectedIndex(0);
300 ((IEnvChoice)_envDialog._envChooser.getSelectedItem()).select();
301 }
302 }
303
304 public String toString() {
305 return "Add ...";
306 }
307 }
308 }
309