Package javax.swing.text

Source Code of javax.swing.text.View

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Alexey A. Ivanov
* @version $Revision$
*/
package javax.swing.text;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.text.AttributedString;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentEvent.ElementChange;
import javax.swing.event.DocumentEvent.EventType;
import javax.swing.text.Position.Bias;
import javax.swing.text.TextInterval.TextIntervalPainter;

import org.apache.harmony.awt.text.ComposedTextParams;
import org.apache.harmony.awt.text.TextKit;
import org.apache.harmony.awt.text.TextUtils;

public abstract class View implements SwingConstants {

    private class TextPainter implements TextIntervalPainter {
        private final TextPaintParams tpp;

        TextPainter(final TextPaintParams tpp) {
            this.tpp = tpp;
        }

        public int paintSelected(final Graphics g,
                                 final int start, final int end,
                                 final int x, final int y)
            throws BadLocationException {

            return drawSelectedText(g, x, y, start, end);
        }

        public int paintUnselected(final Graphics g,
                                   final int start, final int end,
                                   final int x, final int y)
            throws BadLocationException {

            return drawUnselectedText(g, x, y, start, end);
        }

        public int paintComposed(final Graphics g,
                                 final int start, final int end,
                                 final int x, final int y)
            throws BadLocationException {

            return drawComposedText(g, tpp.color, tpp.composedText, x, y);
        }
    }

    public static final int BadBreakWeight = 0;
    public static final int GoodBreakWeight = 1000;
    public static final int ExcellentBreakWeight = 2000;
    public static final int ForcedBreakWeight = 3000;

    public static final int X_AXIS = 0;
    public static final int Y_AXIS = 1;

    static final float ALIGN_LEFT   = 0.0f;
    static final float ALIGN_CENTER = 0.5f;
    static final float ALIGN_RIGHT  = 1.0f;

    Component component;

    private Element element;
    private View    parent;

    public View(final Element element) {
        this.element = element;
    }

    public abstract float getPreferredSpan(final int axis);

    public abstract Shape modelToView(final int pos, final Shape shape,
                                      final Bias bias)
        throws BadLocationException;

    public abstract int viewToModel(final float x,
                                    final float y,
                                    final Shape shape,
                                    final Bias[] biasReturn);

    public abstract void paint(final Graphics g, final Shape shape);

    public View breakView(final int axis, final int offset, final float pos,
                          final float len) {
        return this;
    }

    public View createFragment(final int startOffset, final int endOffset) {
        return this;
    }

    public float getAlignment(final int axis) {
        return ALIGN_CENTER;
    }

    public AttributeSet getAttributes() {
        return getElement().getAttributes();
    }

    public int getBreakWeight(final int axis, final float pos,
                              final float len) {
        return getPreferredSpan(axis) < len ? GoodBreakWeight : BadBreakWeight;
    }

    public Shape getChildAllocation(final int index, final Shape shape) {
        return null;
    }

    public Container getContainer() {
        return getParent() != null ? getParent().getContainer() : null;
    }

    public Document getDocument() {
        return getElement().getDocument();
    }

    public Element getElement() {
        return element;
    }

    public int getStartOffset() {
        return getElement().getStartOffset();
    }

    public int getEndOffset() {
        return getElement().getEndOffset();
    }

    public Graphics getGraphics() {
        return getComponent().getGraphics();
    }

    /**
     * If view is not resizable, returns <code>getPreferredSpan(axis)</code>.
     * Otherwise (resizable), returns 0.
     */
    public float getMinimumSpan(final int axis) {
        return getResizeWeight(axis) <= 0 ? getPreferredSpan(axis) : 0;
    }

    /**
     * If view is not resizable, returns <code>getPreferredSpan(axis)</code>.
     * Otherwise (resizable), returns Integer.MAX_VALUE.
     */
    public float getMaximumSpan(final int axis) {
        return getResizeWeight(axis) <= 0 ? getPreferredSpan(axis)
                                          : Integer.MAX_VALUE;
    }

    public int getNextVisualPositionFrom(final int pos,
                                         final Bias bias,
                                         final Shape shape,
                                         final int direction,
                                         final Bias[] biasRet)
        throws BadLocationException {

        return TextUtils.getNextVisualPositionFrom(getTextKit(), this,
                                                   pos, bias, shape,
                                                   direction, biasRet);
    }

    public View getParent() {
        return parent;
    }

    public int getResizeWeight(final int axis) {
        return 0;
    }

