001 /*
002 * Copyright (c) Holger Pfaff - http://pfaff.ws
003 *
004 * This software maybe used for any purpose provided the
005 * above copyright notice is retained. It is supplied as is.
006 * No warranty expressed or implied - Use at your own risk.
007 */
008
009 import java.awt.*;
010 import java.awt.event.*;
011 import java.util.Enumeration;
012
013 /**
014 * (#)DialogBox.java
015 * @author Holger Pfaff
016 * @version 3.2 19-Mar-2004<br><br>
017 *
018 * A Wrapper arount the AWT Dialog class. Standard dialogs are
019 * supplied as static member functions. Can be used without
020 * specifying a parent frame (creates its own parent)
021 *
022 * Attention: Dialog crashes on some Netscape 4.7x Version on
023 * Solaris in combination with LANG=en_US (or != C) and
024 * Dialog contains a TextField/TextArea (Problem is related
025 * to XInputMethods)
026 */
027
028 public class DialogBox implements ActionListener, WindowListener {
029
030 /**
031 * error image for standard dialogboxes
032 */
033 public static final Image Err = Awt.loadImageFromArchive("Err.gif");
034
035 /**
036 * warning image for standard dialogboxes
037 */
038 public static final Image Wrn = Awt.loadImageFromArchive("Wrn.gif");;
039
040 /**
041 * info image for standard dialogboxes
042 */
043 public static final Image Inf = Awt.loadImageFromArchive("Inf.gif");;
044
045 /**
046 * busy image for standard dialogboxes
047 */
048 public static final Image Bsy = Awt.loadImageFromArchive("Bsy.gif");;
049
050 /**
051 * OK string for standard dialogboxes (no i18n)
052 */
053 public static final String OK = "OK";
054
055 /**
056 * Cancel string for standard dialogboxes (no i18n)
057 */
058 public static final String CANCEL = "Cancel";
059
060 /**
061 * Error string for standard dialogboxes (no i18n)
062 */
063 public static final String ERR = "ERROR";
064
065 /**
066 * Warning string for standard dialogboxes (no i18n)
067 */
068 public static final String WRN = "Warning";
069
070 /**
071 * Info string for standard dialogboxes (no i18n)
072 */
073 public static final String INF = "Info";
074
075 /**
076 * Event Listeners
077 */
078 private ActionListener ali = null;
079
080 /**
081 * dialog object
082 */
083 private Dialog dia = null;
084
085 /**
086 * parent frame
087 */
088 private Frame frm = new Frame();
089
090 /**
091 * main panel
092 */
093 private Panel pan = null;
094
095 /**
096 * button panel
097 */
098 private Awt bpn = new BorderPanel(BorderPanel.RAISED);
099
100 /**
101 * title for dialog frame (window manager)
102 */
103 private String tit = "";
104
105 /**
106 * return code for modal dialogs
107 */
108 private Object ret = null;
109
110 /**
111 * modal dialog ?
112 */
113 private boolean mod = true;
114
115 /**
116 * resizable dialog ?
117 */
118 private boolean res = false;
119
120 /**
121 * command (actionstring) that closes the dialog window
122 */
123 private String cwc = null;
124
125 /**
126 * Construct a new Dialog.
127 *
128 * @param p the content of this dialog.
129 * @param t title for dialog frame (window manager).
130 * @param b comma separated list of buttons.
131 */
132 public DialogBox(Panel p, String t, String b) {
133 bpn.setInsets(new Insets(0,1,1,1));
134 setPanel(p);
135 setTitle(t);
136 addButtons(b);
137 }
138
139 /**
140 * Construct a new Dialog.
141 * This empty contructor is intended for custom dialogs.
142 * Use <code>setPanel</code> and <code>addButtons</code> to make this
143 * DialogBox useable.
144 *
145 */
146 public DialogBox() {
147 }
148
149 /**
150 * Get parent frame.
151 */
152 public Frame getFrame() {
153 return frm;
154 }
155
156 /**
157 * Get parent frame.
158 */
159 public Frame getParent() {
160 return frm;
161 }
162
163 /**
164 * Set parent.
165 *
166 * @param c use this components parent frame.
167 */
168 public void setParent(Component c) {
169 while(c != null) {
170 if(c instanceof Frame) {
171 if(frm.equals((Frame) c) == false) {
172 frm = (Frame) c;
173 dia = null;
174 }
175 break;
176 } else {
177 c = c.getParent();
178 }
179 }
180 }
181
182 /**
183 * Get the main panel (content of this dialog).
184 */
185 public Panel getPanel() {
186 return pan;
187 }
188
189 /**
190 * Set the main panel (content of this dialog).
191 *
192 * @param p use this panel for the dialogbox's content.
193 */
194 public void setPanel(Panel p) {
195 if(p != null) {
196 pan = p;
197 }
198 }
199
200 /**
201 * Get the title of this dialog.
202 */
203 public String getTitle() {
204 return tit;
205 }
206
207 /**
208 * Set the title of this dialog. Has no effect after <code>show()</code>
209 *
210 * @param title title string
211 */
212 public void setTitle(String t) {
213 if(t != null) {
214 tit = t;
215 if(dia != null) {
216 dia.setTitle(t);
217 }
218 }
219 }
220
221 /**
222 * Get the modal behavior of this dialog.
223 */
224 public boolean isModal() {
225 return mod;
226 }
227
228 /**
229 * Set the modal behavior of this dialog.
230 *
231 * @param m blocking or not ?
232 */
233 public void setModal(boolean m) {
234 mod = m;
235 }
236
237 /**
238 * Dialog on screen ?
239 */
240 public boolean isShowing() {
241 return dia == null ? false : dia.isShowing();
242 }
243
244 /**
245 * Set if Dialog is resizeable
246 *
247 * @param r resizeable or not ?
248 */
249 public void setResizable(boolean r) {
250 res = r;
251 }
252
253 /**
254 * Dialog resizeable ?
255 */
256 public boolean getResizable() {
257 return res;
258 }
259
260 /**
261 * Add ActionListener to this dialog
262 *
263 * @param l ActionListener to add
264 */
265 public void addActionListener(ActionListener l) {
266 ali = AWTEventMulticaster.add(ali, l);
267 }
268
269 /**
270 * Remove ActionListener to this dialog
271 *
272 * @param l ActionListener to remove
273 */
274 public void removeActionListener(ActionListener l) {
275 ali = AWTEventMulticaster.remove(ali, l);
276 }
277
278 /**
279 * Remove all ActionListener
280 */
281 public void removeActionListeners() {
282 ali = null;
283 }
284
285 /**
286 * Notify all ActionListener
287 *
288 * @param but Index of button that was pressed
289 */
290 public void notifyActionListeners(int but) {
291 Knob b = getButton(but);
292 if(b != null) {
293 notifyActionListeners(new ActionEvent(b, but, b.getActionCommand()));
294 }
295 }
296
297 /**
298 * Notify all ActionListener
299 *
300 * @param e ActionEvent
301 */
302 private synchronized void notifyActionListeners(ActionEvent e) {
303 if(ali != null) {
304 ali.actionPerformed(e);
305 }
306 }
307
308 /**
309 * Get the close window command of this dialog.
310 */
311 public String getCloseWindowCommand() {
312 return cwc;
313 }
314
315 /**
316 * Set the close window command of this dialog. The action
317 * with this string causes the dialog to disappear.
318 * Default null means close on any dialog button
319 *
320 * @param c the closing string
321 */
322 public void setCloseWindowCommand(String c) {
323 cwc = c;
324 }
325
326 /**
327 * Add a dialog button to this box.
328 *
329 * @param l the label to show
330 * @param c the action command for this button.
331 * See <code>setCloseWindowCommand</code>.
332 */
333 public void addButton(String l, String c) {
334 Knob b = new Knob(l);
335 b.setActionCommand(c);
336 b.addActionListener(this);
337 bpn.add(b);
338 }
339
340 /**
341 * Add a dialog button to this box. Label = action command
342 *
343 * @param l the label and action command
344 */
345 public void addButton(String l) {
346 addButton(l, l);
347 }
348
349 /**
350 * Add a dialog buttons to this box. Label = action command
351 *
352 * @param l comma separated list of labels and action commands
353 */
354 public void addButtons(String l) {
355 if(l != null) {
356 for(StringSplitter sp = new StringSplitter(l, ","); sp.hasMoreTokens(); ) {
357 addButton(sp.nextToken());
358 }
359 }
360 }
361
362 /**
363 * Get the button object for a specific dialog button.
364 * The index depends on the order the buttons were added.
365 *
366 * @param i which button ?
367 */
368 public Knob getButton(int i) {
369 if(i < bpn.getComponentCount()) {
370 return (Knob) bpn.getComponent(i);
371 } else {
372 return null;
373 }
374 }
375
376 /**
377 * Utility method to en-/disable a dialog button.
378 *
379 * @param i which button ?
380 * @param e active ?
381 */
382 public void setButtonEnabled(int i, boolean e) {
383 if(i < bpn.getComponentCount()) {
384 getButton(i).setEnabled(e);
385 }
386 }
387
388 /**
389 * Utility method to change the action string for a dialog button.
390 *
391 * @param i which button ?
392 * @param a new action
393 */
394 public void setButtonAction(int i, String a) {
395 if(i < bpn.getComponentCount()) {
396 getButton(i).setActionCommand(a);
397 }
398 }
399
400 /**
401 * Implement the Action listener interface.
402 * Dispose this dialog depending on closeWindowCommand.
403 */
404 public void actionPerformed(ActionEvent e) {
405 notifyActionListeners(e);
406 if(cwc == null ||
407 cwc.equals(e.getActionCommand())) {
408 ret = e.getActionCommand();
409 dia.setVisible(false);
410 }
411 }
412
413 /**
414 * Implement the Window listener interface.
415 * Dispose this dialog depending on event and closeWindowCommand.
416 */
417 public void windowClosing(WindowEvent e) {
418 dia.setVisible(false);
419 }
420
421 /**
422 * Implement the Window listener interface.
423 * Dispose this dialog depending on event and closeWindowCommand.
424 */
425 public void windowIconified(WindowEvent e) {
426 dia.setVisible(false);
427 }
428
429 /**
430 * Implement the Window listener interface.
431 */
432 public void windowDeiconified(WindowEvent e) {
433 }
434
435 /**
436 * Implement the Window listener interface.
437 */
438 public void windowOpened(WindowEvent e) {
439 }
440
441 /**
442 * Implement the Window listener interface.
443 */
444 public void windowActivated(WindowEvent e) {
445 }
446
447 /**
448 * Implement the Window listener interface.
449 */
450 public void windowDeactivated(WindowEvent e) {
451 }
452
453 /**
454 * Implement the Window listener interface.
455 */
456 public void windowClosed(WindowEvent e) {
457 }
458
459 /**
460 * Shows this dialog. Block if dialog is modal.
461 */
462 public Object show() {
463 return show(frm, false);
464 }
465
466 /**
467 * Shows this dialog. Block if dialog is modal.
468 *
469 * @param bep seems handy for error dialogs.
470 */
471 public Object show(boolean bep) {
472 return show(frm, bep);
473 }
474
475 /**
476 * Shows this dialog. Block if dialog is modal.
477 *
478 * @param p use this components parent frame.
479 */
480 public Object show(Component p) {
481 return show(p, false);
482 }
483
484 /**
485 * Shows this dialog. Block if dialog is modal.
486 *
487 * @param parent use this components parent frame.
488 * @param beep seems handy for error dialogs.
489 */
490 public Object show(Component p, boolean bep) {
491 if(pan == null) {
492 return null;
493 }
494 if(p == null) {
495 p = frm;
496 }
497 if(bep == true) {
498 Toolkit.getDefaultToolkit().beep();
499 }
500 setParent(p);
501 if(dia == null) {
502 dia = new Dialog(frm);
503 dia.setLayout(new BorderLayout());
504 dia.addWindowListener(this);
505 dia.setFont(p.getFont());
506 dia.setBackground(p.getBackground());
507 dia.setForeground(p.getForeground());
508 if(bpn instanceof Awt) ((Awt) bpn).setBGIfNull(p);
509 if(pan instanceof Awt) ((Awt) pan).setBGIfNull(p);
510 } else if(dia.isShowing()) {
511 return null;
512 }
513 ret = "";
514 dia.setModal(mod);
515 dia.setTitle(tit);
516 dia.setResizable(res);
517 dia.requestFocus();
518 pack();
519 dia.setVisible(true);
520 return ret;
521 }
522
523 /**
524 * Make it nice looking
525 */
526 public void pack() {
527 dia.removeAll();
528 dia.add(BorderLayout.CENTER, pan);
529 dia.add(BorderLayout.SOUTH, bpn);
530 dia.pack();
531 Awt.centerWindow(dia);
532 }
533
534 /**
535 * Destroys this dialog
536 *
537 * @param retCode return this to the calling method
538 */
539 public void dispose(Object retCode) {
540 if(dia == null) {
541 return;
542 }
543 ret = retCode;
544 dia.setVisible(false);
545 }
546
547 /**
548 * Static utility method to create a standard Dialog with optional image
549 *
550 * @param tit title string
551 * @param msg message to show
552 * @param but comma separated list of dialog buttons
553 * @param img optional image to show on left hand side
554 */
555 public static DialogBox standardDialog(String tit, String msg, String but, Image img) {
556 final DialogBox dia = new DialogBox(new BorderPanel(BorderPanel.RAISED), tit, but);
557 dia.getPanel().setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
558 if(img != null) {
559 dia.getPanel().add(new ImageCanvas(img));
560 }
561 if(msg != null) {
562 dia.getPanel().add(new Caption(msg));
563 }
564 return dia;
565 }
566
567 /**
568 * Static utility method to create a standard error dialog
569 *
570 * @param obj the object to show in the error dialog
571 */
572 public static DialogBox errorDialog(String msg) {
573 return standardDialog(ERR, msg, OK, Err);
574 }
575
576 /**
577 * Static utility method to create a standard warning dialog.
578 *
579 * @param msg the warning message
580 */
581 public static DialogBox warnDialog(String msg) {
582 return standardDialog(WRN, msg, OK, Wrn);
583 }
584
585 /**
586 * Static utility method to create a standard info dialog.
587 *
588 * @param msg the info message
589 */
590 public static DialogBox infoDialog(String msg) {
591 return standardDialog(INF, msg, OK, Inf);
592 }
593
594 /**
595 * Static utility method to create a standard busy dialog.
596 *
597 * @param msg the info message
598 */
599 public static DialogBox busyDialog(String msg) {
600 return standardDialog(INF, msg, CANCEL, Bsy);
601 }
602 };