KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > text > FieldView


1 /*
2  * @(#)FieldView.java 1.25 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.text;
8
9 import java.awt.*;
10 import javax.swing.*;
11 import javax.swing.event.*;
12
13 /**
14  * Extends the multi-line plain text view to be suitable
15  * for a single-line editor view. If the view is
16  * allocated extra space, the field must adjust for it.
17  * If the hosting component is a JTextField, this view
18  * will manage the ranges of the associated BoundedRangeModel
19  * and will adjust the horizontal allocation to match the
20  * current visibility settings of the JTextField.
21  *
22  * @author Timothy Prinzing
23  * @version 1.25 12/19/03
24  * @see View
25  */

26 public class FieldView extends PlainView JavaDoc {
27
28     /**
29      * Constructs a new FieldView wrapped on an element.
30      *
31      * @param elem the element
32      */

33     public FieldView(Element JavaDoc elem) {
34     super(elem);
35     }
36
37     /**
38      * Fetches the font metrics associated with the component hosting
39      * this view.
40      *
41      * @return the metrics
42      */

43     protected FontMetrics getFontMetrics() {
44     Component c = getContainer();
45     return c.getFontMetrics(c.getFont());
46     }
47
48     /**
49      * Adjusts the allocation given to the view
50      * to be a suitable allocation for a text field.
51      * If the view has been allocated more than the
52      * preferred span vertically, the allocation is
53      * changed to be centered vertically. Horizontally
54      * the view is adjusted according to the horizontal
55      * alignment property set on the associated JTextField
56      * (if that is the type of the hosting component).
57      *
58      * @param a the allocation given to the view, which may need
59      * to be adjusted.
60      * @return the allocation that the superclass should use.
61      */

62     protected Shape adjustAllocation(Shape a) {
63     if (a != null) {
64         Rectangle bounds = a.getBounds();
65         int vspan = (int) getPreferredSpan(Y_AXIS);
66         int hspan = (int) getPreferredSpan(X_AXIS);
67         if (bounds.height != vspan) {
68         int slop = bounds.height - vspan;
69         bounds.y += slop / 2;
70         bounds.height -= slop;
71         }
72
73         // horizontal adjustments
74
Component c = getContainer();
75         if (c instanceof JTextField) {
76         JTextField field = (JTextField) c;
77         BoundedRangeModel vis = field.getHorizontalVisibility();
78         int max = Math.max(hspan, bounds.width);
79         int value = vis.getValue();
80         int extent = Math.min(max, bounds.width - 1);
81         if ((value + extent) > max) {
82             value = max - extent;
83         }
84         vis.setRangeProperties(value, extent, vis.getMinimum(),
85                        max, false);
86         if (hspan < bounds.width) {
87             // horizontally align the interior
88
int slop = bounds.width - 1 - hspan;
89
90             int align = ((JTextField)c).getHorizontalAlignment();
91             if(Utilities.isLeftToRight(c)) {
92                 if(align==LEADING) {
93                 align = LEFT;
94             }
95             else if(align==TRAILING) {
96                 align = RIGHT;
97             }
98             }
99             else {
100                 if(align==LEADING) {
101                 align = RIGHT;
102             }
103             else if(align==TRAILING) {
104                 align = LEFT;
105             }
106             }
107
108             switch (align) {
109             case SwingConstants.CENTER:
110             bounds.x += slop / 2;
111             bounds.width -= slop;
112             break;
113             case SwingConstants.RIGHT:
114             bounds.x += slop;
115             bounds.width -= slop;
116             break;
117             }
118         } else {
119             // adjust the allocation to match the bounded range.
120
bounds.width = hspan;
121             bounds.x -= vis.getValue();
122         }
123         }
124         return bounds;
125     }
126     return null;
127     }
128
129     /**
130      * Update the visibility model with the associated JTextField
131      * (if there is one) to reflect the current visibility as a
132      * result of changes to the document model. The bounded
133      * range properties are updated. If the view hasn't yet been
134      * shown the extent will be zero and we just set it to be full
135      * until determined otherwise.
136      */

137     void updateVisibilityModel() {
138     Component c = getContainer();
139     if (c instanceof JTextField) {
140         JTextField field = (JTextField) c;
141         BoundedRangeModel vis = field.getHorizontalVisibility();
142         int hspan = (int) getPreferredSpan(X_AXIS);
143         int extent = vis.getExtent();
144         int maximum = Math.max(hspan, extent);
145         extent = (extent == 0) ? maximum : extent;
146         int value = maximum - extent;
147         int oldValue = vis.getValue();
148         if ((oldValue + extent) > maximum) {
149         oldValue = maximum - extent;
150         }
151         value = Math.max(0, Math.min(value, oldValue));
152         vis.setRangeProperties(value, extent, 0, maximum, false);
153     }
154     }
155
156     // --- View methods -------------------------------------------
157

158     /**
159      * Renders using the given rendering surface and area on that surface.
160      * The view may need to do layout and create child views to enable
161      * itself to render into the given allocation.
162      *
163      * @param g the rendering surface to use
164      * @param a the allocated region to render into
165      *
166      * @see View#paint
167      */

168     public void paint(Graphics g, Shape a) {
169     Rectangle r = (Rectangle) a;
170     g.clipRect(r.x, r.y, r.width, r.height);
171     super.paint(g, a);
172     }
173
174     /**
175      * Adjusts <code>a</code> based on the visible region and returns it.
176      */

177     Shape adjustPaintRegion(Shape a) {
178     return adjustAllocation(a);
179     }
180
181     /**
182      * Determines the preferred span for this view along an
183      * axis.
184      *
185      * @param axis may be either View.X_AXIS or View.Y_AXIS
186      * @return the span the view would like to be rendered into >= 0.
187      * Typically the view is told to render into the span
188      * that is returned, although there is no guarantee.
189      * The parent may choose to resize or break the view.
190      */

191     public float getPreferredSpan(int axis) {
192     switch (axis) {
193     case View.X_AXIS:
194         Segment JavaDoc buff = SegmentCache.getSharedSegment();
195         Document JavaDoc doc = getDocument();
196         int width;
197         try {
198                 FontMetrics fm = getFontMetrics();
199         doc.getText(0, doc.getLength(), buff);
200         width = Utilities.getTabbedTextWidth(buff, fm, 0, this, 0);
201                 if (buff.count > 0) {
202                     Component c = getContainer();
203                     firstLineOffset = com.sun.java.swing.SwingUtilities2.
204                         getLeftSideBearing((c instanceof JComponent) ?
205                                            (JComponent)c : null, fm,
206                                            buff.array[buff.offset]);
207                     firstLineOffset = Math.max(0, -firstLineOffset);
208                 }
209                 else {
210                     firstLineOffset = 0;
211                 }
212         } catch (BadLocationException JavaDoc bl) {
213         width = 0;
214         }
215             SegmentCache.releaseSharedSegment(buff);
216         return width + firstLineOffset;
217     default:
218         return super.getPreferredSpan(axis);
219     }
220     }
221
222     /**
223      * Determines the resizability of the view along the
224      * given axis. A value of 0 or less is not resizable.
225      *
226      * @param axis View.X_AXIS or View.Y_AXIS
227      * @return the weight -> 1 for View.X_AXIS, else 0
228      */

229     public int getResizeWeight(int axis) {
230     if (axis == View.X_AXIS) {
231         return 1;
232     }
233     return 0;
234     }
235
236     /**
237      * Provides a mapping from the document model coordinate space
238      * to the coordinate space of the view mapped to it.
239      *
240      * @param pos the position to convert >= 0
241      * @param a the allocated region to render into
242      * @return the bounding box of the given position
243      * @exception BadLocationException if the given position does not
244      * represent a valid location in the associated document
245      * @see View#modelToView
246      */

247     public Shape modelToView(int pos, Shape a, Position.Bias JavaDoc b) throws BadLocationException JavaDoc {
248     return super.modelToView(pos, adjustAllocation(a), b);
249     }
250
251     /**
252      * Provides a mapping from the view coordinate space to the logical
253      * coordinate space of the model.
254      *
255      * @param fx the X coordinate >= 0.0f
256      * @param fy the Y coordinate >= 0.0f
257      * @param a the allocated region to render into
258      * @return the location within the model that best represents the
259      * given point in the view
260      * @see View#viewToModel
261      */

262     public int viewToModel(float fx, float fy, Shape a, Position.Bias JavaDoc[] bias) {
263     return super.viewToModel(fx, fy, adjustAllocation(a), bias);
264     }
265
266     /**
267      * Gives notification that something was inserted into the document
268      * in a location that this view is responsible for.
269      *
270      * @param changes the change information from the associated document
271      * @param a the current allocation of the view
272      * @param f the factory to use to rebuild if the view has children
273      * @see View#insertUpdate
274      */

275     public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory JavaDoc f) {
276     super.insertUpdate(changes, adjustAllocation(a), f);
277     updateVisibilityModel();
278     }
279
280     /**
281      * Gives notification that something was removed from the document
282      * in a location that this view is responsible for.
283      *
284      * @param changes the change information from the associated document
285      * @param a the current allocation of the view
286      * @param f the factory to use to rebuild if the view has children
287      * @see View#removeUpdate
288      */

289     public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory JavaDoc f) {
290     super.removeUpdate(changes, adjustAllocation(a), f);
291     updateVisibilityModel();
292     }
293
294 }
295
Popular Tags