    public String getToolTipText(final float x, final float y,
                                 final Shape shape) {
        final int index = getViewIndex(x, y, shape);
        if (index == -1) {
            return null;
        }

        final View view = getView(index);
        return view != null
               ? view.getToolTipText(x, y, getChildAllocation(index, shape))
               : null;
    }

    public View getView(final int index) {
        return null;
    }

    public int getViewCount() {
        return 0;
    }

    public ViewFactory getViewFactory() {
        return getParent() != null ? getParent().getViewFactory() : null;
    }

    public int getViewIndex(final float x, final float y, final Shape shape) {
        if (shape == null) {
            return -1;
        }

        final int count = getViewCount();
        for (int i = 0; i < count; i++) {
            final Shape childAllocation = getChildAllocation(i, shape);
            if (childAllocation != null && childAllocation.contains(x, y)) {
                return i;
            }
        }
        return -1;
    }

    public int getViewIndex(final int pos, final Bias bias) {
        return -1;
    }

    public void changedUpdate(final DocumentEvent event, final Shape shape,
                              final ViewFactory factory) {
        updateView(event, shape, factory);
    }

    public void insertUpdate(final DocumentEvent event, final Shape shape,
                             final ViewFactory factory) {
        updateView(event, shape, factory);
    }

    public void removeUpdate(final DocumentEvent event, final Shape shape,
                             final ViewFactory factory) {
        updateView(event, shape, factory);
    }

    public boolean isVisible() {
        return true;
    }

    public void preferenceChanged(final View child,
                                  final boolean width,
                                  final boolean height) {
        if (getParent() != null) {
            getParent().preferenceChanged(this, width, height);
        }
    }

    public void append(final View view) {
        replace(getViewCount(), 0, new View[] {view});
    }

    public void insert(final int index, final View view) {
        replace(index, 0, new View[] {view});
    }

    public void remove(final int index) {
        replace(index, 1, null);
    }

    public void removeAll() {
        replace(0, getViewCount(), null);
    }

    public void replace(final int index, final int length, final View[] views) {
    }

    public void setParent(final View parent) {
        this.parent = parent;
        if (parent == null) {
            for (int i = 0; i < getViewCount(); i++) {
                getView(i).setParent(null);
            }
        }
    }

    public void setSize(final float width, final float height) {
    }

    public Shape modelToView(final int p1, final Bias b1,
                             final int p2, final Bias b2,
                             final Shape shape) throws BadLocationException {
        Rectangle r1 = modelToView(p1, shape, b1).getBounds();
        Rectangle r2 = modelToView(p2, shape, b2).getBounds();
        return r1.union(r2);
    }

    /**
     * @deprecated
     */
    public Shape modelToView(final int pos, final Shape shape)
        throws BadLocationException {

        return modelToView(pos, shape, Bias.Forward);
    }

    /**
     * @deprecated
     */
    public int viewToModel(final float x, final float y, final Shape shape) {
        return viewToModel(x, y, shape, new Bias[] {Bias.Forward});
    }

    /**
     * The event is forwarded to all child views that lie in the range of
     * the change, i.e. <code>event.getOffset()</code> up to
     * <code>(event.getOffset() + event.getLength())</code>.
     * <p>
     * If <code>event.getOffset()</code> is boundary of children, then
     * the previous child is included to the update range.
     * <p>
     * If <code>change</code> is not <code>null</code>, children that
     * have just been added by <code>updateChildren</code> are excluded
     * from the update range.
     * <p>
     * <code>change</code> can be <code>null</code> if the element this view
     * represents has not changed, or if its children represent portions of
     * elements.
     *
     * @param change is always <code>null</code>
     *               if <code>updateChildren</code> returned <code>false</code>,
     *               otherwise it has the value returned by
     *               <code>event.getChange(getElement())</code>.
     */
    protected void forwardUpdate(final DocumentEvent.ElementChange change,
                                 final DocumentEvent event,
                                 final Shape shape,
                                 final ViewFactory factory) {
        final int offset = event.getOffset();
        int start = getViewIndex(offset, Bias.Forward);
        if (start < 0) {
            start = 0;
        }
        int end = event.getType() == EventType.REMOVE
                  ? start
                  : getViewIndex(offset + event.getLength(), Bias.Forward);
        if (end < 0) {
            end = getViewCount() - 1;
        }

        if (start > 0 && getView(start - 1).getEndOffset() == offset) {
            --start;
        }

        if (change != null) {
            end -= change.getChildrenAdded().length;
        }

        for (int i = start; i <= end; i++) {
            forwardUpdateToView(getView(i), event,
                                getChildAllocation(i, shape), factory);
        }
    }

