Package charvax.swing

Source Code of charvax.swing.JScrollPane

/* class JScrollPane
*
* Copyright (C) 2001, 2002, 2003  R M Pitman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package charvax.swing;

import charva.awt.Component;
import charva.awt.Container;
import charva.awt.Dimension;
import charva.awt.Insets;
import charva.awt.Point;
import charva.awt.Rectangle;
import charva.awt.Scrollable;
import charva.awt.Toolkit;
import charva.awt.event.ScrollEvent;
import charva.awt.event.ScrollListener;
import charvax.swing.border.Border;
import charvax.swing.table.TableHeader;

/**
* provides a scrollable view of a component.
*/
public class JScrollPane extends Container implements ScrollListener {

    /**
     * Creates an empty JScrollPane.
     */
    public JScrollPane() {
    }

    /**
     * Create a JScrollPane that displays the contents of the specified
     * component.
     *
     * @param component_
     *            The component to be displayed. This component must implement
     *            the Scrollable interface.
     */
    public JScrollPane(Component component_) {
        setViewportView(component_);
    }

    /**
     * Creates a viewport if necessary, and then sets its view.
     *
     * @param component_
     *            the view to set in the viewport.
     */
    public void setViewportView(Component component_) {
        _child = component_;

        _childViewport.setView(component_);
        add(_childViewport);
        _childViewport.setParent(this);

        /*
         * This will cause a ClassCastException if the component does not
         * implement the Scrollable interface.
         */
        Scrollable scrollable = (Scrollable) component_;
        scrollable.addScrollListener(this);

        /*
         * If the child component is a JTable, we display two viewports instead
         * of one; the TableHeader corresponding to the table is displayed in
         * the top viewport and scrolls left and right but not up and down. The
         * contents of the table are displayed in the bottom viewport and
         * scroll in all directions.
         */
        if (component_ instanceof JTable) {
            JTable table = (JTable) component_;
            TableHeader header = new TableHeader(table.getModel());
            _headerViewport = new JViewport();
            _headerViewport.setView(header);
            add(_headerViewport);
            _headerViewport.setParent(this);

            _childViewport.setLocation(new Point(0, 1));
            _childViewport.setViewPosition(new Point(0, -1));
        }
    }

    /**
     * Returns the viewport of the component being displayed.
     */
    public JViewport getViewport() {
        return _childViewport;
    }

    /**
     * Overrides the corresponding method in Container.
     */
    public void setSize(int width_, int height_) {
        super.setSize(width_, height_);
        Dimension size = new Dimension(width_, height_);
        if (_border != null) {
            Insets borderInsets = _border.getBorderInsets(this);
            size.height -= (borderInsets.top + borderInsets.bottom);
            size.width -= (borderInsets.left + borderInsets.right);
        }

        // Set the size of the viewport(s) as well
        setViewportExtents(size);
    }

    /**
     * Overrides the corresponding method in Container.
     */
    public void setSize(Dimension size_) {
        this.setSize(size_.width, size_.height);
    }

    /**
     * Overrides the minimumSize() method of Container.
     */
    public Dimension minimumSize() {

        Dimension size = new Dimension();
        Component view = getViewport().getView();
        if (view instanceof Scrollable) {
            Scrollable s = (Scrollable) view;
            size.setSize(s.getPreferredScrollableViewportSize());
        } else {
            size.setSize(view.getSize());
        }

        // Set the size of the viewport(s) as well
        setViewportExtents(size);

        if (_border != null) {
            Insets borderInsets = _border.getBorderInsets(this);
            size.height += (borderInsets.top + borderInsets.bottom);
            size.width += (borderInsets.left + borderInsets.right);
        }

        return size;
    }

