Java Graphics Draw String drawLine(String pLine, Graphics2D pG, int pX, int pY, int pWidth, String pJustification)

Here you can find the source of drawLine(String pLine, Graphics2D pG, int pX, int pY, int pWidth, String pJustification)

Description

Draw a line of text with justification

License

Open Source License

Parameter

Parameter Description
pLine String of text to draw
pG Graphics object to draw on
pX Position to start at
pY Position to start at
pWidth Width of the line, to know where to right align to
pJustification LEFT|RIGHT|CENTRE justification

Declaration

public static void drawLine(String pLine, Graphics2D pG, int pX, int pY, int pWidth, String pJustification) 

Method Source Code

//package com.java2s;
//License from project: Open Source License 

import java.awt.*;

public class Main {
    /**//from  w w  w . ja v  a 2  s  .c o m
     * Draw a line of text with justification
     *
     * @param pLine String of text to draw
     * @param pG Graphics object to draw on
     * @param pX Position to start at
     * @param pY Position to start at
     * @param pWidth Width of the line, to know where to right align to
     * @param pJustification LEFT|RIGHT|CENTRE justification
     */
    public static void drawLine(String pLine, Graphics2D pG, int pX, int pY, int pWidth, String pJustification) {
        FontMetrics lFontMetrics = pG.getFontMetrics();
        if (pLine.trim().length() > 0) {
            if ("RIGHT".equals(pJustification.toUpperCase())) {
                pG.drawString(pLine.trim(), pX + pWidth - lFontMetrics.stringWidth(pLine.trim()), pY);
            } else if ("CENTRE".equals(pJustification.toUpperCase())) {
                pG.drawString(pLine.trim(), pX + (pWidth / 2) - (lFontMetrics.stringWidth(pLine.trim()) / 2), pY);
            } else {
                pG.drawString(pLine.trim(), pX, pY);
            }
        }
    }

