Source Code Cross Referenced for SComponent.java in  » Swing-Library » wings3 » org » wings » 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 » wings3 » org.wings 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2000,2005 wingS development team.
0003:         *
0004:         * This file is part of wingS (http://wingsframework.org).
0005:         *
0006:         * wingS is free software; you can redistribute it and/or modify
0007:         * it under the terms of the GNU Lesser General Public License
0008:         * as published by the Free Software Foundation; either version 2.1
0009:         * of the License, or (at your option) any later version.
0010:         *
0011:         * Please see COPYING for the complete licence.
0012:         */
0013:        package org.wings;
0014:
0015:        import org.apache.commons.logging.Log;
0016:        import org.apache.commons.logging.LogFactory;
0017:        import org.wings.border.SBorder;
0018:        import org.wings.event.SComponentEvent;
0019:        import org.wings.event.SComponentListener;
0020:        import org.wings.event.SParentFrameEvent;
0021:        import org.wings.event.SParentFrameListener;
0022:        import org.wings.event.SRenderEvent;
0023:        import org.wings.event.SRenderListener;
0024:        import org.wings.io.Device;
0025:        import org.wings.plaf.ComponentCG;
0026:        import org.wings.plaf.Update;
0027:        import org.wings.script.JavaScriptListener;
0028:        import org.wings.script.ScriptListener;
0029:        import org.wings.session.Session;
0030:        import org.wings.session.SessionManager;
0031:        import org.wings.style.CSSAttributeSet;
0032:        import org.wings.style.CSSProperty;
0033:        import org.wings.style.CSSStyle;
0034:        import org.wings.style.CSSStyleSheet;
0035:        import org.wings.style.Selector;
0036:        import org.wings.style.Style;
0037:        import org.wings.util.ComponentVisitor;
0038:        import org.wings.util.SStringBuilder;
0039:
0040:        import javax.swing.Action;
0041:        import javax.swing.ActionMap;
0042:        import javax.swing.InputMap;
0043:        import javax.swing.JComponent;
0044:        import javax.swing.event.EventListenerList;
0045:        import java.awt.Color;
0046:        import java.awt.Rectangle;
0047:        import java.awt.event.ActionEvent;
0048:        import java.beans.BeanInfo;
0049:        import java.beans.Introspector;
0050:        import java.beans.PropertyDescriptor;
0051:        import java.io.IOException;
0052:        import java.io.ObjectInputStream;
0053:        import java.io.ObjectOutputStream;
0054:        import java.io.Serializable;
0055:        import java.lang.reflect.Array;
0056:        import java.lang.reflect.Method;
0057:        import java.util.Arrays;
0058:        import java.util.Collection;
0059:        import java.util.Collections;
0060:        import java.util.EventListener;
0061:        import java.util.HashMap;
0062:        import java.util.LinkedList;
0063:        import java.util.List;
0064:        import java.util.Map;
0065:
0066:        /**
0067:         * Object having a graphical representation that can be displayed on the
0068:         * screen and that can interact with the user.
0069:         *
0070:         * @author <a href="mailto:haaf@mercatis.de">Armin Haaf</a>
0071:         */
0072:        public abstract class SComponent implements  Cloneable, Serializable,
0073:                Renderable {
0074:
0075:            private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
0076:
0077:            private static final Log log = LogFactory.getLog(SComponent.class);
0078:
0079:            private static final int ACTION_CONDITIONS_AMOUNT = 2;
0080:
0081:            /* Components unique name. */
0082:            private String name;
0083:
0084:            /**
0085:             * the session
0086:             */
0087:            private transient Session session;
0088:
0089:            /**
0090:             * The code generation delegate, which is responsible for
0091:             * the visual representation of this component.
0092:             */
0093:            private transient ComponentCG cg;
0094:
0095:            /**
0096:             * Vertical alignment
0097:             */
0098:            private int verticalAlignment = SConstants.NO_ALIGN;
0099:
0100:            /**
0101:             * Horizontal alignment
0102:             */
0103:            private int horizontalAlignment = SConstants.NO_ALIGN;
0104:
0105:            /**
0106:             * The name of the style class
0107:             */
0108:            private String style;
0109:
0110:            /**
0111:             * Map of {@link Selector} to CSS {@link Style}s currently assigned to this component.
0112:             */
0113:            protected Map<Selector, Style> dynamicStyles;
0114:
0115:            /**
0116:             * Visibility of the component.
0117:             */
0118:            protected boolean visible = true;
0119:
0120:            /**
0121:             * Enabled / disabled.
0122:             */
0123:            protected boolean enabled = true;
0124:
0125:            /**
0126:             * The container, this component resides in.
0127:             */
0128:            private SContainer parent;
0129:
0130:            /**
0131:             * The frame in which this component resides.
0132:             */
0133:            private SFrame parentFrame;
0134:
0135:            /**
0136:             * The border for the component.
0137:             */
0138:            private SBorder border;
0139:
0140:            /**
0141:             * The tooltip for this component.
0142:             */
0143:            private String tooltip;
0144:
0145:            /**
0146:             * The focus traversal Index
0147:             */
0148:            private int focusTraversalIndex = -1;
0149:
0150:            /**
0151:             * Preferred size of component in pixel.
0152:             */
0153:            private SDimension preferredSize;
0154:
0155:            /**
0156:             * This is for performance optimizations. With this flag is set, property change
0157:             * events are generated and so every property setter method has to test if a property
0158:             * has changed and temporarily store the old value to generate the property
0159:             * change event
0160:             */
0161:            private boolean fireComponentChangeEvents = false;
0162:
0163:            /**
0164:             * Generate and fire {@link SParentFrameEvent}s. Performace optimitation
0165:             */
0166:            private boolean fireParentFrameChangeEvents = false;
0167:
0168:            /**
0169:             * Flag indiccating if {@link SRenderEvent}s should be fired. Used for performace reasons
0170:             */
0171:            private boolean fireRenderEvents = false;
0172:
0173:            /**
0174:             * All event listeners of this component
0175:             */
0176:            private EventListenerList listeners;
0177:
0178:            private boolean showAsFormComponent = true;
0179:
0180:            private boolean reloadForced = false;
0181:
0182:            private SPopupMenu popupMenu;
0183:
0184:            /*private boolean inheritsPopupMenu;*/
0185:
0186:            private InputMap[] inputMaps;
0187:
0188:            /**
0189:             * Contains all script listeners of the component.
0190:             */
0191:            private List<ScriptListener> scriptListenerList;
0192:
0193:            private ActionMap actionMap;
0194:
0195:            private Map<Action, ActionEvent> actionEvents;
0196:
0197:            private transient SRenderEvent renderEvent;
0198:
0199:            private SParentFrameListener globalInputMapListener;
0200:
0201:            private Map<Object, Object> clientProperties;
0202:
0203:            /**
0204:             * Internal constants for {@link #fireRenderEvent(int)}
0205:             */
0206:            public static final int START_RENDERING = 1;
0207:
0208:            /**
0209:             * Internal constants for {@link #fireRenderEvent(int)}
0210:             */
0211:            public static final int DONE_RENDERING = 2;
0212:
0213:            /**
0214:             * Constants for conditions on which actions are triggered. Mainly two
0215:             * cases: the focus has either to be at the component (or at a child)
0216:             * or somewhere in the parent frame.
0217:             *
0218:             * @see #setInputMap(int, javax.swing.InputMap)
0219:             */
0220:            public static final int WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT = 0;
0221:
0222:            /**
0223:             * Constants for conditions on which actions are triggered. Mainly two
0224:             * cases: the focus has either to be at the component (or at a child)
0225:             * or somewhere in the parent frame.
0226:             *
0227:             * @see #setInputMap(int, javax.swing.InputMap)
0228:             */
0229:            public static final int WHEN_IN_FOCUSED_FRAME = 1;
0230:
0231:            /**
0232:             * Global CSS selector 
0233:             */
0234:            public static final Selector SELECTOR_ALL = new Selector(
0235:                    "everything");
0236:
0237:            /**
0238:             * Performance improvement constant
0239:             */
0240:            private static final ScriptListener[] EMPTY_SCRIPTLISTENERLIST = new ScriptListener[0];
0241:
0242:            /**
0243:             * Default empty constructor.
0244:             * The method updateCG is called during construction time to get a cg delegate installed (renderer).
0245:             */
0246:            public SComponent() {
0247:                updateCG();
0248:            }
0249:
0250:            /**
0251:             * Returns the border of this component or null if no border has been set.
0252:             *
0253:             * @return the border object
0254:             * @see #setBorder(SBorder)
0255:             */
0256:            public SBorder getBorder() {
0257:                return border;
0258:            }
0259:
0260:            /**
0261:             * Sets the border for this component.
0262:             *
0263:             * @param border the border to be set for the component
0264:             */
0265:            public void setBorder(SBorder border) {
0266:                reloadIfChange(this .border, border);
0267:                if (this .border != null)
0268:                    this .border.setComponent(null);
0269:                this .border = border;
0270:                if (this .border != null)
0271:                    this .border.setComponent(this );
0272:            }
0273:
0274:            /**
0275:             * Return the parent container.
0276:             *
0277:             * @return the container this component resides in
0278:             */
0279:            public final SContainer getParent() {
0280:                return parent;
0281:            }
0282:
0283:            /**
0284:             * Sets the parent container. Also gets the parent frame from the parent.
0285:             *
0286:             * @param parent the container
0287:             */
0288:            public void setParent(SContainer parent) {
0289:                this .parent = parent;
0290:                if (parent != null)
0291:                    setParentFrame(parent.getParentFrame());
0292:                else
0293:                    setParentFrame(null);
0294:            }
0295:
0296:            /**
0297:             * Sets the parent frame.
0298:             *
0299:             * @param parentFrame the frame
0300:             */
0301:            protected void setParentFrame(SFrame parentFrame) {
0302:                if (this .parentFrame == parentFrame) {
0303:                    return;
0304:                }
0305:
0306:                if (this .parentFrame != null) {
0307:                    unregister();
0308:                    fireParentFrameEvent(new SParentFrameEvent(this ,
0309:                            SParentFrameEvent.PARENTFRAME_REMOVED,
0310:                            this .parentFrame));
0311:                }
0312:
0313:                this .parentFrame = parentFrame;
0314:
0315:                if (this .parentFrame != null) {
0316:                    register();
0317:                    // notify the listeners...
0318:                    fireParentFrameEvent(new SParentFrameEvent(this ,
0319:                            SParentFrameEvent.PARENTFRAME_ADDED,
0320:                            this .parentFrame));
0321:                }
0322:
0323:                if (this .popupMenu != null) {
0324:                    popupMenu.setParentFrame(parentFrame);
0325:                }
0326:
0327:                //reload();
0328:                if (getScriptListeners().length > 0)
0329:                    reload();
0330:                if (dynamicStyles != null && dynamicStyles.size() > 0)
0331:                    reload();
0332:            }
0333:
0334:            /*public void setInheritsPopupMenu(boolean inheritsPopupMenu) {
0335:                reloadIfChange(this.inheritsPopupMenu, inheritsPopupMenu);
0336:                this.inheritsPopupMenu = inheritsPopupMenu;
0337:            }
0338:
0339:            public boolean getInheritsPopupMenu() {
0340:                return inheritsPopupMenu;
0341:            }*/
0342:
0343:            public void setComponentPopupMenu(SPopupMenu popupMenu) {
0344:                reloadIfChange(this .popupMenu, popupMenu);
0345:                if (this .popupMenu != null) {
0346:                    getSession().getMenuManager().deregisterMenuLink(
0347:                            this .popupMenu, this );
0348:                    this .popupMenu.setParentFrame(null);
0349:                }
0350:                this .popupMenu = popupMenu;
0351:                if (this .popupMenu != null) {
0352:                    getSession().getMenuManager().registerMenuLink(
0353:                            this .popupMenu, this );
0354:                    this .popupMenu.setParentFrame(getParentFrame());
0355:                }
0356:            }
0357:
0358:            public SPopupMenu getComponentPopupMenu() {
0359:                /* (OL) we probably don't need the recursive stuff here... */
0360:                //        if (!getInheritsPopupMenu())
0361:                //            return popupMenu;
0362:                //
0363:                //        if (popupMenu == null) {
0364:                //            // Search parents for its popup
0365:                //            SContainer parent = getParent();
0366:                //            while (parent != null) {
0367:                //                if (parent instanceof SComponent) {
0368:                //                    return ((SComponent) parent).getComponentPopupMenu();
0369:                //                }
0370:                //                if (parent instanceof SFrame)
0371:                //                    break;
0372:                //
0373:                //                parent = parent.getParent();
0374:                //            }
0375:                //            return null;
0376:                //        }
0377:                return popupMenu;
0378:            }
0379:
0380:            /*  No reason -- even JComponent does not define such a method.
0381:                Undo change also in DynamicScriptResource.visit().
0382:            public boolean hasComponentPopupMenu() {
0383:                return popupMenu != null;
0384:            } */
0385:
0386:            /**
0387:             * The URL under which this component is accessible for the browser.
0388:             * This is equivalent to the URL of the component's root frame, as this is the
0389:             * node externalized to the browser via the {@link org.wings.resource.ReloadResource}
0390:             * externalizer.
0391:             *
0392:             * @return The HTTP URL where this component can be accessed.
0393:             */
0394:            public RequestURL getRequestURL() {
0395:                SFrame p = getParentFrame();
0396:                if (p == null)
0397:                    throw new IllegalStateException("no parent frame");
0398:
0399:                return p.getRequestURL();
0400:            }
0401:
0402:            /**
0403:             * Set the preferred size of the receiving component in pixel.
0404:             * It is not guaranteed that the component accepts this property because of
0405:             * missing implementations in the component cg or html properties.
0406:             * If <i>width</i> or <i>height</i> is zero, it is ignored and the browser
0407:             * defines the size.
0408:             *
0409:             * @see org.wings.SComponent#getPreferredSize
0410:             */
0411:            public void setPreferredSize(SDimension preferredSize) {
0412:                reloadIfChange(this .preferredSize, preferredSize);
0413:                this .preferredSize = preferredSize;
0414:            }
0415:
0416:            /**
0417:             * Get the preferred size of this component.
0418:             *
0419:             * @see SComponent#setPreferredSize
0420:             */
0421:            public SDimension getPreferredSize() {
0422:                return preferredSize;
0423:            }
0424:
0425:            /**
0426:             * Adds the specified component listener to receive component events from
0427:             * this component.
0428:             * If l is null, no exception is thrown and no action is performed.
0429:             *
0430:             * @param l the component listener.
0431:             * @see org.wings.event.SComponentEvent
0432:             * @see org.wings.event.SComponentListener
0433:             * @see org.wings.SComponent#removeComponentListener
0434:             */
0435:            public final void addComponentListener(SComponentListener l) {
0436:                addEventListener(SComponentListener.class, l);
0437:                fireComponentChangeEvents = true;
0438:            }
0439:
0440:            /**
0441:             * Removes the specified component listener so that it no longer
0442:             * receives component events from this component. This method performs
0443:             * no function, nor does it throw an exception, if the listener
0444:             * specified by the argument was not previously added to this component.
0445:             * If l is null, no exception is thrown and no action is performed.
0446:             *
0447:             * @param l the component listener.
0448:             * @see org.wings.event.SComponentEvent
0449:             * @see org.wings.event.SComponentListener
0450:             * @see org.wings.SComponent#addComponentListener
0451:             */
0452:            public final void removeComponentListener(SComponentListener l) {
0453:                removeEventListener(SComponentListener.class, l);
0454:            }
0455:
0456:            /**
0457:             * Registers a "parent frame listener" to receive events from
0458:             * this component when the parent frame chanegs i.e. via {@link #setParentFrame(SFrame)}.
0459:             * If l is null, no exception is thrown and no action is performed.
0460:             *
0461:             * @param l the parent frame listener. May be <code>null</code>.
0462:             * @see org.wings.event.SParentFrameEvent
0463:             * @see org.wings.event.SParentFrameListener
0464:             * @see org.wings.SComponent#removeParentFrameListener
0465:             * @see SComponent#removeNotify()
0466:             * @see SComponent#addNotify()
0467:             */
0468:            public final void addParentFrameListener(SParentFrameListener l) {
0469:                addEventListener(SParentFrameListener.class, l);
0470:                fireParentFrameChangeEvents = true;
0471:            }
0472:
0473:            /**
0474:             * Removes the specified parent frame listener so that it no longer
0475:             * receives events from this component. This method performs
0476:             * no function, nor does it throw an exception, if the listener
0477:             * specified by the argument was not previously added to this component.
0478:             * If l is null, no exception is thrown and no action is performed.
0479:             *
0480:             * @param l the parent frame listener.
0481:             * @see org.wings.event.SParentFrameEvent
0482:             * @see org.wings.event.SParentFrameListener
0483:             * @see org.wings.SComponent#addParentFrameListener
0484:             * @see SComponent#removeNotify()
0485:             * @see SComponent#addNotify()
0486:             */
0487:            public final void removeParentFrameListener(SParentFrameListener l) {
0488:                removeEventListener(SParentFrameListener.class, l);
0489:            }
0490:
0491:            /**
0492:             * Reports a component change.
0493:             *
0494:             * @param aEvent report this event to all listeners
0495:             * @see org.wings.event.SComponentListener
0496:             */
0497:            protected void fireComponentChangeEvent(SComponentEvent aEvent) {
0498:                // maybe the better way to do this is to user the getListenerList
0499:                // and iterate through all listeners, this saves the creation of
0500:                // an array but it must cast to the apropriate listener
0501:                Object[] listeners = getListenerList();
0502:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0503:                    if (listeners[i] == SComponentListener.class) {
0504:                        // Lazily create the event:
0505:                        processComponentEvent(
0506:                                (SComponentListener) listeners[i + 1], aEvent);
0507:                    }
0508:                }
0509:
0510:            }
0511:
0512:            /**
0513:             * Reports a parent frame change.
0514:             *
0515:             * @param aEvent report this event to all listeners
0516:             * @see org.wings.event.SParentFrameListener
0517:             */
0518:            private void fireParentFrameEvent(SParentFrameEvent aEvent) {
0519:                // are listeners registered?
0520:                if (fireParentFrameChangeEvents) {
0521:                    // maybe the better way to do this is to user the getListenerList
0522:                    // and iterate through all listeners, this saves the creation of
0523:                    // an array but it must cast to the apropriate listener
0524:                    Object[] listeners = getListenerList();
0525:                    for (int i = listeners.length - 2; i >= 0; i -= 2) {
0526:                        if (listeners[i] == SParentFrameListener.class) {
0527:                            // Lazily create the event:
0528:                            processParentFrameEvent(
0529:                                    (SParentFrameListener) listeners[i + 1],
0530:                                    aEvent);
0531:                        }
0532:                    }
0533:                }
0534:
0535:            }
0536:
0537:            /**
0538:             * Processes parent frame events occurring on this component by
0539:             * dispatching them to any registered
0540:             * <code>SParentFrameListener</code> objects.
0541:             * <p/>
0542:             */
0543:            private void processParentFrameEvent(SParentFrameListener listener,
0544:                    SParentFrameEvent event) {
0545:                int id = event.getID();
0546:                switch (id) {
0547:                case SParentFrameEvent.PARENTFRAME_ADDED:
0548:                    listener.parentFrameAdded(event);
0549:                    break;
0550:                case SParentFrameEvent.PARENTFRAME_REMOVED:
0551:                    listener.parentFrameRemoved(event);
0552:                    break;
0553:                }
0554:            }
0555:
0556:            /**
0557:             * Processes component events occurring on this component by
0558:             * dispatching them to any registered
0559:             * <code>SComponentListener</code> objects.
0560:             * <p/>
0561:             * This method is not called unless component events are
0562:             * enabled for this component. Component events are enabled
0563:             * when one of the following occurs:
0564:             * <p><ul>
0565:             * <li>A <code>SComponentListener</code> object is registered
0566:             * via <code>addComponentListener</code>.
0567:             * </ul>
0568:             *
0569:             * @param e the component event.
0570:             * @see org.wings.event.SComponentEvent
0571:             * @see org.wings.event.SComponentListener
0572:             * @see org.wings.SComponent#addComponentListener
0573:             */
0574:            protected void processComponentEvent(SComponentListener listener,
0575:                    SComponentEvent e) {
0576:                int id = e.getID();
0577:                switch (id) {
0578:                case SComponentEvent.COMPONENT_RESIZED:
0579:                    listener.componentResized(e);
0580:                    break;
0581:                case SComponentEvent.COMPONENT_MOVED:
0582:                    listener.componentMoved(e);
0583:                    break;
0584:                case SComponentEvent.COMPONENT_SHOWN:
0585:                    listener.componentShown(e);
0586:                    break;
0587:                case SComponentEvent.COMPONENT_HIDDEN:
0588:                    listener.componentHidden(e);
0589:                    break;
0590:                }
0591:            }
0592:
0593:            /**
0594:             * Adds the specified component listener to receive component events from
0595:             * this component.
0596:             * If l is null, no exception is thrown and no action is performed.
0597:             * If there is already a ScriptListener which is equal, the new one is not
0598:             * added.
0599:             *
0600:             * @param listener the component listener.
0601:             * @see org.wings.event.SComponentEvent
0602:             * @see org.wings.event.SComponentListener
0603:             * @see org.wings.SComponent#removeComponentListener
0604:             */
0605:            public final void addScriptListener(ScriptListener listener) {
0606:                if (scriptListenerList != null
0607:                        && scriptListenerList.contains(listener))
0608:                    return;
0609:
0610:                if (scriptListenerList == null) {
0611:                    scriptListenerList = new LinkedList<ScriptListener>();
0612:                }
0613:
0614:                int placingPosition = -1;
0615:                for (int i = 0; i < scriptListenerList.size()
0616:                        && placingPosition < 0; i++) {
0617:                    ScriptListener existingListener = scriptListenerList.get(i);
0618:                    if (existingListener.getPriority() < listener.getPriority())
0619:                        placingPosition = i;
0620:                }
0621:                reload();
0622:                if (placingPosition >= 0)
0623:                    scriptListenerList.add(placingPosition, listener);
0624:                else
0625:                    scriptListenerList.add(listener);
0626:            }
0627:
0628:            /**
0629:             * Removes the specified component listener so that it no longer
0630:             * receives component events from this component. This method performs
0631:             * no function, nor does it throw an exception, if the listener
0632:             * specified by the argument was not previously added to this component.
0633:             * If l is null, no exception is thrown and no action is performed.
0634:             *
0635:             * @param listener the component listener.
0636:             * @see org.wings.event.SComponentEvent
0637:             * @see org.wings.event.SComponentListener
0638:             * @see org.wings.SComponent#addComponentListener
0639:             */
0640:            public final void removeScriptListener(ScriptListener listener) {
0641:                if (scriptListenerList != null) {
0642:                    scriptListenerList.remove(listener);
0643:                    reload();
0644:                }
0645:            }
0646:
0647:            /**
0648:             * returns the script listeners of this component
0649:             *
0650:             * @return the ScriptListener Array.
0651:             */
0652:            public ScriptListener[] getScriptListeners() {
0653:                if (scriptListenerList != null) {
0654:                    return scriptListenerList
0655:                            .toArray(new ScriptListener[scriptListenerList
0656:                                    .size()]);
0657:                } else {
0658:                    return EMPTY_SCRIPTLISTENERLIST;
0659:                }
0660:            }
0661:
0662:            /**
0663:             * Returns the script listeners of this component.
0664:             *
0665:             * @return The <code>ScriptListener</code>s in a <code>List</code>.
0666:             */
0667:            public List<ScriptListener> getScriptListenerList() {
0668:                if (scriptListenerList != null) {
0669:                    return Collections.unmodifiableList(scriptListenerList);
0670:                } else {
0671:                    return Collections.emptyList();
0672:                }
0673:            }
0674:
0675:            /**
0676:             * Sets the name property of a component which must be <b>unique</b>!
0677:             * <br/>Assigning the same name multiple times will cause strange results!
0678:             * <p/>
0679:             * <p>Valid names must begin with a letter ([A-Za-z]), underscores ("_") or dollars ("$") and may be followed by any number of
0680:             * letters, digits ([0-9]), underscores ("_") and dollars ("$")
0681:             * <p/>
0682:             * <p>If no name is set, it is generated when necessary.
0683:             * <p/>
0684:             * <p><i>Explanation:</i> This property is an identifier which is used inside the generated HTML as an element identifier (id="")
0685:             * and sometimes as a javascript function name.
0686:             *
0687:             * @param uniqueName A <b>unique</b> name to set. <b>Only valid identifier as described are allowed!</b>
0688:             * @see Character
0689:             */
0690:            public void setName(String uniqueName) {
0691:                if (uniqueName != null) {
0692:                    char ch = uniqueName.charAt(0);
0693:                    if (uniqueName.length() == 0
0694:                            || !(Character.isLetter(ch) || ch == '_' || ch == '$'))
0695:                        throw new IllegalArgumentException(uniqueName
0696:                                + " is not a valid identifier");
0697:                    for (int i = 1; i < uniqueName.length(); i++) {
0698:                        ch = uniqueName.charAt(i);
0699:                        if (!(Character.isLetter(ch) || Character.isDigit(ch)
0700:                                || ch == '_' || ch == '$'))
0701:                            throw new IllegalArgumentException(uniqueName
0702:                                    + " is not a valid identifier");
0703:                    }
0704:                }
0705:                setNameRaw(uniqueName);
0706:            }
0707:
0708:            /**
0709:             * <b>Direct setter for name. Do not use unless you explicitly know what you're doing!</b>
0710:             * (Former package) protected raw setter for component name to avoid sanity check.
0711:             *
0712:             * @param uncheckedName String to use as componentn name/identifier.
0713:             */
0714:            public void setNameRaw(String uncheckedName) {
0715:                reloadIfChange(this .name, uncheckedName);
0716:                this .name = uncheckedName;
0717:            }
0718:
0719:            /**
0720:             * Gets the name property of a component. This property is an identifier,so it should be always unique.
0721:             * For details refer to {@link #setName(String)}
0722:             *
0723:             * @return The name of the component.
0724:             */
0725:            public final String getName() {
0726:                if (name == null)
0727:                    name = getSession().createUniqueId();
0728:                return name;
0729:            }
0730:
0731:            /**
0732:             * Return the session this component belongs to.
0733:             *
0734:             * @return the session
0735:             */
0736:            public final Session getSession() {
0737:                if (session == null) {
0738:                    session = SessionManager.getSession();
0739:                }
0740:
0741:                return session;
0742:            }
0743:
0744:            /*
0745:             * If a subclass implements the {@link LowLevelEventListener} interface,
0746:             * it will be unregistered at the associated dispatcher.
0747:             */
0748:            final void unregister() {
0749:                if (getSession().getDispatcher() != null
0750:                        && this  instanceof  LowLevelEventListener) {
0751:                    getSession().getDispatcher().unregister(
0752:                            (LowLevelEventListener) this );
0753:                }
0754:            }
0755:
0756:            /*
0757:             * If a subclass implements the {@link LowLevelEventListener} interface,
0758:             * it will be registered at the associated dispatcher.
0759:             */
0760:            final void register() {
0761:                if (getSession().getDispatcher() != null
0762:                        && this  instanceof  LowLevelEventListener) {
0763:                    getSession().getDispatcher().register(
0764:                            (LowLevelEventListener) this );
0765:                }
0766:            }
0767:
0768:            /**
0769:             * Set an CSS class name provided by the laf-provided Cascading Style Sheet (CSS), which should
0770:             * be applied to this component.
0771:             * <p>
0772:             * <b>Note:</b> Probably the {@link #addStyle(String)} method is more what you want.
0773:             * <p>By <b>default</b> this is set to the wingS component class name (i.e. "SLabel").
0774:             * <p>The PLAFs render the value of this String to an <code>class="<i>cssClassName</i>"</code> attribute
0775:             * inside the generated HTML code of this component.
0776:             * <p>The default wingS plaf initializes this by default to the wingS component class name
0777:             * (i.e. <code>SButton</code> for button instances). <br/>Please be aware if you <b>replace</b> this
0778:             * default value, the default wingS style will no longer take effect, as they operate on these
0779:             * default styles. To avoid this you should append your CSS styles via spaces i.e.<br>
0780:             * <code>c.setStyle(c.getStyle + "myStyle");</code>
0781:             *
0782:             * @param cssClassName The new CSS name value for this component
0783:             * @see #addStyle(String)
0784:             * @see #removeStyle(String)
0785:             */
0786:            // <p>Please consider using {@link #addStyle(String)} to avoid disabling of default wingS stylesheet set.
0787:            public void setStyle(String cssClassName) {
0788:                reloadIfChange(style, cssClassName);
0789:                this .style = cssClassName;
0790:            }
0791:
0792:            /**
0793:             * Append a style class name to the style string. Use this method if you want to append a specific CSS
0794:             * class to a componentn without loosing the other CSS styles assigned to the component (i.e. the wingS
0795:             * default styles.)
0796:             * @param additionalCssClassName The style class to remove (if existing).
0797:             * @see #removeStyle(String)
0798:             */
0799:            public void addStyle(String additionalCssClassName) {
0800:                if (this .style == null || this .style.length() == 0) {
0801:                    setStyle(additionalCssClassName); // trivial case
0802:                } else {
0803:                    if (this .style.indexOf(additionalCssClassName) < 0) {
0804:                        setStyle(this .style + " " + additionalCssClassName);
0805:                    }
0806:                }
0807:            }
0808:
0809:            /**
0810:             * Remove a style class definiton from this component.
0811:             * @param cssStyleClassName The style class to remove (if existing).
0812:             */
0813:            public void removeStyle(String cssStyleClassName) {
0814:                if (this .style != null && cssStyleClassName != null
0815:                        && this .style.indexOf(cssStyleClassName) >= 0) {
0816:                    if (this .style.length() == cssStyleClassName.length())
0817:                        setStyle(null); // trivial case
0818:                    else
0819:                        setStyle(this .style.replaceAll(
0820:                                "\\b" + cssStyleClassName + "\\b", "")
0821:                                .replaceAll("  ", " ").trim());
0822:                }
0823:            }
0824:
0825:            /**
0826:             * @return The current CSS style class name. Defaults to the unqualified wingS component class name.
0827:             * @see #setStyle(String)
0828:             */
0829:            public String getStyle() {
0830:                return style;
0831:            }
0832:
0833:            /**
0834:             * Register a new CSS style on this component for a specfic CSS selector.
0835:             * <p>Typically you will want to use the method {@link #setAttribute(org.wings.style.CSSProperty, String)}
0836:             * to specify a single CSS property/value pair on this component.
0837:             *
0838:             * @param style A Style instance.
0839:             */
0840:            public void addDynamicStyle(Style style) {
0841:                if (dynamicStyles == null)
0842:                    dynamicStyles = new HashMap<Selector, Style>(4);
0843:                dynamicStyles.put(style.getSelector(), style);
0844:                reload();
0845:            }
0846:
0847:            /**
0848:             * Remove all CSS style definitions defined for the passed CSS selector.
0849:             *
0850:             * @param selector The selector. The default selector for most CSS attributes is {@link #SELECTOR_ALL}.
0851:             */
0852:            public void removeDynamicStyle(Selector selector) {
0853:                if (dynamicStyles == null)
0854:                    return;
0855:                dynamicStyles.remove(selector);
0856:                reload();
0857:            }
0858:
0859:            /**
0860:             * Returns the style defined for the passed CSS selector.
0861:             *
0862:             * @param selector The CSS selector the style to retrieve. See {@link org.wings.style.Style#getSelector()}.
0863:             *         The default selector for most CSS styles is {@link #SELECTOR_ALL}.
0864:             * @return A style (collection of css property/value pairs) or <code>null</code>
0865:             */
0866:            public Style getDynamicStyle(Selector selector) {
0867:                if (dynamicStyles == null)
0868:                    return null;
0869:                return dynamicStyles.get(selector);
0870:            }
0871:
0872:            /**
0873:             * Adds the passed collection of {@link Style} definitions. Existing Styles for the same CSS selectors
0874:             * (see {@link org.wings.style.Style#getSelector()}) are overwritten.
0875:             *
0876:             * @param dynamicStyles A collection collection of {@link Style} definitions.
0877:             */
0878:            public void setDynamicStyles(Collection dynamicStyles) {
0879:                if (dynamicStyles == null)
0880:                    return;
0881:                if (this .dynamicStyles == null)
0882:                    this .dynamicStyles = new HashMap<Selector, Style>(4);
0883:                for (Object dynamicStyle : dynamicStyles) {
0884:                    Style style = (Style) dynamicStyle;
0885:                    this .dynamicStyles.put(style.getSelector(), style);
0886:                }
0887:                reload();
0888:            }
0889:
0890:            /**
0891:             * Returns the collection of currently defined CSS styles on this component.
0892:             *
0893:             * @return A unmodifyable collection of {@link Style} instances.
0894:             */
0895:            public Collection getDynamicStyles() {
0896:                if (dynamicStyles == null || dynamicStyles.size() == 0)
0897:                    return null;
0898:                return Collections.unmodifiableCollection(dynamicStyles
0899:                        .values());
0900:            }
0901:
0902:            /**
0903:             * Defines a free text css property / value pair to this component.
0904:             * The CSS property will appear as an inline style in the generated HTML code.
0905:             */
0906:            public void setAttribute(String cssPropertyName, String value) {
0907:                final CSSProperty property = CSSProperty
0908:                        .valueOf(cssPropertyName);
0909:                if (CSSProperty.BORDER_PROPERTIES.contains(property))
0910:                    throw new IllegalArgumentException(
0911:                            "Border properties have to be applied to the border!");
0912:                setAttribute(SELECTOR_ALL, property, value);
0913:            }
0914:
0915:            /**
0916:             * Assign or overwrite a CSS property/value pair on this component. This CSS property definition will
0917:             * use a CSS selector which adresses this component as whole as CSS selector (<code>new CSSProperty(this)</code>).
0918:             * The CSS property will appear as an inline style in the generated HTML code.
0919:             *
0920:             * @param property      The CSS property (i.e. {@link CSSProperty#BACKGROUND}).
0921:             * @param propertyValue A valid string value for this CSS property (i.e. <code>red</code> or <code>#fff</code> in our example).
0922:             */
0923:            public void setAttribute(CSSProperty property, String propertyValue) {
0924:                if (CSSProperty.BORDER_PROPERTIES.contains(property))
0925:                    throw new IllegalArgumentException(
0926:                            "Border properties have to be applied to the border!");
0927:                setAttribute(SELECTOR_ALL, property, propertyValue);
0928:            }
0929:
0930:            /**
0931:             * Assign or overwrite a CSS property/value pair at this component. This CSS property definition will
0932:             * use the CSS selector you passed, so in the most exotic case it could affect a totally different
0933:             * component or component area. Typically you use this method to assign CSS property values to
0934:             * pseudo CSS selectors {@link Selector}. This are selector affecting only a part of a component
0935:             * and not the component at all..
0936:             * The CSS property will appear as an inline style in the generated HTML code.
0937:             *
0938:             * @param selector A valid CSS selector. Typically values are i.e. the {@link #SELECTOR_ALL}
0939:             * or other <code>SELECTOR_xxx</code> value instances declared in the component.
0940:             * (look ie. at {@link STabbedPane#SELECTOR_CONTENT}) or manually constructed instances of
0941:             * <code>Selector</code>. In most case {@link #setAttribute(org.wings.style.CSSProperty, String)} will be your
0942:             * choice.
0943:             * @param property The css property you want to define a value for
0944:             * @param propertyValue A valid string value for this property.
0945:             */
0946:            public void setAttribute(Selector selector, CSSProperty property,
0947:                    String propertyValue) {
0948:                Style style = getDynamicStyle(selector);
0949:                if (style == null) {
0950:                    addDynamicStyle(new CSSStyle(selector, property,
0951:                            propertyValue));
0952:                } else {
0953:                    String old = style.put(property, propertyValue);
0954:                    reloadIfChange(old, propertyValue);
0955:                }
0956:            }
0957:
0958:            /**
0959:             * Convenience variant of {@link #setAttribute(org.wings.style.Selector, org.wings.style.CSSProperty, String)}.
0960:             * Converts the passed icon into a URL and applies the according CSS style.
0961:             *
0962:             * @param selector A valid CSS selector. Typically values are i.e. the {@link #SELECTOR_ALL}
0963:             * or other <code>SELECTOR_xxx</code> value instances declared in the component.
0964:             * (look ie. at {@link STabbedPane#SELECTOR_CONTENT}) or manually constructed instances of
0965:             * <code>Selector</code>. In most case {@link #setAttribute(org.wings.style.CSSProperty, String)} will be your
0966:             * choice.
0967:             * @param property The css property you want to define a value for (in this case
0968:             *                 mostly something like {@link CSSProperty#BACKGROUND_IMAGE}.
0969:             * @param icon     The icon you want to assign.
0970:             */
0971:            public void setAttribute(Selector selector, CSSProperty property,
0972:                    SIcon icon) {
0973:                setAttribute(selector, property, icon != null ? "url('"
0974:                        + icon.getURL().toString() + "')" : "none");
0975:            }
0976:
0977:            /**
0978:             * Convenience variant of {@link #setAttribute(org.wings.style.Selector, org.wings.style.CSSProperty, String)}.
0979:             * Converts the passed color into according color string.
0980:             *
0981:             * @param selector A valid CSS selector. Typically values are i.e. the {@link #SELECTOR_ALL}
0982:             * or other <code>SELECTOR_xxx</code> value instances declared in the component.
0983:             * (look ie. at {@link STabbedPane#SELECTOR_CONTENT}) or manually constructed instances of
0984:             * <code>Selector</code>. In most case {@link #setAttribute(org.wings.style.CSSProperty, String)} will be your
0985:             * choice.
0986:             * @param property The css property you want to define a value for (in this case
0987:             *                 mostly something like {@link CSSProperty#BACKGROUND_IMAGE}.
0988:             * @param color    The color value you want to assign.
0989:             */
0990:            public void setAttribute(Selector selector, CSSProperty property,
0991:                    Color color) {
0992:                setAttribute(selector, property, CSSStyleSheet
0993:                        .getAttribute(color));
0994:            }
0995:
0996:            public void setAttributes(Selector selector,
0997:                    CSSAttributeSet attributes) {
0998:                Style style = getDynamicStyle(selector);
0999:                if (style == null) {
1000:                    addDynamicStyle(new CSSStyle(selector, attributes));
1001:                } else {
1002:                    boolean changed = style.putAll(attributes);
1003:                    if (changed)
1004:                        reload();
1005:                }
1006:            }
1007:
1008:            /**
1009:             * Returns the current background color of this component.
1010:             *
1011:             * @return The current background color or <code>null</code>
1012:             */
1013:            public Color getBackground() {
1014:                return dynamicStyles == null
1015:                        || dynamicStyles.get(SELECTOR_ALL) == null ? null
1016:                        : CSSStyleSheet
1017:                                .getBackground((CSSAttributeSet) dynamicStyles
1018:                                        .get(SELECTOR_ALL));
1019:            }
1020:
1021:            /**
1022:             * Set the components foreground color.
1023:             *
1024:             * @param color the new foreground color or <code>null</code>
1025:             */
1026:            public void setBackground(Color color) {
1027:                setAttribute(SELECTOR_ALL, CSSProperty.BACKGROUND_COLOR,
1028:                        CSSStyleSheet.getAttribute(color));
1029:            }
1030:
1031:            /**
1032:             * Return the components foreground color.
1033:             *
1034:             * @return the foreground color or <code>null</code>
1035:             */
1036:            public Color getForeground() {
1037:                return dynamicStyles == null
1038:                        || dynamicStyles.get(SELECTOR_ALL) == null ? null
1039:                        : CSSStyleSheet
1040:                                .getForeground((CSSAttributeSet) dynamicStyles
1041:                                        .get(SELECTOR_ALL));
1042:            }
1043:
1044:            /**
1045:             * Set the foreground color.
1046:             *
1047:             * @param color the new foreground color or <code>null</code>
1048:             */
1049:            public void setForeground(Color color) {
1050:                setAttribute(SELECTOR_ALL, CSSProperty.COLOR, CSSStyleSheet
1051:                        .getAttribute(color));
1052:            }
1053:
1054:            /**
1055:             * Set the font.
1056:             *
1057:             * @param font the new font
1058:             */
1059:            public void setFont(SFont font) {
1060:                CSSAttributeSet attributes = CSSStyleSheet.getAttributes(font);
1061:                Style style = getDynamicStyle(SELECTOR_ALL);
1062:                if (style == null) {
1063:                    addDynamicStyle(new CSSStyle(SELECTOR_ALL, attributes));
1064:                } else {
1065:                    style.remove(CSSProperty.FONT);
1066:                    style.remove(CSSProperty.FONT_FAMILY);
1067:                    style.remove(CSSProperty.FONT_SIZE);
1068:                    style.remove(CSSProperty.FONT_STYLE);
1069:                    style.remove(CSSProperty.FONT_WEIGHT);
1070:                    style.putAll(attributes);
1071:                    reload();
1072:                }
1073:            }
1074:
1075:            /**
1076:             * Return the font used inside this component.
1077:             *
1078:             * @return The current font declaration or <code>null</code>
1079:             */
1080:            public SFont getFont() {
1081:                return dynamicStyles == null
1082:                        || dynamicStyles.get(SELECTOR_ALL) == null ? null
1083:                        : CSSStyleSheet.getFont((CSSAttributeSet) dynamicStyles
1084:                                .get(SELECTOR_ALL));
1085:            }
1086:
1087:            /**
1088:             * Set the visibility.
1089:             *
1090:             * @param visible wether this component will show or not
1091:             */
1092:            public void setVisible(boolean visible) {
1093:                boolean old = this .visible;
1094:                this .visible = visible;
1095:                if (visible != old) {
1096:                    if (fireComponentChangeEvents) {
1097:                        fireComponentChangeEvent(new SComponentEvent(this ,
1098:                                visible ? SComponentEvent.COMPONENT_SHOWN
1099:                                        : SComponentEvent.COMPONENT_HIDDEN));
1100:                    }
1101:
1102:                    if (parent != null) {
1103:                        parent.reload();
1104:                    } else {
1105:                        reload();
1106:                    }
1107:                }
1108:            }
1109:
1110:            /**
1111:             * Return the <b>local</b> visibility. If set to <code>true</code> this ccmponent
1112:             * should be visible if all parent components are visible, too.
1113:             *
1114:             * @return <code>true</code> If the component and it's children should show, <code>false</code> otherwise
1115:             * @see #isRecursivelyVisible()
1116:             */
1117:            public boolean isVisible() {
1118:                return visible;
1119:            }
1120:
1121:            /**
1122:             * Return the visibility. If the Component itself or any of it's parent is invisible,
1123:             * this method will return <code>false</code>.
1124:             *
1125:             * @return <code>true</code> if this component and all it's ancestors are visible, <code>false</code> otherwise.
1126:             */
1127:            public boolean isRecursivelyVisible() {
1128:                return visible
1129:                        && (parent == null || (parent.isShowingChildren() && parent
1130:                                .isRecursivelyVisible()));
1131:            }
1132:
1133:            /**
1134:             * Set wether this component should be enabled.
1135:             *
1136:             * @param enabled true if the component is enabled, false otherwise
1137:             */
1138:            public void setEnabled(boolean enabled) {
1139:                reloadIfChange(this .enabled, enabled);
1140:                this .enabled = enabled;
1141:            }
1142:
1143:            /**
1144:             * Return true if this component is enabled.
1145:             *
1146:             * @return true if component is enabled
1147:             */
1148:            public boolean isEnabled() {
1149:                return enabled;
1150:            }
1151:
1152:            /**
1153:             * Marks this component as subject to reload.
1154:             * The component will be registered with the ReloadManager.
1155:             */
1156:            public void reload() {
1157:                getSession().getReloadManager().reload(this );
1158:            }
1159:
1160:            /**
1161:             * Hands the given update to the Reload Manager.
1162:             * @param update  the update for this component
1163:             */
1164:            public void update(Update update) {
1165:                getSession().getReloadManager().addUpdate(this , update);
1166:            }
1167:
1168:            protected boolean isUpdatePossible() {
1169:                return getSession().getReloadManager().isUpdateMode();
1170:            }
1171:
1172:            public boolean isReloadForced() {
1173:                return reloadForced;
1174:            }
1175:
1176:            public void setReloadForced(boolean forced) {
1177:                if (reloadForced != forced) {
1178:                    Object clientProperty = getClientProperty("onChangeSubmitListener");
1179:                    if (clientProperty != null
1180:                            && clientProperty instanceof  JavaScriptListener) {
1181:                        removeScriptListener((JavaScriptListener) clientProperty);
1182:                        putClientProperty("onChangeSubmitListener", null);
1183:                    }
1184:                    reloadForced = forced;
1185:                    reload();
1186:                }
1187:            }
1188:
1189:            /**
1190:             * Mark this component as subject to reload if the property,
1191:             * that is given in its old and new fashion, changed.
1192:             *
1193:             * @param oldVal the old value of some property
1194:             * @param newVal the new value of some property
1195:             */
1196:            protected final void reloadIfChange(Object oldVal, Object newVal) {
1197:                if (isDifferent(oldVal, newVal))
1198:                    reload();
1199:            }
1200:
1201:            /**
1202:             * Mark this component as subject to reload if the property,
1203:             * that is given in its old and new fashion, changed.
1204:             *
1205:             * @param oldVal the old value of some property
1206:             * @param newVal the new value of some property
1207:             */
1208:            protected final void reloadIfChange(int oldVal, int newVal) {
1209:                if (oldVal != newVal)
1210:                    reload();
1211:            }
1212:
1213:            /**
1214:             * Mark this component as subject to reload if the property,
1215:             * that is given in its old and new fashion, changed.
1216:             *
1217:             * @param oldVal the old value of some property
1218:             * @param newVal the new value of some property
1219:             */
1220:            protected final void reloadIfChange(boolean oldVal, boolean newVal) {
1221:                if (oldVal != newVal)
1222:                    reload();
1223:            }
1224:
1225:            /**
1226:             * Mark this component as subject to reload if the property,
1227:             * that is given in its old and new fashion, changed.
1228:             *
1229:             * @param oldVal the old value of some property
1230:             * @param newVal the new value of some property
1231:             */
1232:            protected final void reloadIfChange(byte oldVal, byte newVal) {
1233:                if (oldVal != newVal)
1234:                    reload();
1235:            }
1236:
1237:            /**
1238:             * Mark this component as subject to reload if the property,
1239:             * that is given in its old and new fashion, changed.
1240:             *
1241:             * @param oldVal the old value of some property
1242:             * @param newVal the new value of some property
1243:             */
1244:            protected final void reloadIfChange(short oldVal, short newVal) {
1245:                if (oldVal != newVal)
1246:                    reload();
1247:            }
1248:
1249:            /**
1250:             * Mark this component as subject to reload if the property,
1251:             * that is given in its old and new fashion, changed.
1252:             *
1253:             * @param oldVal the old value of some property
1254:             * @param newVal the new value of some property
1255:             */
1256:            protected final void reloadIfChange(long oldVal, long newVal) {
1257:                if (oldVal != newVal)
1258:                    reload();
1259:            }
1260:
1261:            /**
1262:             * Mark this component as subject to reload if the property,
1263:             * that is given in its old and new fashion, changed.
1264:             *
1265:             * @param oldVal the old value of some property
1266:             * @param newVal the new value of some property
1267:             */
1268:            protected final void reloadIfChange(float oldVal, float newVal) {
1269:                if (oldVal != newVal)
1270:                    reload();
1271:            }
1272:
1273:            /**
1274:             * Mark this component as subject to reload if the property,
1275:             * that is given in its old and new fashion, changed.
1276:             *
1277:             * @param oldVal the old value of some property
1278:             * @param newVal the new value of some property
1279:             */
1280:            protected final void reloadIfChange(double oldVal, double newVal) {
1281:                if (oldVal != newVal)
1282:                    reload();
1283:            }
1284:
1285:            /**
1286:             * Mark this component as subject to reload if the property,
1287:             * that is given in its old and new fashion, changed.
1288:             *
1289:             * @param oldVal the old value of some property
1290:             * @param newVal the new value of some property
1291:             */
1292:            protected final void reloadIfChange(char oldVal, char newVal) {
1293:                if (oldVal != newVal)
1294:                    reload();
1295:            }
1296:
1297:            /**
1298:             * Mark this component as subject to reload if the property,
1299:             * that is given in its old and new fashion, changed.
1300:             */
1301:            @SuppressWarnings({"unchecked"})
1302:            public void write(Device s) throws IOException {
1303:                try {
1304:                    if (visible) {
1305:                        cg.write(s, this );
1306:                    }
1307:                } catch (IOException se) {
1308:                    // Typical double-clicks. Not severe
1309:                    log
1310:                            .debug("Not Severe: Socket exception during code generation for "
1311:                                    + getClass().getName() + se);
1312:                } catch (Throwable t) {
1313:                    // should we warn here? or maybe throw an error...
1314:                    log.error("Exception during code generation for "
1315:                            + getClass().getName(), t);
1316:                }
1317:            }
1318:
1319:            /**
1320:             * A string representation of this component. Uses the {@link #paramString()} methods
1321:             *
1322:             * @return string representation of this component with all properties.
1323:             */
1324:            @Override
1325:            public String toString() {
1326:                return getClass().getName() + "[" + getName() + "]";
1327:            }
1328:
1329:            /**
1330:             * Generates a string describing this <code>SComponent</code>.
1331:             * This method is mainly for debugging purposes.
1332:             *
1333:             * @return a string containing all properties
1334:             */
1335:            protected String paramString() {
1336:                SStringBuilder buffer = new SStringBuilder(getClass().getName());
1337:                buffer.append("[");
1338:
1339:                try {
1340:                    BeanInfo info = Introspector.getBeanInfo(getClass());
1341:                    PropertyDescriptor[] descriptors = info
1342:                            .getPropertyDescriptors();
1343:
1344:                    boolean first = true;
1345:                    for (PropertyDescriptor descriptor : descriptors) {
1346:                        try {
1347:                            Method getter = descriptor.getReadMethod();
1348:                            if (getter == null
1349:                                    || getter.getName().startsWith("getParent")) {
1350:                                continue;
1351:                            }
1352:                            // System.out.println("invoking " + this.getClass().getDescription()+"."+getter.getDescription());
1353:                            Object value = getter.invoke(this );
1354:                            if (first) {
1355:                                first = false;
1356:                            } else {
1357:                                buffer.append(",");
1358:                            }
1359:                            buffer.append(descriptor.getName() + "=" + value);
1360:                        } catch (Exception e) {
1361:                            log.debug("Exception during paramString()" + e);
1362:                        }
1363:                    }
1364:                } catch (Exception e) {
1365:                    log.debug("Exception during paramString()" + e);
1366:                }
1367:
1368:                buffer.append("]");
1369:                return buffer.toString();
1370:            }
1371:
1372:            /**
1373:             * Default implementation of the method in
1374:             * {@link LowLevelEventListener}.
1375:             */
1376:            public String getLowLevelEventId() {
1377:                return getName();
1378:            }
1379:
1380:            /**
1381:             * Return the parent frame.
1382:             * <p><b>NOTE:</b> You will receive <code>null</code> if you call this i.e. during
1383:             * component creation time, as the parent frame is set when you add it to a visible {@link SContainer}.
1384:             * Use {@link #addParentFrameListener(org.wings.event.SParentFrameListener)} in this case.
1385:             *
1386:             * @return the parent frame
1387:             * @see #addParentFrameListener(org.wings.event.SParentFrameListener)
1388:             */
1389:            public SFrame getParentFrame() {
1390:                return parentFrame;
1391:            }
1392:
1393:            /**
1394:             * Return true, if this component is contained in a form.
1395:             *
1396:             * @return true, if this component resides in a form, false otherwise
1397:             */
1398:            public boolean getResidesInForm() {
1399:                SComponent parent = getParent();
1400:
1401:                boolean actuallyDoes = parent instanceof  SForm;
1402:                while (parent != null && !actuallyDoes) {
1403:                    parent = parent.getParent();
1404:                    actuallyDoes = parent instanceof  SForm;
1405:                }
1406:
1407:                return actuallyDoes;
1408:            }
1409:
1410:            /**
1411:             * Set the tooltip text. To style use HTML tags.
1412:             *
1413:             * @param t the new tooltip text
1414:             */
1415:            public void setToolTipText(String t) {
1416:                reloadIfChange(this .tooltip, t);
1417:                this .tooltip = t;
1418:            }
1419:
1420:            /**
1421:             * Return the tooltip text.
1422:             *
1423:             * @return the tooltip text
1424:             */
1425:            public String getToolTipText() {
1426:                return tooltip;
1427:            }
1428:
1429:            /**
1430:             * The index in which the focus is traversed using Tab. This is
1431:             * a very simplified notion of traversing the focus, but that is,
1432:             * what browser like interfaces currently offer. This has a bit rough
1433:             * edge, since you have to make sure, that the index is unique within
1434:             * the whole frame. You probably don't want to change this
1435:             * programmatically, but this is set usually by the template property
1436:             * manager.
1437:             *
1438:             * @param index the focus traversal index. Pressing the focus traversal
1439:             *              key (usually TAB) in the browser jumps to the next index.
1440:             *              Must not be zero.
1441:             */
1442:            public void setFocusTraversalIndex(int index) {
1443:                reloadIfChange(this .focusTraversalIndex, index);
1444:                focusTraversalIndex = index;
1445:            }
1446:
1447:            /**
1448:             * returns the focus traversal index.
1449:             *
1450:             * @see #setFocusTraversalIndex(int)
1451:             */
1452:            public int getFocusTraversalIndex() {
1453:                return focusTraversalIndex;
1454:            }
1455:
1456:            /**
1457:             * Clone this component.
1458:             *
1459:             * @return a clone of this component
1460:             */
1461:            @Override
1462:            public Object clone() {
1463:                try {
1464:                    return super .clone();
1465:                } catch (Exception e) {
1466:                    log.error("Unable to clone component", e);
1467:                    return null;
1468:                }
1469:            }
1470:
1471:            /**
1472:             * Return the value of the horizontal alignment property.
1473:             *
1474:             * @return the horizontal alignment
1475:             * @see SConstants
1476:             */
1477:            public int getHorizontalAlignment() {
1478:                return horizontalAlignment;
1479:            }
1480:
1481:            /**
1482:             * Set the horizontal alignment.
1483:             *
1484:             * @param alignment new value for the horizontal alignment
1485:             * @see SConstants
1486:             */
1487:            public void setHorizontalAlignment(int alignment) {
1488:                reloadIfChange(this .horizontalAlignment, alignment);
1489:                horizontalAlignment = alignment;
1490:            }
1491:
1492:            /**
1493:             * Set the vertical alignment.
1494:             *
1495:             * @param alignment new value for the vertical alignment
1496:             * @see SConstants
1497:             */
1498:            public void setVerticalAlignment(int alignment) {
1499:                reloadIfChange(this .verticalAlignment, alignment);
1500:                verticalAlignment = alignment;
1501:            }
1502:
1503:            /**
1504:             * Return the value of the vertical alignment property.
1505:             *
1506:             * @return the vertical alignment
1507:             * @see SConstants
1508:             */
1509:            public int getVerticalAlignment() {
1510:                return verticalAlignment;
1511:            }
1512:
1513:            /**
1514:             * @return a small HashMap
1515:             * @see #putClientProperty
1516:             * @see #getClientProperty
1517:             */
1518:            private Map<Object, Object> getClientProperties() {
1519:                if (clientProperties == null) {
1520:                    clientProperties = new HashMap<Object, Object>(2);
1521:                }
1522:                return clientProperties;
1523:            }
1524:
1525:            /**
1526:             * Returns the value of the property with the specified key.  Only
1527:             * properties added with <code>putClientProperty</code> will return
1528:             * a non-null value.
1529:             *
1530:             * @return the value of this property or null
1531:             * @see #putClientProperty
1532:             */
1533:            public final Object getClientProperty(Object key) {
1534:                if (clientProperties == null) {
1535:                    return null;
1536:                } else {
1537:                    return getClientProperties().get(key);
1538:                }
1539:            }
1540:
1541:            /**
1542:             * Add an arbitrary key/value "client property" to this component.
1543:             * <p/>
1544:             * The <code>get/putClientProperty<code> methods provide access to
1545:             * a small per-instance hashtable. Callers can use get/putClientProperty
1546:             * to annotate components that were created by another module, e.g. a
1547:             * layout manager might store per child constraints this way.  For example:
1548:             * <pre>
1549:             * componentA.putClientProperty("to the left of", componentB);
1550:             * </pre>
1551:             * <p/>
1552:             * If value is null this method will remove the property.
1553:             * Changes to client properties are reported with PropertyChange
1554:             * events.  The name of the property (for the sake of PropertyChange
1555:             * events) is <code>key.toString()</code>.
1556:             * <p/>
1557:             * The clientProperty dictionary is not intended to support large
1558:             * scale extensions to SComponent nor should be it considered an
1559:             * alternative to subclassing when designing a new component.
1560:             *
1561:             * @see #getClientProperty
1562:             */
1563:            public final void putClientProperty(Object key, Object value) {
1564:                if (value != null) {
1565:                    getClientProperties().put(key, value);
1566:                } else {
1567:                    getClientProperties().remove(key);
1568:                }
1569:            }
1570:
1571:            /**
1572:             * Set the look and feel delegate for this component.
1573:             * SComponent subclasses generally override this method
1574:             * to narrow the argument type, e.g. in STextField:
1575:             * <pre>
1576:             * public void setCG(TextFieldCG newCG) {
1577:             *     super.setCG(newCG);
1578:             * }
1579:             * </pre>
1580:             *
1581:             * @see #updateCG
1582:             * @see org.wings.plaf.CGManager#getLookAndFeel
1583:             * @see org.wings.plaf.CGManager#getCG
1584:             */
1585:            @SuppressWarnings({"unchecked"})
1586:            public void setCG(ComponentCG newCG) {
1587:                /* We do not check that the CG instance is different
1588:                 * before allowing the switch in order to enable the
1589:                 * same CG instance *with different default settings*
1590:                 * to be installed.
1591:                 */
1592:                if (cg != null) {
1593:                    cg.uninstallCG(this );
1594:                }
1595:                ComponentCG oldCG = cg;
1596:                cg = newCG;
1597:                if (cg != null) {
1598:                    cg.installCG(this );
1599:                }
1600:                reloadIfChange(cg, oldCG);
1601:            }
1602:
1603:            /**
1604:             * Return the look and feel delegate.
1605:             *
1606:             * @return the componet's cg
1607:             */
1608:            public ComponentCG getCG() {
1609:                return cg;
1610:            }
1611:
1612:            /**
1613:             * Notification from the CGFactory that the L&F has changed.
1614:             *
1615:             * @see SComponent#updateCG
1616:             */
1617:            public void updateCG() {
1618:                if (getSession() == null) {
1619:                    log.warn("no session yet.");
1620:                } else if (getSession().getCGManager() == null) {
1621:                    log.warn("no CGManager");
1622:                } else {
1623:                    setCG(getSession().getCGManager().getCG(this ));
1624:                }
1625:            }
1626:
1627:            /**
1628:             * Invite a ComponentVisitor.
1629:             * Invokes visit(SComponent) on the ComponentVisitor.
1630:             *
1631:             * @param visitor the visitor to be invited
1632:             */
1633:            public void invite(ComponentVisitor visitor) throws Exception {
1634:                visitor.visit(this );
1635:            }
1636:
1637:            /**
1638:             * use this method for changing a variable. if a new value is different
1639:             * from the old value set the new one and notify e.g. the reloadmanager...
1640:             */
1641:            protected static boolean isDifferent(Object oldObject,
1642:                    Object newObject) {
1643:                if (oldObject == newObject)
1644:                    return false;
1645:
1646:                if (oldObject == null)
1647:                    return true;
1648:
1649:                return !oldObject.equals(newObject);
1650:            }
1651:
1652:            /**
1653:             * Adds an event listener for the given event class
1654:             *
1655:             * @param type     The class/type of events to listen to.
1656:             * @param listener The listener itself.
1657:             */
1658:            protected final <T extends EventListener> void addEventListener(
1659:                    Class<T> type, T listener) {
1660:                if (listeners == null) {
1661:                    listeners = new EventListenerList();
1662:                }
1663:                listeners.add(type, listener);
1664:            }
1665:
1666:            /**
1667:             * Removed named event listener.
1668:             *
1669:             * @param type     The class/type of events to listen to.
1670:             * @param listener The listener itself.
1671:             */
1672:            protected final <T extends EventListener> void removeEventListener(
1673:                    Class<T> type, T listener) {
1674:                if (listeners != null) {
1675:                    listeners.remove(type, listener);
1676:                }
1677:            }
1678:
1679:            /**
1680:             * Returns the number of listeners of the specified type for this component.
1681:             *
1682:             * @param type The type of listeners
1683:             * @return The number of listeners
1684:             * @see EventListenerList
1685:             */
1686:            protected final int getListenerCount(Class type) {
1687:                if (listeners != null) {
1688:                    return listeners.getListenerCount(type);
1689:                } else {
1690:                    return 0;
1691:                }
1692:            }
1693:
1694:            /**
1695:             * Returns all the listeners of this component. For performance reasons, this is the actual data
1696:             * structure and so no modification of this array should be made.
1697:             *
1698:             * @return All listeners of this component. The result array has a pair structure,
1699:             *         the first element of each pair is the listener type, the second the listener
1700:             *         itself. It is guaranteed that this returns a non-null array.
1701:             * @see EventListenerList
1702:             */
1703:            protected final Object[] getListenerList() {
1704:                if (listeners == null) {
1705:                    return EMPTY_OBJECT_ARRAY;
1706:                } else {
1707:                    return listeners.getListenerList();
1708:                } // end of else
1709:            }
1710:
1711:            /**
1712:             * Creates an typed array of all listeners of the specified type
1713:             *
1714:             * @param type All listeners of this type are added to the result array
1715:             * @return an array of the specified type with all listeners of the specified type
1716:             * @see EventListenerList
1717:             */
1718:            public final EventListener[] getListeners(
1719:                    Class<? extends EventListener> type) {
1720:                if (listeners != null) {
1721:                    return listeners.getListeners(type);
1722:                } else {
1723:                    return (EventListener[]) Array.newInstance(type, 0);
1724:                }
1725:            }
1726:
1727:            /**
1728:             * Adds a listenere to this component which wil get notified when the rendering of
1729:             * this components starts. (This happens after all events / request has been processed and wingS
1730:             * starts to build the response).
1731:             *
1732:             * @param renderListener
1733:             * @see SRenderListener
1734:             */
1735:            public final void addRenderListener(SRenderListener renderListener) {
1736:                addEventListener(SRenderListener.class, renderListener);
1737:                fireRenderEvents = true;
1738:            }
1739:
1740:            /**
1741:             * Removes the named render listener.
1742:             *
1743:             * @param renderListener Render listener to remove
1744:             * @see #addRenderListener(org.wings.event.SRenderListener)
1745:             * @see SRenderListener
1746:             */
1747:            public final void removeRenderListener(
1748:                    SRenderListener renderListener) {
1749:                removeEventListener(SRenderListener.class, renderListener);
1750:            }
1751:
1752:            /**
1753:             * <b>Internal method</b> called by the CGs to indicate different states of the rendering process.
1754:             *
1755:             * @param type Either {@link #DONE_RENDERING} or {@link #START_RENDERING}.
1756:             */
1757:            public final void fireRenderEvent(int type) {
1758:                if (fireRenderEvents) {
1759:                    // maybe the better way to do this is to user the getListenerList
1760:                    // and iterate through all listeners, this saves the creation of
1761:                    // an array but it must cast to the apropriate listener
1762:                    Object[] listeners = getListenerList();
1763:                    for (int i = listeners.length - 2; i >= 0; i -= 2) {
1764:                        if (listeners[i] == SRenderListener.class) {
1765:                            // Lazily create the event:
1766:                            if (renderEvent == null) {
1767:                                renderEvent = new SRenderEvent(this );
1768:                            } // end of if ()
1769:
1770:                            switch (type) {
1771:                            case START_RENDERING:
1772:                                ((SRenderListener) listeners[i + 1])
1773:                                        .startRendering(renderEvent);
1774:                                break;
1775:                            case DONE_RENDERING:
1776:                                ((SRenderListener) listeners[i + 1])
1777:                                        .doneRendering(renderEvent);
1778:                                break;
1779:                            }
1780:                        }
1781:                    }
1782:                }
1783:            }
1784:
1785:            /**
1786:             * Forwards the scrollRectToVisible() message to the SComponent's
1787:             * parent. Components that can service the request, such as
1788:             * SScrollPane, override this method and perform the scrolling.
1789:             *
1790:             * @param aRect the visible Rectangle
1791:             * @see SScrollPane
1792:             */
1793:            public void scrollRectToVisible(Rectangle aRect) {
1794:                if (parent != null) {
1795:                    parent.scrollRectToVisible(aRect);
1796:                }
1797:            }
1798:
1799:            /**
1800:             * Requests the edit focus for this component for the following renderings
1801:             * by calling {@link SFrame#setFocus(SComponent)}.
1802:             */
1803:            public void requestFocus() {
1804:                if (getParentFrame() != null) {
1805:                    getParentFrame().setFocus(this );
1806:                }
1807:            }
1808:
1809:            /**
1810:             * Returns <code>true</code> if this <code>SComponent</code> is owning the edit focus.
1811:             *
1812:             * @return <code>true</code> if this <code>SComponent</code> is owning the edit focus otherwise <code>false</code>
1813:             * @see #requestFocus()
1814:             */
1815:            public boolean isFocusOwner() {
1816:                if (getParentFrame() != null)
1817:                    return this  == getParentFrame().getFocus();
1818:                return false;
1819:            }
1820:
1821:            /**
1822:             * Set display mode (href or form-component).
1823:             * An AbstractButton can appear as HTML-Form-Button or as
1824:             * HTML-HREF. If button is inside a {@link SForm} the default
1825:             * is displaying it as html form button.
1826:             * Setting <i>showAsFormComponent</i> to <i>false</i> will
1827:             * force displaying as href even if button is inside
1828:             * a form.
1829:             *
1830:             * @param showAsFormComponent if true, display as link, if false as html form component.
1831:             */
1832:            public void setShowAsFormComponent(boolean showAsFormComponent) {
1833:                if (this .showAsFormComponent != showAsFormComponent) {
1834:                    this .showAsFormComponent = showAsFormComponent;
1835:                    reload();
1836:                }
1837:            }
1838:
1839:            /**
1840:             * Test, what display method is set.
1841:             *
1842:             * @return true, if displayed as link, false when displayed as html form component.
1843:             * @see #setShowAsFormComponent(boolean)
1844:             */
1845:            public boolean getShowAsFormComponent() {
1846:                return showAsFormComponent && getResidesInForm();
1847:            }
1848:
1849:            /**
1850:             * Binds action names to {@link Action}s. Use for key binding feature.
1851:             *
1852:             * @param actionMap The new action map.
1853:             * @see #setInputMap(javax.swing.InputMap)
1854:             * @see ActionMap
1855:             * @see InputMap
1856:             */
1857:            public void setActionMap(ActionMap actionMap) {
1858:                this .actionMap = actionMap;
1859:            }
1860:
1861:            /**
1862:             * Action map for key binding feature
1863:             *
1864:             * @return The current action map
1865:             * @see #setActionMap(javax.swing.ActionMap)
1866:             */
1867:            public ActionMap getActionMap() {
1868:                if (actionMap == null)
1869:                    actionMap = new ActionMap();
1870:                return actionMap;
1871:            }
1872:
1873:            /**
1874:             * Map for key binding feature. (?) Binds input keystrokes to action names (?).
1875:             *
1876:             * @param inputMap The current input map.
1877:             * @see InputMap
1878:             * @see ActionMap
1879:             * @see #setActionMap(javax.swing.ActionMap)
1880:             * @see JComponent#setInputMap(int, javax.swing.InputMap)
1881:             */
1882:            public void setInputMap(InputMap inputMap) {
1883:                setInputMap(WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT,
1884:                        inputMap);
1885:            }
1886:
1887:            /**
1888:             * Sets The current input map.
1889:             *
1890:             * @param inputMap  The new input map
1891:             * @param condition Either {@link #WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT} or {@link #WHEN_IN_FOCUSED_FRAME}
1892:             * @see JComponent#setInputMap(int, javax.swing.InputMap)
1893:             */
1894:            public void setInputMap(int condition, InputMap inputMap) {
1895:                initInputMaps();
1896:                this .inputMaps[condition] = inputMap;
1897:                registerGlobalInputMapWithFrame();
1898:            }
1899:
1900:            /**
1901:             * @return The input map for the condition {@link #WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT}
1902:             * @see #setInputMap(javax.swing.InputMap)
1903:             */
1904:            public InputMap getInputMap() {
1905:                return getInputMap(WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT);
1906:            }
1907:
1908:            /**
1909:             * @param condition Either {@link #WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT} or {@link #WHEN_IN_FOCUSED_FRAME}
1910:             * @return The input map for the given condition.
1911:             * @see #setInputMap(int, javax.swing.InputMap)
1912:             */
1913:            public InputMap getInputMap(int condition) {
1914:                initInputMaps();
1915:                InputMap result = inputMaps[condition];
1916:                if (result == null) {
1917:                    inputMaps[condition] = new InputMap();
1918:                    result = inputMaps[condition];
1919:                }
1920:                registerGlobalInputMapWithFrame();
1921:                return result;
1922:            }
1923:
1924:            private void registerGlobalInputMapWithFrame() {
1925:                final SFrame parentFrame = getParentFrame();
1926:                if (parentFrame != null)
1927:                    parentFrame.registerGlobalInputMapComponent(this );
1928:
1929:                if (globalInputMapListener == null) {
1930:                    globalInputMapListener = new GlobalInputMapParentFrameListener(
1931:                            this );
1932:                    addParentFrameListener(globalInputMapListener);
1933:                }
1934:            }
1935:
1936:            private void initInputMaps() {
1937:                if (inputMaps == null) {
1938:                    inputMaps = new InputMap[ACTION_CONDITIONS_AMOUNT];
1939:                }
1940:            }
1941:
1942:            protected void processLowLevelEvent(String name, String[] values) {
1943:            }
1944:
1945:            protected boolean processKeyEvents(String[] values) {
1946:                if (actionMap == null)
1947:                    return false;
1948:
1949:                if (log.isDebugEnabled())
1950:                    log.debug("processKeyEvents " + Arrays.asList(values));
1951:
1952:                boolean arm = false;
1953:                for (String value : values) {
1954:                    final Action action = actionMap.get(value);
1955:                    if (action != null) {
1956:                        if (actionEvents == null)
1957:                            actionEvents = new HashMap<Action, ActionEvent>();
1958:
1959:                        actionEvents.put(action,
1960:                                new ActionEvent(this , 0, value));
1961:                        arm = true;
1962:                    }
1963:                }
1964:                if (arm)
1965:                    SForm.addArmedComponent((LowLevelEventListener) this );
1966:
1967:                return arm;
1968:            }
1969:
1970:            /**
1971:             * Internal event trigger used by CGs.
1972:             * This Method is called internal and should not be called directly
1973:             */
1974:            public void fireFinalEvents() {
1975:                fireKeyEvents();
1976:            }
1977:
1978:            /**
1979:             * Internal method to trigger firing of key events.
1980:             */
1981:            protected void fireKeyEvents() {
1982:                if (actionEvents != null) {
1983:                    for (Map.Entry<Action, ActionEvent> entry : actionEvents
1984:                            .entrySet()) {
1985:                        Action action = entry.getKey();
1986:                        ActionEvent event = entry.getValue();
1987:                        action.actionPerformed(event);
1988:                    }
1989:                    actionEvents.clear();
1990:                }
1991:            }
1992:
1993:            /**
1994:             * Method called to notify this <code>SComponent</code> that it has no longer a parent component.
1995:             * This Method is called internal and should not be called directly, but can be overerloaded
1996:             * to react on this event.
1997:             */
1998:            public void removeNotify() {
1999:                /* currently nothing to do, but great to overwrite for some dangling eventListener */
2000:            }
2001:
2002:            /**
2003:             * Method called to notify this <code>SComponent</code> that it has a new parent component.
2004:             * This Method is called internal and should not be called directly, but can be overerloaded
2005:             * to react on this event.
2006:             */
2007:            public void addNotify() {
2008:                /* currently nothing to do */
2009:            }
2010:
2011:            // Nice: undocumented and useless
2012:            /*public ArrayList getMenus() {
2013:                ArrayList menus = new ArrayList();
2014:                if (isVisible()) {
2015:                    SPopupMenu pmenu = getComponentPopupMenu();
2016:                    if (pmenu != null) {
2017:                        menus.add(pmenu);
2018:                    }
2019:                }
2020:                return menus;
2021:            } */
2022:
2023:            private void readObject(ObjectInputStream in) throws IOException,
2024:                    ClassNotFoundException {
2025:                // preprocessing, e. g. serialize static vars or transient variables as cipher text
2026:                in.defaultReadObject(); // default serialization
2027:                // do postprocessing here
2028:            }
2029:
2030:            private void writeObject(ObjectOutputStream out) throws IOException {
2031:                try {
2032:                    // preprocessing
2033:                    out.defaultWriteObject(); // default
2034:                    // postprocessing
2035:                } catch (IOException e) {
2036:                    log.warn("Unexpected Exception", e);
2037:                    throw e;
2038:                }
2039:            }
2040:
2041:            /**
2042:             * Listener registering/deregistering this component on the parent frame.
2043:             */
2044:            private final static class GlobalInputMapParentFrameListener
2045:                    implements  SParentFrameListener, Serializable {
2046:                private final SComponent me;
2047:
2048:                public GlobalInputMapParentFrameListener(SComponent me) {
2049:                    this .me = me;
2050:                }
2051:
2052:                public void parentFrameAdded(SParentFrameEvent e) {
2053:                    if (e.getParentFrame() != null)
2054:                        e.getParentFrame().registerGlobalInputMapComponent(me);
2055:                }
2056:
2057:                public void parentFrameRemoved(SParentFrameEvent e) {
2058:                    if (e.getParentFrame() != null)
2059:                        e.getParentFrame()
2060:                                .deregisterGlobalInputMapComponent(me);
2061:                }
2062:            }
2063:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.