1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 package org.mlc.swing.layout;
37
38 import bsh.Interpreter;
39 import com.jgoodies.forms.factories.Borders;
40 import com.jgoodies.forms.factories.ButtonBarFactory;
41 import java.awt.Component;
42 import java.awt.Window;
43 import java.awt.event.*;
44 import javax.swing.*;
45
46 /***
47 * When performing drag-and-drop from the component palette to the table,
48 * this class is used to define or edit a component's settings. These
49 * settings include the import, declaration, configuration lines which
50 * will be used to generate the code for the component. The same settings
51 * are used to create a 'preview' component to be shown in the preview
52 * window.
53 *
54 * @author Michael Connor
55 */
56 @SuppressWarnings("serial")
57 public class NewComponentDialog extends JPanel
58 {
59 JLabel componentNameLabel = new JLabel("Name");
60 JTextField componentNameTextField = new JTextField();
61
62 JLabel importsLabel = new JLabel("Imports");
63 JTextArea importsComponent = createTextArea(3, 40);
64
65 JLabel declarationsLabel = new JLabel("Declarations");
66 JTextArea declarationsComponent = createTextArea(3, 40);
67
68 JLabel configureLabel = new JLabel("Configure");
69 JTextArea configureComponent = createTextArea(4, 40);
70
71 JLabel addToContainerLabel = new JLabel("Add");
72 JTextArea addToContainerComponent = createTextArea(3, 40);
73
74 JLabel removeFromContainerLabel = new JLabel("Remove");
75 JTextArea removeFromContainerComponent = createTextArea(2, 40);
76
77 JLabel previewLabel = new JLabel("Preview");
78 JScrollPane previewComponent = new JScrollPane();
79
80 JButton prevButton = new JButton("Preview");
81 JButton okButton = new JButton("OK");
82 JButton cancelButton = new JButton("Cancel");
83 Component buttonBar = ButtonBarFactory.buildRightAlignedBar(new JButton[] {
84 prevButton, okButton, cancelButton });
85
86 ComponentDef componentDef;
87 private String preview;
88 Window myOwner;
89 private boolean success = false;
90
91 public boolean succeeded()
92 {
93 return success;
94 }
95
96 /*** Creates a new instance of NewComponentDialog */
97 public NewComponentDialog(Window owner)
98 {
99 myOwner = owner;
100 LayoutConstraintsManager layoutConstraintsManager = LayoutConstraintsManager
101 .getLayoutConstraintsManager(NewComponentDialog.class.getResourceAsStream(
102 "editableLayoutConstraints.xml"));
103
104 this.setBorder(Borders.DIALOG_BORDER);
105
106 layoutConstraintsManager.setLayout("newComponentPanel", this);
107
108
109
110 add(new JScrollPane(removeFromContainerComponent),
111 "removeFromContainerComponent");
112
113 add(configureLabel, "configureLabel");
114 add(new JScrollPane(importsComponent), "importsComponent");
115 add(new JScrollPane(declarationsComponent), "declarationsComponent");
116 add(new JScrollPane(configureComponent), "configureComponent");
117 add(new JScrollPane(addToContainerComponent), "addToContainerComponent");
118 add(buttonBar, "buttonBar");
119 add(declarationsLabel, "declarationsLabel");
120 add(componentNameLabel, "componentNameLabel");
121 add(importsLabel, "importsLabel");
122 add(addToContainerLabel, "addToContainerLabel");
123 add(componentNameTextField, "componentNameTextField");
124 add(removeFromContainerLabel, "removeFromContainerLabel");
125
126 add(previewLabel, "previewLabel");
127 add(previewComponent, "previewComponent");
128
129 prevButton.addActionListener(new ActionListener()
130 {
131 public void actionPerformed(ActionEvent e)
132 {
133 doPreview();
134 }
135 });
136 okButton.addActionListener(new ActionListener()
137 {
138 public void actionPerformed(ActionEvent e)
139 {
140 success = true;
141 componentDef.add = getAdd();
142 componentDef.configure = getConfiguration();
143 componentDef.declarations = getDeclarations();
144 componentDef.name = componentNameTextField.getText().trim();
145 componentDef.imports = getImports();
146 UserPrefs.getPrefs().saveWinLoc("newcomp", myOwner);
147 myOwner.setVisible(false);
148 }
149 });
150 cancelButton.addActionListener(new ActionListener()
151 {
152 public void actionPerformed(ActionEvent e)
153 {
154 success = false;
155 UserPrefs.getPrefs().saveWinLoc("newcomp", myOwner);
156 myOwner.setVisible(false);
157 }
158 });
159 }
160
161
162
163
164
165
166
167
168
169
170
171 /***
172 Get an instance of the specified component. In FormLayoutMaker,
173 this instance is placed in the preview panel.
174 <p>
175 For example, if the component is a JButton, this method is the
176 equivalent of <code>new JButton(<i>text</i>)</code>.
177
178 @return Component An instance of the component, null if there
179 is a problem in the specification. [It is recommended that the
180 'Preview' button should be clicked before exiting the dialog.]
181 */
182 public Component getInstance()
183 {
184 Component component = null;
185 String script;
186 if (preview == null || preview.length() == 0)
187 script = getImports() + "\n" + getDeclarations() + "\n"
188 + getConfiguration();
189 else
190 script = preview.trim();
191 String componentName = componentNameTextField.getText();
192 script = script.replaceAll("//$//{name//}", componentName);
193
194 Interpreter interpreter = new Interpreter();
195 interpreter.setStrictJava(true);
196
197 JPanel temporaryContainer = null;
198 try
199 {
200
201 interpreter.set("container", temporaryContainer);
202 interpreter.eval(script);
203 component = (Component) interpreter.get(componentName);
204
205 }
206 catch (bsh.EvalError error)
207 {
208 System.out.println(error);
209 }
210 return component;
211 }
212
213 private void doPreview()
214 {
215 Component component = getInstance();
216 if (component == null)
217 return;
218 JPanel temporaryContainer = new JPanel();
219 temporaryContainer.add(component);
220 if (temporaryContainer != null)
221 {
222 previewComponent.setViewportView(temporaryContainer);
223 }
224 }
225
226 /*** Get the component's name */
227 public String getComponentName()
228 {
229 return componentNameTextField.getText();
230 }
231
232 public void setComponentName(String componentName)
233 {
234 componentNameTextField.setText(componentName);
235 }
236
237 /*** Get the component's <imports> section. */
238 public String getImports()
239 {
240 return importsComponent.getText().trim();
241 }
242
243 /*** Get the component's <declarations> section. */
244 public String getDeclarations()
245 {
246 return declarationsComponent.getText().trim();
247 }
248
249 /*** Get the component's <configuration> section. */
250 public String getConfiguration()
251 {
252 return configureComponent.getText().trim();
253 }
254
255 public String getAdd()
256 {
257 String res = addToContainerComponent.getText();
258 return cleanString(res);
259 }
260
261 public void setRemove(String remove)
262 {
263 removeFromContainerComponent.setText(remove);
264 }
265
266 public void setComponentDef(ComponentDef componentDef)
267 {
268 editComponentDef(componentDef.clone());
269 }
270
271 public void editComponentDef(ComponentDef componentDef)
272 {
273 this.componentDef = componentDef;
274
275 importsComponent.setText(cleanString(componentDef.imports));
276 declarationsComponent.setText(cleanString(componentDef.declarations));
277 configureComponent.setText(cleanString(componentDef.configure));
278 addToContainerComponent.setText(cleanString(componentDef.add));
279 removeFromContainerComponent.setText(cleanString(componentDef.remove));
280 preview = cleanString(componentDef.preview);
281 }
282
283 /*** Cleans a string. Removes extra newlines.
284 *
285 * @param instr
286 * @return
287 */
288 private String cleanString(String instr)
289 {
290 if ( instr == null )
291 return instr;
292
293
294
295
296
297 String [] outstrs = instr.split("\n");
298 StringBuffer outstr = new StringBuffer();
299 for ( int i = 0 ; i < outstrs.length; i++ )
300 {
301 String tmp = outstrs[i].trim();
302 outstr.append(tmp.length() > 0 ? (tmp + "\n") : "");
303 }
304 return outstr.toString();
305 }
306
307 private static JTextArea createTextArea(int rows, int cols)
308 {
309 JTextArea textArea = new JTextArea(rows, cols);
310
311
312
313 return textArea;
314 }
315
316 /***
317 * Creates and displays a dialog for editing a component's settings. See
318 * @see doDialog for an example.
319 */
320 public static NewComponentDialog editDialog(JFrame owner,
321 ComponentDef componentDef)
322 {
323 JDialog dlg = new JDialog(owner, "Edit Component", true);
324 UserPrefs.getPrefs().useSavedBounds("newcomp",dlg);
325 dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
326 NewComponentDialog panel = new NewComponentDialog(dlg);
327 panel.editComponentDef(componentDef);
328 panel.setComponentName(componentDef.name);
329 dlg.getContentPane().add(panel);
330 dlg.pack();
331 dlg.setVisible(true);
332 return panel;
333 }
334
335 /***
336 * Creates and displays a dialog for defining a new component's settings. The
337 dialog should be used as follows:
338 <code>
339 NewComponentDialog dlg = NewComponentDialog.doDialog(frame, componentDef);
340 if (dlg.succeeded())
341 {
342 [do something with dlg.componentDef]
343 }
344 <code>
345 */
346 public static NewComponentDialog doDialog(JFrame owner,
347 ComponentDef componentDef)
348 {
349 JDialog dlg = new JDialog(owner, "New Component", true);
350 UserPrefs.getPrefs().useSavedBounds("newcomp",dlg);
351 dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
352 NewComponentDialog panel = new NewComponentDialog(dlg);
353 panel.setComponentDef(componentDef);
354 panel.setComponentName("untitled");
355 dlg.getContentPane().add(panel);
356 dlg.pack();
357 dlg.setVisible(true);
358 return panel;
359 }
360
361 /*** Unit testing.
362 */
363 public static void main(String[] args)
364 {
365 JFrame frame = new JFrame();
366 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
367 NewComponentDialog dialog = new NewComponentDialog(frame);
368
369 ComponentDef componentDef = new ComponentDef();
370 componentDef.imports = "import javax.swing.JLabel;";
371 componentDef.declarations = "JLabel ${name} = new JLabel(\"Hello World\");";
372 componentDef.configure = "";
373 componentDef.add = "${container}.add(${name}, \"${name}\");";
374 componentDef.remove = "${container}.remove($name);";
375 dialog.setComponentName("untitled");
376 dialog.setComponentDef(componentDef);
377
378 frame.getContentPane().add(dialog);
379 frame.pack();
380 frame.setVisible(true);
381 }
382
383 }