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 };