alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (BlockView.java)

This example Java source code file (BlockView.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

attributeset, awt, blockview, border, boxview, event, gui, htmldocument, illegalargumentexception, invalid, object, rectangle, shape, sizerequirements, stylesheet, swing, text, view, viewfactory, x_axis

The BlockView.java Java example source code

/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
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
 */
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 orthogonal 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 orthogonal 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
     *  would be used to layout the children.
     * @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
     *           or <code>View.Y_AXIS
     * @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
     *           or <code>View.Y_AXIS
     * @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
     *           or <code>View.Y_AXIS
     * @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 to fit in the minimum size specified
     * by <code>min.
     */
    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;

}

Other Java examples (source code examples)

Here is a short list of links related to this Java BlockView.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.