001: /*
002: * WbSwingUtilities.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui;
013:
014: import java.awt.Color;
015: import java.awt.Component;
016: import java.awt.Cursor;
017: import java.awt.Dimension;
018: import java.awt.EventQueue;
019: import java.awt.Font;
020: import java.awt.FontMetrics;
021: import java.awt.Insets;
022: import java.awt.Point;
023: import java.awt.Toolkit;
024: import java.awt.Window;
025: import java.awt.event.KeyEvent;
026: import java.awt.event.WindowAdapter;
027: import java.awt.event.WindowEvent;
028: import javax.swing.JComponent;
029: import javax.swing.JDialog;
030: import javax.swing.JOptionPane;
031: import javax.swing.JPasswordField;
032: import javax.swing.JTextField;
033: import javax.swing.KeyStroke;
034: import javax.swing.SwingUtilities;
035: import javax.swing.border.BevelBorder;
036: import javax.swing.border.Border;
037: import javax.swing.border.CompoundBorder;
038: import javax.swing.border.EmptyBorder;
039: import javax.swing.border.EtchedBorder;
040: import javax.swing.border.LineBorder;
041: import workbench.WbManager;
042: import workbench.db.WbConnection;
043: import workbench.gui.components.TextComponentMouseListener;
044: import workbench.gui.components.ValidatingDialog;
045: import workbench.interfaces.SimplePropertyEditor;
046: import workbench.log.LogMgr;
047: import workbench.resource.ResourceMgr;
048: import workbench.util.StringUtil;
049:
050: /**
051: * Some helper functions to deal with Swing stuff
052: */
053: public class WbSwingUtilities {
054: public static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
055: public static final LineBorder FOCUSED_CELL_BORDER = new LineBorder(
056: Color.YELLOW);
057: public static final Border EMPTY_BORDER = new EmptyBorder(0, 0, 0,
058: 0);
059: public static final Border FLAT_BUTTON_BORDER = new CompoundBorder(
060: new EtchedBorder(), new EmptyBorder(1, 6, 1, 6));
061:
062: public static final KeyStroke CTRL_TAB = KeyStroke
063: .getKeyStroke("control TAB");
064: public static final KeyStroke TAB = KeyStroke.getKeyStroke("TAB");
065: public static final KeyStroke ENTER = KeyStroke
066: .getKeyStroke("ENTER");
067: public static final KeyStroke CTRL_ENTER = KeyStroke
068: .getKeyStroke("control ENTER");
069: public static final KeyStroke ALT_ENTER = KeyStroke
070: .getKeyStroke("alt ENTER");
071:
072: public static Border getBevelBorder() {
073: BevelBorder b = new BevelBorder(BevelBorder.LOWERED);
074: Color c = Color.LIGHT_GRAY;
075: return new BevelBorder(BevelBorder.LOWERED, b
076: .getHighlightOuterColor(), c, b
077: .getHighlightInnerColor(), b.getShadowInnerColor());
078:
079: }
080:
081: public static Border getBevelBorderRaised() {
082: BevelBorder b = new BevelBorder(BevelBorder.LOWERED);
083: Color c = Color.LIGHT_GRAY;
084: return new BevelBorder(BevelBorder.RAISED, b
085: .getHighlightOuterColor(), c, b
086: .getHighlightInnerColor(), b.getShadowInnerColor());
087: }
088:
089: public static final void waitForEmptyQueue() {
090: if (EventQueue.isDispatchThread())
091: return;
092:
093: EventQueue queue = Toolkit.getDefaultToolkit()
094: .getSystemEventQueue();
095: int counter = 0;
096: while (queue.peekEvent() != null) {
097: try {
098: Thread.sleep(25);
099: } catch (Throwable th) {
100: }
101: counter++;
102: if (counter > 20) {
103: break;
104: }
105: }
106: }
107:
108: /**
109: * Synchronously execute code on the EDT.
110: * If the current thread is the EDT, this merely calls r.run()
111: * otherwise EventQueue.invokeAndWait() is called with the passed runnable.
112: *
113: * Exceptions that can be thrown by EventQueue.invokeAndWait() are
114: * caught and logged.
115: */
116: public static final void invoke(Runnable r) {
117: if (EventQueue.isDispatchThread()) {
118: r.run();
119: } else {
120: try {
121: EventQueue.invokeAndWait(r);
122: } catch (Exception e) {
123: LogMgr.logError("WbSwingUtilities.invoke()",
124: "Error executing on EventQueue", e);
125: }
126: }
127: }
128:
129: /**
130: * Centers the given window either agains anotherone on the screen
131: * If a second window is passed the first window is centered
132: * against that one
133: *
134: * @param aWinToCenter the window to be centered
135: * @param aReference center against this window. If null -> center on screen
136: */
137: public static void center(Window aWinToCenter, Component aReference) {
138: Point location = getLocationToCenter(aWinToCenter, aReference);
139: aWinToCenter.setLocation(location);
140: }
141:
142: public static Window getWindowAncestor(Component caller) {
143: if (caller instanceof Window) {
144: return (Window) caller;
145: }
146: return SwingUtilities.getWindowAncestor(caller);
147: }
148:
149: public static Point getLocationToCenter(Window aWinToCenter,
150: Component aReference) {
151: int screenWidth, screenHeight;
152: if (aReference == null) {
153: Dimension screen = Toolkit.getDefaultToolkit()
154: .getScreenSize();
155: screenWidth = (int) screen.getWidth();
156: screenHeight = (int) screen.getHeight();
157: } else {
158: screenWidth = aReference.getWidth();
159: screenHeight = aReference.getHeight();
160: }
161: int winWidth, winHeight;
162: if (aWinToCenter == null) {
163: winWidth = 0;
164: winHeight = 0;
165: } else {
166: winWidth = aWinToCenter.getWidth();
167: winHeight = aWinToCenter.getHeight();
168: }
169:
170: int x = 1, y = 1;
171:
172: // Get center points
173: if (screenWidth > winWidth) {
174: x = ((screenWidth / 2) - (winWidth / 2));
175: }
176: if (screenHeight > winHeight) {
177: y = ((screenHeight / 2) - (winHeight / 2));
178: }
179:
180: if (aReference != null && aReference.isVisible()) {
181: try {
182: Point p = aReference.getLocationOnScreen();
183: x += p.getX();
184: y += p.getY();
185: } catch (Exception e) {
186: LogMgr.logWarning(
187: "WbSwingUtilities.getLocationToCenter()",
188: "Error getting parent location!", e);
189: }
190: }
191:
192: return new Point(x, y);
193: }
194:
195: public static void showWaitCursorOnWindow(Component caller) {
196: showCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR),
197: caller, true, false);
198: }
199:
200: public static void showDefaultCursorOnWindow(Component caller) {
201: showDefaultCursor(caller, true);
202: }
203:
204: public static void showWaitCursor(final Component caller) {
205: showCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR),
206: caller, false, true);
207: }
208:
209: public static void showDefaultCursor(final Component caller) {
210: showDefaultCursor(caller, false);
211: }
212:
213: public static void showDefaultCursor(final Component caller,
214: final boolean includeParents) {
215: showCursor(null, caller, includeParents, true);
216: }
217:
218: private static void showCursor(final Cursor cursor,
219: final Component caller, final boolean includeParents,
220: boolean immediate) {
221: if (caller == null)
222: return;
223: Runnable r = new Runnable() {
224: public void run() {
225: caller.setCursor(cursor);
226: if (includeParents) {
227: final Window w = SwingUtilities
228: .getWindowAncestor(caller);
229: if (w != null)
230: w.setCursor(cursor);
231: }
232: }
233: };
234:
235: if (EventQueue.isDispatchThread()) {
236: r.run();
237: } else {
238: if (immediate) {
239: try {
240: EventQueue.invokeAndWait(r);
241: } catch (Throwable th) {
242: }
243: } else {
244: EventQueue.invokeLater(r);
245: }
246: }
247: }
248:
249: public static void showErrorMessageKey(Component aCaller, String key) {
250: showErrorMessage(aCaller, ResourceMgr.TXT_PRODUCT_NAME,
251: ResourceMgr.getString(key));
252: }
253:
254: public static void showErrorMessage(String aMessage) {
255: showErrorMessage(null, ResourceMgr.TXT_PRODUCT_NAME, aMessage);
256: }
257:
258: public static void showErrorMessage(Component aCaller,
259: String aMessage) {
260: showErrorMessage(aCaller, ResourceMgr.TXT_PRODUCT_NAME,
261: aMessage);
262: }
263:
264: public static void showErrorMessage(Component aCaller,
265: String title, String aMessage) {
266: if (WbManager.getInstance().isBatchMode())
267: return;
268: if (aCaller == null) {
269: aCaller = WbManager.getInstance().getCurrentWindow();
270: } else if (!(aCaller instanceof Window)) {
271: aCaller = SwingUtilities.getWindowAncestor(aCaller);
272: }
273: JOptionPane.showMessageDialog(aCaller, aMessage, title,
274: JOptionPane.ERROR_MESSAGE);
275: }
276:
277: public static void showMessage(Component aCaller, Object aMessage) {
278: JOptionPane.showMessageDialog(aCaller, aMessage,
279: ResourceMgr.TXT_PRODUCT_NAME,
280: JOptionPane.INFORMATION_MESSAGE);
281: }
282:
283: public static void showMessage(Component aCaller, String title,
284: Object aMessage) {
285: JOptionPane.showMessageDialog(aCaller, aMessage, title,
286: JOptionPane.PLAIN_MESSAGE);
287: }
288:
289: public static void showMessageKey(Component aCaller, String aKey) {
290: JOptionPane.showMessageDialog(aCaller, ResourceMgr
291: .getString(aKey), ResourceMgr.TXT_PRODUCT_NAME,
292: JOptionPane.INFORMATION_MESSAGE);
293: }
294:
295: public static boolean getYesNo(Component aCaller, String aMessage) {
296: int result = JOptionPane
297: .showConfirmDialog(SwingUtilities
298: .getWindowAncestor(aCaller), aMessage,
299: ResourceMgr.TXT_PRODUCT_NAME,
300: JOptionPane.YES_NO_OPTION,
301: JOptionPane.QUESTION_MESSAGE);
302: return (result == JOptionPane.YES_OPTION);
303: }
304:
305: public static int getYesNoCancel(Component aCaller, String aMessage) {
306: int result = JOptionPane.showConfirmDialog(SwingUtilities
307: .getWindowAncestor(aCaller), aMessage,
308: ResourceMgr.TXT_PRODUCT_NAME,
309: JOptionPane.YES_NO_CANCEL_OPTION,
310: JOptionPane.QUESTION_MESSAGE);
311: return result;
312: }
313:
314: public static final int IGNORE_ALL = JOptionPane.YES_OPTION
315: + JOptionPane.NO_OPTION + JOptionPane.CANCEL_OPTION + 1;
316: public static final int EXECUTE_ALL = JOptionPane.YES_OPTION
317: + JOptionPane.NO_OPTION + JOptionPane.CANCEL_OPTION + 2;
318:
319: public static int getYesNoIgnoreAll(Component aCaller,
320: String aMessage) {
321: String[] options = new String[] {
322: ResourceMgr.getString("LblYes"),
323: ResourceMgr.getString("LblNo"),
324: ResourceMgr.getString("LblIgnoreAll") };
325: JOptionPane ignorePane = new JOptionPane(aMessage,
326: JOptionPane.QUESTION_MESSAGE,
327: JOptionPane.YES_NO_CANCEL_OPTION, null, options);
328: JDialog dialog = ignorePane.createDialog(SwingUtilities
329: .getWindowAncestor(aCaller),
330: ResourceMgr.TXT_PRODUCT_NAME);
331: dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
332: int rvalue = -1;
333: try {
334: dialog.setResizable(true);
335: dialog.pack();
336: dialog.setVisible(true);
337: Object result = ignorePane.getValue();
338: if (result == null)
339: rvalue = JOptionPane.YES_OPTION;
340: else if (result.equals(options[0]))
341: rvalue = JOptionPane.YES_OPTION;
342: else if (result.equals(options[1]))
343: rvalue = JOptionPane.NO_OPTION;
344: else if (result.equals(options[2]))
345: rvalue = IGNORE_ALL;
346: else
347: rvalue = JOptionPane.NO_OPTION;
348: } finally {
349: dialog.dispose();
350: dialog = null;
351: }
352: return rvalue;
353: }
354:
355: public static int getYesNoExecuteAll(Component aCaller,
356: String aMessage) {
357: String[] options = new String[] {
358: ResourceMgr.getString("LblYes"),
359: ResourceMgr.getString("LblExecuteAll"),
360: ResourceMgr.getString("LblNo"),
361: ResourceMgr.getString("ButtonLabelCancel") };
362: JOptionPane ignorePane = new JOptionPane(aMessage,
363: JOptionPane.QUESTION_MESSAGE,
364: JOptionPane.YES_NO_CANCEL_OPTION, null, options);
365: JDialog dialog = ignorePane.createDialog(aCaller,
366: ResourceMgr.TXT_PRODUCT_NAME);
367: try {
368: dialog.setResizable(true);
369: dialog.pack();
370: dialog.setVisible(true);
371: Object result = ignorePane.getValue();
372: if (result == null)
373: return JOptionPane.YES_OPTION;
374: else if (result.equals(options[0]))
375: return JOptionPane.YES_OPTION;
376: else if (result.equals(options[1]))
377: return EXECUTE_ALL;
378: else if (result.equals(options[2]))
379: return JOptionPane.NO_OPTION;
380: else if (result.equals(options[3]))
381: return JOptionPane.CANCEL_OPTION;
382: else
383: return JOptionPane.NO_OPTION;
384: } finally {
385: dialog.dispose();
386: }
387: }
388:
389: public static int getYesNo(Component aCaller, String aMessage,
390: String[] options) {
391: return getYesNo(aCaller, aMessage, options,
392: JOptionPane.PLAIN_MESSAGE);
393: }
394:
395: public static int getYesNo(Component aCaller, String aMessage,
396: String[] options, int type) {
397: JOptionPane ignorePane = new JOptionPane(aMessage,
398: JOptionPane.QUESTION_MESSAGE,
399: JOptionPane.YES_NO_OPTION, null, options, options[1]);
400: ignorePane.setMessageType(type);
401: JDialog dialog = ignorePane.createDialog(aCaller,
402: ResourceMgr.TXT_PRODUCT_NAME);
403: try {
404: dialog.setResizable(true);
405: dialog.pack();
406: dialog.setVisible(true);
407: Object result = ignorePane.getValue();
408: if (result == null)
409: return JOptionPane.YES_OPTION;
410: else if (result.equals(options[0]))
411: return 0;
412: else if (result.equals(options[1]))
413: return 1;
414: else
415: return -1;
416: } finally {
417: dialog.dispose();
418: }
419: }
420:
421: public static boolean getOKCancel(String title, Component aCaller,
422: Component message) {
423: return getOKCancel(title, aCaller, message, null);
424: }
425:
426: public static boolean getOKCancel(String title, Component aCaller,
427: Component message, final Runnable doLater) {
428: JOptionPane pane = new JOptionPane(message,
429: JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
430: JDialog dialog = pane.createDialog(aCaller, title);
431: dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
432: if (doLater != null) {
433: WindowAdapter w = new WindowAdapter() {
434: public void windowOpened(WindowEvent evt) {
435: EventQueue.invokeLater(doLater);
436: }
437: };
438: dialog.addWindowListener(w);
439: }
440:
441: dialog.setResizable(true);
442: dialog.pack();
443: dialog.setVisible(true);
444: dialog.dispose();
445: Object value = pane.getValue();
446: if (value == null)
447: return false;
448: if (value instanceof Number) {
449: int choice = ((Number) value).intValue();
450: return choice == 0;
451: }
452: return false;
453: }
454:
455: public static final int DO_COMMIT = 0;
456: public static final int DO_ROLLBACK = 1;
457:
458: public static int getCommitRollbackQuestion(Component aCaller,
459: String aMessage) {
460: String[] options = new String[] {
461: ResourceMgr.getString("LblCommit"),
462: ResourceMgr.getString("LblRollback") };
463: JOptionPane ignorePane = new JOptionPane(aMessage,
464: JOptionPane.QUESTION_MESSAGE,
465: JOptionPane.YES_NO_OPTION, null, options);
466: int w = 0;
467: try {
468: Font f = ignorePane.getFont();
469: FontMetrics fm = ignorePane.getFontMetrics(f);
470: w = fm.stringWidth(aMessage);
471: } catch (Throwable th) {
472: th.printStackTrace();
473: w = 300;
474: }
475: JDialog dialog = ignorePane.createDialog(aCaller,
476: ResourceMgr.TXT_PRODUCT_NAME);
477: dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
478: dialog.setSize(w + 130, dialog.getHeight());
479: dialog.setResizable(true);
480: dialog.setVisible(true);
481: dialog.dispose();
482: Object result = ignorePane.getValue();
483: if (result == null)
484: return DO_ROLLBACK;
485: else if (result.equals(options[0]))
486: return DO_COMMIT;
487: else if (result.equals(options[1]))
488: return DO_ROLLBACK;
489: else
490: return DO_ROLLBACK;
491: }
492:
493: public static String getUserInput(Component caller, String aTitle,
494: String initialValue) {
495: return getUserInput(caller, aTitle, initialValue, false);
496: }
497:
498: public static String getUserInput(Component caller, String aTitle,
499: String initialValue, boolean hideInput) {
500: Window parent = SwingUtilities.getWindowAncestor(caller);
501:
502: final JTextField input;
503: if (hideInput)
504: input = new JPasswordField();
505: else
506: input = new JTextField();
507:
508: input.setColumns(40);
509: input.setText(initialValue);
510: if (initialValue != null) {
511: input.selectAll();
512: }
513: input.addMouseListener(new TextComponentMouseListener());
514: EventQueue.invokeLater(new Runnable() {
515: public void run() {
516: input.grabFocus();
517: }
518: });
519:
520: boolean ok = ValidatingDialog.showConfirmDialog(parent, input,
521: aTitle);
522: if (!ok)
523: return null;
524:
525: String value = input.getText();
526: return value;
527: }
528:
529: public static String getKeyName(int keyCode) {
530: if (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_9
531: || keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z) {
532: return String.valueOf((char) keyCode);
533: }
534:
535: // Check for other ASCII keyCodes.
536: int index = ",./;=[\\]".indexOf(keyCode);
537: if (index >= 0) {
538: return String.valueOf((char) keyCode);
539: }
540:
541: switch (keyCode) {
542: case KeyEvent.VK_ENTER:
543: return "VK_ENTER";
544: case KeyEvent.VK_BACK_SPACE:
545: return "VK_BACK_SPACE";
546: case KeyEvent.VK_TAB:
547: return "VK_TAB";
548: case KeyEvent.VK_CANCEL:
549: return "VK_CANCEL";
550: case KeyEvent.VK_CLEAR:
551: return "VK_CLEAR";
552: case KeyEvent.VK_SHIFT:
553: return "VK_SHIFT";
554: case KeyEvent.VK_CONTROL:
555: return "VK_CONTROL";
556: case KeyEvent.VK_ALT:
557: return "VK_ALT";
558: case KeyEvent.VK_PAUSE:
559: return "VK_PAUSE";
560: case KeyEvent.VK_CAPS_LOCK:
561: return "VK_CAPS_LOCK";
562: case KeyEvent.VK_ESCAPE:
563: return "VK_ESCAPE";
564: case KeyEvent.VK_SPACE:
565: return "VK_SPACE";
566: case KeyEvent.VK_PAGE_UP:
567: return "VK_PAGE_UP";
568: case KeyEvent.VK_PAGE_DOWN:
569: return "VK_PAGE_UP";
570: case KeyEvent.VK_END:
571: return "VK_END";
572: case KeyEvent.VK_HOME:
573: return "VK_HOME";
574:
575: case KeyEvent.VK_LEFT:
576: case KeyEvent.VK_KP_LEFT:
577: return "VK_LEFT";
578:
579: case KeyEvent.VK_UP:
580: case KeyEvent.VK_KP_UP:
581: return "VK_UP";
582:
583: case KeyEvent.VK_RIGHT:
584: case KeyEvent.VK_KP_RIGHT:
585: return "VK_RIGHT";
586:
587: case KeyEvent.VK_DOWN:
588: case KeyEvent.VK_KP_DOWN:
589: return "VK_DOWN";
590: case KeyEvent.VK_F1:
591: return "F1";
592: case KeyEvent.VK_F2:
593: return "F2";
594: case KeyEvent.VK_F3:
595: return "F3";
596: case KeyEvent.VK_F4:
597: return "F4";
598: case KeyEvent.VK_F5:
599: return "F5";
600: case KeyEvent.VK_F6:
601: return "F6";
602: case KeyEvent.VK_F7:
603: return "F7";
604: case KeyEvent.VK_F8:
605: return "F8";
606: case KeyEvent.VK_F9:
607: return "F9";
608: case KeyEvent.VK_F10:
609: return "F10";
610: case KeyEvent.VK_F11:
611: return "F11";
612: case KeyEvent.VK_F12:
613: return "F12";
614: case KeyEvent.VK_F13:
615: return "F13";
616: case KeyEvent.VK_F14:
617: return "F14";
618: case KeyEvent.VK_F15:
619: return "F15";
620: case KeyEvent.VK_F16:
621: return "F16";
622: case KeyEvent.VK_F17:
623: return "F17";
624: case KeyEvent.VK_F18:
625: return "F18";
626: case KeyEvent.VK_F19:
627: return "F19";
628: case KeyEvent.VK_F20:
629: return "F20";
630: case KeyEvent.VK_F21:
631: return "F21";
632: case KeyEvent.VK_F22:
633: return "F22";
634: case KeyEvent.VK_F23:
635: return "F23";
636: case KeyEvent.VK_F24:
637: return "F24";
638: }
639: if (keyCode >= KeyEvent.VK_NUMPAD0
640: && keyCode <= KeyEvent.VK_NUMPAD9) {
641: String numpad = "NumPad";
642: char c = (char) (keyCode - KeyEvent.VK_NUMPAD0 + '0');
643: return numpad + "-" + c;
644: }
645: return "KeyCode: 0x" + Integer.toString(keyCode, 16);
646: }
647:
648: public static void callRepaint(final Component c) {
649: c.validate();
650: c.repaint();
651: }
652:
653: public static void repaintNow(final Component c) {
654: invoke(new Runnable() {
655: public void run() {
656: callRepaint(c);
657: }
658: });
659: }
660:
661: public static void repaintLater(final Component c) {
662: EventQueue.invokeLater(new Runnable() {
663: public void run() {
664: callRepaint(c);
665: }
666: });
667: }
668:
669: public static void requestFocus(final Window win,
670: final JComponent comp) {
671: win.addWindowListener(new WindowAdapter() {
672: public void windowActivated(WindowEvent evt) {
673: EventQueue.invokeLater(new Runnable() {
674: public void run() {
675: comp.requestFocus();
676: }
677: });
678: win.removeWindowListener(this );
679: }
680: });
681: }
682:
683: public static void requestFocus(final JComponent comp) {
684: EventQueue.invokeLater(new Runnable() {
685: public void run() {
686: comp.requestFocus();
687: }
688: });
689: }
690:
691: public static void initPropertyEditors(Object bean, JComponent root) {
692: for (int i = 0; i < root.getComponentCount(); i++) {
693: Component c = root.getComponent(i);
694: if (c instanceof SimplePropertyEditor) {
695: SimplePropertyEditor editor = (SimplePropertyEditor) c;
696: String property = c.getName();
697: if (!StringUtil.isEmptyString(property)) {
698: editor.setSourceObject(bean, property);
699: editor.setImmediateUpdate(true);
700: }
701: } else if (c instanceof JComponent) {
702: initPropertyEditors(bean, (JComponent) c);
703: }
704: }
705: }
706:
707: public static boolean checkConnection(Component parent,
708: WbConnection dbConnection) {
709: if (dbConnection.isBusy()) {
710: showMessageKey(parent, "ErrConnectionBusy");
711: return false;
712: }
713: return true;
714: }
715:
716: }
|