001: /*
002: * TableDataPanel.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.dbobjects;
013:
014: import java.awt.BorderLayout;
015: import java.awt.Dimension;
016: import java.awt.Font;
017: import java.awt.Image;
018: import java.awt.Window;
019: import java.awt.event.ActionEvent;
020: import java.awt.event.ActionListener;
021: import java.beans.PropertyChangeEvent;
022: import java.sql.ResultSet;
023: import java.sql.SQLException;
024: import java.sql.Statement;
025: import java.util.List;
026: import javax.swing.Box;
027: import javax.swing.BoxLayout;
028: import javax.swing.ImageIcon;
029: import javax.swing.JButton;
030: import javax.swing.JCheckBox;
031: import javax.swing.JLabel;
032: import javax.swing.JOptionPane;
033: import javax.swing.JPanel;
034: import javax.swing.SwingConstants;
035: import javax.swing.SwingUtilities;
036: import workbench.db.TableIdentifier;
037: import workbench.db.WbConnection;
038: import workbench.gui.actions.SelectionFilterAction;
039: import workbench.gui.components.FlatButton;
040: import workbench.interfaces.PropertyStorage;
041: import workbench.interfaces.Resettable;
042: import workbench.util.ExceptionUtil;
043: import workbench.gui.WbSwingUtilities;
044: import workbench.gui.actions.ReloadAction;
045: import workbench.gui.actions.StopAction;
046: import workbench.gui.components.WbButton;
047: import workbench.gui.components.WbToolbar;
048: import workbench.gui.sql.DwPanel;
049: import workbench.interfaces.Interruptable;
050: import workbench.interfaces.Reloadable;
051: import workbench.interfaces.TableDeleteListener;
052: import workbench.log.LogMgr;
053: import workbench.resource.ResourceMgr;
054: import workbench.resource.Settings;
055: import workbench.util.SqlUtil;
056: import workbench.util.WbThread;
057: import workbench.interfaces.JobErrorHandler;
058: import java.awt.Cursor;
059: import java.awt.EventQueue;
060: import java.beans.PropertyChangeListener;
061: import java.sql.Savepoint;
062: import java.util.ArrayList;
063: import java.util.Collections;
064: import workbench.gui.MainWindow;
065: import workbench.gui.actions.FilterPickerAction;
066: import workbench.interfaces.DbExecutionListener;
067: import workbench.interfaces.DbExecutionNotifier;
068: import workbench.storage.NamedSortDefinition;
069: import workbench.util.WbWorkspace;
070:
071: /**
072: *
073: * @author support@sql-workbench.net
074: *
075: */
076: public class TableDataPanel extends JPanel implements ActionListener,
077: PropertyChangeListener, Reloadable, Interruptable,
078: TableDeleteListener, Resettable, DbExecutionNotifier {
079: private WbConnection dbConnection;
080: protected DwPanel dataDisplay;
081:
082: private ReloadAction reloadAction;
083:
084: private JButton config;
085: private JLabel tableNameLabel;
086: private JLabel rowCountLabel;
087: private WbButton rowCountButton;
088: private JCheckBox autoRetrieve;
089: private JPanel topPanel;
090:
091: private int warningThreshold = -1;
092: private boolean retrieveRunning = false;
093: private boolean updateRunning = false;
094: private boolean autoloadRowCount = true;
095: private TableIdentifier table;
096: private ImageIcon loadingIcon;
097: private Image loadingImage;
098: protected StopAction cancelRetrieve;
099: private List<DbExecutionListener> execListener;
100: private Savepoint currentSavepoint;
101: private Statement rowCountRetrieveStmt = null;
102: private boolean rememberSort;
103: private NamedSortDefinition lastSort;
104:
105: public TableDataPanel() throws Exception {
106: this .setBorder(WbSwingUtilities.EMPTY_BORDER);
107: this .setLayout(new BorderLayout());
108:
109: this .dataDisplay = new DwPanel() {
110: public synchronized int saveChanges(
111: WbConnection aConnection,
112: JobErrorHandler errorHandler) throws SQLException {
113: int result = -1;
114: try {
115: dbUpdateStart();
116: result = super .saveChanges(aConnection,
117: errorHandler);
118: } finally {
119: dbUpdateEnd();
120: }
121: return result;
122: }
123: };
124:
125: this .dataDisplay.setManageUpdateAction(true);
126: this .dataDisplay.setShowLoadProcess(true);
127: this .dataDisplay.setDefaultStatusMessage("");
128:
129: topPanel = new JPanel();
130: topPanel.setMaximumSize(new Dimension(32768, 32768));
131: BoxLayout box = new BoxLayout(topPanel, BoxLayout.X_AXIS);
132: topPanel.setLayout(box);
133:
134: this .reloadAction = new ReloadAction(this );
135: this .reloadAction.setTooltip(ResourceMgr.getDescription(
136: "TxtLoadTableData", true));
137: this .reloadAction.addToInputMap(this .dataDisplay.getTable());
138:
139: WbToolbar mytoolbar = new WbToolbar();
140: mytoolbar.addDefaultBorder();
141: topPanel.add(mytoolbar);
142: mytoolbar.add(this .reloadAction);
143: mytoolbar.addSeparator();
144:
145: this .cancelRetrieve = new StopAction(this );
146: this .cancelRetrieve.setEnabled(false);
147: mytoolbar.add(this .cancelRetrieve);
148: mytoolbar.addSeparator();
149:
150: topPanel.add(Box.createHorizontalStrut(15));
151: JLabel l = new JLabel(ResourceMgr.getString("LblTable") + ":");
152: topPanel.add(l);
153: Font std = l.getFont();
154: Font bold = std.deriveFont(Font.BOLD);
155: tableNameLabel = new JLabel();
156: tableNameLabel.setFont(bold);
157: topPanel.add(Box.createHorizontalStrut(5));
158: topPanel.add(tableNameLabel);
159:
160: topPanel.add(Box.createHorizontalStrut(10));
161: rowCountButton = new WbButton();
162: rowCountButton.setResourceKey("LblTableDataRowCount");
163: rowCountButton.enableBasicRollover();
164: rowCountButton.addActionListener(this );
165: rowCountButton.setToolTipText(ResourceMgr
166: .getDescription("LblTableDataRowCountButton"));
167: rowCountButton.setFocusable(false);
168:
169: topPanel.add(rowCountButton);
170: topPanel.add(Box.createHorizontalStrut(5));
171: rowCountLabel = new JLabel();
172: rowCountLabel.setFont(bold);
173: rowCountLabel.setHorizontalTextPosition(SwingConstants.LEFT);
174: topPanel.add(rowCountLabel);
175: topPanel.add(Box.createHorizontalStrut(10));
176:
177: autoRetrieve = new JCheckBox(ResourceMgr
178: .getString("LblAutoLoad"));
179: autoRetrieve.setToolTipText(ResourceMgr
180: .getDescription("LblAutoLoadTableData"));
181: autoRetrieve.setHorizontalTextPosition(SwingConstants.LEFT);
182: topPanel.add(autoRetrieve);
183:
184: topPanel.add(Box.createHorizontalGlue());
185: this .config = new FlatButton(ResourceMgr
186: .getString("LblConfigureWarningThreshold"));
187: this .config.setToolTipText(ResourceMgr
188: .getDescription("LblConfigureWarningThreshold"));
189: this .config.addActionListener(this );
190: topPanel.add(this .config);
191:
192: this .add(topPanel, BorderLayout.NORTH);
193:
194: mytoolbar.add(this .dataDisplay.getUpdateDatabaseAction());
195: mytoolbar.add(this .dataDisplay.getSelectKeysAction());
196: mytoolbar.addSeparator();
197: mytoolbar.add(this .dataDisplay.getInsertRowAction());
198: mytoolbar.add(this .dataDisplay.getCopyRowAction());
199: mytoolbar.add(this .dataDisplay.getDeleteRowAction());
200: mytoolbar.addSeparator();
201: SelectionFilterAction a = new SelectionFilterAction();
202: a.setClient(this .dataDisplay.getTable());
203: mytoolbar.add(a);
204: mytoolbar.addSeparator();
205: mytoolbar.add(this .dataDisplay.getTable().getFilterAction());
206:
207: FilterPickerAction p = new FilterPickerAction(dataDisplay
208: .getTable());
209: mytoolbar.add(p);
210: mytoolbar.addSeparator();
211: mytoolbar.add(this .dataDisplay.getTable()
212: .getResetFilterAction());
213:
214: this .add(dataDisplay, BorderLayout.CENTER);
215: this .rememberSort = Settings.getInstance()
216: .getRememberSortInDbExplorer();
217: Settings.getInstance().addPropertyChangeListener(this ,
218: Settings.PROPERTY_DBEXP_REMEMBER_SORT);
219: }
220:
221: public void propertyChange(PropertyChangeEvent evt) {
222: this .rememberSort = Settings.getInstance()
223: .getRememberSortInDbExplorer();
224: }
225:
226: public void showFocusBorder() {
227: this .dataDisplay.getTable().showFocusBorder();
228: }
229:
230: public void setResultContainer(MainWindow container) {
231: if (this .dataDisplay != null && container != null) {
232: this .dataDisplay.initTableNavigation(container);
233: }
234: }
235:
236: private ImageIcon getLoadingIndicator() {
237: if (this .loadingIcon == null) {
238: this .loadingImage = ResourceMgr.getPicture("wait")
239: .getImage();
240: this .loadingIcon = new ImageIcon(this .loadingImage);
241: }
242: return this .loadingIcon;
243: }
244:
245: public void dispose() {
246: this .reset();
247: Settings.getInstance().removePropertyChangeListener(this );
248: }
249:
250: public void disconnect() {
251: this .dbConnection = null;
252: this .reset();
253: }
254:
255: public void reset() {
256: if (this .isRetrieving())
257: return;
258: if (this .rememberSort) {
259: // getCurrentSort() must be called before calling
260: // clearContent() as the sort definition is maintained
261: // in the TableModel and that is deleted when the data is cleared
262: this .lastSort = dataDisplay.getCurrentSort();
263: } else {
264: this .lastSort = null;
265: }
266: this .dataDisplay.clearContent();
267: this .rowCountLabel.setText(ResourceMgr
268: .getString("LblNotAvailable"));
269: this .clearLoadingImage();
270: }
271:
272: public void setConnection(WbConnection aConnection) {
273: this .dbConnection = aConnection;
274: try {
275: this .dataDisplay.setConnection(aConnection);
276: } catch (Throwable th) {
277: LogMgr.logError("TableDataPanel.setConnection()",
278: "Error when setting connection", th);
279: }
280: }
281:
282: private boolean rowCountCancel = false;
283:
284: private void startRetrieveRowCount() {
285: Thread t = null;
286: if (rowCountRetrieveStmt != null) {
287: t = new WbThread("RowCount cancel") {
288: public void run() {
289: cancelRowCountRetrieve();
290: }
291: };
292: } else {
293: t = new WbThread("RowCount Retrieve") {
294: public void run() {
295: showRowCount();
296: }
297: };
298: }
299: t.start();
300: }
301:
302: private void setSavepoint() {
303: if (dbConnection.getDbSettings().useSavePointForDML()
304: && !this .isOwnTransaction()) {
305: try {
306: this .currentSavepoint = this .dbConnection
307: .setSavepoint();
308: } catch (SQLException e) {
309: this .currentSavepoint = null;
310: }
311: }
312: }
313:
314: public long showRowCount() {
315: if (this .dbConnection == null)
316: return -1;
317: if (this .isRetrieving())
318: return -1;
319:
320: this .rowCountLabel.setText("");
321: this .rowCountLabel.setIcon(this .getLoadingIndicator());
322:
323: this .reloadAction.setEnabled(false);
324: this .dataDisplay.setStatusMessage(ResourceMgr
325: .getString("MsgCalculatingRowCount"));
326:
327: String sql = this .buildSqlForTable(true);
328: if (sql == null)
329: return -1;
330:
331: long rowCount = 0;
332: ResultSet rs = null;
333:
334: boolean error = false;
335:
336: try {
337: setSavepoint();
338: retrieveStart();
339: rowCountButton.setToolTipText(ResourceMgr
340: .getDescription("LblTableDataRowCountCancel"));
341:
342: rowCountRetrieveStmt = this .dbConnection
343: .createStatementForQuery();
344: rs = rowCountRetrieveStmt.executeQuery(sql);
345: if (rs.next()) {
346: rowCount = rs.getLong(1);
347: }
348: this .rowCountLabel.setText(Long.toString(rowCount));
349: this .rowCountLabel.setToolTipText(null);
350: } catch (Exception e) {
351: rowCount = -1;
352: error = true;
353: LogMgr.logError("TableDataPanel.showRowCount()",
354: "Error retrieving rowcount for "
355: + this .table.getTableExpression() + ": "
356: + ExceptionUtil.getDisplay(e), e);
357: if (rowCountCancel) {
358: this .rowCountLabel.setText(ResourceMgr
359: .getString("LblNotAvailable"));
360: this .rowCountLabel.setToolTipText(null);
361: } else {
362: this .rowCountLabel.setText(ResourceMgr
363: .getString("TxtError"));
364: this .rowCountLabel.setToolTipText(ExceptionUtil
365: .getDisplay(e));
366: }
367: String title = ResourceMgr.getString("TxtErrorRowCount");
368: WbSwingUtilities.showErrorMessage(SwingUtilities
369: .getWindowAncestor(this ), title, ExceptionUtil
370: .getDisplay(e));
371: } finally {
372: SqlUtil.closeAll(rs, rowCountRetrieveStmt);
373: this .rowCountCancel = false;
374: this .dataDisplay.setStatusMessage("");
375: this .clearLoadingImage();
376: this .reloadAction.setEnabled(true);
377: rowCountButton.setToolTipText(ResourceMgr
378: .getDescription("LblTableDataRowCountButton"));
379: if (error) {
380: rollbackIfNeeded();
381: } else {
382: commitRetrieveIfNeeded();
383: }
384: retrieveEnd();
385: rowCountRetrieveStmt = null;
386: }
387: return rowCount;
388: }
389:
390: protected void cancelRowCountRetrieve() {
391: if (this .rowCountRetrieveStmt != null) {
392: try {
393: this .dataDisplay.setStatusMessage(ResourceMgr
394: .getString("MsgCancelRowCount"));
395: this .rowCountCancel = true;
396: this .rowCountRetrieveStmt.cancel();
397: } catch (Throwable th) {
398: LogMgr.logError(
399: "TableDataPanel.cancelRowCountRetrieve()",
400: "Error when cancelling row count retrieve", th);
401: }
402: }
403: }
404:
405: /**
406: * Define the table for which the data should be displayed
407: */
408: public void setTable(TableIdentifier aTable) {
409: if (!this .isRetrieving())
410: reset();
411: this .table = aTable;
412: this .lastSort = null;
413: WbSwingUtilities.invoke(new Runnable() {
414: public void run() {
415: dataDisplay.getTable().clearLastFilter(true);
416: dataDisplay.getTable().resetFilter();
417: tableNameLabel.setText(table.getTableName());
418: }
419: });
420: }
421:
422: private String buildSqlForTable(boolean forRowCount) {
423: if (this .table == null)
424: return null;
425:
426: StringBuilder sql = new StringBuilder(100);
427: if (forRowCount)
428: sql.append("SELECT COUNT(*) FROM ");
429: else
430: sql.append("SELECT * FROM ");
431:
432: sql.append(this .table.getTableExpression(this .dbConnection));
433: String s = sql.toString();
434: return s;
435: }
436:
437: private void clearLoadingImage() {
438: if (this .loadingImage != null)
439: this .loadingImage.flush();
440: this .rowCountLabel.setIcon(null);
441: }
442:
443: public boolean confirmCancel() {
444: return true;
445: }
446:
447: /**
448: * Directly cancel the retrieval (in the same thread)
449: */
450: public void cancelRetrieve() {
451: dataDisplay.cancelExecution();
452: }
453:
454: /**
455: * Implementation of the Interruptable interface.
456: * This will kick off a Thread that cancels the retrieval.
457: */
458: public void cancelExecution() {
459: Thread t = new WbThread("Cancel thread") {
460: public void run() {
461: try {
462: dataDisplay.cancelExecution();
463: } finally {
464: cancelRetrieve.setEnabled(false);
465: WbSwingUtilities.showDefaultCursor(dataDisplay);
466: }
467: }
468: };
469: t.start();
470: }
471:
472: protected void retrieveStart() {
473: fireDbExecStart();
474: this .retrieveRunning = true;
475: }
476:
477: private void retrieveEnd() {
478: this .retrieveRunning = false;
479: fireDbExecEnd();
480: }
481:
482: protected void dbUpdateStart() {
483: this .reloadAction.setEnabled(false);
484: fireDbExecStart();
485: this .updateRunning = true;
486: }
487:
488: protected void dbUpdateEnd() {
489: try {
490: this .reloadAction.setEnabled(true);
491: } finally {
492: this .updateRunning = false;
493: fireDbExecEnd();
494: }
495: }
496:
497: public boolean isRetrieving() {
498: return this .retrieveRunning || this .updateRunning;
499: }
500:
501: private boolean isOwnTransaction() {
502: return (!this .dbConnection.getAutoCommit() && this .dbConnection
503: .getProfile().getUseSeparateConnectionPerTab());
504: }
505:
506: private void rollbackIfNeeded() {
507: if (isOwnTransaction()) {
508: try {
509: this .dbConnection.rollback();
510: } catch (Throwable th) {
511: }
512: } else if (this .currentSavepoint != null) {
513: this .dbConnection.rollback(this .currentSavepoint);
514: this .currentSavepoint = null;
515: }
516: }
517:
518: private void commitRetrieveIfNeeded() {
519: if (isOwnTransaction()) {
520: if (this .dbConnection.selectStartsTransaction()) {
521: try {
522: this .dbConnection.commit();
523: } catch (Throwable th) {
524: }
525: }
526: } else if (this .currentSavepoint != null) {
527: this .dbConnection.releaseSavepoint(this .currentSavepoint);
528: this .currentSavepoint = null;
529: }
530: }
531:
532: protected void doRetrieve(boolean respectMaxRows) {
533: if (this .isRetrieving())
534: return;
535:
536: String sql = this .buildSqlForTable(false);
537: if (sql == null)
538: return;
539:
540: this .retrieveStart();
541:
542: this .cancelRetrieve.setEnabled(true);
543: this .reloadAction.setEnabled(false);
544: boolean error = false;
545:
546: try {
547: dataDisplay.setStatusMessage(ResourceMgr
548: .getString("LblLoadingProgress"));
549:
550: setSavepoint();
551:
552: error = !dataDisplay.runQuery(sql, respectMaxRows);
553:
554: // By directly setting the update table, we avoid
555: // another round-trip to the database to check the table from the
556: // passed SQL statement.
557: dataDisplay.setUpdateTableToBeUsed(this .table);
558: dataDisplay.getSelectKeysAction().setEnabled(true);
559: String header = ResourceMgr
560: .getString("TxtTableDataPrintHeader")
561: + " " + table;
562: dataDisplay.setPrintHeader(header);
563: dataDisplay.showlastExecutionTime();
564:
565: if (this .lastSort != null) {
566: dataDisplay.setSortDefinition(lastSort);
567: }
568: } catch (Throwable e) {
569: error = true;
570: final String msg;
571:
572: if (e instanceof OutOfMemoryError) {
573: try {
574: dataDisplay.getTable().reset();
575: } catch (Throwable th) {
576: }
577: System.gc();
578: msg = ResourceMgr.getString("MsgOutOfMemoryError");
579: } else {
580: msg = ExceptionUtil.getDisplay(e);
581: }
582:
583: LogMgr.logError("TableDataPanel.doRetrieve()",
584: "Error retrieving table data", e);
585: EventQueue.invokeLater(new Runnable() {
586: public void run() {
587: WbSwingUtilities.showErrorMessage(
588: TableDataPanel.this , msg);
589: }
590: });
591: } finally {
592: dataDisplay.clearStatusMessage();
593: cancelRetrieve.setEnabled(false);
594: reloadAction.setEnabled(true);
595: this .retrieveEnd();
596: WbSwingUtilities.showDefaultCursor(this );
597: if (error) {
598: rollbackIfNeeded();
599: } else {
600: commitRetrieveIfNeeded();
601: }
602: }
603:
604: if (!error
605: && Settings.getInstance()
606: .getSelectDataPanelAfterRetrieve()) {
607: EventQueue.invokeLater(new Runnable() {
608: public void run() {
609: dataDisplay.getTable().requestFocus();
610: }
611: });
612: }
613: }
614:
615: public void setCursor(Cursor newCursor) {
616: super .setCursor(newCursor);
617: this .dataDisplay.setCursor(null);
618: }
619:
620: /**
621: * Start a new thread to retrieve the table data.
622: * @param respectMaxRows
623: */
624: public void retrieve(final boolean respectMaxRows) {
625: if (this .isRetrieving())
626: return;
627:
628: Thread t = new WbThread("TableDataPanel retrieve thread") {
629: public void run() {
630: doRetrieve(respectMaxRows);
631: }
632: };
633: t.start();
634: }
635:
636: private String getWorkspacePrefix(int index) {
637: return "dbexplorer" + index + ".tabledata.";
638: }
639:
640: /**
641: * Save the settings to a Workspace
642: */
643: public void saveToWorkspace(WbWorkspace wb, int index) {
644: String prefix = getWorkspacePrefix(index);
645: saveSettings(prefix, wb.getSettings());
646: }
647:
648: /**
649: * Restore the settings from a Workspace
650: */
651: public void readFromWorkspace(WbWorkspace wb, int index) {
652: this .restoreSettings(); // load "global" settings first;
653: String prefix = getWorkspacePrefix(index);
654: this .readSettings(prefix, wb.getSettings());
655: }
656:
657: /**
658: * Store global settings for this DbExplorer
659: */
660: public void saveSettings() {
661: String prefix = TableDataPanel.class.getName() + ".";
662: saveSettings(prefix, Settings.getInstance());
663: }
664:
665: private void saveSettings(String prefix, PropertyStorage props) {
666: props.setProperty(prefix + "maxrows", this .dataDisplay
667: .getMaxRows());
668: props.setProperty(prefix + "autoretrieve", this .autoRetrieve
669: .isSelected());
670: props.setProperty(prefix + "autoloadrowcount",
671: this .autoloadRowCount);
672: props.setProperty(prefix + "warningthreshold",
673: this .warningThreshold);
674: }
675:
676: /**
677: * Restore global settings for this DbExplorer
678: */
679: public void restoreSettings() {
680: String prefix = TableDataPanel.class.getName() + ".";
681: readSettings(prefix, Settings.getInstance());
682: }
683:
684: private void readSettings(String prefix, PropertyStorage props) {
685: int max = props.getIntProperty(prefix + "maxrows", 500);
686: if (max != -1)
687: this .dataDisplay.setMaxRows(max);
688: boolean auto = props.getBoolProperty(prefix + "autoretrieve",
689: true);
690: this .autoRetrieve.setSelected(auto);
691: this .autoloadRowCount = props.getBoolProperty(prefix
692: + "autoloadrowcount", true);
693: this .warningThreshold = props.getIntProperty(prefix
694: + "warningthreshold", 1500);
695: }
696:
697: public void showData() {
698: this .showData(true);
699: }
700:
701: public void showData(boolean includeData) {
702: if (this .isRetrieving())
703: return;
704:
705: this .reset();
706: long rows = -1;
707: if (this .autoloadRowCount) {
708: rows = this .showRowCount();
709: // -1 means an error occurred. No need to continue in that case.
710: if (rows == -1)
711: return;
712: }
713:
714: if (this .autoRetrieve.isSelected() && includeData) {
715: int max = this .dataDisplay.getMaxRows();
716: if (this .warningThreshold > 0
717: && rows > this .warningThreshold && max == 0) {
718: String msg = ResourceMgr
719: .getString("MsgDataDisplayWarningThreshold");
720: msg = msg.replaceAll("%rows%", Long.toString(rows));
721: int choice = JOptionPane.showConfirmDialog(this , msg,
722: ResourceMgr.TXT_PRODUCT_NAME,
723: JOptionPane.YES_NO_OPTION);
724: if (choice == JOptionPane.NO_OPTION)
725: return;
726: }
727: this .doRetrieve(true);
728: }
729: }
730:
731: public void reload() {
732: this .reset();
733: long rows = -1;
734: boolean ctrlPressed = this .reloadAction.ctrlPressed();
735:
736: if (this .autoloadRowCount) {
737: rows = this .showRowCount();
738: // An error occurred --> no need to continue
739: if (rows == -1)
740: return;
741: }
742: this .retrieve(!ctrlPressed);
743: }
744:
745: public Window getParentWindow() {
746: return SwingUtilities.getWindowAncestor(this );
747: }
748:
749: public void actionPerformed(ActionEvent e) {
750: if (e.getSource() == this .config) {
751: TableDataSettings p = new TableDataSettings();
752: p.setThresholdValue(this .warningThreshold);
753: p.setAutoloadData(this .autoRetrieve.isSelected());
754: p.setAutoloadRowCount(this .autoloadRowCount);
755: Window parent = SwingUtilities.getWindowAncestor(this );
756: int choice = JOptionPane
757: .showConfirmDialog(
758: parent,
759: p,
760: ResourceMgr
761: .getString("LblConfigureWarningThresholdTitle"),
762: JOptionPane.OK_CANCEL_OPTION,
763: JOptionPane.PLAIN_MESSAGE);
764: if (choice == JOptionPane.OK_OPTION) {
765: this .warningThreshold = p.getThresholdValue();
766: this .autoRetrieve.setSelected(p.getAutoloadData());
767: this .autoloadRowCount = p.getAutoloadRowCount();
768: }
769: } else if (e.getSource() == this .rowCountButton) {
770: this .startRetrieveRowCount();
771: }
772: }
773:
774: public void setReadOnly(boolean aFlag) {
775: this .dataDisplay.setReadOnly(aFlag);
776: }
777:
778: public void tableDataDeleted(List tables) {
779: if (tables == null)
780: return;
781: if (this .table == null)
782: return;
783: if (tables.contains(this .table)) {
784: this .reset();
785: }
786: }
787:
788: public synchronized void addDbExecutionListener(
789: DbExecutionListener l) {
790: if (this .execListener == null)
791: this .execListener = Collections
792: .synchronizedList(new ArrayList<DbExecutionListener>());
793: this .execListener.add(l);
794: }
795:
796: public synchronized void removeDbExecutionListener(
797: DbExecutionListener l) {
798: if (this .execListener == null)
799: return;
800: this .execListener.remove(l);
801: }
802:
803: protected synchronized void fireDbExecStart() {
804: this .dbConnection.executionStart(this .dbConnection, this );
805: if (this .execListener == null)
806: return;
807: for (DbExecutionListener l : execListener) {
808: if (l != null)
809: l.executionStart(this .dbConnection, this );
810: }
811: }
812:
813: protected synchronized void fireDbExecEnd() {
814: this .dbConnection.executionEnd(this .dbConnection, this );
815: if (this .execListener == null)
816: return;
817: for (DbExecutionListener l : execListener) {
818: if (l != null)
819: l.executionEnd(this.dbConnection, this);
820: }
821: }
822:
823: }
|