    protected void forwardUpdateToView(final View view,
                                       final DocumentEvent event,
                                       final Shape shape,
                                       final ViewFactory factory) {
        final DocumentEvent.EventType type = event.getType();

        if (type == DocumentEvent.EventType.INSERT) {
            view.insertUpdate(event, shape, factory);
        } else if (type == DocumentEvent.EventType.REMOVE) {
            view.removeUpdate(event, shape, factory);
        } else if (type == DocumentEvent.EventType.CHANGE) {
            view.changedUpdate(event, shape, factory);
        }
    }

    protected boolean updateChildren(final DocumentEvent.ElementChange change,
                                     final DocumentEvent event,
                                     final ViewFactory factory) {
        final Element[] added = change.getChildrenAdded();
        View[] views = null;
        if (added != null && added.length > 0) {
            views = new View[added.length];
            for (int i = 0; i < added.length; i++) {
                views[i] = factory.create(added[i]);
            }
        }
        replace(change.getIndex(), change.getChildrenRemoved().length, views);
        return true;
    }

    protected void updateLayout(final DocumentEvent.ElementChange change,
                                final DocumentEvent event, final Shape shape) {
        if (change != null) {
            preferenceChanged(null, true, true);
            final Component c = getComponent();
            if (c != null) {
                c.repaint();
            }
        }
    }

    final int drawComposedText(final Graphics g, final Color color,
                               final ComposedTextParams composedTextParams,
                               final int x, final int y) {
        final Color oldColor = g.getColor();
        g.setColor(color);
        AttributedString text = composedTextParams.getComposedText();
        int result = text == null
                     ? x
                     : TextUtils.drawComposedText(getTextKit(), text, g, x, y);
        g.setColor(oldColor);
        return result;
    }

    void drawLine(final TextPaintParams tpp,
                  final int start, final int end,
                  final Graphics g, final int x, final int y) {

        TextPainter painter = new TextPainter(tpp);
        UnselectedTextInterval ui =
                new UnselectedTextInterval(start, end, painter);
        SelectedTextInterval si =
                new SelectedTextInterval(tpp.selStart, tpp.selEnd, painter);

        TextInterval[] uisi = ui.dissect(si);
        List intervals;

        if (tpp.composedText != null) {
            intervals = new LinkedList();
            ComposedTextInterval ci =
                new ComposedTextInterval(tpp.composedStart, tpp.composedEnd,
                                         painter);
            for (int i = 0; i < uisi.length; i++) {
                TextInterval[] uisici = uisi[i].dissect(ci);
                for (int j = 0; j < uisici.length; j++) {
                    if (!intervals.contains(uisici[j])) {
                        intervals.add(uisici[j]);
                    }
                }
            }
        } else {
            intervals = Arrays.asList(uisi);
        }

        try {
            int nextX = x;
            for (Iterator it = intervals.iterator(); it.hasNext();) {
                TextInterval interval = (TextInterval)it.next();
                nextX = interval.paint(g, nextX, y);
            }
        } catch (BadLocationException e) { }
    }

    int drawSelectedText(final Graphics g,
                         final int x, final int y,
                         final int start, final int end)
        throws BadLocationException {

        return 0;
    }

    final int drawText(final Graphics g, final Color color,
                       final TextPaintParams tpp,
                       final int x, final int y,
                       final int start, final int end)
        throws BadLocationException {

        getDocument().getText(start, end - start, tpp.buffer);

        final Color oldColor = g.getColor();
        g.setColor(color);
        int result = TextUtils.drawTabbedText(tpp.buffer, x, y, g,
                                              (TabExpander)tpp.view, start);
        g.setColor(oldColor);
        return result;

    }

    int drawUnselectedText(final Graphics g,
                         final int x, final int y,
                         final int start, final int end)
        throws BadLocationException {

        return 0;
    }

    Component getComponent() {
        final Component comp = getContainer();
        if (comp == null) {
            return getParent() != null ? getParent().getComponent() : null;
        } else {
            return comp;
        }
    }

    final TextKit getTextKit() {
        final Component c = getComponent();
        return c != null ? TextUtils.getTextKit(getComponent()) : null;
    }

    private void updateView(final DocumentEvent event, final Shape shape,
                            final ViewFactory factory) {
        if (getViewCount() == 0) {
            return;
        }

        ElementChange change = event.getChange(getElement());
        if (change != null && !updateChildren(change, event, factory)) {
            // updateChildren returned false, then forwardUpdate and
            // updateLayout must be passed null as change despite
            // change is not null
            change = null;
        }

        forwardUpdate(change, event, shape, factory);
        updateLayout(change, event, shape);
    }
}
TOP

Related Classes of javax.swing.text.View

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.