    /**
     * Called by a Scrollable object such as JTable or JList, when its state
     * changes in such a way that it may need to be scrolled.
     */
    public void scroll(ScrollEvent e_) {
        Scrollable scrollable = e_.getScrollable();

        int direction = e_.getDirection();

        /*
         * "limit" gives the row and column of the view component that must
         * appear just inside the JViewport after scrolling.
         */
        Point limit = e_.getLimit();

        /*
         * Determine the value of "limit" relative to the top left corner of
         * the JScrollPane.
         */
        Point viewportLocation = getViewport().getLocation();
        limit.translate(viewportLocation.x, viewportLocation.y);
        limit.translate(scrollable.getLocation());

        /*
         * Get the bounding rectangle of the child viewport, relative to the
         * top left corner of the JScrollPane.
         */
        Rectangle viewport = _childViewport.getBounds();
        //Dimension viewportExtent = _childViewport.getExtentSize();

        Point viewPosition = _childViewport.getViewPosition();
        Point headerPosition = null;
        if (_headerViewport != null)
                headerPosition = _headerViewport.getViewPosition();

        /*
         * If the limit is inside the viewport, the component doesn't need to
         * be scrolled. First do the left/right scrolling.
         */
        if (limit.x > viewport.getRight()) {
            if ((direction == ScrollEvent.LEFT
                    || direction == ScrollEvent.UP_LEFT || direction == ScrollEvent.DOWN_LEFT)) {

                viewPosition.x -= (limit.x - viewport.getRight());
                if (_headerViewport != null)
                        headerPosition.x -= (limit.x - viewport.getRight());
            } else if (direction == ScrollEvent.RIGHT
                    || direction == ScrollEvent.UP_RIGHT
                    || direction == ScrollEvent.DOWN_RIGHT) {

                viewPosition.x += (viewport.getLeft() - limit.x);
                if (_headerViewport != null)
                        headerPosition.x += (viewport.getLeft() - limit.x);
            }
        } else if (limit.x < viewport.getLeft()) {
            if (direction == ScrollEvent.RIGHT
                    || direction == ScrollEvent.UP_RIGHT
                    || direction == ScrollEvent.DOWN_RIGHT) {

                viewPosition.x += (viewport.getLeft() - limit.x);
                if (_headerViewport != null)
                        headerPosition.x += (viewport.getLeft() - limit.x);
            } else if (direction == ScrollEvent.LEFT
                    || direction == ScrollEvent.UP_LEFT
                    || direction == ScrollEvent.DOWN_LEFT) {
                viewPosition.x -= (limit.x - viewport.getRight());
                if (_headerViewport != null)
                        headerPosition.x -= (limit.x - viewport.getRight());
            }
        }

        // Now do the up/down scrolling
        if (limit.y < viewport.getTop()
                && (direction == ScrollEvent.DOWN
                        || direction == ScrollEvent.DOWN_LEFT || direction == ScrollEvent.DOWN_RIGHT)) {

            viewPosition.y += (viewport.getTop() - limit.y);
        } else if (limit.y > viewport.getBottom()
                && (direction == ScrollEvent.UP
                        || direction == ScrollEvent.UP_LEFT || direction == ScrollEvent.UP_RIGHT)) {

            viewPosition.y -= (limit.y - viewport.getBottom());
        }

        _childViewport.setViewPosition(viewPosition);
        if (_headerViewport != null)
                _headerViewport.setViewPosition(headerPosition);

        draw(Toolkit.getDefaultToolkit());

        /*
         * Ensure the cursor is within the viewport (if the component contained
         * within the viewport is offset a long way to the left, the cursor
         * position can get scrambled).
         */
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Point cursor = toolkit.getCursor();
        Point viewportOrigin = _childViewport.getLocationOnScreen();
        if (cursor.x < viewportOrigin.x || cursor.y < viewportOrigin.y) {
            if (cursor.x < viewportOrigin.x) cursor.x = viewportOrigin.x;
            if (cursor.y < viewportOrigin.y) cursor.y = viewportOrigin.y;
            toolkit.setCursor(cursor);
        }
    }

