API Overview API Index Package Overview Direct link to this page
JDK 1.6
  javax.swing.text.html. BlockView View Javadoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

/*
 * @(#)BlockView.java	1.38 06/02/14
 *
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package javax.swing.text.html;

import java.util.Enumeration;
import java.awt.*;
import javax.swing.SizeRequirements;
import javax.swing.border.*;
import javax.swing.event.DocumentEvent;
import javax.swing.text.*;

/**
 * A view implementation to display a block (as a box)
 * with CSS specifications.
 *
 * @author  Timothy Prinzing
 * @version 1.38 02/14/06
 */
public class BlockView extends BoxView  {

    /**
     * Creates a new view that represents an
     * html box.  This can be used for a number
     * of elements.
     *
     * @param elem the element to create a view for
     * @param axis either View.X_AXIS or View.Y_AXIS
     */
    public BlockView(Element elem, int axis) {
	super(elem, axis);
    }

    /**
     * Establishes the parent view for this view.  This is
     * guaranteed to be called before any other methods if the
     * parent view is functioning properly.
     * <p> 
     * This is implemented
     * to forward to the superclass as well as call the
     * {@link #setPropertiesFromAttributes()}
     * method to set the paragraph properties from the css
     * attributes.  The call is made at this time to ensure
     * the ability to resolve upward through the parents 
     * view attributes.
     *
     * @param parent the new parent, or null if the view is
     *  being removed from a parent it was previously added
     *  to
     */
    public void setParent(View parent) {
	super.setParent(parent);
        if (parent != null) {
            setPropertiesFromAttributes();
        }
    }

