Source Code Cross Referenced for DwPanel.java in  » Database-Client » SQL-Workbench » workbench » gui » sql » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database Client » SQL Workbench » workbench.gui.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DwPanel.java
0003:         *
0004:         * This file is part of SQL Workbench/J, http://www.sql-workbench.net
0005:         *
0006:         * Copyright 2002-2008, Thomas Kellerer
0007:         * No part of this code maybe reused without the permission of the author
0008:         *
0009:         * To contact the author please send an email to: support@sql-workbench.net
0010:         *
0011:         */
0012:        package workbench.gui.sql;
0013:
0014:        import java.awt.BorderLayout;
0015:        import java.awt.Component;
0016:        import java.awt.Cursor;
0017:        import java.awt.EventQueue;
0018:        import java.awt.Window;
0019:        import java.sql.ResultSet;
0020:        import java.sql.SQLException;
0021:        import java.util.List;
0022:        import javax.swing.BorderFactory;
0023:        import javax.swing.CellEditor;
0024:        import javax.swing.JOptionPane;
0025:        import javax.swing.JOptionPane;
0026:        import javax.swing.JOptionPane;
0027:        import javax.swing.JPanel;
0028:        import javax.swing.JTextField;
0029:        import javax.swing.ListSelectionModel;
0030:        import javax.swing.SwingConstants;
0031:        import javax.swing.SwingUtilities;
0032:        import javax.swing.border.Border;
0033:        import javax.swing.border.EmptyBorder;
0034:        import javax.swing.border.EtchedBorder;
0035:        import javax.swing.event.ChangeEvent;
0036:        import javax.swing.event.ChangeListener;
0037:        import javax.swing.event.ListSelectionEvent;
0038:        import javax.swing.event.ListSelectionListener;
0039:        import javax.swing.event.TableModelEvent;
0040:        import javax.swing.event.TableModelListener;
0041:        import javax.swing.table.TableColumn;
0042:        import javax.swing.table.TableColumnModel;
0043:        import javax.swing.table.TableModel;
0044:        import workbench.db.ColumnIdentifier;
0045:        import workbench.db.TableIdentifier;
0046:        import workbench.db.WbConnection;
0047:        import workbench.gui.MainWindow;
0048:        import workbench.gui.components.GenericRowMonitor;
0049:        import workbench.gui.components.WbTextCellEditor;
0050:        import workbench.util.ExceptionUtil;
0051:        import workbench.gui.WbSwingUtilities;
0052:        import workbench.gui.actions.CopyRowAction;
0053:        import workbench.gui.actions.DeleteDependentRowsAction;
0054:        import workbench.gui.actions.DeleteRowAction;
0055:        import workbench.gui.actions.InsertRowAction;
0056:        import workbench.gui.actions.SelectKeyColumnsAction;
0057:        import workbench.gui.actions.UpdateDatabaseAction;
0058:        import workbench.gui.components.DataStoreTableModel;
0059:        import workbench.gui.components.OneLineTableModel;
0060:        import workbench.gui.components.TextComponentMouseListener;
0061:        import workbench.gui.components.WbScrollPane;
0062:        import workbench.gui.components.WbTable;
0063:        import workbench.interfaces.DbData;
0064:        import workbench.interfaces.DbUpdater;
0065:        import workbench.interfaces.Interruptable;
0066:        import workbench.interfaces.JobErrorHandler;
0067:        import workbench.interfaces.StatementRunner;
0068:        import workbench.log.LogMgr;
0069:        import workbench.resource.ResourceMgr;
0070:        import workbench.resource.Settings;
0071:        import workbench.sql.StatementRunnerResult;
0072:        import workbench.storage.DataStore;
0073:        import workbench.storage.NamedSortDefinition;
0074:        import workbench.storage.RowActionMonitor;
0075:        import workbench.util.NumberStringCache;
0076:        import workbench.util.StringUtil;
0077:        import workbench.util.WbThread;
0078:
0079:        /**
0080:         *	A Panel which displays the result of a SELECT statement and
0081:         *  can save changes to the database
0082:         *
0083:         *	@author support@sql-workbench.net
0084:         */
0085:        public class DwPanel extends JPanel implements  TableModelListener,
0086:                ListSelectionListener, ChangeListener, DbData, DbUpdater,
0087:                Interruptable, JobErrorHandler {
0088:            public static final String PROP_UPDATE_TABLE = "updateTable";
0089:
0090:            protected WbTable dataTable;
0091:
0092:            protected DwStatusBar statusBar;
0093:
0094:            private String sql;
0095:            private String lastMessage;
0096:            protected WbConnection dbConnection;
0097:            private boolean hasResultSet;
0098:
0099:            protected WbScrollPane scrollPane;
0100:            private long lastExecutionTime = 0;
0101:
0102:            private boolean showLoadProgress;
0103:            private boolean savingData = false;
0104:
0105:            protected UpdateDatabaseAction updateAction;
0106:            protected InsertRowAction insertRow;
0107:            protected CopyRowAction duplicateRow;
0108:            protected DeleteRowAction deleteRow;
0109:            protected DeleteDependentRowsAction deleteDependentRow;
0110:            protected SelectKeyColumnsAction selectKeys;
0111:
0112:            private boolean editingStarted;
0113:            private boolean batchUpdate;
0114:            private boolean manageUpdateAction;
0115:            private boolean readOnly;
0116:
0117:            private String[] lastResultMessages;
0118:            private StatementRunner stmtRunner;
0119:            private GenericRowMonitor genericRowMonitor;
0120:            private ReferenceTableNavigator referenceNavigator;
0121:
0122:            public DwPanel() {
0123:                this (null);
0124:            }
0125:
0126:            public DwPanel(DwStatusBar aStatusBar) {
0127:                JTextField stringField = new JTextField();
0128:                stringField.setBorder(WbSwingUtilities.EMPTY_BORDER);
0129:                stringField.addMouseListener(new TextComponentMouseListener());
0130:
0131:                JTextField numberField = new JTextField();
0132:                numberField.setBorder(WbSwingUtilities.EMPTY_BORDER);
0133:                numberField.setHorizontalAlignment(SwingConstants.RIGHT);
0134:                numberField.addMouseListener(new TextComponentMouseListener());
0135:
0136:                this .initLayout(aStatusBar);
0137:
0138:                this .setDoubleBuffered(true);
0139:                this .dataTable.addTableModelListener(this );
0140:
0141:                this .updateAction = new UpdateDatabaseAction(this );
0142:                this .insertRow = new InsertRowAction(this );
0143:                this .deleteRow = new DeleteRowAction(this );
0144:                this .deleteDependentRow = new DeleteDependentRowsAction(this );
0145:                this .duplicateRow = new CopyRowAction(this );
0146:                this .selectKeys = new SelectKeyColumnsAction(this );
0147:
0148:                dataTable.addPopupAction(this .updateAction, true);
0149:                dataTable.addPopupAction(this .insertRow, true);
0150:                dataTable.addPopupAction(this .deleteRow, false);
0151:                dataTable.addPopupAction(this .deleteDependentRow, false);
0152:
0153:                this .dataTable
0154:                        .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0155:                this .dataTable.setRowSelectionAllowed(true);
0156:                this .dataTable.getSelectionModel().addListSelectionListener(
0157:                        this );
0158:                this .dataTable.setHighlightRequiredFields(Settings
0159:                        .getInstance().getHighlightRequiredFields());
0160:                this .dataTable.setStatusBar(this .statusBar);
0161:                this .genericRowMonitor = new GenericRowMonitor(this .statusBar);
0162:            }
0163:
0164:            public void initTableNavigation(MainWindow container) {
0165:                this .referenceNavigator = new ReferenceTableNavigator(this ,
0166:                        container);
0167:            }
0168:
0169:            public SelectKeyColumnsAction getSelectKeysAction() {
0170:                return this .selectKeys;
0171:            }
0172:
0173:            public void checkAndSelectKeyColumns() {
0174:                if (checkUpdateTable()) {
0175:                    dataTable.selectKeyColumns();
0176:                }
0177:            }
0178:
0179:            public void setManageUpdateAction(boolean aFlag) {
0180:                this .manageUpdateAction = aFlag;
0181:            }
0182:
0183:            public void setDefaultStatusMessage(String aMessage) {
0184:                this .statusBar.setReadyMsg(aMessage);
0185:            }
0186:
0187:            public void disconnect() {
0188:                this .setConnection(null);
0189:            }
0190:
0191:            public void setCursor(Cursor newCursor) {
0192:                super .setCursor(newCursor);
0193:                this .dataTable.setCursor(newCursor);
0194:            }
0195:
0196:            public void setShowLoadProcess(boolean aFlag) {
0197:                this .showLoadProgress = aFlag;
0198:            }
0199:
0200:            public void setPrintHeader(String header) {
0201:                this .dataTable.setPrintHeader(header);
0202:            }
0203:
0204:            public void dispose() {
0205:                this .clearContent();
0206:                if (this .stmtRunner != null) {
0207:                    this .stmtRunner.dispose();
0208:                }
0209:                this .stmtRunner = null;
0210:            }
0211:
0212:            /**
0213:             *	Defines the connection for this DwPanel.
0214:             */
0215:            public void setConnection(WbConnection aConn) {
0216:                this .clearContent();
0217:                this .dbConnection = aConn;
0218:                if (this .stmtRunner != null) {
0219:                    this .stmtRunner.done();
0220:                }
0221:                this .stmtRunner = null;
0222:                this .clearStatusMessage();
0223:            }
0224:
0225:            private void createStatementRunner() {
0226:                if (this .stmtRunner == null) {
0227:                    this .stmtRunner = StatementRunner.Factory.createRunner();
0228:                    this .stmtRunner.setRowMonitor(this .genericRowMonitor);
0229:                }
0230:
0231:                if (this .stmtRunner != null) {
0232:                    this .stmtRunner.setConnection(this .dbConnection);
0233:                }
0234:            }
0235:
0236:            /**
0237:             *	Sets the handler which performs the update to the database.
0238:             *
0239:             *  This delegate is passed to the UpdateDatabaseAction. The action will in turn
0240:             *  call the delegate's saveChangesToDatabase() method instead of ours.
0241:             *
0242:             *  @see workbench.interfaces.DbUpdater#saveChangesToDatabase()
0243:             *  @see #saveChangesToDatabase()
0244:             *  @see workbench.gui.sql.SqlPanel#saveChangesToDatabase()
0245:             */
0246:            public void setUpdateHandler(DbUpdater aDelegate) {
0247:                this .updateAction.setClient(aDelegate);
0248:            }
0249:
0250:            /**
0251:             * Prepare the DwPanel for saving any changes to the database.
0252:             * This will check for the PK columns and if necessary
0253:             * ask the user to specify them. 
0254:             * It will also prompt the user to verify the generated
0255:             * update statements. 
0256:             * If everything is OK, true will be returned
0257:             * If the user cancels the PK column selection or the 
0258:             * statement preview, false will be returned. In that 
0259:             * case saveChanges() should not be called
0260:             */
0261:            boolean prepareDatabaseUpdate() {
0262:                if (this .dbConnection == null)
0263:                    return false;
0264:                DataStore ds = this .dataTable.getDataStore();
0265:                if (ds == null)
0266:                    return false;
0267:
0268:                boolean needPk = ds.needPkForUpdate();
0269:                if (needPk) {
0270:                    boolean hasPk = dataTable.detectDefinedPkColumns();
0271:                    if (!hasPk) {
0272:                        hasPk = getTable().selectKeyColumns();
0273:                    }
0274:                    if (!hasPk)
0275:                        return false;
0276:                }
0277:
0278:                boolean pkComplete = ds.pkColumnsComplete();
0279:                if (needPk && !pkComplete) {
0280:                    List<ColumnIdentifier> columns = ds.getMissingPkColumns();
0281:                    MissingPkDialog dialog = new MissingPkDialog(columns);
0282:                    boolean ok = dialog.checkContinue(this );
0283:                    if (!ok)
0284:                        return false;
0285:                }
0286:
0287:                // check if we really want to save the currentData
0288:                // it fhe SQL Preview is not enabled this will
0289:                // always return true, otherwise it depends on the user's
0290:                // selection after the SQL preview has been displayed
0291:                if (!this .shouldSaveChanges(this .dbConnection))
0292:                    return false;
0293:                return true;
0294:            }
0295:
0296:            /**
0297:             * Starts the saving of the data in the background
0298:             */
0299:            public void saveChangesToDatabase() {
0300:                if (savingData) {
0301:                    Exception e = new IllegalStateException(
0302:                            "Concurrent save called");
0303:                    LogMgr.logWarning("DwPanel.saveChangesToDatase()",
0304:                            "Save changes called while save in progress", e);
0305:                    return;
0306:                }
0307:
0308:                if (!this .prepareDatabaseUpdate())
0309:                    return;
0310:
0311:                final JobErrorHandler handler = this ;
0312:                WbThread t = new WbThread("DwPanel update") {
0313:                    public void run() {
0314:                        try {
0315:                            saveChanges(dbConnection, handler);
0316:                        } catch (Exception e) {
0317:                            // Exception have already been displayed to the user --> Log only
0318:                            LogMgr.logError("DwPanel.doSave()",
0319:                                    "Error saving data", e);
0320:                        }
0321:                    }
0322:                };
0323:                t.start();
0324:
0325:            }
0326:
0327:            public boolean shouldSaveChanges(WbConnection aConnection) {
0328:                if (!Settings.getInstance().getPreviewDml()
0329:                        && !this .dbConnection.getProfile().isConfirmUpdates())
0330:                    return true;
0331:
0332:                this .dataTable.stopEditing();
0333:                DataStore ds = this .dataTable.getDataStore();
0334:                DwUpdatePreview preview = new DwUpdatePreview();
0335:
0336:                boolean doSave = preview.confirmUpdate(this , ds, dbConnection);
0337:
0338:                return doSave;
0339:            }
0340:
0341:            public int saveChanges(WbConnection aConnection,
0342:                    JobErrorHandler errorHandler) throws SQLException {
0343:                int rows = 0;
0344:
0345:                synchronized (this ) {
0346:                    this .dataTable.stopEditing();
0347:                    if (this .manageUpdateAction) {
0348:                        this .disableUpdateActions();
0349:                    }
0350:
0351:                    try {
0352:                        setStatusMessage(ResourceMgr
0353:                                .getString("MsgUpdatingDatabase"));
0354:                        savingData = true;
0355:                        DataStore ds = this .dataTable.getDataStore();
0356:                        long start, end;
0357:                        ds.setProgressMonitor(this .genericRowMonitor);
0358:                        start = System.currentTimeMillis();
0359:                        rows = ds.updateDb(aConnection, errorHandler);
0360:                        end = System.currentTimeMillis();
0361:                        ds.setProgressMonitor(null);
0362:                        long sqlTime = (end - start);
0363:                        this .lastMessage = ResourceMgr
0364:                                .getString("MsgUpdateSuccessfull");
0365:                        this .lastMessage = this .lastMessage + "\n" + rows + " "
0366:                                + ResourceMgr.getString("MsgRowsAffected")
0367:                                + "\n";
0368:                        this .lastMessage = this .lastMessage
0369:                                + ResourceMgr.getString("MsgExecTime") + " "
0370:                                + (((double) sqlTime) / 1000.0) + "s";
0371:                        if (!ds.lastUpdateHadErrors()) {
0372:                            endEdit();
0373:                        }
0374:                    } catch (SQLException e) {
0375:                        this .lastMessage = ExceptionUtil.getDisplay(e);
0376:                        rows = -1;
0377:                        throw e;
0378:                    } finally {
0379:                        savingData = false;
0380:                        this .clearStatusMessage();
0381:                        if (this .manageUpdateAction)
0382:                            this .checkResultSetActions();
0383:                    }
0384:                }
0385:
0386:                return rows;
0387:            }
0388:
0389:            protected void disableUpdateActions() {
0390:                this .updateAction.setEnabled(false);
0391:                this .insertRow.setEnabled(false);
0392:                this .duplicateRow.setEnabled(false);
0393:                this .deleteRow.setEnabled(false);
0394:                this .deleteDependentRow.setEnabled(false);
0395:            }
0396:
0397:            /**
0398:             * Pass the table to be used for future updates to the underlying 
0399:             * DataStore. 
0400:             * This will also reset the internal cache of the ReferenceTableNavigator.
0401:             * 
0402:             * @see workbench.gui.sql.ReferenceTableNavigator#reset()
0403:             * @see workbench.storage.DataStore#setUpdateTableToBeUsed(workbench.db.TableIdentifier)
0404:             */
0405:            public void setUpdateTableToBeUsed(TableIdentifier table) {
0406:                DataStore ds = this .dataTable.getDataStore();
0407:                if (ds != null) {
0408:                    ds.setUpdateTableToBeUsed(table);
0409:                }
0410:                referenceNavigator.reset();
0411:            }
0412:
0413:            /**
0414:             * Define the update table to be used.
0415:             * @see workbench.storage.DataStore#setUpdateTable(TableIdentifier)
0416:             */
0417:            public void setUpdateTable(TableIdentifier table) {
0418:                this .setStatusMessage(ResourceMgr
0419:                        .getString("MsgRetrieveUpdateTableInfo"));
0420:                try {
0421:                    DataStore ds = this .dataTable.getDataStore();
0422:                    if (ds != null) {
0423:                        ds.setUpdateTable(table);
0424:                    }
0425:                    checkResultSetActions();
0426:                    this .fireUpdateTableChanged();
0427:                } finally {
0428:                    this .clearStatusMessage();
0429:                }
0430:            }
0431:
0432:            private void fireUpdateTableChanged() {
0433:                TableIdentifier table = null;
0434:
0435:                if (this .getTable() != null) {
0436:                    DataStore ds = this .getTable().getDataStore();
0437:                    if (ds != null)
0438:                        table = ds.getUpdateTable();
0439:                }
0440:                if (table != null)
0441:                    firePropertyChange(PROP_UPDATE_TABLE, null, table
0442:                            .getTableExpression());
0443:            }
0444:
0445:            public void setReadOnly(boolean aFlag) {
0446:                this .readOnly = aFlag;
0447:                if (this .readOnly && this .editingStarted) {
0448:                    this .endEdit();
0449:                    this .disableUpdateActions();
0450:                    this .dataTable.restoreOriginalValues();
0451:                } else {
0452:                    this .insertRow.setEnabled(true);
0453:                }
0454:            }
0455:
0456:            public boolean isReadOnly() {
0457:                return this .readOnly;
0458:            }
0459:
0460:            public boolean checkUpdateTable() {
0461:                if (this .readOnly)
0462:                    return false;
0463:
0464:                setStatusMessage(ResourceMgr
0465:                        .getString("MsgCheckingUpdateTable"));
0466:                statusBar.forcePaint();
0467:
0468:                boolean result = false;
0469:                try {
0470:                    DataStore ds = this .dataTable.getDataStore();
0471:                    if (ds == null)
0472:                        return false;
0473:                    if (this .dbConnection == null)
0474:                        return false;
0475:                    if (this .sql == null)
0476:                        return false;
0477:                    result = ds.checkUpdateTable(this .dbConnection);
0478:
0479:                    if (!result) {
0480:                        TableIdentifier tbl = dataTable.selectUpdateTable();
0481:                        if (tbl != null) {
0482:                            this .setUpdateTable(tbl);
0483:                            result = true;
0484:                        }
0485:                    }
0486:
0487:                    if (result) {
0488:                        this .fireUpdateTableChanged();
0489:                    }
0490:
0491:                    this .selectKeys.setEnabled(result);
0492:                } finally {
0493:                    this .clearStatusMessage();
0494:                }
0495:                return result;
0496:            }
0497:
0498:            public boolean hasKeyColumns() {
0499:                if (this .dataTable.getDataStore() == null)
0500:                    return false;
0501:                return this .dataTable.getDataStore().hasPkColumns();
0502:            }
0503:
0504:            public boolean isUpdateable() {
0505:                if (this .dataTable.getDataStore() == null)
0506:                    return false;
0507:                return this .dataTable.getDataStore().isUpdateable();
0508:            }
0509:
0510:            public boolean hasUpdateableColumns() {
0511:                if (this .dataTable.getDataStore() == null)
0512:                    return false;
0513:                return this .dataTable.getDataStore().hasUpdateableColumns();
0514:            }
0515:
0516:            public int getQueryTimeout() {
0517:                return this .statusBar.getQueryTimeout();
0518:            }
0519:
0520:            public void setQueryTimeout(int value) {
0521:                this .statusBar.setQueryTimeout(value);
0522:            }
0523:
0524:            public int getMaxRows() {
0525:                return this .statusBar.getMaxRows();
0526:            }
0527:
0528:            public void setMaxRows(int aMax) {
0529:                this .statusBar.setMaxRows(aMax);
0530:            }
0531:
0532:            /**
0533:             * Displays the last execution time in the status bar
0534:             */
0535:            public void showlastExecutionTime() {
0536:                statusBar.setExecutionTime(lastExecutionTime);
0537:            }
0538:
0539:            public void setSortDefinition(NamedSortDefinition sort) {
0540:                DataStoreTableModel model = this .dataTable
0541:                        .getDataStoreTableModel();
0542:                if (model != null) {
0543:                    model.setSortDefinition(sort);
0544:                }
0545:            }
0546:
0547:            public NamedSortDefinition getCurrentSort() {
0548:                NamedSortDefinition currentSort = null;
0549:                DataStoreTableModel model = this .dataTable
0550:                        .getDataStoreTableModel();
0551:                if (model != null) {
0552:                    currentSort = model.getSortDefinition();
0553:                }
0554:                return currentSort;
0555:            }
0556:
0557:            /**
0558:             *	Execute the given SQL statement and display the result. 
0559:             */
0560:            public boolean runQuery(String aSql, boolean respectMaxRows)
0561:                    throws SQLException, Exception {
0562:                if (this .stmtRunner == null)
0563:                    this .createStatementRunner();
0564:
0565:                boolean success = false;
0566:
0567:                try {
0568:                    this .clearContent();
0569:
0570:                    this .sql = aSql;
0571:                    int max = (respectMaxRows ? this .statusBar.getMaxRows() : 0);
0572:                    int timeout = this .statusBar.getQueryTimeout();
0573:
0574:                    this .stmtRunner.runStatement(aSql, max, timeout);
0575:                    StatementRunnerResult result = this .stmtRunner.getResult();
0576:
0577:                    if (result != null) {
0578:                        if (result.isSuccess()) {
0579:                            success = true;
0580:                            this .showData(result);
0581:                        } else {
0582:                            String err = result.getMessageBuffer().toString();
0583:                            showError(err);
0584:                            WbSwingUtilities.showErrorMessage(SwingUtilities
0585:                                    .getWindowAncestor(this ), err);
0586:                        }
0587:                    }
0588:                } finally {
0589:                    this .stmtRunner.done();
0590:                    this .clearStatusMessage();
0591:                }
0592:                return success;
0593:            }
0594:
0595:            /**
0596:             * Display any result set that is contained in the StatementRunnerResult. 
0597:             * @param result the result from the {@link workbench.interfaces.StatementRunner} to be displayed
0598:             *
0599:             * @see workbench.sql.DefaultStatementRunner
0600:             */
0601:            public void showData(final StatementRunnerResult result)
0602:                    throws SQLException {
0603:                if (result == null || !result.isSuccess()) {
0604:                    this .lastExecutionTime = 0;
0605:                    this .hasResultSet = false;
0606:                } else {
0607:                    this .lastExecutionTime = result.getExecutionTime();
0608:
0609:                    if (result.hasDataStores()) {
0610:                        showData(result.getDataStores().get(0), result
0611:                                .getSourceCommand());
0612:                    } else if (result.hasResultSets()) {
0613:                        showData(result.getResultSets().get(0), result
0614:                                .getSourceCommand());
0615:                    }
0616:                }
0617:            }
0618:
0619:            public void showData(final ResultSet result, final String sql)
0620:                    throws SQLException {
0621:                DataStore newData = null;
0622:
0623:                // passing the maxrows to the datastore is a workaround for JDBC drivers
0624:                // which do not support the setMaxRows() method.
0625:                // The datastore will make sure that not more rows are read than really requested
0626:                if (this .showLoadProgress) {
0627:                    newData = new DataStore(result, true,
0628:                            this .genericRowMonitor, this .getMaxRows(),
0629:                            this .dbConnection);
0630:                } else {
0631:                    newData = new DataStore(result, true, null, this 
0632:                            .getMaxRows(), this .dbConnection);
0633:                }
0634:                showData(newData, sql);
0635:            }
0636:
0637:            public void showData(final DataStore newData, final String statement)
0638:                    throws SQLException {
0639:                try {
0640:                    this .setBatchUpdate(true);
0641:                    this .hasResultSet = true;
0642:                    this .sql = statement;
0643:
0644:                    newData.setOriginalConnection(this .dbConnection);
0645:                    newData.setProgressMonitor(null);
0646:                    this .clearStatusMessage();
0647:
0648:                    WbSwingUtilities.invoke(new Runnable() {
0649:                        public void run() {
0650:                            dataTable.reset();
0651:                            dataTable.setAutoCreateColumnsFromModel(true);
0652:                            dataTable.setModel(
0653:                                    new DataStoreTableModel(newData), true);
0654:                            dataTable.adjustOrOptimizeColumns();
0655:                            //StringBuilder header = new StringBuilder(80);
0656:                            //header.append(ResourceMgr.getString("TxtPrintHeaderResultFrom"));
0657:                            //header.append(sql);
0658:                            setPrintHeader(sql);
0659:                            dataTable.checkCopyActions();
0660:                            checkResultSetActions();
0661:                        }
0662:                    });
0663:
0664:                } finally {
0665:                    setBatchUpdate(false);
0666:                }
0667:            }
0668:
0669:            private void checkResultSetActions() {
0670:                boolean hasResult = this .hasResultSet();
0671:                int rows = this .getTable().getSelectedRowCount();
0672:                this .dataTable.getExportAction().setEnabled(hasResult);
0673:                if (this .updateAction != null)
0674:                    this .updateAction.setEnabled(isModified());
0675:                if (this .duplicateRow != null)
0676:                    this .duplicateRow.setEnabled(rows == 1);
0677:                if (this .deleteRow != null)
0678:                    this .deleteRow.setEnabled(rows > 0);
0679:                if (this .deleteDependentRow != null)
0680:                    this .deleteDependentRow.setEnabled(rows > 0);
0681:                if (this .insertRow != null)
0682:                    this .insertRow.setEnabled(hasResult);
0683:                if (this .selectKeys != null)
0684:                    this .selectKeys.setEnabled(hasResult);
0685:                this .dataTable.checkCopyActions();
0686:            }
0687:
0688:            /**
0689:             *  This method will update the row info display on the statusbar.
0690:             */
0691:            public void rowCountChanged() {
0692:                int startRow = 0;
0693:                int endRow = 0;
0694:                int count = 0;
0695:                startRow = this .dataTable.getFirstVisibleRow();
0696:                endRow = this .dataTable.getLastVisibleRow(startRow);
0697:                count = this .dataTable.getRowCount();
0698:                statusBar.setRowcount(startRow + 1, endRow + 1, count);
0699:            }
0700:
0701:            public int duplicateRow() {
0702:                if (this .dataTable.getSelectedRowCount() != 1)
0703:                    return -1;
0704:                int row = this .dataTable.getSelectedRow();
0705:                if (row < 0)
0706:                    return -1;
0707:
0708:                if (this .readOnly)
0709:                    return -1;
0710:                if (!this .startEdit(false))
0711:                    return -1;
0712:                final int newRow = this .dataTable.duplicateRow(row);
0713:
0714:                if (newRow >= 0) {
0715:                    // Make the new row the current row
0716:                    // and start editing in the first column
0717:                    EventQueue.invokeLater(new Runnable() {
0718:                        public void run() {
0719:                            dataTable.getSelectionModel().setSelectionInterval(
0720:                                    newRow, newRow);
0721:                            dataTable.setEditingRow(newRow);
0722:                            dataTable.setEditingColumn(1);
0723:                            dataTable.editCellAt(newRow, 1);
0724:                            CellEditor edit = dataTable
0725:                                    .getCellEditor(newRow, 1);
0726:                            if (edit instanceof  WbTextCellEditor) {
0727:                                ((WbTextCellEditor) edit).requestFocus();
0728:                            }
0729:                            rowCountChanged();
0730:                        }
0731:                    });
0732:                }
0733:
0734:                return newRow;
0735:            }
0736:
0737:            public void deleteRowWithDependencies() {
0738:                if (this .readOnly)
0739:                    return;
0740:
0741:                if (!this .startEdit(true))
0742:                    return;
0743:
0744:                setStatusMessage(ResourceMgr.getString("MsgCalcDependencies"));
0745:                final Component c = this ;
0746:                WbSwingUtilities.showWaitCursor(this );
0747:
0748:                // As checking all dependent tables can potentially
0749:                // take some time (especially with Oracle...) 
0750:                // I'm starting a new thread to do the work
0751:                // And I cannot re-use the deleteRow() function as
0752:                // that wouldn't allow me to change the status message
0753:                // to indicate the dependency checking is running
0754:                // startEdit() is also changing the status message
0755:                // and would be executed after a local change here
0756:                // if I reused deleteRow()
0757:                Thread t = new WbThread("DeleteDependency") {
0758:                    public void run() {
0759:                        try {
0760:                            dbConnection.setBusy(true);
0761:                            dataTable.deleteRow(true);
0762:                            rowCountChanged();
0763:                        } catch (SQLException e) {
0764:                            LogMgr.logError("DwPanel.deleteRow()",
0765:                                    "Error deleting row from table", e);
0766:                            WbSwingUtilities.showErrorMessage(ExceptionUtil
0767:                                    .getDisplay(e));
0768:                        } finally {
0769:                            dbConnection.setBusy(false);
0770:                            clearStatusMessage();
0771:                            WbSwingUtilities.showDefaultCursor(c);
0772:                        }
0773:                    }
0774:                };
0775:                t.start();
0776:            }
0777:
0778:            public void deleteRow() {
0779:                if (this .readOnly)
0780:                    return;
0781:                if (!this .startEdit(true))
0782:                    return;
0783:                try {
0784:                    this .dataTable.deleteRow(false);
0785:                    this .rowCountChanged();
0786:                } catch (SQLException e) {
0787:                    LogMgr.logError("DwPanel.deleteRow()",
0788:                            "Error deleting row from table", e);
0789:                    WbSwingUtilities.showErrorMessage(ExceptionUtil
0790:                            .getDisplay(e));
0791:                }
0792:            }
0793:
0794:            public long addRow() {
0795:                if (this .readOnly)
0796:                    return -1;
0797:                if (!this .startEdit())
0798:                    return -1;
0799:                long newRow = this .dataTable.addRow();
0800:                if (newRow > -1)
0801:                    this .rowCountChanged();
0802:                return newRow;
0803:            }
0804:
0805:            public boolean confirmCancel() {
0806:                return true;
0807:            }
0808:
0809:            public void cancelExecution() {
0810:                if (this .stmtRunner != null) {
0811:                    this .stmtRunner.cancel();
0812:                }
0813:            }
0814:
0815:            public String getLastMessage() {
0816:                if (this .lastResultMessages != null) {
0817:                    StringBuilder msg = new StringBuilder(
0818:                            lastResultMessages.length * 80);
0819:                    for (int i = 0; i < lastResultMessages.length; i++) {
0820:                        msg.append(lastResultMessages[i]);
0821:                        msg.append('\n');
0822:                    }
0823:                    this .lastMessage = msg.toString();
0824:                    this .lastResultMessages = null;
0825:                }
0826:
0827:                if (this .lastMessage == null)
0828:                    this .lastMessage = "";
0829:
0830:                return this .lastMessage;
0831:            }
0832:
0833:            public boolean hasResultSet() {
0834:                return this .hasResultSet;
0835:            }
0836:
0837:            /**
0838:             *	Returns true if the DataStore of the Table has been modified.
0839:             *	@see workbench.storage.DataStore#isModified()
0840:             */
0841:            public boolean isModified() {
0842:                DataStore ds = this .dataTable.getDataStore();
0843:                if (ds == null)
0844:                    return false;
0845:                else
0846:                    return ds.isModified();
0847:            }
0848:
0849:            private void initLayout(DwStatusBar status) {
0850:                this .setLayout(new BorderLayout());
0851:                this .setBorder(WbSwingUtilities.EMPTY_BORDER);
0852:                this .dataTable = new WbTable(true, true, true);
0853:                this .dataTable.setRowResizeAllowed(Settings.getInstance()
0854:                        .getAllowRowHeightResizing());
0855:                if (status != null) {
0856:                    this .statusBar = status;
0857:                } else {
0858:                    this .statusBar = new DwStatusBar();
0859:                    Border b = BorderFactory.createCompoundBorder(
0860:                            new EmptyBorder(2, 0, 0, 0), new EtchedBorder());
0861:                    this .statusBar.setBorder(b);
0862:                    this .add(this .statusBar, BorderLayout.SOUTH);
0863:                }
0864:
0865:                this .statusBar.setFocusable(false);
0866:                this .setFocusable(false);
0867:                this .scrollPane = new WbScrollPane(this .dataTable);
0868:                this .scrollPane.getViewport().addChangeListener(this );
0869:
0870:                this .add(this .scrollPane, BorderLayout.CENTER);
0871:                this .dataTable.setBorder(WbSwingUtilities.EMPTY_BORDER);
0872:                this .dataTable.setAdjustToColumnLabel(true);
0873:            }
0874:
0875:            public void updateStatusBar() {
0876:                this .rowCountChanged();
0877:            }
0878:
0879:            /**
0880:             *	Show a message in the status panel.
0881:             * 
0882:             *  @see DwStatusBar#setStatusMessage(String)
0883:             */
0884:            public void setStatusMessage(final String aMsg) {
0885:                this .statusBar.setStatusMessage(aMsg);
0886:            }
0887:
0888:            /**
0889:             *	Clears the display on the status bar.
0890:             * 
0891:             *  @see DwStatusBar#clearStatusMessage()
0892:             */
0893:            public void clearStatusMessage() {
0894:                this .statusBar.clearStatusMessage();
0895:            }
0896:
0897:            public void showError(String error) {
0898:                this .setMessageDisplayModel(this .getErrorTableModel(error));
0899:            }
0900:
0901:            protected void setMessageDisplayModel(final TableModel aModel) {
0902:                if (this .dataTable.getModel() == aModel)
0903:                    return;
0904:                WbSwingUtilities.invoke(new Runnable() {
0905:                    public void run() {
0906:                        dataTable.setModel(aModel);
0907:                        TableColumnModel colMod = dataTable.getColumnModel();
0908:                        TableColumn col = colMod.getColumn(0);
0909:                        col.setPreferredWidth(getWidth() - 10);
0910:                        statusBar.setRowcount(0, 0, 0);
0911:                    }
0912:                });
0913:            }
0914:
0915:            /**
0916:             *	Clears everything.
0917:             *	<ul>
0918:             *	<li>Ends the edit mode</li>
0919:             *	<li>removes all rows from the table</li>
0920:             *	<li>sets the hasResultSet flag to false</li>
0921:             *  <li>the lastMessage is set to an empty string</li>
0922:             *  <li>the last SQL is set to null</li>
0923:             *  <li>the statusbar display is cleared</li>
0924:             *  </ul>
0925:             */
0926:            public void clearContent() {
0927:                this .endEdit();
0928:                this .dataTable.reset();
0929:                this .hasResultSet = false;
0930:                this .lastMessage = null;
0931:                this .sql = null;
0932:                this .statusBar.clearRowcount();
0933:                this .statusBar.clearExecutionTime();
0934:                this .selectKeys.setEnabled(false);
0935:                checkResultSetActions();
0936:            }
0937:
0938:            public int getActionOnError(int errorRow, String errorColumn,
0939:                    String data, String errorMessage) {
0940:                String msg = ResourceMgr.getString("ErrUpdateSqlError");
0941:                try {
0942:                    String d = "";
0943:                    if (data != null) {
0944:                        if (data.length() > 50)
0945:                            d = data.substring(0, 50) + "...";
0946:                        else
0947:                            d = data;
0948:                    }
0949:
0950:                    msg = StringUtil.replace(msg, "%statement%", d);
0951:                    msg = StringUtil.replace(msg, "%message%", errorMessage);
0952:
0953:                    String r = "";
0954:                    if (errorRow > -1) {
0955:                        r = ResourceMgr.getString("TxtErrorRow").replaceAll(
0956:                                "%row%",
0957:                                NumberStringCache.getNumberString(errorRow));
0958:                    }
0959:                    msg = StringUtil.replace(msg, "%row%", r);
0960:                } catch (Exception e) {
0961:                    LogMgr.logError("DwPanel.getActionOnError()",
0962:                            "Error while building error message", e);
0963:                    msg = "An error occurred during update: \n" + errorMessage;
0964:                }
0965:
0966:                Window w = SwingUtilities.getWindowAncestor(this );
0967:                int choice = WbSwingUtilities.getYesNoIgnoreAll(w, msg);
0968:
0969:                int result = JobErrorHandler.JOB_ABORT;
0970:
0971:                if (choice == JOptionPane.YES_OPTION) {
0972:                    result = JobErrorHandler.JOB_CONTINUE;
0973:                } else if (choice == WbSwingUtilities.IGNORE_ALL) {
0974:                    result = JobErrorHandler.JOB_IGNORE_ALL;
0975:                }
0976:                return result;
0977:            }
0978:
0979:            /**
0980:             *	Returns a TableModel which displays an error text.
0981:             *	This is used to show a hint in the table panel that an error
0982:             *  occurred and the actual error message is displayed in the log
0983:             *  panel
0984:             */
0985:            private TableModel getErrorTableModel(String aMsg) {
0986:                String title = ResourceMgr.getString("ErrMessageTitle");
0987:                OneLineTableModel errorMessageModel = new OneLineTableModel(
0988:                        title, aMsg);
0989:                return errorMessageModel;
0990:            }
0991:
0992:            public WbTable getTable() {
0993:                return this .dataTable;
0994:            }
0995:
0996:            /**
0997:             *	Stops the editing mode of the displayed WbTable:
0998:             *	<ul>
0999:             *	<li>the status column is turned off</li>
1000:             *  <li>the edit actions are enabled/disabled correctly </li>
1001:             *  <li>the originalValues for the DataStore are restored </li>
1002:             *  </ul>
1003:             */
1004:            public void endEdit() {
1005:                endEdit(true);
1006:            }
1007:
1008:            public void endEdit(boolean restoreData) {
1009:                if (!this .editingStarted)
1010:                    return;
1011:                this .editingStarted = false;
1012:                this .dataTable.stopEditing();
1013:                this .dataTable.setShowStatusColumn(false);
1014:                this .checkResultSetActions();
1015:                this .updateAction.setEnabled(false);
1016:                if (restoreData)
1017:                    this .dataTable.restoreOriginalValues();
1018:            }
1019:
1020:            public boolean startEdit() {
1021:                return startEdit(true);
1022:            }
1023:
1024:            /**
1025:             *	Starts the "edit" mode of the table. It will not start the edit
1026:             *  mode, if the table is "read only" meaning if no update table (=database
1027:             *  table) is defined.
1028:             *  The following actions are carried out:
1029:             *	<ul>
1030:             *	<li>if the updateable flag is not yet set, try to find out which table to update</li>
1031:             *  <li>the status column is displayec</li>
1032:             *  <li>the corresponding actions (insert row, delete row) are enabled</li>
1033:             *  <li>the startEdit action is turned to "switched on"</li>
1034:             *  </ul>
1035:             * @param restoreSelection if true the selected rows before starting the edit mode are restored
1036:             */
1037:            public boolean startEdit(boolean restoreSelection) {
1038:                if (this .readOnly)
1039:                    return false;
1040:
1041:                this .editingStarted = false;
1042:
1043:                final int[] selectedRows = this .dataTable.getSelectedRows();
1044:                final int currentRow = this .dataTable.getEditingRow();
1045:                final int currentColumn = this .dataTable.getEditingColumn();
1046:
1047:                Window w = SwingUtilities.getWindowAncestor(this );
1048:
1049:                // if the result is not yet updateable (automagically)
1050:                // then try to find the table. If the table cannot be
1051:                // determined, then ask the user
1052:                boolean updateTablePresent = this .checkUpdateTable();
1053:                boolean updateable = this .isUpdateable();
1054:
1055:                if (!updateable && !updateTablePresent) {
1056:                    // checkUpdateTable() will have taken every attempt to find an update table
1057:                    // including asking the user to select a table from a multi-table result set
1058:
1059:                    // So if we wind up here, there is no way to update the
1060:                    // underlying DataStore
1061:                    WbSwingUtilities.showErrorMessageKey(w, "MsgNoTables");
1062:                    this .setUpdateTable(null);
1063:                    this .disableUpdateActions();
1064:                    this .selectKeys.setEnabled(false);
1065:                    return false;
1066:                }
1067:
1068:                if (updateable) {
1069:                    this .dataTable.setShowStatusColumn(true);
1070:                    this .editingStarted = true;
1071:
1072:                    // When changing the table model (which is happening
1073:                    // when the status column is displayed) we need to restore
1074:                    // the current editing column/row
1075:                    if (restoreSelection) {
1076:                        if (currentRow > -1 && currentColumn > -1) {
1077:                            dataTable.selectCell(currentRow, currentColumn + 1);
1078:                            dataTable.setColumnSelectionAllowed(false);
1079:                        } else if (currentRow > -1) {
1080:                            dataTable.scrollToRow(currentRow);
1081:                            dataTable.setRowSelectionInterval(currentRow,
1082:                                    currentRow);
1083:                        } else if (selectedRows != null) {
1084:                            ListSelectionModel model = dataTable
1085:                                    .getSelectionModel();
1086:                            model.setValueIsAdjusting(true);
1087:                            // make sure nothing is selected, then restore the old selection
1088:                            model.clearSelection();
1089:                            for (int i = 0; i < selectedRows.length; i++) {
1090:                                model.addSelectionInterval(selectedRows[i],
1091:                                        selectedRows[i]);
1092:                            }
1093:                            model.setValueIsAdjusting(false);
1094:                        }
1095:                        dataTable.requestFocusInWindow();
1096:                    }
1097:
1098:                    EventQueue.invokeLater(new Runnable() {
1099:                        public void run() {
1100:                            checkResultSetActions();
1101:                        }
1102:                    });
1103:                } else {
1104:                    String msg = null;
1105:                    TableIdentifier tbl = (this .dataTable.getDataStore() != null ? this .dataTable
1106:                            .getDataStore().getUpdateTable()
1107:                            : null);
1108:                    if (tbl == null) {
1109:                        msg = ResourceMgr.getString("MsgNoUpdateTable");
1110:                    } else if (!this .hasUpdateableColumns()) {
1111:                        msg = ResourceMgr.getString("MsgNoUpdateColumns");
1112:                        msg = StringUtil.replace(msg, "%table%", tbl
1113:                                .getTableExpression());
1114:                    }
1115:                    WbSwingUtilities.showErrorMessage(w, msg);
1116:                }
1117:
1118:                return updateable;
1119:            }
1120:
1121:            public InsertRowAction getInsertRowAction() {
1122:                return this .insertRow;
1123:            }
1124:
1125:            public CopyRowAction getCopyRowAction() {
1126:                return this .duplicateRow;
1127:            }
1128:
1129:            public DeleteRowAction getDeleteRowAction() {
1130:                return this .deleteRow;
1131:            }
1132:
1133:            public DeleteDependentRowsAction getDeleteDependentRowsAction() {
1134:                return this .deleteDependentRow;
1135:            }
1136:
1137:            public UpdateDatabaseAction getUpdateDatabaseAction() {
1138:                return this .updateAction;
1139:            }
1140:
1141:            /**
1142:             *	Turns on the batchUpdate mode.
1143:             *  In this mode, the automatic switch to edit mode is disabled. This
1144:             *  is used when populating the table from the database otherwise, the
1145:             *  first row, which is retrieved will start the edit mode
1146:             */
1147:            public void setBatchUpdate(boolean aFlag) {
1148:                this .batchUpdate = aFlag;
1149:            }
1150:
1151:            public RowActionMonitor getRowMonitor() {
1152:                return this .genericRowMonitor;
1153:            }
1154:
1155:            /**
1156:             *	If the user changes something in the result set (which is possible, as
1157:             *  the table defaults to beeing editable) the edit mode (with status column
1158:             *  and the different actions enabled) is switched on automatically.
1159:             */
1160:            public void tableChanged(TableModelEvent e) {
1161:                if (this .batchUpdate)
1162:                    return;
1163:                if (this .readOnly)
1164:                    return;
1165:
1166:                if (!editingStarted
1167:                        && e.getFirstRow() != TableModelEvent.ALL_COLUMNS
1168:                        && e.getFirstRow() != TableModelEvent.HEADER_ROW
1169:                        && this .isModified()) {
1170:                    EventQueue.invokeLater(new Runnable() {
1171:                        public void run() {
1172:                            startEdit();
1173:                        }
1174:                    });
1175:                }
1176:            }
1177:
1178:            /**
1179:             *	This is called when the selection in the table changes.
1180:             *  The copy row action will be enabled when exactly one row
1181:             *  is selected
1182:             */
1183:            public void valueChanged(ListSelectionEvent e) {
1184:                if (this .readOnly)
1185:                    return;
1186:                checkResultSetActions();
1187:            }
1188:
1189:            /**
1190:             *	Called from the viewport, when the display has been scrolled
1191:             *  We need to update the row display then.
1192:             */
1193:            public void stateChanged(ChangeEvent e) {
1194:                this .rowCountChanged();
1195:            }
1196:
1197:            public void fatalError(String msg) {
1198:                WbSwingUtilities.showErrorMessage(this, msg);
1199:            }
1200:
1201:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.