textutilities.java

来自「JfreeChart 常用图表例子」· Java 代码 · 共 885 行 · 第 1/3 页

JAVA
885
字号
/* ======================================================================== * JCommon : a free general purpose class library for the Java(tm) platform * ======================================================================== * * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. *  * Project Info:  http://www.jfree.org/jcommon/index.html * * 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. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc.  * in the United States and other countries.] *  * ------------------ * TextUtilities.java * ------------------ * (C) Copyright 2004, 2005, by Object Refinery Limited and Contributors. * * Original Author:  David Gilbert (for Object Refinery Limited); * Contributor(s):   -; * * $Id: TextUtilities.java,v 1.11 2005/06/01 14:12:29 taqua Exp $ * * Changes * ------- * 07-Jan-2004 : Version 1 (DG); * 24-Mar-2004 : Added 'paint' argument to createTextBlock() method (DG); * 07-Apr-2004 : Added getTextBounds() method and useFontMetricsGetStringBounds *               flag (DG); * 08-Apr-2004 : Changed word break iterator to line break iterator in the  *               createTextBlock() method - see bug report 926074 (DG); * 03-Sep-2004 : Updated createTextBlock() method to add ellipses when limit  *               is reached (DG); * 30-Sep-2004 : Modified bounds returned by drawAlignedString() method (DG); * 10-Nov-2004 : Added new createTextBlock() method that works with  *               newlines (DG); * 19-Apr-2005 : Changed default value of useFontMetricsGetStringBounds (DG); * 17-May-2005 : createTextBlock() now recognises '\n' (DG); *  */package org.jfree.text;import java.awt.Font;import java.awt.FontMetrics;import java.awt.Graphics2D;import java.awt.Paint;import java.awt.Shape;import java.awt.font.FontRenderContext;import java.awt.font.LineMetrics;import java.awt.font.TextLayout;import java.awt.geom.AffineTransform;import java.awt.geom.Rectangle2D;import java.text.BreakIterator;import org.jfree.ui.TextAnchor;import org.jfree.util.Log;import org.jfree.util.LogContext;/** * Some utility methods for working with text. * * @author David Gilbert */public class TextUtilities {    /** Access to logging facilities. */    protected static final LogContext logger         = Log.createContext(TextUtilities.class);    /**     * Private constructor prevents object creation.     */    private TextUtilities() {    }    /**     * Creates a {@link TextBlock} from a <code>String</code>.  Line breaks      * are added where the <code>String</code> contains '\n' characters.     *      * @param text  the text.     * @param font  the font.     * @param paint  the paint.     *      * @return A text block.     */    public static TextBlock createTextBlock(final String text,                                             final Font font,                                             final Paint paint) {        if (text == null) {            throw new IllegalArgumentException("Null 'text' argument.");        }        final TextBlock result = new TextBlock();        String input = text;        boolean moreInputToProcess = (text.length() > 0);        final int start = 0;        while (moreInputToProcess) {            final int index = input.indexOf("\n");            if (index > start) {                final String line = input.substring(start, index);                if (index < input.length() - 1) {                    result.addLine(line, font, paint);                    input = input.substring(index + 1);                }                else {                    moreInputToProcess = false;                }            }            else if (index == start) {                if (index < input.length() - 1) {                    input = input.substring(index + 1);                }                else {                    moreInputToProcess = false;                }            }            else {                result.addLine(input, font, paint);                moreInputToProcess = false;            }        }        return result;    }        /**     * Creates a new text block from the given string, breaking the     * text into lines so that the <code>maxWidth</code> value is     * respected.     *      * @param text  the text.     * @param font  the font.     * @param paint  the paint.     * @param maxWidth  the maximum width for each line.     * @param measurer  the text measurer.     *      * @return A text block.     */    public static TextBlock createTextBlock(final String text,                                            final Font font,                                            final Paint paint,                                            final float maxWidth,                                            final TextMeasurer measurer) {        return createTextBlock(            text, font, paint, maxWidth, Integer.MAX_VALUE, measurer        );    }        /**     * Creates a new text block from the given string, breaking the     * text into lines so that the <code>maxWidth</code> value is     * respected.     *      * @param text  the text.     * @param font  the font.     * @param paint  the paint.     * @param maxWidth  the maximum width for each line.     * @param maxLines  the maximum number of lines.     * @param measurer  the text measurer.     *      * @return A text block.     */    public static TextBlock createTextBlock(final String text,                                            final Font font,                                            final Paint paint,                                            final float maxWidth,                                            final int maxLines,                                            final TextMeasurer measurer) {        final TextBlock result = new TextBlock();        final BreakIterator iterator = BreakIterator.getLineInstance();        iterator.setText(text);        int current = 0;        int lines = 0;        final int length = text.length();        while (current < length && lines < maxLines) {            final int next = nextLineBreak(                text, current, maxWidth, iterator, measurer            );            if (next == BreakIterator.DONE) {                result.addLine(text.substring(current), font, paint);                 return result;            }            result.addLine(text.substring(current, next), font, paint);            lines++;            current = next;            while (text.charAt(current) == '\n' && current < text.length()) {                current++;            }        }        if (current < length) {            final TextLine lastLine = result.getLastLine();            final TextFragment lastFragment = lastLine.getLastTextFragment();            final String oldStr = lastFragment.getText();            String newStr = "...";            if (oldStr.length() > 3) {                newStr = oldStr.substring(0, oldStr.length() - 3) + "...";            }                        lastLine.removeFragment(lastFragment);            final TextFragment newFragment = new TextFragment(                newStr, lastFragment.getFont(), lastFragment.getPaint()            );            lastLine.addFragment(newFragment);        }        return result;    }        /**     * Returns the character index of the next line break.     *      * @param text  the text.     * @param start  the start index.     * @param width  the target display width.     * @param iterator  the word break iterator.     * @param measurer  the text measurer.     *      * @return The index of the next line break.     */    private static int nextLineBreak(final String text, final int start,                                      final float width,                                     final BreakIterator iterator,                                      final TextMeasurer measurer) {        // this method is (loosely) based on code in JFreeReport's         // TextParagraph class        int current = start;        int end;        float x = 0.0f;        boolean firstWord = true;        int newline = text.indexOf('\n', start);        if (newline < 0) {            newline = Integer.MAX_VALUE;           }        while (((end = iterator.next()) != BreakIterator.DONE)) {            if (end > newline) {                return newline;            }            x += measurer.getStringWidth(text, current, end);              if (x > width) {                if (firstWord) {                    while (measurer.getStringWidth(text, start, end) > width) {                        end--;                        if (end <= start) {                            return end;                           }                    }                    return end;                }                else {                    end = iterator.previous();                    return end;                }            }            // we found at least one word that fits ...            firstWord = false;            current = end;        }        return BreakIterator.DONE;    }        /**     * Returns the bounds for the specified text.     *      * @param text  the text (<code>null</code> permitted).     * @param g2  the graphics context (not <code>null</code>).     * @param fm  the font metrics (not <code>null</code>).     *      * @return The text bounds (<code>null</code> if the <code>text</code>      *         argument is <code>null</code>).     */    public static Rectangle2D getTextBounds(final String text,                                            final Graphics2D g2,                                             final FontMetrics fm) {        final Rectangle2D bounds;        if (TextUtilities.useFontMetricsGetStringBounds) {            bounds = fm.getStringBounds(text, g2);        }        else {            final double width = fm.stringWidth(text);            final double height = fm.getHeight();            if (logger.isDebugEnabled()) {                logger.debug("Height = " + height);               }            bounds = new Rectangle2D.Double(                0.0, -fm.getAscent(), width, height

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?