    /**
     * @param toolkit
     */
    public void draw(Toolkit toolkit) {

        /*
         * Get the absolute origin of this component.
         */
        Point origin = getLocationOnScreen();
        Insets borderInsets;
        if (getViewportBorder() != null) {
            borderInsets = getViewportBorder().getBorderInsets(this);
        } else
            borderInsets = new Insets(0, 0, 0, 0);

        int colorpair = getCursesColor();
        Dimension size = minimumSize();

        if (_border != null) {

            _border.paintBorder(this, 0, origin.x, origin.y, size.width,
                    size.height, toolkit);
        }

        // Don't draw scrollbars if the child component is a TableHeader.
        if (_child instanceof TableHeader) return;

        /*
         * If the child component is larger than the viewport, draw scrollbars.
         */

        // The size of the component displayed within the viewport.
        Dimension childSize = getViewport().getViewSize();

        // The size of the viewport
        Dimension extentSize = getViewport().getExtentSize();
        Point viewPosition = getViewport().getViewPosition();

        // If the child is a JTable, we have to adjust the
        // parameters a bit because the viewport includes the header.
        /*
         * if (_child instanceof JTable) { viewport_height--; child_height--;
         * view_y++;
         */

        if (childSize.height > extentSize.height) {

            int scrollbar_height = (extentSize.height * extentSize.height)
                    / childSize.height;

            // Round the height upwards to the nearest integer.
            if (((extentSize.height * extentSize.height) % childSize.height) != 0)
                    scrollbar_height++;

            int scrollbar_offset = (-1 * viewPosition.y * extentSize.height)
                    / childSize.height;

            for (int i = 0; i < extentSize.height; i++) {

                toolkit.setCursor(origin.addOffset(borderInsets.left
                        + extentSize.width, borderInsets.top + i));
                if (i >= scrollbar_offset
                        && i < scrollbar_offset + scrollbar_height) {
                    toolkit.addChar(Toolkit.ACS_CKBOARD, 0, colorpair);
                }
            }
        }

        if (childSize.width > extentSize.width) {

            int scrollbar_width = (extentSize.width * extentSize.width)
                    / childSize.width;

            // Round the width upwards to the nearest integer.
            if (((extentSize.width * extentSize.width) % childSize.width) != 0)
                    scrollbar_width++;

            int scrollbar_offset = (-1 * viewPosition.x * extentSize.width)
                    / childSize.width;

            for (int i = 0; i < extentSize.width; i++) {

                toolkit.setCursor(origin.addOffset(borderInsets.left + i,
                        borderInsets.top + extentSize.height));
                if (i >= scrollbar_offset
                        && i < scrollbar_offset + scrollbar_width) {
                    toolkit.addChar(Toolkit.ACS_CKBOARD, 0, colorpair);
                }
            }
        }

        // Draw the child viewport(s) by calling the draw() method
        // of the Container class.
        super.draw(toolkit);
    }

    /**
     * Adds a border around the viewport.
     */
    public void setViewportBorder(Border viewportBorder_) {
        _border = viewportBorder_;
        Insets insets = _border.getBorderInsets(this);

        if (_headerViewport != null) {
            // This must be a JTable.
            _headerViewport.setLocation(new Point(insets.left, insets.top));
            _childViewport.setLocation(new Point(insets.left, insets.top + 1));
        } else
            _childViewport.setLocation(new Point(insets.left, insets.top));
    }

    /**
     * Returns a reference to the border around the JScrollPane's viewport.
     */
    public Border getViewportBorder() {
        return _border;
    }

    public void debug(int level_) {
        for (int i = 0; i < level_; i++)
            System.err.print("    ");
        System.err.println("JScrollPane origin=" + _origin + " size="
                + getSize());
        super.debug(level_ + 1);
    }

    public String toString() {
        return ("JScrollPane origin=" + _origin + " size=" + getSize());
    }

    /**
     * Sets the size of the visible part of the view.
     */
    private void setViewportExtents(Dimension size) {
        if (_headerViewport != null) {
            _headerViewport.setExtentSize(size.width, 1);
            _childViewport.setExtentSize(size.width, size.height - 1);
        } else {
            _childViewport.setExtentSize(size.width, size.height);
        }
    }

    //====================================================================
    // INSTANCE VARIABLES

    private Component _child;

    /**
     * This is used only if the contained component is a JTable.
     */
    private JViewport _headerViewport = null;

    /**
     * A JViewport container that holds the (single) child component.
     */
    private JViewport _childViewport = new JViewport();

    //private JScrollBar _vertical;

    //private JScrollBar _horiz;

    private Border _border;
}
TOP

Related Classes of charvax.swing.JScrollPane

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.