Source Code Cross Referenced for DataSetViewerEditableTablePanel.java in  » Database-Client » squirrel-sql-2.6.5a » net » sourceforge » squirrel_sql » fw » datasetviewer » 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 » squirrel sql 2.6.5a » net.sourceforge.squirrel_sql.fw.datasetviewer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sourceforge.squirrel_sql.fw.datasetviewer;
002:
003:        /*
004:         * Copyright (C) 2001-2003 Colin Bell
005:         * colbell@users.sourceforge.net
006:         *
007:         * This library is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU Lesser General Public
009:         * License as published by the Free Software Foundation; either
010:         * version 2.1 of the License, or (at your option) any later version.
011:         *
012:         * This library is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this library; if not, write to the Free Software
019:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020:         */
021:
022:        import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.CellComponentFactory;
023:        import net.sourceforge.squirrel_sql.fw.gui.SortableTableModel;
024:        import net.sourceforge.squirrel_sql.fw.gui.TablePopupMenu;
025:        import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
026:        import net.sourceforge.squirrel_sql.fw.util.StringManager;
027:
028:        import javax.swing.*;
029:        import javax.swing.table.TableColumnModel;
030:        import javax.swing.table.TableColumn;
031:        import java.awt.*;
032:        import java.awt.event.MouseAdapter;
033:        import java.awt.event.MouseEvent;
034:        import java.util.ArrayList;
035:
036:        /**
037:         * @author gwg
038:         *
039:         * Table view that allows editing of the data.
040:         */
041:        public class DataSetViewerEditableTablePanel extends
042:                DataSetViewerTablePanel {
043:
044:            private static final StringManager s_stringMgr = StringManagerFactory
045:                    .getStringManager(DataSetViewerEditableTablePanel.class);
046:
047:            /* Menu for right-mouse-click when in cell editors */
048:            TablePopupMenu cellPopupMenu = null;
049:
050:            /**
051:             * Internal definitions
052:             */
053:            public void init(IDataSetUpdateableModel updateableModel) {
054:                super .init(updateableModel);
055:                setUpdateableModelReference(updateableModel);
056:            }
057:
058:            ///////////////////////////////////////////////////////////////////////////
059:            //
060:            // Override the functions that need to be changed to tell the table
061:            // mechanisms how to do editing.
062:            //
063:            //////////////////////////////////////////////////////////////////////////
064:
065:            /**
066:             * Tell the table that it is editable.  This is called from within
067:             * MyTable.isCellEditable().  Certain column data types may not be editable.
068:             */
069:            public boolean isTableEditable() {
070:                return true;
071:            }
072:
073:            /**
074:             * Tell the table whether a particular column may be edited or not
075:             * based on whether the class associated with that column is known
076:             * or not known, where "not known" is signaled by Object.class.
077:             */
078:            public boolean isColumnEditable(int col, Object originalValue) {
079:                if (_colDefs == null)
080:                    return false; // cannot edit something that we do not know anything about
081:
082:                if (RowNumberTableColumn.ROW_NUMBER_MODEL_INDEX == col)
083:                    return false;
084:
085:                // Cannot edit the rowID column, if present
086:                if (((IDataSetUpdateableTableModel) getUpdateableModel())
087:                        .getRowidCol() == col)
088:                    return false;
089:
090:                return CellComponentFactory.isEditableInCell(_colDefs[col],
091:                        originalValue);
092:            }
093:
094:            /**
095:             * Function to set up CellEditors for each of the data types
096:             * to be handled in this table. Since different columns have different
097:             * parameters (e.g. nullable or not nullable) we set the cell editors on the columns
098:             * rather than on the table as a whole.
099:             */
100:            public void setCellEditors(JTable table) {
101:                // we need to table column model to be able to add CellEditors to the
102:                // individual columns
103:                cellPopupMenu = new TablePopupMenu(getUpdateableModel(), this ,
104:                        table);
105:
106:                for (int i = 0; i < _colDefs.length; i++) {
107:                    // use factory to get the appropriate editor
108:                    DefaultCellEditor editor = CellComponentFactory
109:                            .getInCellEditor(table, _colDefs[i]);
110:
111:                    // add right-click menu to cell editor
112:                    editor.getComponent().addMouseListener(new MouseAdapter() {
113:                        public void mousePressed(MouseEvent evt) {
114:                            if (evt.isPopupTrigger()) {
115:                                DataSetViewerEditableTablePanel.this .cellPopupMenu
116:                                        .show(evt.getComponent(), evt.getX(),
117:                                                evt.getY());
118:                            }
119:                        }
120:
121:                        public void mouseReleased(MouseEvent evt) {
122:                            if (evt.isPopupTrigger()) {
123:                                DataSetViewerEditableTablePanel.this .cellPopupMenu
124:                                        .show(evt.getComponent(), evt.getX(),
125:                                                evt.getY());
126:                            }
127:                        }
128:                    });
129:
130:                    // We have to look for the modelindex because of the Row Number column
131:                    getColumnForModelIndex(i, table.getColumnModel())
132:                            .setCellEditor(editor);
133:                }
134:            }
135:
136:            private TableColumn getColumnForModelIndex(int modelIndex,
137:                    TableColumnModel columnModel) {
138:                for (int i = 0; i < columnModel.getColumnCount(); i++) {
139:                    if (columnModel.getColumn(i).getModelIndex() == modelIndex) {
140:                        return columnModel.getColumn(i);
141:                    }
142:                }
143:
144:                throw new IllegalArgumentException("No column for model index "
145:                        + modelIndex);
146:            }
147:
148:            /**
149:             * Call the underlaying object to update the data represented by the JTable.
150:             * Both the old and the new value are objects of the appropriate
151:             * Data Type for the column.  The newValue has been validated as part of
152:             * the conversion from the external user representation (a String) into the
153:             * internal object.
154:             */
155:            public int[] changeUnderlyingValueAt(int row, int col,
156:                    Object newValue, Object oldValue) {
157:                String message = null;
158:
159:                // At this point the user input has been validated and both the
160:                // new and old values are objects of the appropriate data type.
161:                // Either or both of newValue and oldValue may be null.
162:
163:                // if there is no updateable model, then we cannot update anything
164:                // (should never happen - just being safe here)
165:                if (getUpdateableModelReference() == null)
166:                    return new int[0]; // no underlying data, so cannot be changed
167:
168:                // check to see if new data is same as old data, in which case we
169:                // do not update the underlying data.
170:                //
171:                // This is NOT an optimization (though it does
172:                // speed things up).  We need to do this to avoid an error when we check for
173:                // rows being changed in the DB.  If the new value and old value are the same,
174:                // when we look to see if any rows already exist with the new value, it will find
175:                // the existing row and claim that the update will make one row identical to the
176:                // changed row (i.e. that there will be two identical rows in the DB) which is
177:                // not true.  So we avoid the problem by not updating the DB if the data has not
178:                // been changed.  This can happen if user changes the cell contents, then changes
179:                // them back before exiting the cell.
180:
181:                // first look to see if they are identical objects, e.g. both null
182:                if (newValue == oldValue)
183:                    return new int[0]; // the caller does not need to know that nothing happened
184:
185:                // if either of the values is null and the other is not, then the data has
186:                // changed and we fall-through to the change process.  Otherwise, check
187:                // the object contents.
188:                if (oldValue != null && newValue != null) {
189:                    // ask the DataType object if the two values are the same
190:                    if (CellComponentFactory.areEqual(_colDefs[col], oldValue,
191:                            newValue))
192:                        return new int[0]; // the caller does not need to know that nothing happened
193:
194:                    // if we reach this point, the value has been changed,
195:                    // so fall through to next section
196:                }
197:
198:                // call the function in the app code that checks for unexpected
199:                // conditions in the current DB
200:                if (getUpdateableModelReference() != null)
201:                    message = ((IDataSetUpdateableTableModel) getUpdateableModelReference())
202:                            .getWarningOnCurrentData(getRow(row), _colDefs,
203:                                    col, oldValue);
204:
205:                if (message != null) {
206:                    // set up dialog to ask user if it is ok to proceed
207:                    // IMPORTANT: this dialog is SYNCHRONOUS (ie. we do not proceed until
208:                    // user gives a response).  This is critical since this function provides
209:                    // a return value to its caller that depends on the user input.
210:                    // i18n[baseDataSetViewerDestination.warning=Warning]
211:                    int option = JOptionPane
212:                            .showConfirmDialog(
213:                                    null,
214:                                    message,
215:                                    s_stringMgr
216:                                            .getString("baseDataSetViewerDestination.warning"),
217:                                    JOptionPane.YES_NO_OPTION,
218:                                    JOptionPane.WARNING_MESSAGE);
219:                    if (option != JOptionPane.YES_OPTION) {
220:                        return new int[0]; // no update done to underlying data
221:                    }
222:                }
223:
224:                // call the function in the app code that checks for unexpected
225:                // conditions in the DB as it will be after doing the update
226:                if (getUpdateableModelReference() != null)
227:                    message = ((IDataSetUpdateableTableModel) getUpdateableModelReference())
228:                            .getWarningOnProjectedUpdate(getRow(row), _colDefs,
229:                                    col, newValue);
230:
231:                if (message != null) {
232:                    // set up dialog to ask user if it is ok to proceed
233:                    // IMPORTANT: this dialog is SYNCHRONOUS (ie. we do not proceed until
234:                    // user gives a response).  This is critical since this function provides
235:                    // a return value to its caller that depends on the user input.
236:                    // i18n[baseDataSetViewerDestination.warning2=Warning]
237:                    int option = JOptionPane
238:                            .showConfirmDialog(
239:                                    null,
240:                                    message,
241:                                    s_stringMgr
242:                                            .getString("baseDataSetViewerDestination.warning2"),
243:                                    JOptionPane.YES_NO_OPTION,
244:                                    JOptionPane.WARNING_MESSAGE);
245:                    if (option != JOptionPane.YES_OPTION) {
246:                        return new int[0]; // no update done to underlying data
247:                    }
248:                }
249:
250:                // call the function in the app code that saves the data in the
251:                // persistant storage (e.g. a database).
252:                // The success or failure of that function (as indicated by the absance or
253:                // presence of a result errpor/warning message) determines the result of this call.
254:                // (Since the table is supposed to be editable, we should have an
255:                // IDataSetUpdateableTableModel object set in our super class.)
256:
257:                message = ((IDataSetUpdateableTableModel) getUpdateableModelReference())
258:                        .updateTableComponent(getRow(row), _colDefs, col,
259:                                oldValue, newValue);
260:
261:                if (message != null) {
262:                    // tell user that there was a problem
263:                    // i18n[baseDataSetViewerDestination.error=Error]
264:                    JOptionPane.showMessageDialog(null, message, s_stringMgr
265:                            .getString("baseDataSetViewerDestination.error"),
266:                            JOptionPane.ERROR_MESSAGE);
267:
268:                    // tell caller that the underlying data was not updated
269:                    //?? is this always true, or could the data be updated with a warning?
270:                    return new int[0];
271:                }
272:
273:                // No problems, so indicate a successful update of the underlying data.
274:                // In case we are editing an SQL result that contains the edited colum
275:                // more than once, we need to tell the caller to update all columns.
276:                // Otherwise generation of where clauses for further editing will fail.
277:                ArrayList<Integer> buf = new ArrayList<Integer>();
278:                for (int i = 0; i < _colDefs.length; i++) {
279:                    if (_colDefs[i].getFullTableColumnName().equalsIgnoreCase(
280:                            _colDefs[col].getFullTableColumnName())) {
281:                        buf.add(Integer.valueOf(i));
282:                    }
283:                }
284:
285:                int[] ret = new int[buf.size()];
286:
287:                for (int i = 0; i < ret.length; i++) {
288:                    ret[i] = buf.get(i);
289:                }
290:
291:                return ret;
292:            }
293:
294:            /**
295:             * Delete a set of rows from the table.
296:             * The indexes are the row indexes in the SortableModel.
297:             */
298:            public void deleteRows(int[] rows) {
299:                // The list of rows may be empty, in which case
300:                // we tell user they should select something first
301:                if (rows.length == 0) {
302:                    JOptionPane
303:                            .showMessageDialog(
304:                                    null,
305:                                    // i18n[dataSetViewerEditableTablePanel.selectionNeeded=You must select something in the table to delete.]
306:                                    s_stringMgr
307:                                            .getString("dataSetViewerEditableTablePanel.selectionNeeded"));
308:                    return;
309:                }
310:
311:                // i18n[dataSetViewerEditableTablePanel.deleteRosQuestion=Do you wish to delete {0} rows from this table?]
312:                String msg = s_stringMgr.getString(
313:                        "dataSetViewerEditableTablePanel.deleteRosQuestion",
314:                        rows.length);
315:
316:                // Non-empty set of rows to delete.  Make sure user wants to delete
317:                int option = JOptionPane
318:                        .showConfirmDialog(
319:                                null,
320:                                msg,
321:                                // i18n[dataSetViewerEditableTablePanel.warning=Warning]
322:                                s_stringMgr
323:                                        .getString("dataSetViewerEditableTablePanel.warning"),
324:                                JOptionPane.YES_NO_OPTION,
325:                                JOptionPane.WARNING_MESSAGE);
326:
327:                if (option != JOptionPane.YES_OPTION) {
328:                    return; // no update done to underlying data
329:                }
330:
331:                //cancel any current cell editing operations
332:                if (currentCellEditor != null) {
333:                    currentCellEditor.cancelCellEditing();
334:                    currentCellEditor = null;
335:                }
336:
337:                // create data structure containing contents of rows to be deleted
338:                // We cannot use the getRow() method because that uses MyJTable whereas
339:                // the indexes that we have are indexes in the SortableTableModel.
340:                SortableTableModel tableModel = (SortableTableModel) ((JTable) getComponent())
341:                        .getModel();
342:
343:                Object[][] rowData = new Object[rows.length][_colDefs.length];
344:                for (int i = 0; i < rows.length; i++) {
345:                    for (int j = 0; j < _colDefs.length; j++)
346:                        rowData[i][j] = tableModel.getValueAt(rows[i], j);
347:                }
348:
349:                // tell creator to delete from DB
350:                String message = ((IDataSetUpdateableTableModel) getUpdateableModel())
351:                        .deleteRows(rowData, _colDefs);
352:
353:                if (message != null) {
354:                    // tell user that there was a problem
355:                    JOptionPane
356:                            .showMessageDialog(
357:                                    null,
358:                                    // i18n[dataSetViewerEditableTablePanel.noRowsDeleted={0}\nNo rows deleted from database.]
359:                                    s_stringMgr
360:                                            .getString(
361:                                                    "dataSetViewerEditableTablePanel.noRowsDeleted",
362:                                                    message),
363:                                    // i18n[dataSetViewerEditableTablePanel.error=Error]
364:                                    s_stringMgr
365:                                            .getString("dataSetViewerEditableTablePanel.error"),
366:                                    JOptionPane.ERROR_MESSAGE);
367:
368:                    return;
369:                }
370:
371:                // DB delete worked correctly, so now delete from table
372:                //IMPORTANT: The user and the creator both work through the
373:                // SortableTableModel, not the Actual model.  Thus the row
374:                // indexes to delete are given in the SortableTableModel row numbers,
375:                // so we must work through that model model to actually do the delete.
376:                ((SortableTableModel) ((MyJTable) getComponent()).getModel())
377:                        .deleteRows(rows);
378:                ((MyJTable) getComponent()).clearSelection();
379:            }
380:
381:            /**
382:             * Initiate operations to insert a new row into the table.
383:             * This method just creates the panel to get the row input from the user.
384:             */
385:            public void insertRow() {
386:                JTable table = (JTable) getComponent();
387:
388:                // Setting the starting position is ugly.  I just picked a point.
389:                Point pt = new Point(10, 200);
390:
391:                Component comp = SwingUtilities.getRoot(table);
392:                Component newComp = null;
393:
394:                // get the default values from the DB for the table columns
395:                String[] dbDefaultValues = ((IDataSetUpdateableTableModel) getUpdateableModelReference())
396:                        .getDefaultValues(_colDefs);
397:
398:                // based on defaults from DB, get the default object instance
399:                // for each column
400:                Object[] initialValues = new Object[dbDefaultValues.length];
401:                for (int i = 0; i < initialValues.length; i++) {
402:                    initialValues[i] = CellComponentFactory.getDefaultValue(
403:                            _colDefs[i], dbDefaultValues[i]);
404:                }
405:
406:                // The following only works if SwingUtilities.getRoot(table) returns
407:                // and instanceof BaseMDIParentFrame.
408:                // If SwingTUilities.getRoot(table) returns and instance of Dialog or
409:                // Frame, then other code must be used.
410:                RowDataInputFrame rdif = new RowDataInputFrame(_colDefs,
411:                        initialValues, this );
412:                ((IMainFrame) comp).addInternalFrame(rdif, false);
413:                rdif.setLayer(JLayeredPane.POPUP_LAYER);
414:                rdif.pack();
415:                newComp = rdif;
416:
417:                Dimension dim = newComp.getSize();
418:                boolean dimChanged = false;
419:                if (dim.width < 300) {
420:                    dim.width = 300;
421:                    dimChanged = true;
422:                }
423:
424:                if (dimChanged) {
425:                    newComp.setSize(dim);
426:                }
427:
428:                // Determine the position to place the new internal frame. Ensure that the right end
429:                // of the internal frame doesn't exend past the right end the parent frame.	Use a
430:                // fudge factor as the dim.width doesn't appear to get the final width of the internal
431:                // frame (e.g. where pt.x + dim.width == parentBounds.width, the new internal frame
432:                // still extends past the right end of the parent frame).
433:                int fudgeFactor = 100;
434:                Rectangle parentBounds = comp.getBounds();
435:                if (parentBounds.width <= (dim.width + fudgeFactor)) {
436:                    dim.width = parentBounds.width - fudgeFactor;
437:                    pt.x = fudgeFactor / 2;
438:                    newComp.setSize(dim);
439:                } else {
440:                    if ((pt.x + dim.width + fudgeFactor) > (parentBounds.width)) {
441:                        pt.x -= (pt.x + dim.width + fudgeFactor)
442:                                - parentBounds.width;
443:                    }
444:                }
445:
446:                newComp.setLocation(pt);
447:                newComp.setVisible(true);
448:            }
449:
450:            /**
451:             * Insert a new row into the table after the user has entered the row's data.
452:             */
453:            protected String insertRow(Object[] values) {
454:
455:                String message = ((IDataSetUpdateableTableModel) getUpdateableModelReference())
456:                        .insertRow(values, _colDefs);
457:
458:                if (message != null) {
459:                    // there was a problem inserting into the DB
460:                    JOptionPane
461:                            .showMessageDialog(
462:                                    null,
463:                                    // i18n[dataSetViewereditableTablePanel.error2=Error]
464:                                    message,
465:                                    s_stringMgr
466:                                            .getString("dataSetViewereditableTablePanel.error2"),
467:                                    JOptionPane.ERROR_MESSAGE);
468:
469:                    return "Error"; // non-null return tells caller there was a problem
470:                }
471:
472:                // add the data to the existing tables
473:
474:                // Do not try to be fancy and insert the data where the user is looking,
475:                // just stuff it into the actual model and re-paint the table
476:                // when the 'table changed' event is fired.
477:
478:                SortableTableModel sortedModel = (SortableTableModel) ((JTable) getComponent())
479:                        .getModel();
480:
481:                sortedModel.insertRow(values);
482:
483:                // everything is ok
484:                return null;
485:            }
486:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.