    /**
     * Calculate the requirements of the block along the major
     * axis (i.e. the axis along with it tiles).  This is implemented
     * to provide the superclass behavior and then adjust it if the 
     * CSS width or height attribute is specified and applicable to
     * the axis.
     */
    protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) {
	if (r == null) {
	    r = new SizeRequirements();
	}
	if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {
	    r = super.calculateMajorAxisRequirements(axis, r);
	}
        else {
            // Offset by the margins so that pref/min/max return the
            // right value.
            SizeRequirements parentR = super.calculateMajorAxisRequirements(
                                      axis, null);
            int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
                                            getTopInset() + getBottomInset();
            r.minimum -= margin;
            r.preferred -= margin;
            r.maximum -= margin;
            constrainSize(axis, r, parentR);
        }
	return r;
    }

    /**
     * Calculate the requirements of the block along the minor
     * axis (i.e. the axis orthoginal to the axis along with it tiles).  
     * This is implemented
     * to provide the superclass behavior and then adjust it if the 
     * CSS width or height attribute is specified and applicable to
     * the axis.
     */
    protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
	if (r == null) {
	    r = new SizeRequirements();
	}

	if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {

	    /*
	     * The requirements were not directly specified by attributes, so
	     * compute the aggregate of the requirements of the children.  The
	     * children that have a percentage value specified will be treated 
	     * as completely stretchable since that child is not limited in any
	     * way.
	     */ 
/*
	    int min = 0;
	    long pref = 0;
	    int max = 0;
	    int n = getViewCount();
	    for (int i = 0; i < n; i++) {
		View v = getView(i);
		min = Math.max((int) v.getMinimumSpan(axis), min);
		pref = Math.max((int) v.getPreferredSpan(axis), pref);
		if (
		max = Math.max((int) v.getMaximumSpan(axis), max);

	    }
	    r.preferred = (int) pref;
	    r.minimum = min;
	    r.maximum = max;
	    */
	    r = super.calculateMinorAxisRequirements(axis, r);
	}
        else {
            // Offset by the margins so that pref/min/max return the
            // right value.
            SizeRequirements parentR = super.calculateMinorAxisRequirements(
                                      axis, null);
            int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
                                            getTopInset() + getBottomInset();
            r.minimum -= margin;
            r.preferred -= margin;
            r.maximum -= margin;
            constrainSize(axis, r, parentR);
        }

	/*
	 * Set the alignment based upon the CSS properties if it is
	 * specified.  For X_AXIS this would be text-align, for 
	 * Y_AXIS this would be vertical-align.
	 */
	if (axis == X_AXIS) {
	    Object o = getAttributes().getAttribute(CSS.Attribute.TEXT_ALIGN);
	    if (o != null) {
		String align = o.toString();
		if (align.equals("center")) {
		    r.alignment = 0.5f;
		} else if (align.equals("right")) {
		    r.alignment = 1.0f;
		} else {
		    r.alignment = 0.0f;
		}
	    }
	}
	// Y_AXIS TBD
	return r;
    }

    boolean isPercentage(int axis, AttributeSet a) {
	if (axis == X_AXIS) {
	    if (cssWidth != null) {
		return cssWidth.isPercentage();
	    }
	} else {
	    if (cssHeight != null) {
		return cssHeight.isPercentage();
	    }
	}
	return false;
    }
	    
    /**
     * Adjust the given requirements to the CSS width or height if
     * it is specified along the applicable axis.  Return true if the
     * size is exactly specified, false if the span is not specified 
     * in an attribute or the size specified is a percentage.
     */
    static boolean spanSetFromAttributes(int axis, SizeRequirements r,
                                         CSS.LengthValue cssWidth,
                                         CSS.LengthValue cssHeight) {
	if (axis == X_AXIS) {
	    if ((cssWidth != null) && (! cssWidth.isPercentage())) {
		r.minimum = r.preferred = r.maximum = (int) cssWidth.getValue();
		return true;
	    }
	} else {
	    if ((cssHeight != null) && (! cssHeight.isPercentage())) {
		r.minimum = r.preferred = r.maximum = (int) cssHeight.getValue();
		return true;
	    }
	}
	return false;
    }

    /**
     * Performs layout for the minor axis of the box (i.e. the
     * axis orthoginal to the axis that it represents). The results 
     * of the layout (the offset and span for each children) are 
     * placed in the given arrays which represent the allocations to 
     * the children along the minor axis.
     *
     * @param targetSpan the total span given to the view, which
     *  whould be used to layout the childre.
     * @param axis the axis being layed out
     * @param offsets the offsets from the origin of the view for
     *  each of the child views; this is a return value and is
     *  filled in by the implementation of this method
     * @param spans the span of each child view; this is a return
     *  value and is filled in by the implementation of this method
     */
    protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
	int n = getViewCount();
	Object key = (axis == X_AXIS) ? CSS.Attribute.WIDTH : CSS.Attribute.HEIGHT;
	for (int i = 0; i < n; i++) {
	    View v = getView(i);
	    int min = (int) v.getMinimumSpan(axis);
	    int max;

	    // check for percentage span
	    AttributeSet a = v.getAttributes();
	    CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(key);
	    if ((lv != null) && lv.isPercentage()) {
		// bound the span to the percentage specified
		min = Math.max((int) lv.getValue(targetSpan), min);
		max = min;
	    } else {
                max = (int)v.getMaximumSpan(axis);
	    }

	    // assign the offset and span for the child
	    if (max < targetSpan) {
		// can't make the child this wide, align it
		float align = v.getAlignment(axis);
		offsets[i] = (int) ((targetSpan - max) * align);
		spans[i] = max;
	    } else {
		// make it the target width, or as small as it can get.
		offsets[i] = 0;
		spans[i] = Math.max(min, targetSpan);
	    }
	}
    }


    /**
     * Renders using the given rendering surface and area on that
     * surface.  This is implemented to delegate to the css box
     * painter to paint the border and background prior to the
     * interior.
     *
     * @param g the rendering surface to use
     * @param allocation the allocated region to render into
     * @see View#paint
     */
    public void paint(Graphics g, Shape allocation) {
	Rectangle a = (Rectangle) allocation;
	painter.paint(g, a.x, a.y, a.width, a.height, this);
	super.paint(g, a);
    }

    /**
     * Fetches the attributes to use when rendering.  This is
     * implemented to multiplex the attributes specified in the
     * model with a StyleSheet.
     */
    public AttributeSet getAttributes() {
	if (attr == null) {
	    StyleSheet sheet = getStyleSheet();
	    attr = sheet.getViewAttributes(this);
	}
	return attr;
    }

    /**
     * Gets the resize weight.
     *
     * @param axis may be either X_AXIS or Y_AXIS
     * @return the weight
     * @exception IllegalArgumentException for an invalid axis
     */
    public int getResizeWeight(int axis) {
	switch (axis) {
	case View.X_AXIS:
	    return 1;
	case View.Y_AXIS:
	    return 0;
	default:
	    throw new IllegalArgumentException("Invalid axis: " + axis);
	}
    }

    /**
     * Gets the alignment.
     *
     * @param axis may be either X_AXIS or Y_AXIS
     * @return the alignment
     */
    public float getAlignment(int axis) {
	switch (axis) {
	case View.X_AXIS:
	    return 0;
	case View.Y_AXIS:
	    if (getViewCount() == 0) {
		return 0;
	    }
	    float span = getPreferredSpan(View.Y_AXIS);
	    View v = getView(0);
	    float above = v.getPreferredSpan(View.Y_AXIS);
	    float a = (((int)span) != 0) ? (above * v.getAlignment(View.Y_AXIS)) / span: 0;
	    return a;
	default:
	    throw new IllegalArgumentException("Invalid axis: " + axis);
	}
    }

    public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
	super.changedUpdate(changes, a, f);
	int pos = changes.getOffset();
	if (pos <= getStartOffset() && (pos + changes.getLength()) >=
	    getEndOffset()) {
	    setPropertiesFromAttributes();
	}
    }

    /**
     * Determines the preferred span for this view along an
     * axis.
     *
     * @param axis may be either <code>View.X_AXIS</code>
     *		 or <code>View.Y_AXIS</code>
     * @return   the span the view would like to be rendered into >= 0;
     *           typically the view is told to render into the span
     *           that is returned, although there is no guarantee; 
     *           the parent may choose to resize or break the view
     * @exception IllegalArgumentException for an invalid axis type
     */
    public float getPreferredSpan(int axis) {
	return super.getPreferredSpan(axis);
    }

    /**
     * Determines the minimum span for this view along an
     * axis.
     *
     * @param axis may be either <code>View.X_AXIS</code>
     *		 or <code>View.Y_AXIS</code>
     * @return  the span the view would like to be rendered into >= 0;
     *           typically the view is told to render into the span
     *           that is returned, although there is no guarantee;  
     *           the parent may choose to resize or break the view
     * @exception IllegalArgumentException for an invalid axis type
     */
    public float getMinimumSpan(int axis) {
	return super.getMinimumSpan(axis);
    }

    /**
     * Determines the maximum span for this view along an
     * axis.
     *
     * @param axis may be either <code>View.X_AXIS</code>
     *		 or <code>View.Y_AXIS</code>
     * @return   the span the view would like to be rendered into >= 0;
     *           typically the view is told to render into the span
     *           that is returned, although there is no guarantee;  
     *           the parent may choose to resize or break the view
     * @exception IllegalArgumentException for an invalid axis type
     */
    public float getMaximumSpan(int axis) {
	return super.getMaximumSpan(axis);
    }

    /**
     * Update any cached values that come from attributes.
     */
    protected void setPropertiesFromAttributes() {

	// update attributes
	StyleSheet sheet = getStyleSheet();
	attr = sheet.getViewAttributes(this);

	// Reset the painter
	painter = sheet.getBoxPainter(attr);
	if (attr != null) {
	    setInsets((short) painter.getInset(TOP, this),
		      (short) painter.getInset(LEFT, this),
		      (short) painter.getInset(BOTTOM, this),
		      (short) painter.getInset(RIGHT, this));
	}

	// Get the width/height
	cssWidth = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.WIDTH);
	cssHeight = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.HEIGHT);
    }

    protected StyleSheet getStyleSheet() {
	HTMLDocument doc = (HTMLDocument) getDocument();
	return doc.getStyleSheet();
    }

    /**
     * Constrains <code>want</code> to fit in the minimum size specified
     * by <code>min</code>.
     */
    private void constrainSize(int axis, SizeRequirements want,
                               SizeRequirements min) {
        if (min.minimum > want.minimum) {
            want.minimum = want.preferred = min.minimum;
            want.maximum = Math.max(want.maximum, min.maximum);
        }
    }

    private AttributeSet attr;
    private StyleSheet.BoxPainter painter;

    private CSS.LengthValue cssWidth;
    private CSS.LengthValue cssHeight;

}

Generated By: JavaOnTracks Doclet 0.1.4     ©Thibaut Colar