OSDN Git Service

Imported GNU Classpath 0.20
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / text / ComponentView.java
1 /* ComponentView.java -- 
2    Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package javax.swing.text;
39
40 import java.awt.Component;
41 import java.awt.Container;
42 import java.awt.Graphics;
43 import java.awt.Rectangle;
44 import java.awt.Shape;
45
46 import javax.swing.SwingConstants;
47 import javax.swing.SwingUtilities;
48
49 /**
50  * A {@link View} implementation that is able to render arbitrary
51  * {@link Component}s. This uses the attribute
52  * {@link StyleConstants#ComponentAttribute} to determine the
53  * <code>Component</code> that should be rendered. This <code>Component</code>
54  * becomes a direct child of the <code>JTextComponent</code> that contains
55  * this <code>ComponentView</code>, so this view must not be shared between
56  * multiple <code>JTextComponent</code>s.
57  *
58  * @author Roman Kennke (kennke@aicas.com)
59  * @author original author unknown
60  */
61 public class ComponentView extends View
62 {
63
64   /**
65    * The component that is displayed by this view.
66    */
67   private Component comp;
68
69   /**
70    * Creates a new instance of <code>ComponentView</code> for the specified
71    * <code>Element</code>.
72    *
73    * @param elem the element that this <code>View</code> is rendering
74    */
75   public ComponentView(Element elem)
76   {
77     super(elem);
78   }
79
80   /**
81    * Creates the <code>Component</code> that this <code>View</code> is
82    * rendering. The <code>Component</code> is determined using
83    * the {@link StyleConstants#ComponentAttribute} of the associated
84    * <code>Element</code>.
85    *
86    * @return the component that is rendered
87    */
88   protected Component createComponent()
89   {
90     return StyleConstants.getComponent(getElement().getAttributes());
91   }
92
93   /**
94    * Returns the alignment of this <code>View</code> along the specified axis.
95    *
96    * @param axis either {@link View#X_AXIS} or {@link View#Y_AXIS}
97    *
98    * @return the alignment of this <code>View</code> along the specified axis
99    */
100   public float getAlignment(int axis)
101   {
102     float align;
103     if (axis == X_AXIS)
104       align = getComponent().getAlignmentX();
105     else if (axis == Y_AXIS)
106       align = getComponent().getAlignmentY();
107     else
108       throw new IllegalArgumentException();
109     return align;
110   }
111
112   /**
113    * Returns the <code>Component</code> that is rendered by this
114    * <code>ComponentView</code>.
115    *
116    * @return the <code>Component</code> that is rendered by this
117    *         <code>ComponentView</code>
118    */
119   public final Component getComponent()
120   {
121     if (comp == null)
122       comp = createComponent();
123     return comp;
124   }
125
126   /**
127    * Returns the maximum span of this <code>View</code> along the specified
128    * axis.
129    *
130    * This will return {@link Component#getMaximumSize()} for the specified
131    * axis.
132    *
133    * @return the maximum span of this <code>View</code> along the specified
134    *         axis
135    */
136   public float getMaximumSpan(int axis)
137   {
138     float span;
139     if (axis == X_AXIS)
140       span = getComponent().getMaximumSize().width;
141     else if (axis == Y_AXIS)
142       span = getComponent().getMaximumSize().height;
143     else
144       throw new IllegalArgumentException();
145     return span;
146   }
147
148   public float getMinimumSpan(int axis)
149   {
150     float span;
151     if (axis == X_AXIS)
152       span = getComponent().getMinimumSize().width;
153     else if (axis == Y_AXIS)
154       span = getComponent().getMinimumSize().height;
155     else
156       throw new IllegalArgumentException();
157     return span;
158   }
159
160   public float getPreferredSpan(int axis)
161   {
162     float span;
163     if (axis == X_AXIS)
164       span = getComponent().getPreferredSize().width;
165     else if (axis == Y_AXIS)
166       span = getComponent().getPreferredSize().height;
167     else
168       throw new IllegalArgumentException();
169     return span;
170   }
171
172   public Shape modelToView(int pos, Shape a, Position.Bias b)
173     throws BadLocationException
174   {
175     Element el = getElement();
176     if (pos < el.getStartOffset() || pos >= el.getEndOffset())
177       throw new BadLocationException("Illegal offset for this view", pos);
178     Rectangle r = a.getBounds();
179     Component c = getComponent();
180     return new Rectangle(r.x, r.y, c.getWidth(), c.getHeight());
181   }
182
183   /**
184    * The real painting behavour is performed by normal component painting,
185    * triggered by the text component that hosts this view. This method does
186    * not paint by itself. However, it sets the size of the component according
187    * to the allocation that is passed here.
188    *
189    * @param g the graphics context
190    * @param a the allocation of the child
191    */
192   public void paint(Graphics g, Shape a)
193   {
194     Rectangle r = a.getBounds();
195     getComponent().setBounds(r.x, r.y, r.width, r.height);
196   }
197
198   /**
199    * This sets up the component when the view is added to its parent, or
200    * cleans up the view when it is removed from its parent.
201    *
202    * When this view is added to a parent view, the component of this view
203    * is added to the container that hosts this view. When <code>p</code> is
204    * <code>null</code>, then the view is removed from it's parent and we have
205    * to also remove the component from it's parent container.
206    *
207    * @param p the parent view or <code>null</code> if this view is removed
208    *        from it's parent
209    */
210   public void setParent(final View p)
211   {
212     if (SwingUtilities.isEventDispatchThread())
213       setParentImpl(p);
214     else
215       SwingUtilities.invokeLater
216       (new Runnable()
217        {
218          public void run()
219          {
220            setParentImpl(p);
221          }
222        });
223   }
224
225   /**
226    * The implementation of {@link #setParent}. This is package private to
227    * avoid a synthetic accessor method.
228    *
229    * @param p the parent view to set
230    */
231   void setParentImpl(View p)
232   {
233     if (p != null)
234       {
235         Component c = getComponent();
236         p.getContainer().add(c);
237       }
238     else
239       {
240         Component c = getComponent();
241         Container parent = c.getParent();
242         parent.remove(c);
243         comp = null;
244       }
245   }
246     
247   /**
248    * Maps coordinates from the <code>View</code>'s space into a position
249    * in the document model.
250    *
251    * @param x the x coordinate in the view space
252    * @param y the y coordinate in the view space
253    * @param a the allocation of this <code>View</code>
254    * @param b the bias to use
255    *
256    * @return the position in the document that corresponds to the screen
257    *         coordinates <code>x, y</code>
258    */
259   public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
260   {
261     // The element should only have one character position and it is clear
262     // that this position is the position that best matches the given screen
263     // coordinates, simply because this view has only this one position.
264     Element el = getElement();
265     return el.getStartOffset();
266   }
267 }