    /**
     * Draw a string onto a graphics2d object, wrapping words at pWidth pixels wide.
     * If a word has to be cut, if less than 75% is cut off it's added back on and the word shrunk, if pShrinkWords == true
     *
     * @param pString Words to draw
     * @param pG Graphics2D object reference used to draw
     * @param pX Top left ordinate of where to start drawing down from
     * @param pY Top left ordinate of where to start drawing down from
     * @param pWidth Width to wrap string at in pixels
     * @param pHeight Height to cut off overflow at in pixels
     * @param pYOverflow Boolean to allow overflow or not
     * @param pShrinkWords Boolean to shrink words that are bigger than the width
     * @param pJustification Left/right/centre line justification
     * @param pDraw Boolean to switch drawing on or off (handy for just getting bounds before drawing)
     * @return Rectangle of the bounding box
     */
    public static Rectangle drawString(String pString, Graphics2D pG, int pX, int pY, int pWidth, int pHeight,
            boolean pYOverflow, boolean pShrinkWords, String pJustification, boolean pDraw) {
        FontMetrics lFontMetrics = pG.getFontMetrics();
        Font lDrawFont = pG.getFont();
        char[] lCharacters = pString.toCharArray();
        int lFontHeight = lFontMetrics.getHeight();
        int lLeading = 0;//lFontMetrics.getLeading()/2;
        int lY = pY;
        boolean lFirstLine = true;
        boolean lSuppressLastLine = false;
        Integer lLastSpace = null;
        int lCharsInBuffer = 0;
        StringBuffer lLineBuffer = new StringBuffer();

        for (int i = 0; i < lCharacters.length; ++i) {
            if (lFontMetrics.stringWidth(lLineBuffer.toString() + lCharacters[i]) < pWidth) {
                if (!isNewLine(lCharacters[i])) {
                    lLineBuffer.append(lCharacters[i]);
                    lCharsInBuffer++;
                    if (isBreakable(lCharacters[i])) {
                        lLastSpace = new Integer(i);
                    }
                } else {
                    //Find the next Y position for the new line
                    lY += lFontHeight + (lFirstLine ? -lFontMetrics.getDescent() : lLeading);

                    if ((lY + lFontHeight) > pHeight && pYOverflow == false) {
                        //Break loop if it's hit the Y limit
                        break;
                    }

                    //Draw the line
                    if (pDraw) {
                        drawLine(lLineBuffer.toString(), pG, pX, lY, pWidth, pJustification);
                    }

                    //Start the new buffer
                    lLineBuffer.setLength(0);
                    lLineBuffer.append(lCharacters[i]);
                    lLastSpace = null;
                    lCharsInBuffer = 0;

                    lFirstLine = false;
                }
            } else {
                //Try and go back to the last space
                if (lLastSpace != null) {
                    //Space found in line, cut down buffer and hop i back a bit
                    int lNextBreak = 0;
                    int j;
                    for (j = i; j < Math.min((i + (int) (lCharsInBuffer * 0.15)), lCharacters.length); ++j) {
                        if (isBreakable(lCharacters[j])) {
                            lNextBreak = j;
                            break;
                        }
                    }
                    if (j == lCharacters.length) {
                        lNextBreak = lCharacters.length;
                    }

                    if (lNextBreak != 0 && pShrinkWords) {
                        String lNewString = lLineBuffer.toString() + pString.substring(i, j);
                        int lFontSize;
                        for (lFontSize = lDrawFont.getSize(); lFontSize > 1; lFontSize--) {
                            Font lNewSmallerFont = new Font(lDrawFont.getName(), lDrawFont.getStyle(), lFontSize);
                            pG.setFont(lNewSmallerFont);
                            if (pG.getFontMetrics().stringWidth(lNewString) < pWidth) {
                                lY += pG.getFontMetrics().getHeight()
                                        + (lFirstLine ? -pG.getFontMetrics().getDescent() : lLeading);
                                if (pDraw) {
                                    drawLine(lNewString, pG, pX, lY, pWidth, pJustification);
                                }

                                i = j + 1;

                                pG.setFont(lDrawFont);
                                break;

                            }
                        }
                        if (i >= lCharacters.length) {
                            lSuppressLastLine = true;
                            break;
                        }
                        pG.setFont(lDrawFont);

                        lLineBuffer.setLength(0);
                        lLineBuffer.append(lCharacters[i]);
                        lLastSpace = null;
                        lCharsInBuffer = 0;
                        lFirstLine = false;
                        continue;
                    } else {
                        lLineBuffer.setLength(lCharsInBuffer - (i - lLastSpace.intValue()) + 1);
                        i = lLastSpace.intValue() + 1;
                    }
                } else if (pShrinkWords) {
                    //Shrink word if It's not too big
                    int lNextBreak = 0;
                    int j;
                    for (j = i; j < Math.min((i + (int) (lCharsInBuffer * 0.50)), lCharacters.length); ++j) {
                        if (isBreakable(lCharacters[j])) {
                            lNextBreak = j;
                            break;
                        }
                    }
                    if (j == lCharacters.length) {
                        lNextBreak = lCharacters.length;
                    }
                    if (lNextBreak != 0) {
                        String lNewString = lLineBuffer.toString() + pString.substring(i, j);
                        int lFontSize;
                        for (lFontSize = lDrawFont.getSize(); lFontSize > 1; lFontSize--) {
                            Font lNewSmallerFont = new Font(lDrawFont.getName(), lDrawFont.getStyle(), lFontSize);
                            pG.setFont(lNewSmallerFont);
                            if (pG.getFontMetrics().stringWidth(lNewString) < pWidth) {
                                lY += pG.getFontMetrics().getHeight()
                                        + (lFirstLine ? -pG.getFontMetrics().getDescent() : lLeading);
                                if (pDraw) {
                                    drawLine(lNewString, pG, pX, lY, pWidth, pJustification);
                                }

                                i = j + 1;

                                pG.setFont(lDrawFont);
                                break;

                            }
                        }
                        if (i >= lCharacters.length) {
                            lSuppressLastLine = true;
                            break;
                        }
                        pG.setFont(lDrawFont);

                        lLineBuffer.setLength(0);
                        lLineBuffer.append(lCharacters[i]);
                        lLastSpace = null;
                        lCharsInBuffer = 0;
                        lFirstLine = false;
                        continue;
                    }
                }

                //Find the next Y position for the new line
                lY += lFontHeight + (lFirstLine ? -lFontMetrics.getDescent() : lLeading);

                if ((lY + lFontHeight) > pHeight && pYOverflow == false) {
                    //Break loop if it's hit the Y limit
                    break;
                }

                //Draw the line
                if (pDraw) {
                    drawLine(lLineBuffer.toString(), pG, pX, lY, pWidth, pJustification);
                }

                //Start the new buffer
                lLineBuffer.setLength(0);
                lLineBuffer.append(lCharacters[i]);
                lLastSpace = null;
                lCharsInBuffer = 0;

                lFirstLine = false;
            }
        }

        if (!lSuppressLastLine) {
            //Find the next Y position for the new line
            lY = lY + lFontHeight + (lFirstLine ? -lFontMetrics.getDescent() : lLeading);

            //Draw the line
            if (pDraw) {
                drawLine(lLineBuffer.toString(), pG, pX, lY, pWidth, pJustification);
            }
        }

        //Calculate final bounding box
        int lHeight = lY + lFontMetrics.getDescent() - pY;
        int lWidth = pWidth;
        Rectangle lR = new Rectangle(pX, pY, lWidth, lHeight);
        return lR;
    }

    private static boolean isNewLine(char c) {
        return (c == '\n' || c == '\r');
    }

    private static boolean isBreakable(char c) {
        return (c == ' ' || c == '\t' || c == '-' || c == '\\' || c == '/' || c == '_');
    }
}

Related

  1. drawEmphasizedString(Graphics g, Color foreground, Color emphasis, String s, int underlinedIndex, int x, int y)
  2. drawFitText(Graphics2D g2, int x, int y, int width, int height, String text)
  3. drawFormattedString(Graphics2D g2, String htmlStr, int x, int y, int w, int h)
  4. drawGradient(Graphics g, JComponent c, String prefix)
  5. drawGradientText(Graphics g, String text, int x, int y, Color c)
  6. drawLineDrawChar(Graphics g, int x, int y, int bi, char c, int charWidth, int charHeight)
  7. drawMessage(Graphics2D g, String message)
  8. drawRightJustifiedText(String text, int right, int y, Graphics g)
  9. drawRightText(Graphics g, String str, int x, int y, int width, int height)