Source Code Cross Referenced for ComponentView.java in  » 6.0-JDK-Core » swing » javax » swing » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025        package javax.swing.text;
026
027        import java.awt.*;
028        import java.beans.PropertyChangeEvent;
029        import java.beans.PropertyChangeListener;
030        import javax.swing.SwingUtilities;
031        import javax.swing.event.*;
032
033        /**
034         * Component decorator that implements the view interface.  The
035         * entire element is used to represent the component.  This acts
036         * as a gateway from the display-only View implementations to
037         * interactive lightweight components (ie it allows components
038         * to be embedded into the View hierarchy).
039         * <p>
040         * The component is placed relative to the text baseline 
041         * according to the value returned by 
042         * <code>Component.getAlignmentY</code>.  For Swing components
043         * this value can be conveniently set using the method
044         * <code>JComponent.setAlignmentY</code>.  For example, setting
045         * a value of <code>0.75</code> will cause 75 percent of the 
046         * component to be above the baseline, and 25 percent of the
047         * component to be below the baseline.
048         * <p>
049         * This class is implemented to do the extra work necessary to
050         * work properly in the presence of multiple threads (i.e. from
051         * asynchronous notification of model changes for example) by
052         * ensuring that all component access is done on the event thread.
053         * <p>
054         * The component used is determined by the return value of the
055         * createComponent method.  The default implementation of this
056         * method is to return the component held as an attribute of
057         * the element (by calling StyleConstants.getComponent).  A
058         * limitation of this behavior is that the component cannot 
059         * be used by more than one text component (i.e. with a shared
060         * model).  Subclasses can remove this constraint by implementing
061         * the createComponent to actually create a component based upon
062         * some kind of specification contained in the attributes.  The
063         * ObjectView class in the html package is an example of a
064         * ComponentView implementation that supports multiple component
065         * views of a shared model.
066         *
067         * @author Timothy Prinzing
068         * @version 1.60 05/05/07
069         */
070        public class ComponentView extends View {
071
072            /**
073             * Creates a new ComponentView object.
074             *
075             * @param elem the element to decorate
076             */
077            public ComponentView(Element elem) {
078                super (elem);
079            }
080
081            /**
082             * Create the component that is associated with
083             * this view.  This will be called when it has
084             * been determined that a new component is needed.
085             * This would result from a call to setParent or
086             * as a result of being notified that attributes
087             * have changed.
088             */
089            protected Component createComponent() {
090                AttributeSet attr = getElement().getAttributes();
091                Component comp = StyleConstants.getComponent(attr);
092                return comp;
093            }
094
095            /**
096             * Fetch the component associated with the view.
097             */
098            public final Component getComponent() {
099                return createdC;
100            }
101
102            // --- View methods ---------------------------------------------
103
104            /**
105             * The real paint behavior occurs naturally from the association
106             * that the component has with its parent container (the same
107             * container hosting this view).  This is implemented to do nothing.
108             *
109             * @param g the graphics context
110             * @param a the shape
111             * @see View#paint
112             */
113            public void paint(Graphics g, Shape a) {
114                if (c != null) {
115                    Rectangle alloc = (a instanceof  Rectangle) ? (Rectangle) a
116                            : a.getBounds();
117                    c.setBounds(alloc.x, alloc.y, alloc.width, alloc.height);
118                }
119            }
120
121            /**
122             * Determines the preferred span for this view along an
123             * axis.  This is implemented to return the value
124             * returned by Component.getPreferredSize along the
125             * axis of interest.
126             *
127             * @param axis may be either View.X_AXIS or View.Y_AXIS
128             * @return   the span the view would like to be rendered into >= 0.
129             *           Typically the view is told to render into the span
130             *           that is returned, although there is no guarantee.
131             *           The parent may choose to resize or break the view.
132             * @exception IllegalArgumentException for an invalid axis
133             */
134            public float getPreferredSpan(int axis) {
135                if ((axis != X_AXIS) && (axis != Y_AXIS)) {
136                    throw new IllegalArgumentException("Invalid axis: " + axis);
137                }
138                if (c != null) {
139                    Dimension size = c.getPreferredSize();
140                    if (axis == View.X_AXIS) {
141                        return size.width;
142                    } else {
143                        return size.height;
144                    }
145                }
146                return 0;
147            }
148
149            /**
150             * Determines the minimum span for this view along an
151             * axis.  This is implemented to return the value
152             * returned by Component.getMinimumSize along the
153             * axis of interest.
154             *
155             * @param axis may be either View.X_AXIS or View.Y_AXIS
156             * @return   the span the view would like to be rendered into >= 0.
157             *           Typically the view is told to render into the span
158             *           that is returned, although there is no guarantee.  
159             *           The parent may choose to resize or break the view.
160             * @exception IllegalArgumentException for an invalid axis
161             */
162            public float getMinimumSpan(int axis) {
163                if ((axis != X_AXIS) && (axis != Y_AXIS)) {
164                    throw new IllegalArgumentException("Invalid axis: " + axis);
165                }
166                if (c != null) {
167                    Dimension size = c.getMinimumSize();
168                    if (axis == View.X_AXIS) {
169                        return size.width;
170                    } else {
171                        return size.height;
172                    }
173                }
174                return 0;
175            }
176
177            /**
178             * Determines the maximum span for this view along an
179             * axis.  This is implemented to return the value
180             * returned by Component.getMaximumSize along the
181             * axis of interest.
182             *
183             * @param axis may be either View.X_AXIS or View.Y_AXIS
184             * @return   the span the view would like to be rendered into >= 0.
185             *           Typically the view is told to render into the span
186             *           that is returned, although there is no guarantee.  
187             *           The parent may choose to resize or break the view.
188             * @exception IllegalArgumentException for an invalid axis
189             */
190            public float getMaximumSpan(int axis) {
191                if ((axis != X_AXIS) && (axis != Y_AXIS)) {
192                    throw new IllegalArgumentException("Invalid axis: " + axis);
193                }
194                if (c != null) {
195                    Dimension size = c.getMaximumSize();
196                    if (axis == View.X_AXIS) {
197                        return size.width;
198                    } else {
199                        return size.height;
200                    }
201                }
202                return 0;
203            }
204
205            /**
206             * Determines the desired alignment for this view along an
207             * axis.  This is implemented to give the alignment of the
208             * embedded component.
209             *
210             * @param axis may be either View.X_AXIS or View.Y_AXIS
211             * @return the desired alignment.  This should be a value
212             *   between 0.0 and 1.0 where 0 indicates alignment at the
213             *   origin and 1.0 indicates alignment to the full span
214             *   away from the origin.  An alignment of 0.5 would be the
215             *   center of the view.
216             */
217            public float getAlignment(int axis) {
218                if (c != null) {
219                    switch (axis) {
220                    case View.X_AXIS:
221                        return c.getAlignmentX();
222                    case View.Y_AXIS:
223                        return c.getAlignmentY();
224                    }
225                }
226                return super .getAlignment(axis);
227            }
228
229            /**
230             * Sets the parent for a child view.
231             * The parent calls this on the child to tell it who its
232             * parent is, giving the view access to things like
233             * the hosting Container.  The superclass behavior is
234             * executed, followed by a call to createComponent if
235             * the parent view parameter is non-null and a component
236             * has not yet been created. The embedded components parent
237             * is then set to the value returned by <code>getContainer</code>.
238             * If the parent view parameter is null, this view is being
239             * cleaned up, thus the component is removed from its parent.
240             * <p>
241             * The changing of the component hierarchy will
242             * touch the component lock, which is the one thing 
243             * that is not safe from the View hierarchy.  Therefore,
244             * this functionality is executed immediately if on the
245             * event thread, or is queued on the event queue if
246             * called from another thread (notification of change
247             * from an asynchronous update).
248             *
249             * @param p the parent
250             */
251            public void setParent(View p) {
252                super .setParent(p);
253                if (SwingUtilities.isEventDispatchThread()) {
254                    setComponentParent();
255                } else {
256                    Runnable callSetComponentParent = new Runnable() {
257                        public void run() {
258                            Document doc = getDocument();
259                            try {
260                                if (doc instanceof  AbstractDocument) {
261                                    ((AbstractDocument) doc).readLock();
262                                }
263                                setComponentParent();
264                                Container host = getContainer();
265                                if (host != null) {
266                                    preferenceChanged(null, true, true);
267                                    host.repaint();
268                                }
269                            } finally {
270                                if (doc instanceof  AbstractDocument) {
271                                    ((AbstractDocument) doc).readUnlock();
272                                }
273                            }
274                        }
275                    };
276                    SwingUtilities.invokeLater(callSetComponentParent);
277                }
278            }
279
280            /**
281             * Set the parent of the embedded component 
282             * with assurance that it is thread-safe.
283             */
284            void setComponentParent() {
285                View p = getParent();
286                if (p != null) {
287                    Container parent = getContainer();
288                    if (parent != null) {
289                        if (c == null) {
290                            // try to build a component
291                            Component comp = createComponent();
292                            if (comp != null) {
293                                createdC = comp;
294                                c = new Invalidator(comp);
295                            }
296                        }
297                        if (c != null) {
298                            if (c.getParent() == null) {
299                                // components associated with the View tree are added
300                                // to the hosting container with the View as a constraint.
301                                parent.add(c, this );
302                                parent.addPropertyChangeListener("enabled", c);
303                            }
304                        }
305                    }
306                } else {
307                    if (c != null) {
308                        Container parent = c.getParent();
309                        if (parent != null) {
310                            // remove the component from its hosting container
311                            parent.remove(c);
312                            parent.removePropertyChangeListener("enabled", c);
313                        }
314                    }
315                }
316            }
317
318            /**
319             * Provides a mapping from the coordinate space of the model to
320             * that of the view.
321             *
322             * @param pos the position to convert >= 0
323             * @param a the allocated region to render into
324             * @return the bounding box of the given position is returned
325             * @exception BadLocationException  if the given position does not
326             *   represent a valid location in the associated document
327             * @see View#modelToView
328             */
329            public Shape modelToView(int pos, Shape a, Position.Bias b)
330                    throws BadLocationException {
331                int p0 = getStartOffset();
332                int p1 = getEndOffset();
333                if ((pos >= p0) && (pos <= p1)) {
334                    Rectangle r = a.getBounds();
335                    if (pos == p1) {
336                        r.x += r.width;
337                    }
338                    r.width = 0;
339                    return r;
340                }
341                throw new BadLocationException(pos + " not in range " + p0
342                        + "," + p1, pos);
343            }
344
345            /**
346             * Provides a mapping from the view coordinate space to the logical
347             * coordinate space of the model.
348             *
349             * @param x the X coordinate >= 0
350             * @param y the Y coordinate >= 0
351             * @param a the allocated region to render into
352             * @return the location within the model that best represents
353             *    the given point in the view
354             * @see View#viewToModel
355             */
356            public int viewToModel(float x, float y, Shape a,
357                    Position.Bias[] bias) {
358                Rectangle alloc = (Rectangle) a;
359                if (x < alloc.x + (alloc.width / 2)) {
360                    bias[0] = Position.Bias.Forward;
361                    return getStartOffset();
362                }
363                bias[0] = Position.Bias.Backward;
364                return getEndOffset();
365            }
366
367            // --- member variables ------------------------------------------------
368
369            private Component createdC;
370            private Invalidator c;
371
372            /**
373             * This class feeds the invalidate back to the
374             * hosting View.  This is needed to get the View
375             * hierarchy to consider giving the component
376             * a different size (i.e. layout may have been
377             * cached between the associated view and the
378             * container hosting this component).
379             */
380            class Invalidator extends Container implements 
381                    PropertyChangeListener {
382
383                // NOTE: When we remove this class we are going to have to some
384                // how enforce setting of the focus traversal keys on the children
385                // so that they don't inherit them from the JEditorPane. We need
386                // to do this as JEditorPane has abnormal bindings (it is a focus cycle
387                // root) and the children typically don't want these bindings as well.
388
389                Invalidator(Component child) {
390                    setLayout(null);
391                    add(child);
392                    cacheChildSizes();
393                }
394
395                /**
396                 * The components invalid layout needs 
397                 * to be propagated through the view hierarchy
398                 * so the views (which position the component)
399                 * can have their layout recomputed.
400                 */
401                public void invalidate() {
402                    super .invalidate();
403                    if (getParent() != null) {
404                        preferenceChanged(null, true, true);
405                    }
406                }
407
408                public void doLayout() {
409                    cacheChildSizes();
410                }
411
412                public void setBounds(int x, int y, int w, int h) {
413                    super .setBounds(x, y, w, h);
414                    if (getComponentCount() > 0) {
415                        getComponent(0).setSize(w, h);
416                    }
417                    cacheChildSizes();
418                }
419
420                public void validateIfNecessary() {
421                    if (!isValid()) {
422                        validate();
423                    }
424                }
425
426                private void cacheChildSizes() {
427                    if (getComponentCount() > 0) {
428                        Component child = getComponent(0);
429                        min = child.getMinimumSize();
430                        pref = child.getPreferredSize();
431                        max = child.getMaximumSize();
432                        yalign = child.getAlignmentY();
433                        xalign = child.getAlignmentX();
434                    } else {
435                        min = pref = max = new Dimension(0, 0);
436                    }
437                }
438
439                /**
440                 * Shows or hides this component depending on the value of parameter 
441                 * <code>b</code>.
442                 * @param <code>b</code>  If <code>true</code>, shows this component; 
443                 * otherwise, hides this component.
444                 * @see #isVisible
445                 * @since JDK1.1
446                 */
447                public void setVisible(boolean b) {
448                    super .setVisible(b);
449                    if (getComponentCount() > 0) {
450                        getComponent(0).setVisible(b);
451                    }
452                }
453
454                /**
455                 * Overridden to fix 4759054. Must return true so that content
456                 * is painted when inside a CellRendererPane which is normally
457                 * invisible.
458                 */
459                public boolean isShowing() {
460                    return true;
461                }
462
463                public Dimension getMinimumSize() {
464                    validateIfNecessary();
465                    return min;
466                }
467
468                public Dimension getPreferredSize() {
469                    validateIfNecessary();
470                    return pref;
471                }
472
473                public Dimension getMaximumSize() {
474                    validateIfNecessary();
475                    return max;
476                }
477
478                public float getAlignmentX() {
479                    validateIfNecessary();
480                    return xalign;
481                }
482
483                public float getAlignmentY() {
484                    validateIfNecessary();
485                    return yalign;
486                }
487
488                public java.util.Set getFocusTraversalKeys(int id) {
489                    return KeyboardFocusManager
490                            .getCurrentKeyboardFocusManager()
491                            .getDefaultFocusTraversalKeys(id);
492                }
493
494                public void propertyChange(PropertyChangeEvent ev) {
495                    Boolean enable = (Boolean) ev.getNewValue();
496                    if (getComponentCount() > 0) {
497                        getComponent(0).setEnabled(enable);
498                    }
499                }
500
501                Dimension min;
502                Dimension pref;
503                Dimension max;
504                float yalign;
505                float xalign;
506
507            }
508
509        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.