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

Java example source code file (FrameSetView.java)

This example Java source code file (FrameSetView.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, event, framesetview, frameview, gui, sizerequirements, string, stringtokenizer, swing, text, util

The FrameSetView.java Java example source code

/*
 * Copyright (c) 1998, 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.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;

/**
 * Implements a FrameSetView, intended to support the HTML
 * <FRAMESET> tag.  Supports the ROWS and COLS attributes.
 *
 * @author  Sunita Mani
 *
 *          Credit also to the hotjava browser engineers that
 *          worked on making the allocation of space algorithms
 *          conform to the HTML 4.0 standard and also be netscape
 *          compatible.
 *
 */

class FrameSetView extends javax.swing.text.BoxView {

    String[] children;
    int[] percentChildren;
    int[] absoluteChildren;
    int[] relativeChildren;
    int percentTotals;
    int absoluteTotals;
    int relativeTotals;

    /**
     * Constructs a FrameSetView for the given element.
     *
     * @param elem the element that this view is responsible for
     */
    public FrameSetView(Element elem, int axis) {
        super(elem, axis);
        children = null;
    }

    /**
     * Parses the ROW or COL attributes and returns
     * an array of strings that represent the space
     * distribution.
     *
     */
    private String[] parseRowColSpec(HTML.Attribute key) {

        AttributeSet attributes = getElement().getAttributes();
        String spec = "*";
        if (attributes != null) {
            if (attributes.getAttribute(key) != null) {
                spec = (String)attributes.getAttribute(key);
            }
        }

        StringTokenizer tokenizer = new StringTokenizer(spec, ",");
        int nTokens = tokenizer.countTokens();
        int n = getViewCount();
        String[] items = new String[Math.max(nTokens, n)];
        int i = 0;
        for (; i < nTokens; i++) {
            items[i] = tokenizer.nextToken().trim();
            // As per the spec, 100% is the same as *
            // hence the mapping.
            //
            if (items[i].equals("100%")) {
                items[i] = "*";
            }
        }
        // extend spec if we have more children than specified
        // in ROWS or COLS attribute
        for (; i < items.length; i++) {
            items[i] = "*";
        }
        return items;
    }


    /**
     * Initializes a number of internal state variables
     * that store information about space allocation
     * for the frames contained within the frameset.
     */
    private void init() {
        if (getAxis() == View.Y_AXIS) {
            children = parseRowColSpec(HTML.Attribute.ROWS);
        } else {
            children = parseRowColSpec(HTML.Attribute.COLS);
        }
        percentChildren = new int[children.length];
        relativeChildren = new int[children.length];
        absoluteChildren = new int[children.length];

        for (int i = 0; i < children.length; i++) {
            percentChildren[i] = -1;
            relativeChildren[i] = -1;
            absoluteChildren[i] = -1;

            if (children[i].endsWith("*")) {
                if (children[i].length() > 1) {
                    relativeChildren[i] =
                        Integer.parseInt(children[i].substring(
                            0, children[i].length()-1));
                    relativeTotals += relativeChildren[i];
                } else {
                    relativeChildren[i] = 1;
                    relativeTotals += 1;
                }
            } else if (children[i].indexOf('%') != -1) {
                percentChildren[i] = parseDigits(children[i]);
                percentTotals += percentChildren[i];
            } else {
                absoluteChildren[i] = Integer.parseInt(children[i]);
            }
        }
        if (percentTotals > 100) {
            for (int i = 0; i < percentChildren.length; i++) {
                if (percentChildren[i] > 0) {
                    percentChildren[i] =
                        (percentChildren[i] * 100) / percentTotals;
                }
            }
            percentTotals = 100;
        }
    }

    /**
     * Perform layout for the major axis of the box (i.e. the
     * axis that it represents).  The results of the layout should
     * be placed in the given arrays which represent the allocations
     * to the children along the major 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
     * @return the offset and span for each child view in the
     *  offsets and spans parameters
     */
    protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
                                   int[] spans) {
        if (children == null) {
            init();
        }
        SizeRequirements.calculateTiledPositions(targetSpan, null,
                                                 getChildRequests(targetSpan,
                                                                  axis),
                                                 offsets, spans);
    }

    protected SizeRequirements[] getChildRequests(int targetSpan, int axis) {

        int span[] = new int[children.length];

        spread(targetSpan, span);
        int n = getViewCount();
        SizeRequirements[] reqs = new SizeRequirements[n];
        for (int i = 0, sIndex = 0; i < n; i++) {
            View v = getView(i);
            if ((v instanceof FrameView) || (v instanceof FrameSetView)) {
                reqs[i] = new SizeRequirements((int) v.getMinimumSpan(axis),
                                               span[sIndex],
                                               (int) v.getMaximumSpan(axis),
                                               0.5f);
                sIndex++;
            } else {
                int min = (int) v.getMinimumSpan(axis);
                int pref = (int) v.getPreferredSpan(axis);
                int max = (int) v.getMaximumSpan(axis);
                float a = v.getAlignment(axis);
                reqs[i] = new SizeRequirements(min, pref, max, a);
            }
        }
        return reqs;
    }


    /**
     * This method is responsible for returning in span[] the
     * span for each child view along the major axis.  it
     * computes this based on the information that extracted
     * from the value of the ROW/COL attribute.
     */
    private void spread(int targetSpan, int span[]) {

        if (targetSpan == 0) {
            return;
        }

        int tempSpace = 0;
        int remainingSpace = targetSpan;

        // allocate the absolute's first, they have
        // precedence
        //
        for (int i = 0; i < span.length; i++) {
            if (absoluteChildren[i] > 0) {
                span[i] = absoluteChildren[i];
                remainingSpace -= span[i];
            }
        }

        // then deal with percents.
        //
        tempSpace = remainingSpace;
        for (int i = 0; i < span.length; i++) {
            if (percentChildren[i] > 0 && tempSpace > 0) {
                span[i] = (percentChildren[i] * tempSpace) / 100;
                remainingSpace -= span[i];
            } else if (percentChildren[i] > 0 && tempSpace <= 0) {
                span[i] = targetSpan / span.length;
                remainingSpace -= span[i];
            }
        }

        // allocate remainingSpace to relative
        if (remainingSpace > 0 && relativeTotals > 0) {
            for (int i = 0; i < span.length; i++) {
                if (relativeChildren[i] > 0) {
                    span[i] = (remainingSpace *
                                relativeChildren[i]) / relativeTotals;
                }
            }
        } else if (remainingSpace > 0) {
            // There are no relative columns and the space has been
            // under- or overallocated.  In this case, turn all the
            // percentage and pixel specified columns to percentage
            // columns based on the ratio of their pixel count to the
            // total "virtual" size. (In the case of percentage columns,
            // the pixel count would equal the specified percentage
            // of the screen size.

            // This action is in accordance with the HTML
            // 4.0 spec (see section 8.3, the end of the discussion of
            // the FRAMESET tag).  The precedence of percentage and pixel
            // specified columns is unclear (spec seems to indicate that
            // they share priority, however, unspecified what happens when
            // overallocation occurs.)

            // addendum is that we behave similar to netscape in that specified
            // widths have precedance over percentage widths...

            float vTotal = (float)(targetSpan - remainingSpace);
            float[] tempPercents = new float[span.length];
            remainingSpace = targetSpan;
            for (int i = 0; i < span.length; i++) {
                // ok we know what our total space is, and we know how large each
                // column should be relative to each other... therefore we can use
                // that relative information to deduce their percentages of a whole
                // and then scale them appropriately for the correct size
                tempPercents[i] = ((float)span[i] / vTotal) * 100.00f;
                span[i] = (int) ( ((float)targetSpan * tempPercents[i]) / 100.00f);
                remainingSpace -= span[i];
            }


            // this is for just in case there is something left over.. if there is we just
            // add it one pixel at a time to the frames in order.. We shouldn't really ever get
            // here and if we do it shouldn't be with more than 1 pixel, maybe two.
            int i = 0;
            while (remainingSpace != 0) {
                if (remainingSpace < 0) {
                    span[i++]--;
                    remainingSpace++;
                }
                else {
                    span[i++]++;
                    remainingSpace--;
                }

                // just in case there are more pixels than frames...should never happen..
                if (i == span.length)i = 0;
            }
        }
    }

    /*
     * Users have been known to type things like "%25" and "25 %".  Deal
     * with it.
     */
    private int parseDigits(String mixedStr) {
        int result = 0;
        for (int i = 0; i < mixedStr.length(); i++) {
            char ch = mixedStr.charAt(i);
            if (Character.isDigit(ch)) {
                result = (result * 10) + Character.digit(ch, 10);
            }
        }
        return result;
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java FrameSetView.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.