Source Code Cross Referenced for GridView.java in  » Swing-Library » abeille-forms-designer » com » jeta » forms » gui » form » 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 » Swing Library » abeille forms designer » com.jeta.forms.gui.form 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2004 JETA Software, Inc.  All rights reserved.
0003:         * 
0004:         * Redistribution and use in source and binary forms, with or without modification, 
0005:         * are permitted provided that the following conditions are met:
0006:         *
0007:         *  o Redistributions of source code must retain the above copyright notice, 
0008:         *    this list of conditions and the following disclaimer.
0009:         *
0010:         *  o Redistributions in binary form must reproduce the above copyright notice, 
0011:         *    this list of conditions and the following disclaimer in the documentation 
0012:         *    and/or other materials provided with the distribution.
0013:         *
0014:         *  o Neither the name of JETA Software nor the names of its contributors may 
0015:         *    be used to endorse or promote products derived from this software without 
0016:         *    specific prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
0020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
0021:         * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
0022:         * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
0023:         * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0024:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
0025:         * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
0026:         * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
0027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0028:         */
0029:
0030:        package com.jeta.forms.gui.form;
0031:
0032:        import java.awt.BorderLayout;
0033:        import java.awt.Component;
0034:        import java.awt.Container;
0035:        import java.awt.Rectangle;
0036:        import java.util.Collection;
0037:        import java.util.Iterator;
0038:        import java.util.LinkedList;
0039:
0040:        import javax.swing.JComponent;
0041:        import javax.swing.JLayeredPane;
0042:        import javax.swing.JPanel;
0043:        import javax.swing.JScrollPane;
0044:        import javax.swing.JViewport;
0045:
0046:        import com.jeta.forms.gui.common.FormException;
0047:        import com.jeta.forms.gui.common.FormSpecAdapter;
0048:        import com.jeta.forms.gui.common.FormUtils;
0049:        import com.jeta.forms.gui.components.ComponentFactory;
0050:        import com.jeta.forms.gui.components.ComponentSource;
0051:        import com.jeta.forms.gui.components.EmptyComponentFactory;
0052:        import com.jeta.forms.gui.effects.Paintable;
0053:        import com.jeta.forms.gui.effects.Painter;
0054:        import com.jeta.forms.logger.FormsLogger;
0055:        import com.jeta.forms.store.memento.FormGroupSet;
0056:        import com.jeta.forms.store.properties.effects.PaintProperty;
0057:        import com.jeta.forms.store.support.Matrix;
0058:        import com.jeta.open.gui.framework.JETAPanel;
0059:        import com.jeta.open.registry.JETARegistry;
0060:        import com.jgoodies.forms.layout.CellConstraints;
0061:        import com.jgoodies.forms.layout.ColumnSpec;
0062:        import com.jgoodies.forms.layout.FormLayout;
0063:        import com.jgoodies.forms.layout.RowSpec;
0064:
0065:        /**
0066:         * The <code>GridViewBase</code> is responsible for containing the parent
0067:         * container that contains the components on the form as well as rendering the
0068:         * grid lines during design mode as well as any background and fill effects for
0069:         * grid cells. The GridViewBase employs a JLayeredPane to separate the various
0070:         * elements of the view.
0071:         * 
0072:         * <pre>
0073:         * Containment Hierarchy:
0074:         * 
0075:         *  GridViewBase(this)
0076:         *      |
0077:         *       -- JLayeredPane (m_layered_pane)
0078:         *              |
0079:         *               -- GridViewBase.FormContainer (m_form &lt;-- FormLayout )
0080:         *              |        |
0081:         *              |         -- GridComponent1
0082:         *              |        |
0083:         *              |         -- GridComponent2
0084:         *              |        |
0085:         *              |         -- GridComponentN
0086:         *              |
0087:         *               -- CellPainter (m_cell_painter)
0088:         *              |
0089:         *               -- BackgroundPainter ( m_background_painter - bottom layer )
0090:         * </pre>
0091:         * 
0092:         * @author Jeff Tassin
0093:         */
0094:        public class GridView extends JETAPanel implements  Paintable,
0095:                FormAccessor, GridCellListener {
0096:            /**
0097:             * The JGoodies FormLayout for this view.
0098:             */
0099:            private FormLayout m_formlayout;
0100:
0101:            /**
0102:             * The container that contains the GridComponents. This is also the
0103:             * container whose layout manager is m_formlayout.
0104:             */
0105:            private FormContainer m_form;
0106:
0107:            /**
0108:             * The layered pane for this view [grid overlay] top [ form ] [ cell painter ]
0109:             * [background effects] bottom
0110:             */
0111:            private JLayeredPane m_layered_pane;
0112:
0113:            /**
0114:             * Paints the background effects for a form (i.e. texture, gradient, solid
0115:             * fill, image )
0116:             */
0117:            private BackgroundPainter m_background_painter;
0118:
0119:            /**
0120:             * Maintains a cache of row/column assignments for the GridComponents in
0121:             * this view. This allows us to quickly lookup a component based on the
0122:             * row/column position. Otherwise, we would need to do a linear lookup by
0123:             * iterating over all components in the view. This would be too inefficient
0124:             * when repainting.
0125:             */
0126:            private CellAssignmentCache m_assignment_cache = new CellAssignmentCache(
0127:                    this );
0128:
0129:            /**
0130:             * The object that renders the grid lines.
0131:             */
0132:            private GridOverlay m_overlay;
0133:
0134:            /**
0135:             * A cached LayoutInfo object from the FormLayout. This is needed because
0136:             * the FormLayout returns a copy. This makes painting very slow, so we need
0137:             * to cache it here.
0138:             */
0139:            private FormLayout.LayoutInfo m_layoutinfo = null;
0140:
0141:            /**
0142:             * Paints effects for individual cells in the grid.
0143:             */
0144:            private CellPainter m_cell_painter;
0145:
0146:            /**
0147:             * A matrix of PaintProperty objects that define the fill effects for
0148:             * individual cells in the grid. The matrix cells correspond to the cells in
0149:             * this view's grid. If a PaintProperty is found in the matrix at a given
0150:             * column/row, then it is used to fill the corresponding cell in this view.
0151:             */
0152:            private Matrix m_cell_painters = new Matrix(0, 0);
0153:
0154:            /**
0155:             * Defines the the column groups for this form See:
0156:             * {@link com.jgoodies.forms.layout.FormLayout#.setColumnGroups}
0157:             */
0158:            private FormGroupSet m_col_groups = new FormGroupSet();
0159:
0160:            /**
0161:             * Defines the row groups for this form. See:
0162:             * {@link com.jgoodies.forms.layout.FormLayout#.setRowGroups}
0163:             */
0164:            private FormGroupSet m_row_groups = new FormGroupSet();
0165:
0166:            /**
0167:             * A timestamp of the last time a nested form in this container was
0168:             * modified. This is primarily used to implement the fail-fast FormIterator
0169:             */
0170:            private long m_nested_mod_stamp = -1;
0171:
0172:            /**
0173:             * Flag that indicates if GridViewEvents should be fired.
0174:             */
0175:            private boolean m_events_enabled = false;
0176:
0177:            /**
0178:             * A list of GridViewListener objects that are interested in GridViewEvents
0179:             * from this object.
0180:             */
0181:            private LinkedList m_listeners = new LinkedList();
0182:
0183:            /**
0184:             * The various layers in this view
0185:             */
0186:            public static final Integer BACKGROUND_PAINTER_LAYER = new Integer(
0187:                    0);
0188:            public static final Integer CELL_PAINTER_LAYER = new Integer(1);
0189:            public static final Integer FORM_LAYER = new Integer(2);
0190:            public static final Integer OVERLAY_LAYER = new Integer(9);
0191:            public static final Integer FOCUS_LAYER = new Integer(10);
0192:
0193:            /**
0194:             * Creates a <code>GridView</code> with no rows and columns
0195:             */
0196:            public GridView() {
0197:                setOpaque(true);
0198:            }
0199:
0200:            /**
0201:             * Creates a <code>GridView</code> with the specified column and row
0202:             * specifications. The view is initialized which also creates the columns
0203:             * and rows.
0204:             * 
0205:             * @param colspecs
0206:             *            the encoded column specs (comma delimited) for the form layout
0207:             * @param rowspecs
0208:             *            the encoded row specs (comma delimited) for the form layout
0209:             */
0210:            public GridView(String colspecs, String rowspecs) {
0211:                initialize(colspecs, rowspecs);
0212:            }
0213:
0214:            /**
0215:             * Creates a <code>GridView</code> with the specified columns and rows.
0216:             * The default column and row specifications are applied.
0217:             * 
0218:             * @param cols
0219:             *            the number of columns to create
0220:             * @param row
0221:             *            the number of rows to create.
0222:             */
0223:            public GridView(int cols, int rows) {
0224:                initialize(cols, rows);
0225:            }
0226:
0227:            /**
0228:             * Adds the component at the given row and column. If a component already
0229:             * occupies cells specified by the constraints, it is not overwritten, and
0230:             * the call will still succeed.
0231:             * 
0232:             * @param gc
0233:             *            the grid component to add to this view.
0234:             * @param cc
0235:             *            the cell constraints to apply to the component.
0236:             */
0237:            public void addComponent(GridComponent gc, CellConstraints cc) {
0238:                gc.addListener(this );
0239:                m_form.add(gc, cc);
0240:                m_assignment_cache.addComponent(gc);
0241:
0242:                m_form.revalidate();
0243:                fireGridEvent(new GridViewEvent(this ,
0244:                        GridViewEvent.CELL_CHANGED));
0245:                unitTest();
0246:            }
0247:
0248:            /**
0249:             * Adds the component at the given row and column. If a component already
0250:             * occupies cells specified by the constraints, it is not overwritten, and
0251:             * the call will still succeed.
0252:             * 
0253:             * @param gc
0254:             *            the grid component to add to this view
0255:             * @param cc
0256:             *            the component constraints to apply to the component.
0257:             */
0258:            public void addComponent(GridComponent gc, ComponentConstraints cc) {
0259:                addComponent(gc, cc.createCellConstraints());
0260:            }
0261:
0262:            /**
0263:             * Adds a listener that wants to receive GridViewEvents from this view
0264:             * 
0265:             * @param listener
0266:             *            the listener to add to this view.
0267:             */
0268:            public void addListener(GridViewListener listener) {
0269:                if (listener != null && !m_listeners.contains(listener)) {
0270:                    m_listeners.add(listener);
0271:                }
0272:            }
0273:
0274:            /**
0275:             * cache the last component that was selected. This is needed for
0276:             * performance.
0277:             */
0278:            private GridComponent m_last_comp;
0279:
0280:            /**
0281:             * GridCellListener implementation. Here we are getting events from
0282:             * individual GridComponents owned by this view. Most events are simply
0283:             * forwarded up the chain as GridViewEvents.
0284:             */
0285:            public void cellChanged(GridCellEvent evt) {
0286:                if (evt.getId() == GridCellEvent.EDIT_COMPONENT) {
0287:                    fireGridEvent(new GridViewEvent(this ,
0288:                            GridViewEvent.EDIT_COMPONENT, evt));
0289:                } else if (evt.getId() == GridCellEvent.CELL_SELECTED) {
0290:                    fireGridEvent(new GridViewEvent(this ,
0291:                            GridViewEvent.CELL_SELECTED, evt));
0292:                    m_last_comp = (GridComponent) evt.getSource();
0293:                } else {
0294:                    fireGridEvent(new GridViewEvent(this ,
0295:                            GridViewEvent.CELL_CHANGED, evt));
0296:                }
0297:            }
0298:
0299:            /**
0300:             * Deselects all grid components in the view
0301:             */
0302:            public void deselectAll() {
0303:                if (m_last_comp != null)
0304:                    m_last_comp.setSelected(false);
0305:            }
0306:
0307:            /**
0308:             * Override so we can explicitly tell the form to layout as well.
0309:             */
0310:            public void doLayout() {
0311:                super .doLayout();
0312:                m_form.doLayout();
0313:            }
0314:
0315:            /**
0316:             * Sets the flag that indicates if events should be fired.
0317:             * 
0318:             * @param enable
0319:             *            set to true if GridViewEvents should be fired when this view
0320:             *            is changed.
0321:             */
0322:            public void enableEvents(boolean enable) {
0323:                m_events_enabled = enable;
0324:            }
0325:
0326:            /**
0327:             * Sends a GridViewEvent to all registered listeners. A GridViewEvent is
0328:             * fired when the view changes or one of its child GridComponents changes.
0329:             * This is only needed by the designer.
0330:             * 
0331:             * @param evt
0332:             *            the event to post to all registered listeners.
0333:             */
0334:            public void fireGridEvent(GridViewEvent evt) {
0335:                if (isEventsEnabled()) {
0336:                    if (evt.getId() != GridViewEvent.EDIT_COMPONENT
0337:                            && evt.getId() != GridViewEvent.CELL_SELECTED) {
0338:                        refreshView();
0339:                    }
0340:
0341:                    m_layoutinfo = null;
0342:                    Iterator iter = m_listeners.iterator();
0343:                    while (iter.hasNext()) {
0344:                        try {
0345:                            GridViewListener listener = (GridViewListener) iter
0346:                                    .next();
0347:                            listener.gridChanged(evt);
0348:                        } catch (Exception e) {
0349:                            FormsLogger.debug(e);
0350:                        }
0351:                    }
0352:                }
0353:            }
0354:
0355:            /**
0356:             * Helper method that creates empty components. During design mode, a grid
0357:             * is filled with empty components to provide a minimum space for each cell.
0358:             * Without these components, the grid cells could have a zero width or
0359:             * height when the size is set to <i>Preferred</i> for either the column
0360:             * and/or row.
0361:             * 
0362:             * @param view
0363:             *            the view to be initialized
0364:             * @param compsrc
0365:             *            the component source that is used to help create empty
0366:             *            component objects.
0367:             */
0368:            public static void fillCells(GridView view, ComponentSource compsrc) {
0369:                try {
0370:                    for (int col = 1; col <= view.getColumnCount(); col++) {
0371:                        for (int row = 1; row <= view.getRowCount(); row++) {
0372:                            EmptyComponentFactory factory = new EmptyComponentFactory(
0373:                                    compsrc);
0374:                            StandardComponent gc = (StandardComponent) factory
0375:                                    .createComponent("empty", view);
0376:                            view.addComponent(gc, new ReadOnlyConstraints(col,
0377:                                    row));
0378:                        }
0379:                    }
0380:                } catch (Exception e) {
0381:                    e.printStackTrace();
0382:                }
0383:            }
0384:
0385:            /**
0386:             * Returns the cell bounds at the given column and row.
0387:             * 
0388:             * @param col
0389:             *            the 1-based column
0390:             * @param row
0391:             *            the 1-based row
0392:             * @return the cell bounds at the given row/column.
0393:             */
0394:            public Rectangle getCellBounds(int col, int row) {
0395:                try {
0396:                    int org_x = getColumnOrgX(col);
0397:                    int org_y = getRowOrgY(row);
0398:                    int width = getColumnWidth(col);
0399:                    int height = getRowHeight(col);
0400:                    return new Rectangle(org_x, org_y, width, height);
0401:                } catch (Exception e) {
0402:                    System.out
0403:                            .println("GridView.getCellBounds exception:  col: "
0404:                                    + col + "  row: " + row);
0405:                    e.printStackTrace();
0406:                    return null;
0407:                }
0408:            }
0409:
0410:            /**
0411:             * Returns a Matrix object that contains the cell painter properties
0412:             * (PaintProperty) for cells that have fill effects.
0413:             * 
0414:             * @return A matrix of cell painters
0415:             */
0416:            public Matrix getCellPainters() {
0417:                FormUtils
0418:                        .safeAssert(m_cell_painters.getRowCount() == getRowCount());
0419:                FormUtils
0420:                        .safeAssert(m_cell_painters.getColumnCount() == getColumnCount());
0421:                return m_cell_painters;
0422:            }
0423:
0424:            /**
0425:             * Returns the number of columns in this view.
0426:             * 
0427:             * @return the number of columns in this view
0428:             */
0429:            public int getColumnCount() {
0430:                return m_formlayout.getColumnCount();
0431:            }
0432:
0433:            /**
0434:             * Returns the left location in pixels of the given column.
0435:             * 
0436:             * @param col
0437:             *            the 1-based column
0438:             * @return the column x-origin for the given column.
0439:             */
0440:            public int getColumnOrgX(int col) {
0441:                col--;
0442:                FormLayout.LayoutInfo linfo = getLayoutInfo();
0443:                return linfo.columnOrigins[col];
0444:            }
0445:
0446:            /**
0447:             * Returns a FormGroupSet that specifies the column groups for this view.
0448:             * 
0449:             * @return the column groups for this view
0450:             */
0451:            public FormGroupSet getColumnGroups() {
0452:                return m_col_groups;
0453:            }
0454:
0455:            /**
0456:             * Return a encoded string of all column specs for this view. Each column
0457:             * spec is separated by a comma.
0458:             * 
0459:             * @return the encoded ColumnSpecs for all rows in the view
0460:             */
0461:            public String getColumnSpecs() {
0462:                StringBuffer sbuff = new StringBuffer();
0463:                for (int col = 1; col <= getColumnCount(); col++) {
0464:                    ColumnSpec cs = getColumnSpec(col);
0465:                    if (col > 1)
0466:                        sbuff.append(",");
0467:
0468:                    String colspec = cs.toShortString();
0469:                    sbuff.append(FormSpecAdapter.fixup(colspec));
0470:                }
0471:
0472:                return sbuff.toString();
0473:            }
0474:
0475:            /**
0476:             * Returns the column width in pixels of the given column.
0477:             * 
0478:             * @param col
0479:             *            the 1-based column
0480:             * @return the width for the given column.
0481:             */
0482:            public int getColumnWidth(int col) {
0483:                col--;
0484:                FormLayout.LayoutInfo linfo = getLayoutInfo();
0485:                return linfo.columnOrigins[col + 1] - linfo.columnOrigins[col];
0486:            }
0487:
0488:            /**
0489:             * Returns the ColumnSpec associated with the given column.
0490:             * 
0491:             * @param col
0492:             *            the 1-based column
0493:             * @return the ColumnSpec for the given column
0494:             */
0495:            public ColumnSpec getColumnSpec(int col) {
0496:                return m_formlayout.getColumnSpec(col);
0497:            }
0498:
0499:            /**
0500:             * Returns the FormAccessor associated with this view. A FormAccessor is
0501:             * used to add/remove/iterate components on a form.
0502:             */
0503:            public FormAccessor getFormAccessor() {
0504:                return this ;
0505:            }
0506:
0507:            /**
0508:             * Do not call this method. It is used only for testing. Call iterator() if
0509:             * you need to list the components in the view.
0510:             * 
0511:             * @deprecated
0512:             */
0513:            public Container getFormContainer() {
0514:                return m_form;
0515:            }
0516:
0517:            /**
0518:             * Returns the name assigned to the form component associated with this
0519:             * accessor.
0520:             * 
0521:             * @return the name assigned to the form component associated with this
0522:             *         accessor.
0523:             */
0524:            public String getFormName() {
0525:                return getName();
0526:            }
0527:
0528:            /**
0529:             * Returns the timestamp of the last time a child component was added or
0530:             * removed from the form associated with this view. This is primarily used
0531:             * to implement the fail-fast FormIterator
0532:             * 
0533:             * @return the timestamp of the last time this container was modified.
0534:             */
0535:            long getModificationStamp() {
0536:                return m_form.getModificationStamp();
0537:            }
0538:
0539:            /**
0540:             * Returns the timestamp of the last time a child component was added or
0541:             * removed from a nested form associated with this view. This is primarily
0542:             * used to implement the fail-fast FormIterator
0543:             * 
0544:             * @return the timestamp of the last time a nested form in this view was
0545:             *         modified.
0546:             */
0547:            long getNestedModificationStamp() {
0548:                return m_nested_mod_stamp;
0549:            }
0550:
0551:            /**
0552:             * Returns the number of rows in this view.
0553:             * 
0554:             * @return the number of rows in this view
0555:             */
0556:            public int getRowCount() {
0557:                return m_formlayout.getRowCount();
0558:            }
0559:
0560:            /**
0561:             * Return the layout manager (FormLayout) for the form.
0562:             * 
0563:             * @return the underlying form layout object.
0564:             */
0565:            public FormLayout getFormLayout() {
0566:                return m_formlayout;
0567:            }
0568:
0569:            /**
0570:             * Return the total width of the form as calculated by the FormLayout
0571:             * manager.
0572:             * 
0573:             * @return the width of the form as determined by the FormLayout manager
0574:             */
0575:            public int getFormWidth() {
0576:                FormLayout.LayoutInfo linfo = getLayoutInfo();
0577:                return linfo.getWidth();
0578:            }
0579:
0580:            /**
0581:             * Return the total height of the form as calculated by the FormLayout
0582:             * manager.
0583:             * 
0584:             * @return the height of the form as determined by the FormLayout manager
0585:             */
0586:            public int getFormHeight() {
0587:                FormLayout.LayoutInfo linfo = getLayoutInfo();
0588:                return linfo.getHeight();
0589:            }
0590:
0591:            /**
0592:             * Returns the GridComponent that occupies the cell at the given row/column.
0593:             * Null is returned if a component does not occupy the cell.
0594:             * 
0595:             * @return the grid component that occupies the cell at the given row/column
0596:             */
0597:            public GridComponent getGridComponent(int col, int row) {
0598:                return m_assignment_cache.getGridComponent(col, row);
0599:            }
0600:
0601:            /**
0602:             * Returns the total number of GridComponent objects contained by this form.
0603:             * 
0604:             * @return the number of grid components in this view
0605:             */
0606:            public int getGridComponentCount() {
0607:                return m_form.getComponentCount();
0608:            }
0609:
0610:            /**
0611:             * Returns the GridComponent at the given index in the parent container.
0612:             * 
0613:             * @param index
0614:             *            the 0-based index in the parent container.
0615:             * @return the grid component at the given index.
0616:             */
0617:            public GridComponent getGridComponent(int index) {
0618:                Object obj = m_form.getComponent(index);
0619:                if (obj instanceof  GridComponent)
0620:                    return (GridComponent) obj;
0621:                else
0622:                    return null;
0623:            }
0624:
0625:            /**
0626:             * Return the FormLayout.LayoutInfo.
0627:             * 
0628:             * @return the FormLayout.LayoutInfo. See:
0629:             *         {@link com.jgoodies.forms.layout.FormLayout.LayoutInfo }
0630:             */
0631:            FormLayout.LayoutInfo getLayoutInfo() {
0632:                /**
0633:                 * We need to cache this object because the FormLayout makes a copy
0634:                 * everytime getLayoutInfo is called. This slows down the system when
0635:                 * repainting or dragging the mouse.
0636:                 */
0637:                if (m_layoutinfo == null)
0638:                    m_layoutinfo = m_formlayout.getLayoutInfo(m_form);
0639:
0640:                return m_layoutinfo;
0641:            }
0642:
0643:            /**
0644:             * Return the fill property for the cell at the given column and row.
0645:             * 
0646:             * @param col
0647:             *            the 1-based column
0648:             * @param row
0649:             *            the 1-based row
0650:             * @return the painter at the given column and row. Null is returned if no
0651:             *         painter exists for that cell.
0652:             */
0653:            public PaintProperty getPaintProperty(int col, int row) {
0654:                Object obj = m_cell_painters.getValue(row - 1, col - 1);
0655:                if (obj instanceof  PaintProperty) {
0656:                    PaintProperty pp = (PaintProperty) obj;
0657:                    if (pp != null)
0658:                        return pp;
0659:                    else
0660:                        return null;
0661:                } else {
0662:                    if (obj != null) {
0663:                        System.out
0664:                                .println("GridView.getPaintProperty failed  for col: "
0665:                                        + col
0666:                                        + " row: "
0667:                                        + row
0668:                                        + "  prop: "
0669:                                        + obj.getClass());
0670:                    }
0671:                    return null;
0672:                }
0673:            }
0674:
0675:            /**
0676:             * Returns the FormComponent that contains this GridView. Since the parent
0677:             * of this view is not a FormComponent, the component heirarhcy must be
0678:             * traversed until the first FormComponent instance is found.
0679:             * 
0680:             * @return the FormComponent that contains this view.
0681:             */
0682:            public FormComponent getParentForm() {
0683:                /**
0684:                 * the first parent should be a JETABean. The grandparent is actually
0685:                 * the FormComponent.
0686:                 */
0687:                Component cc = getParent();
0688:                while (cc != null && !(cc instanceof  java.awt.Window)) {
0689:                    if (cc instanceof  FormComponent) {
0690:                        FormComponent fc = (FormComponent) cc;
0691:                        FormUtils
0692:                                .safeAssert(fc.getBean().getDelegate() == this );
0693:                        return fc;
0694:                    }
0695:                    cc = cc.getParent();
0696:                }
0697:                FormUtils.safeAssert(false);
0698:                return null;
0699:            }
0700:
0701:            /**
0702:             * Returns the row height in pixels of the given row.
0703:             * 
0704:             * @param row
0705:             *            the 1-based row
0706:             * @return the row height for the given row.
0707:             */
0708:            public int getRowHeight(int row) {
0709:                row--;
0710:                FormLayout.LayoutInfo linfo = getLayoutInfo();
0711:                return linfo.rowOrigins[row + 1] - linfo.rowOrigins[row];
0712:            }
0713:
0714:            /**
0715:             * Returns the row origin in pixels of the given row.
0716:             * 
0717:             * @param row
0718:             *            the 1-based row
0719:             * @return the row y-origin for the given row.
0720:             */
0721:            public int getRowOrgY(int row) {
0722:                row--;
0723:                FormLayout.LayoutInfo linfo = getLayoutInfo();
0724:                return linfo.rowOrigins[row];
0725:            }
0726:
0727:            /**
0728:             * Returns the GridComponent that overlaps the cell at the given column and
0729:             * row.
0730:             * 
0731:             * @return the component that overlaps the cell at the given column and row.
0732:             *         If no component overlaps, then null is returned.
0733:             */
0734:            public GridComponent getOverlappingComponent(int col, int row) {
0735:                return m_assignment_cache.getOverlappingComponent(col, row);
0736:            }
0737:
0738:            /**
0739:             * Returns the GridOverlay associated with this view. The GridOverlay is
0740:             * responsible for rendering the grid lines when in design mode.
0741:             * 
0742:             * @return the GridOverlay associated with this view.
0743:             */
0744:            public GridOverlay getOverlay() {
0745:                return m_overlay;
0746:            }
0747:
0748:            /**
0749:             * Returns a FormGroupSet that specifies the row groups for this view.
0750:             * 
0751:             * @return the row groups for this view
0752:             */
0753:            public FormGroupSet getRowGroups() {
0754:                return m_row_groups;
0755:            }
0756:
0757:            /**
0758:             * Returns the row spec for the specified row.
0759:             * 
0760:             * @param row
0761:             *            the 1-based row
0762:             * @return the RowSpec for the given row.
0763:             */
0764:            public RowSpec getRowSpec(int row) {
0765:                FormUtils.safeAssert(row >= 1 && row <= getRowCount());
0766:                return m_formlayout.getRowSpec(row);
0767:            }
0768:
0769:            /**
0770:             * Return a encoded string of all row specs for this view. Each orow spec is
0771:             * separated by a comma.
0772:             * 
0773:             * @return the encoded RowSpecs for all rows in the view
0774:             */
0775:            public String getRowSpecs() {
0776:                StringBuffer sbuff = new StringBuffer();
0777:                for (int row = 1; row <= getRowCount(); row++) {
0778:                    RowSpec rs = getRowSpec(row);
0779:                    if (row > 1)
0780:                        sbuff.append(",");
0781:
0782:                    String rowspec = rs.toString();
0783:                    sbuff.append(FormSpecAdapter.fixup(rowspec));
0784:                }
0785:                return sbuff.toString();
0786:            }
0787:
0788:            /**
0789:             * Returns the first selected GridComponent found in the component hierarhcy
0790:             * of this container. Components in nested forms are checked as well.
0791:             * 
0792:             * @returns the first selected component it finds in the component hierarhcy
0793:             *          of this container.
0794:             */
0795:            public GridComponent getSelectedComponent() {
0796:                Iterator iter = gridIterator();
0797:                while (iter.hasNext()) {
0798:                    GridComponent gc = (GridComponent) iter.next();
0799:                    if (gc instanceof  FormComponent) {
0800:                        FormComponent cc = (FormComponent) gc;
0801:                        gc = cc.getSelectedComponent();
0802:                        if (gc != null)
0803:                            return gc;
0804:                    } else if (gc instanceof  FormContainerComponent) {
0805:                        FormContainerComponent cc = (FormContainerComponent) gc;
0806:                        gc = cc.getSelectedComponent();
0807:                        if (gc != null)
0808:                            return gc;
0809:                    } else {
0810:                        if (gc.isSelected())
0811:                            return gc;
0812:                    }
0813:                }
0814:                return null;
0815:            }
0816:
0817:            /**
0818:             * Call this only once to initialize to the default settings for a given
0819:             * number of rows and columns
0820:             * 
0821:             * @param cols
0822:             *            the number of columns in the view
0823:             * @param rows
0824:             *            the number of rows in the view
0825:             */
0826:            public void initialize(int cols, int rows) {
0827:                enableEvents(FormUtils.isDesignMode());
0828:                StringBuffer colspec = new StringBuffer();
0829:                for (int col = 1; col <= cols; col++) {
0830:                    if (col > 1)
0831:                        colspec.append(",");
0832:                    colspec.append("f:d:n");
0833:
0834:                }
0835:                StringBuffer rowspec = new StringBuffer();
0836:                for (int row = 1; row <= rows; row++) {
0837:                    if (row > 1)
0838:                        rowspec.append(",");
0839:                    rowspec.append("c:d:n");
0840:                }
0841:                initialize(colspec.toString(), rowspec.toString());
0842:                m_cell_painters = new Matrix(getRowCount(), getColumnCount());
0843:            }
0844:
0845:            /**
0846:             * Initializes the view. This should be called only once.
0847:             * 
0848:             * @param colspecs
0849:             *            the encoded column specs for the form layout
0850:             * @param rowspecs
0851:             *            the encoded row specs for the form layout
0852:             */
0853:            void initialize(String colspecs, String rowspecs) {
0854:                /**
0855:                 * This should not be needed since initialize should only be called
0856:                 * once. Just in case.
0857:                 */
0858:                removeAll();
0859:
0860:                /**
0861:                 * We need to handle the case where the FormLayout stores the encoded
0862:                 * string in a different form than it takes in the constructor. For
0863:                 * example, the FormLayout stores dlu sizes as dluX or dluY. However,
0864:                 * the FormSpec constructor cannot handle this form.
0865:                 */
0866:                colspecs = FormSpecAdapter.fixupSpecs(colspecs);
0867:                rowspecs = FormSpecAdapter.fixupSpecs(rowspecs);
0868:
0869:                FormUtils.safeAssert(m_formlayout == null);
0870:                setOpaque(true);
0871:
0872:                m_formlayout = new FormLayout(colspecs, rowspecs);
0873:                m_form = new FormContainer();
0874:                m_form.setOpaque(false);
0875:                m_form.setLayout(m_formlayout);
0876:
0877:                setLayout(new BorderLayout());
0878:
0879:                m_layered_pane = new JLayeredPane();
0880:                m_layered_pane.setOpaque(false);
0881:                m_layered_pane.setLayout(new JETALayerLayout());
0882:
0883:                m_background_painter = new BackgroundPainter();
0884:                m_cell_painter = new CellPainter(this );
0885:
0886:                m_layered_pane.add(m_background_painter,
0887:                        BACKGROUND_PAINTER_LAYER);
0888:                m_layered_pane.add(m_cell_painter, CELL_PAINTER_LAYER);
0889:                m_layered_pane.add(m_form, FORM_LAYER);
0890:                super .add(m_layered_pane, BorderLayout.CENTER);
0891:
0892:                if (FormUtils.isDesignMode()) {
0893:                    GridOverlayFactory factory = (GridOverlayFactory) JETARegistry
0894:                            .lookup(GridOverlayFactory.COMPONENT_ID);
0895:                    if (factory != null) {
0896:                        m_overlay = factory.createOverlay(this );
0897:                        ((JComponent) getFormContainer())
0898:                                .setBorder(javax.swing.BorderFactory
0899:                                        .createEmptyBorder(0, 0, 1, 1));
0900:                        m_layered_pane.add((JComponent) m_overlay,
0901:                                OVERLAY_LAYER);
0902:                    } else {
0903:                        FormUtils.safeAssert(false);
0904:                    }
0905:                }
0906:            }
0907:
0908:            /**
0909:             * Inserts a new column into the view at the given column index.
0910:             * 
0911:             * @param col
0912:             *            the 1-based column index where the new column will be
0913:             *            inserted.
0914:             * @param colspec
0915:             *            the specification for the new column.
0916:             * @param factory
0917:             *            a factory used to create components to insert into the empty
0918:             *            cells of the newly created column. This is generally an
0919:             *            EmptyComponentFactory.
0920:             */
0921:            public void insertColumn(int col, ColumnSpec colspec,
0922:                    ComponentFactory factory) throws FormException {
0923:                int old_col_count = getColumnCount();
0924:                /**
0925:                 * first instantiate all components in case an exception is thrown we
0926:                 * don't have an empty column
0927:                 */
0928:                LinkedList comps = new LinkedList();
0929:                for (int row = 1; row <= getRowCount(); row++) {
0930:                    GridComponent gc = factory.createComponent("test", this );
0931:                    comps.add(gc);
0932:                }
0933:
0934:                CellConstraints cc = new CellConstraints();
0935:                FormLayout layout = getFormLayout();
0936:
0937:                if (col > getColumnCount()) {
0938:                    col = getColumnCount() + 1;
0939:                    layout.appendColumn(colspec);
0940:                } else
0941:                    layout.insertColumn(col, colspec);
0942:
0943:                if (FormUtils.isDebug()) {
0944:                    Iterator iter = gridIterator();
0945:                    while (iter.hasNext()) {
0946:                        GridComponent curr_gc = (GridComponent) iter.next();
0947:                        if (curr_gc.getColumn() == col) {
0948:                            System.out
0949:                                    .println("GridView.insertRow failed at: col: "
0950:                                            + col
0951:                                            + " row: "
0952:                                            + curr_gc.getRow()
0953:                                            + "  gc: " + curr_gc);
0954:                        }
0955:                    }
0956:                }
0957:
0958:                Iterator iter = comps.iterator();
0959:                int row = 1;
0960:                while (iter.hasNext()) {
0961:                    GridComponent gc = (GridComponent) iter.next();
0962:                    addComponent(gc, cc.xy(col, row));
0963:                    row++;
0964:                }
0965:
0966:                m_cell_painters.insertColumn(col - 1);
0967:
0968:                FormUtils.safeAssert(getColumnCount() == (old_col_count + 1));
0969:                FormUtils
0970:                        .safeAssert(getGridComponentCount() == getColumnCount()
0971:                                * getRowCount());
0972:
0973:                updateColumnGroups();
0974:                fireGridEvent(new GridViewEvent(this ,
0975:                        GridViewEvent.COLUMN_ADDED));
0976:            }
0977:
0978:            /**
0979:             * Inserts a new row into the view at the given column index.
0980:             * 
0981:             * @param row
0982:             *            the 1-based row index where the new row will be inserted.
0983:             * @param rowspec
0984:             *            the specification for the new row.
0985:             * @param factory
0986:             *            a factory used to create components to insert into the empty
0987:             *            cells of the newly created row. This is generally an
0988:             *            EmptyComponentFactory.
0989:             */
0990:            public void insertRow(int row, RowSpec rowspec,
0991:                    ComponentFactory factory) throws FormException {
0992:                /**
0993:                 * first instantiate all components in case an exception is thrown we
0994:                 * don't have an empty row
0995:                 */
0996:                int old_row_count = getRowCount();
0997:                LinkedList comps = new LinkedList();
0998:                for (int col = 1; col <= getColumnCount(); col++) {
0999:                    GridComponent gc = factory.createComponent("", this );
1000:                    comps.add(gc);
1001:                }
1002:
1003:                CellConstraints cc = new CellConstraints();
1004:                FormLayout layout = getFormLayout();
1005:                if (row > getRowCount()) {
1006:                    row = getRowCount() + 1;
1007:                    layout.appendRow(rowspec);
1008:                } else
1009:                    layout.insertRow(row, rowspec);
1010:
1011:                if (FormUtils.isDebug()) {
1012:                    Iterator iter = gridIterator();
1013:                    while (iter.hasNext()) {
1014:                        GridComponent curr_gc = (GridComponent) iter.next();
1015:                        if (curr_gc.getRow() == row) {
1016:                            System.out
1017:                                    .println("GridView.insertRow failed at: col: "
1018:                                            + curr_gc.getColumn()
1019:                                            + " row: "
1020:                                            + row + "  gc: " + curr_gc);
1021:                        }
1022:                    }
1023:                }
1024:
1025:                Iterator iter = comps.iterator();
1026:                int col = 1;
1027:                while (iter.hasNext()) {
1028:                    // @todo provide a better naming strategy
1029:                    GridComponent gc = (GridComponent) iter.next();
1030:                    addComponent(gc, cc.xy(col, row));
1031:                    col++;
1032:                }
1033:
1034:                m_cell_painters.insertRow(row - 1);
1035:
1036:                FormUtils.safeAssert(getRowCount() == (old_row_count + 1));
1037:                FormUtils
1038:                        .safeAssert(getGridComponentCount() == getColumnCount()
1039:                                * getRowCount());
1040:                updateRowGroups();
1041:                fireGridEvent(new GridViewEvent(this , GridViewEvent.ROW_ADDED));
1042:            }
1043:
1044:            /**
1045:             * Return true if GridViewEvents will be fired from the view.
1046:             * 
1047:             * @return the flag that indicates if events should be fired.
1048:             */
1049:            public boolean isEventsEnabled() {
1050:                return m_events_enabled;
1051:            }
1052:
1053:            /**
1054:             * Return true if the grid lines are visible. This is only needed by the
1055:             * designer.
1056:             * 
1057:             * @return the grid overlay as visible/invisible
1058:             */
1059:            public boolean isGridVisible() {
1060:                return m_overlay.isGridVisible();
1061:            }
1062:
1063:            /**
1064:             * Returns an interator that iterates over the grid components
1065:             * (GridComponent objects) in this view.
1066:             * 
1067:             * @return an interator that iterates over the grid components in this view.
1068:             */
1069:            public Iterator gridIterator() {
1070:                return new ComponentIterator();
1071:            }
1072:
1073:            /**
1074:             * Creates a collection of all child grid components (GridComponent objects)
1075:             * in this view. This method only returns GridComponent objects.
1076:             * 
1077:             * @return a collection of GridComponents contained by this view.
1078:             */
1079:            public Collection listComponents() {
1080:                LinkedList list = new LinkedList();
1081:                Iterator iter = gridIterator();
1082:                while (iter.hasNext()) {
1083:                    Object obj = iter.next();
1084:                    FormUtils.safeAssert(obj instanceof  GridComponent);
1085:                    list.add(obj);
1086:                }
1087:                return list;
1088:            }
1089:
1090:            /**
1091:             * Updates any parameters that need to be updated if the view changed such
1092:             * as adding/deleting/editing a component, row, or column.
1093:             */
1094:            public void refreshView() {
1095:                syncCellAssignments();
1096:                revalidate();
1097:                repaint();
1098:            }
1099:
1100:            /**
1101:             * Removes the given column from the layout/view. Note that all components
1102:             * in the column are removed as well.
1103:             * 
1104:             * @param column
1105:             *            the 1-based index of the column to remove.
1106:             */
1107:            public void removeColumn(int column) {
1108:                if (column < 1 || column > getColumnCount()) {
1109:                    FormUtils.safeAssert(false);
1110:                    return;
1111:                }
1112:                m_cell_painters.removeColumn(column - 1);
1113:
1114:                LinkedList comps = new LinkedList();
1115:                Iterator iter = gridIterator();
1116:                while (iter.hasNext()) {
1117:                    GridComponent gc = (GridComponent) iter.next();
1118:                    if (gc.getColumn() == column) {
1119:                        comps.add(gc);
1120:                    }
1121:                }
1122:
1123:                iter = comps.iterator();
1124:                while (iter.hasNext()) {
1125:                    GridComponent gc = (GridComponent) iter.next();
1126:                    m_form.remove(gc);
1127:                }
1128:                m_formlayout.removeColumn(column);
1129:                updateColumnGroups();
1130:                fireGridEvent(new GridViewEvent(this ,
1131:                        GridViewEvent.COLUMN_DELETED));
1132:            }
1133:
1134:            /**
1135:             * Removes the given listener for the set of listeners that want events from
1136:             * this view
1137:             * 
1138:             * @param listener
1139:             *            the listener to remove
1140:             */
1141:            public void removeListener(GridViewListener listener) {
1142:                if (listener != null)
1143:                    m_listeners.remove(listener);
1144:            }
1145:
1146:            /**
1147:             * Removes the specified row from the layout/view. Note that all components
1148:             * in the row are removed as well.
1149:             * 
1150:             * @param row
1151:             *            the 1-based row to remove from the view.
1152:             */
1153:            public void removeRow(int row) {
1154:
1155:                if (row < 1 || row > getRowCount()) {
1156:                    FormUtils.safeAssert(false);
1157:                    return;
1158:                }
1159:
1160:                m_cell_painters.removeRow(row - 1);
1161:
1162:                LinkedList comps = new LinkedList();
1163:                Iterator iter = gridIterator();
1164:                while (iter.hasNext()) {
1165:                    GridComponent gc = (GridComponent) iter.next();
1166:                    if (gc.getRow() == row) {
1167:                        comps.add(gc);
1168:                    }
1169:                }
1170:
1171:                iter = comps.iterator();
1172:                while (iter.hasNext()) {
1173:                    GridComponent gc = (GridComponent) iter.next();
1174:                    m_form.remove(gc);
1175:                }
1176:                m_formlayout.removeRow(row);
1177:                updateRowGroups();
1178:                fireGridEvent(new GridViewEvent(this , GridViewEvent.ROW_DELETED));
1179:            }
1180:
1181:            /**
1182:             * Replaces a component in the view. Note that components cannot be deleted
1183:             * in the design view. They must be replaced with 'Empty' components if you
1184:             * want to simulate an empty cell.
1185:             */
1186:            public void replaceComponent(GridComponent newComp,
1187:                    GridComponent oldComp) {
1188:                CellConstraints cc = oldComp.getConstraints()
1189:                        .createCellConstraints();
1190:                setComponent(newComp, cc);
1191:                fireGridEvent(new GridViewEvent(this ,
1192:                        GridViewEvent.CELL_CHANGED));
1193:            }
1194:
1195:            /**
1196:             * Override so we can explicitly tell the child form to revalidate as well.
1197:             */
1198:            public void revalidate() {
1199:                if (m_form != null) {
1200:                    m_form.revalidate();
1201:                }
1202:                super .revalidate();
1203:            }
1204:
1205:            /**
1206:             * Sets an object used to render the fill effect for the entire form
1207:             * associated with this view.
1208:             * 
1209:             * @param p
1210:             *            the painter to set for this view.
1211:             */
1212:            public void setBackgroundPainter(Painter p) {
1213:                if (m_background_painter != null)
1214:                    m_background_painter.setBackgroundPainter(p);
1215:            }
1216:
1217:            /**
1218:             * Override setBounds so we can reset the layoutinfo.
1219:             */
1220:            public void setBounds(int x, int y, int width, int height) {
1221:                super .setBounds(x, y, width, height);
1222:                m_layoutinfo = null;
1223:            }
1224:
1225:            /**
1226:             * Sets the cell painters associated with this view
1227:             * 
1228:             * @param painters
1229:             *            a matrix of cell painters (PaintProperty objects)
1230:             */
1231:            public void setCellPainters(Matrix painters) {
1232:                if (painters == null) {
1233:                    m_cell_painters = new Matrix(getRowCount(),
1234:                            getColumnCount());
1235:                } else {
1236:                    m_cell_painters = painters;
1237:                    if ((painters.getRowCount() != getRowCount())
1238:                            || (painters.getColumnCount()) != (getColumnCount()))
1239:                        m_cell_painters = new Matrix(getRowCount(),
1240:                                getColumnCount());
1241:                }
1242:            }
1243:
1244:            /**
1245:             * Updates the columnspecrowspec for the given column
1246:             * 
1247:             * @param colspec
1248:             *            the new columnspec
1249:             * @param col
1250:             *            the column
1251:             */
1252:            public void setColumnSpec(int col, ColumnSpec colspec) {
1253:                FormLayout layout = getFormLayout();
1254:                ColumnSpec newspec = new ColumnSpec(colspec
1255:                        .getDefaultAlignment(), colspec.getSize(), colspec
1256:                        .getResizeWeight());
1257:                layout.setColumnSpec(col, newspec);
1258:                m_form.revalidate();
1259:                fireGridEvent(new GridViewEvent(this ,
1260:                        GridViewEvent.COLUMN_SPEC_CHANGED));
1261:            }
1262:
1263:            /**
1264:             * Sets the component at the given row and column. Removes any existing
1265:             * components that occupy cells which will contain the new component.
1266:             */
1267:            public void setComponent(GridComponent gc, CellConstraints cc) {
1268:
1269:                GridComponent oldcomp = getGridComponent(cc.gridX, cc.gridY);
1270:                if (oldcomp != null) {
1271:                    oldcomp.removeListener(this );
1272:                    m_form.remove(oldcomp);
1273:                }
1274:                gc.addListener(this );
1275:                m_form.add(gc, cc);
1276:                m_form.revalidate();
1277:                syncCellAssignments();
1278:
1279:                fireGridEvent(new GridViewEvent(this ,
1280:                        GridViewEvent.CELL_CHANGED));
1281:                unitTest();
1282:            }
1283:
1284:            /**
1285:             * Sets the component at the given row and column. Removes any existing
1286:             * components that occupy cells which will contain the new component. The
1287:             * component constraints determines the row and column.
1288:             * 
1289:             * @param gc
1290:             *            the grid component
1291:             * @param cc
1292:             *            the component constraints to set.
1293:             */
1294:            public void setComponent(GridComponent gc, ComponentConstraints cc) {
1295:                setComponent(gc, cc.createCellConstraints());
1296:            }
1297:
1298:            /**
1299:             * Sets the constraints for the given component. Note that you should not
1300:             * change the column and row assignments using this method.
1301:             * 
1302:             * @param gc
1303:             *            the grid component
1304:             * @param cc
1305:             *            the cell constraints to set.
1306:             */
1307:            public void setConstraints(GridComponent gc, CellConstraints cc) {
1308:                m_formlayout.setConstraints(gc, cc);
1309:                syncCellAssignments();
1310:                m_form.revalidate();
1311:                fireGridEvent(new GridViewEvent(this ,
1312:                        GridViewEvent.CELL_CHANGED, gc));
1313:            }
1314:
1315:            /**
1316:             * Sets the constraints for the given component. Note that you should not
1317:             * change the column and row assignments using this method.
1318:             * 
1319:             * @param gc
1320:             *            the grid component
1321:             * @param cc
1322:             *            the component constraints to set.
1323:             */
1324:            public void setConstraints(GridComponent gc, ComponentConstraints cc) {
1325:                setConstraints(gc, cc.createCellConstraints());
1326:            }
1327:
1328:            /**
1329:             * Sets the grid overlay as visible/invisible. This is only needed during
1330:             * design mode.
1331:             * 
1332:             * @param bvis
1333:             *            set to true to show the grid. set to false to hide the grid.
1334:             */
1335:            public void setGridVisible(boolean bvis) {
1336:                m_overlay.setGridVisible(bvis);
1337:            }
1338:
1339:            /**
1340:             * Sets the paint property for the given cell. This is the property the is
1341:             * responsible for the fill effect for the cell.
1342:             * 
1343:             * @param col
1344:             *            the 1-based column
1345:             * @param row
1346:             *            the 1-based row
1347:             */
1348:            public void setPaintProperty(int col, int row, PaintProperty pp) {
1349:                m_cell_painters.setValue(row - 1, col - 1, pp);
1350:                repaint();
1351:            }
1352:
1353:            /**
1354:             * Sets the column groups for this form. This call is ignored if the group
1355:             * contains columns that are invalid.
1356:             * 
1357:             * @param groups
1358:             *            the column groups to set for this form.
1359:             */
1360:            public void setColumnGroups(FormGroupSet groups) {
1361:                if (groups != null) {
1362:                    int[][] grp_idxs = groups.toArray();
1363:                    for (int index = 0; index < grp_idxs.length; index++) {
1364:                        int[] col_grp = grp_idxs[index];
1365:                        for (int colidx = 0; colidx < col_grp.length; colidx++) {
1366:                            int col = col_grp[colidx];
1367:                            if (col < 1 || col > getColumnCount()) {
1368:                                FormUtils.safeAssert(false);
1369:                                return;
1370:                            }
1371:                        }
1372:                    }
1373:                    m_formlayout.setColumnGroups(grp_idxs);
1374:                    m_col_groups = groups;
1375:                    fireGridEvent(new GridViewEvent(this ,
1376:                            GridViewEvent.COLUMN_GROUPS_CHANGED));
1377:                }
1378:            }
1379:
1380:            /**
1381:             * Sets the row groups for this form. This call is ignored if the group
1382:             * contains rows that are invalid.
1383:             * 
1384:             * @param groups
1385:             *            the row groups for this form.
1386:             */
1387:            public void setRowGroups(FormGroupSet groups) {
1388:                if (groups != null) {
1389:                    int[][] grp_idxs = groups.toArray();
1390:                    for (int index = 0; index < grp_idxs.length; index++) {
1391:                        int[] row_grp = grp_idxs[index];
1392:                        for (int rowidx = 0; rowidx < row_grp.length; rowidx++) {
1393:                            int row = row_grp[rowidx];
1394:                            if (row < 1 || row > getRowCount()) {
1395:                                FormUtils.safeAssert(false);
1396:                                return;
1397:                            }
1398:                        }
1399:                    }
1400:
1401:                    m_formlayout.setRowGroups(grp_idxs);
1402:                    m_row_groups = groups;
1403:                    fireGridEvent(new GridViewEvent(this ,
1404:                            GridViewEvent.ROW_GROUPS_CHANGED));
1405:                }
1406:            }
1407:
1408:            /**
1409:             * Updates the rowspec for the given row
1410:             * 
1411:             * @param rowspec
1412:             *            the new rowpsec
1413:             * @param row
1414:             *            the row
1415:             */
1416:            public void setRowSpec(int row, RowSpec rowspec) {
1417:                FormLayout layout = getFormLayout();
1418:
1419:                RowSpec newspec = new RowSpec(rowspec.getDefaultAlignment(),
1420:                        rowspec.getSize(), rowspec.getResizeWeight());
1421:                layout.setRowSpec(row, newspec);
1422:                m_form.revalidate();
1423:                fireGridEvent(new GridViewEvent(this ,
1424:                        GridViewEvent.ROW_SPEC_CHANGED));
1425:            }
1426:
1427:            /**
1428:             * Tells the CellAssignmentCache to update itself
1429:             */
1430:            private void syncCellAssignments() {
1431:                m_assignment_cache.sync();
1432:            }
1433:
1434:            /**
1435:             * FormAccessor implementation. Adds a bean to this container using the
1436:             * given constraints.
1437:             * 
1438:             * @param comp
1439:             *            the bean to add to the form.
1440:             * @param cc
1441:             *            the constraints for the bean. This must be a valid
1442:             *            CellConstraints instance.
1443:             */
1444:            public void addBean(Component comp, CellConstraints cc) {
1445:                if (comp == null) {
1446:                    System.err.println("addBean: comp cannot be null");
1447:                    return;
1448:                }
1449:
1450:                if (cc == null) {
1451:                    System.err.println("addBean: cc cannot be null");
1452:                    return;
1453:                }
1454:
1455:                m_form.add(comp, cc);
1456:                refreshView();
1457:            }
1458:
1459:            /**
1460:             * Return the cell constraints associated with the given component. The call
1461:             * is merely forwarded to the FormLayout instance.
1462:             * 
1463:             * @return the constraints associated with the given component.
1464:             * @throws NullPointerException
1465:             *             if component is null or has not been added to the Container
1466:             */
1467:            public CellConstraints getConstraints(Component comp) {
1468:                return getFormLayout().getConstraints(comp);
1469:            }
1470:
1471:            /**
1472:             * Return the actual container that has the given layout. This method should
1473:             * rarely be called. It is only provided for very limited cases.
1474:             * 
1475:             * @return the container associated with the FormLayout
1476:             */
1477:            public Container getContainer() {
1478:                return getFormContainer();
1479:            }
1480:
1481:            /**
1482:             * Defaults to beanIterator(false). See {@link #beanIterator(boolean)}
1483:             * 
1484:             * @return an iterator to all the Java Beans in this container. Beans in
1485:             *         nested containers are not included.
1486:             */
1487:            public Iterator beanIterator() {
1488:                return new FormIterator(this , false);
1489:            }
1490:
1491:            /**
1492:             * Returns an iterator to all Java Beans in this container. This iterator
1493:             * also supports iterating over nested containers if the nested flag is set
1494:             * to true.
1495:             * 
1496:             * @param nested
1497:             *            if true, all components in nested forms will be returned.
1498:             * @return an iterator to all the Java Beans in this container. Beans in
1499:             *         nested containers are included if nested is true.
1500:             */
1501:            public Iterator beanIterator(boolean nested) {
1502:                return new FormIterator(this , nested);
1503:            }
1504:
1505:            /**
1506:             * Removes a bean from the container associated with this accessor.
1507:             * 
1508:             * @param comp
1509:             *            the component to remove.
1510:             * @return the component that was removed. If this method fails for any
1511:             *         reason then null is returned.
1512:             */
1513:            public Component removeBean(Component comp) {
1514:                if (comp == null) {
1515:                    System.err.println("removeBean: comp cannot be null");
1516:                    return null;
1517:                }
1518:
1519:                return replaceBean(comp, null);
1520:            }
1521:
1522:            /**
1523:             * FormAccessor implementation. Removes a bean with the given name from this
1524:             * container.
1525:             * 
1526:             * @param compName
1527:             *            the name of the Java Bean to remove.
1528:             * @return the component that was removed. If this method fails for any
1529:             *         reason then null is returned.
1530:             */
1531:            public Component removeBean(String compName) {
1532:                if (compName == null) {
1533:                    System.err.println("removeBean: compName cannot be null");
1534:                    return null;
1535:                }
1536:
1537:                for (int index = 0; index < m_form.getComponentCount(); index++) {
1538:                    Component comp = m_form.getComponent(index);
1539:                    if (compName.equals(comp.getName())) {
1540:                        m_form.remove(comp);
1541:                        refreshView();
1542:                        return comp;
1543:                    } else if (comp instanceof  GridComponent) {
1544:                        GridComponent gc = (GridComponent) comp;
1545:                        Component bean = gc.getBeanChildComponent();
1546:                        if (bean != null && compName.equals(bean.getName())) {
1547:                            m_form.remove(comp);
1548:                            refreshView();
1549:                            return comp;
1550:                        } else if (bean instanceof  JScrollPane) {
1551:                            JScrollPane scroll = (JScrollPane) bean;
1552:                            JViewport viewport = scroll.getViewport();
1553:                            if (viewport != null) {
1554:                                bean = viewport.getView();
1555:                                if (bean != null
1556:                                        && compName.equals(bean.getName())) {
1557:                                    m_form.remove(scroll);
1558:                                    refreshView();
1559:                                    return scroll;
1560:                                }
1561:                            }
1562:                        }
1563:
1564:                    } else if (comp instanceof  JScrollPane) {
1565:                        JScrollPane scroll = (JScrollPane) comp;
1566:                        JViewport viewport = scroll.getViewport();
1567:                        if (viewport != null) {
1568:                            Component bean = viewport.getView();
1569:                            if (bean != null && compName.equals(bean.getName())) {
1570:                                m_form.remove(comp);
1571:                                refreshView();
1572:                                return comp;
1573:                            }
1574:                        }
1575:                    }
1576:                }
1577:                return null;
1578:            }
1579:
1580:            /**
1581:             * FormAccessor implementation. Replaces an existing bean with a new bean.
1582:             * If the existing bean is not found, the request is ignored.
1583:             * 
1584:             * @param oldComp
1585:             *            the component to replace
1586:             * @param newComponent
1587:             *            the component to add.
1588:             * @return the component that was replaced. If this method fails for any
1589:             *         reason then null is returned.
1590:             */
1591:            public Component replaceBean(Component oldComp,
1592:                    Component newComponent) {
1593:                if (oldComp == null) {
1594:                    System.err
1595:                            .println("replaceBean: oldComponent cannot be null");
1596:                    return null;
1597:                }
1598:
1599:                Component comp = null;
1600:                CellConstraints cc = null;
1601:
1602:                for (int index = 0; index < m_form.getComponentCount(); index++) {
1603:                    comp = m_form.getComponent(index);
1604:                    cc = m_formlayout.getConstraints(comp);
1605:
1606:                    if (oldComp == comp) {
1607:                        break;
1608:                    } else if (comp instanceof  GridComponent) {
1609:                        GridComponent gc = (GridComponent) comp;
1610:                        Component bean = gc.getBeanChildComponent();
1611:                        if (bean instanceof  JScrollPane) {
1612:                            JScrollPane scroll = (JScrollPane) bean;
1613:                            JViewport viewport = scroll.getViewport();
1614:                            if (viewport != null) {
1615:                                Component vbean = viewport.getView();
1616:                                if (vbean == oldComp) {
1617:                                    comp = scroll;
1618:                                    break;
1619:                                }
1620:                            }
1621:                        }
1622:
1623:                        if (bean == oldComp) {
1624:                            break;
1625:                        }
1626:
1627:                    } else if (comp instanceof  JScrollPane) {
1628:                        JScrollPane scroll = (JScrollPane) comp;
1629:                        JViewport viewport = scroll.getViewport();
1630:                        if (viewport != null) {
1631:                            Component bean = viewport.getView();
1632:                            if (bean == oldComp) {
1633:                                break;
1634:                            }
1635:                        }
1636:                    }
1637:                    comp = null;
1638:                }
1639:
1640:                if (comp != null) {
1641:                    m_form.remove(comp);
1642:                    if (newComponent != null) {
1643:                        m_form.add(newComponent, cc);
1644:                    }
1645:                    refreshView();
1646:                    return comp;
1647:                }
1648:
1649:                System.err
1650:                        .println("replaceBean failed.  Unable to find oldComp: "
1651:                                + oldComp.getClass()
1652:                                + "  name: "
1653:                                + oldComp.getName());
1654:                return null;
1655:            }
1656:
1657:            /**
1658:             * FormAccessor implementation. Locates an existing bean with the given name
1659:             * and replaces it with a new bean. If the existing bean cannot be found,
1660:             * the request is ignored.
1661:             * 
1662:             * @param compName
1663:             *            the name of the component to replace
1664:             * @param newComponent
1665:             *            the component to add.
1666:             * @return the component that was replaced. If this method fails for any
1667:             *         reason null is returned.
1668:             */
1669:            public Component replaceBean(String compName, Component newComponent) {
1670:                if (compName == null) {
1671:                    System.err
1672:                            .println("replaceBean failed.  compName cannot be null. ");
1673:                    return null;
1674:                }
1675:
1676:                Iterator iter = beanIterator(false);
1677:                while (iter.hasNext()) {
1678:                    Component comp = (Component) iter.next();
1679:                    if (compName.equals(comp.getName())) {
1680:                        return replaceBean(comp, newComponent);
1681:                    }
1682:                }
1683:                System.err
1684:                        .println("replaceBean failed.  Unable to find compName: "
1685:                                + compName);
1686:                return null;
1687:            }
1688:
1689:            /**
1690:             * Runs unit test routines on this View. Internally used method.
1691:             */
1692:            private void unitTest() {
1693:                // JETATestFactory.runTest(
1694:                // "test.jeta.forms.gui.form.GridViewValidator", this );
1695:            }
1696:
1697:            /**
1698:             * Updates the local column groups reference so that it is consistent with
1699:             * the form layout. The column groups are stored in a FormGroupSet variable.
1700:             * This variable is updated to correspond to the column groups in the
1701:             * FormLayout.
1702:             */
1703:            public void updateColumnGroups() {
1704:                try {
1705:                    FormGroupSet gset = new FormGroupSet();
1706:                    int[][] groups = m_formlayout.getColumnGroups();
1707:                    for (int gindex = 0; gindex < groups.length; gindex++) {
1708:                        int[] cols = groups[gindex];
1709:                        if (cols != null) {
1710:                            Integer ckey = new Integer(gindex + 1);
1711:                            for (int cindex = 0; cindex < cols.length; cindex++) {
1712:                                gset.assignToGroup(ckey, cols[cindex]);
1713:                            }
1714:                        }
1715:                    }
1716:                    m_col_groups = gset;
1717:                } catch (Exception e) {
1718:                    FormsLogger.debug(e);
1719:                }
1720:            }
1721:
1722:            /**
1723:             * Updates the local row groups reference so that it is consistent with the
1724:             * form layout. The row groups are stored in a FormGroupSet variable. This
1725:             * variable is updated to correspond to the row groups in the FormLayout.
1726:             */
1727:            public void updateRowGroups() {
1728:                try {
1729:                    FormGroupSet gset = new FormGroupSet();
1730:                    int[][] groups = m_formlayout.getRowGroups();
1731:                    for (int gindex = 0; gindex < groups.length; gindex++) {
1732:                        int[] rows = groups[gindex];
1733:                        if (rows != null) {
1734:                            Integer rkey = new Integer(gindex + 1);
1735:                            for (int rindex = 0; rindex < rows.length; rindex++) {
1736:                                gset.assignToGroup(rkey, rows[rindex]);
1737:                            }
1738:                        }
1739:                    }
1740:                    m_row_groups = gset;
1741:                } catch (Exception e) {
1742:                    FormsLogger.debug(e);
1743:                }
1744:            }
1745:
1746:            /**
1747:             * Traverses the container hierarhcy of a given container and notifies all
1748:             * containers that are GridView instances that a nested form has changed.
1749:             * 
1750:             * @param c
1751:             *            the container whose parent containment hiearchy to traverse
1752:             * @param nestedModStamp
1753:             *            a time stamp indicating that a child component has changed.
1754:             *            This is needed to support fail-fast component iterators.
1755:             */
1756:            private void updateParentModicationStamps(Container c,
1757:                    long nestedModStamp) {
1758:                while (c != null) {
1759:                    if (c instanceof  GridView) {
1760:                        GridView gv = (GridView) c;
1761:                        gv.m_nested_mod_stamp = nestedModStamp;
1762:                    }
1763:                    c = c.getParent();
1764:                    if (c instanceof  java.awt.Window
1765:                            || c instanceof  javax.swing.JInternalFrame)
1766:                        break;
1767:                }
1768:            }
1769:
1770:            /**
1771:             * Used for iterating over the GridComponents in this view. This iterator
1772:             * accesses all child components of the form container. Only components that
1773:             * are GridComponent instances are returned by the iterator.
1774:             */
1775:            private class ComponentIterator implements  Iterator {
1776:                private int m_pos = -1;
1777:
1778:                public boolean hasNext() {
1779:                    int pos = m_pos + 1;
1780:                    while (pos < m_form.getComponentCount()) {
1781:                        Object obj = m_form.getComponent(pos);
1782:                        if (obj instanceof  GridComponent) {
1783:                            m_pos = pos - 1;
1784:                            return true;
1785:                        }
1786:                        pos++;
1787:                    }
1788:                    return false;
1789:                }
1790:
1791:                public Object next() {
1792:                    m_pos++;
1793:                    while (m_pos < m_form.getComponentCount()) {
1794:                        Object obj = m_form.getComponent(m_pos);
1795:                        if (obj instanceof  GridComponent)
1796:                            return obj;
1797:
1798:                    }
1799:                    throw new java.util.NoSuchElementException();
1800:                }
1801:
1802:                public void remove() {
1803:                    throw new UnsupportedOperationException();
1804:                }
1805:            }
1806:
1807:            /**
1808:             * This is the container that has the actual FormLayout. This class
1809:             * overrides JPanel mainly to intercept add/remove calls so the timestamp
1810:             * can be modified. We keep track of the timestamp to support fail-fast
1811:             * FormIterators.
1812:             */
1813:            private class FormContainer extends JPanel {
1814:                /**
1815:                 * A timestamp of the last time this container was modified. This is
1816:                 * primarily used to implement the fail-fast FormIterator
1817:                 */
1818:                private long m_mod_stamp;
1819:
1820:                protected void addImpl(Component comp, Object constraints,
1821:                        int index) {
1822:                    super .addImpl(comp, constraints, index);
1823:                    m_mod_stamp = System.currentTimeMillis();
1824:                    updateParentModicationStamps(GridView.this .getParent(),
1825:                            m_mod_stamp);
1826:                }
1827:
1828:                public void remove(int index) {
1829:                    super .remove(index);
1830:                    m_mod_stamp = System.currentTimeMillis();
1831:                    updateParentModicationStamps(GridView.this .getParent(),
1832:                            m_mod_stamp);
1833:                }
1834:
1835:                public void removeAll() {
1836:                    super .removeAll();
1837:                    m_mod_stamp = System.currentTimeMillis();
1838:                    updateParentModicationStamps(GridView.this .getParent(),
1839:                            m_mod_stamp);
1840:                }
1841:
1842:                /**
1843:                 * @return the timestamp of the last time this container was modified.
1844:                 *         This is primarily used to implement the fail-fast
1845:                 *         FormIterator
1846:                 */
1847:                long getModificationStamp() {
1848:                    return m_mod_stamp;
1849:                }
1850:            }
1851:
1852:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.