Here you can find the source of drawString(Graphics g, Font font, String text, int x, int y, int width, int height, int align)
public static Rectangle drawString(Graphics g, Font font, String text, int x, int y, int width, int height, int align)
//package com.java2s; /*/*from w ww .j a va 2 s. c om*/ * ?Copyright (C) 2013 Atlas of Living Australia * All Rights Reserved. * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. */ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Toolkit; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; public class Main { public static boolean DEBUG = false; public static final int TEXT_ALIGN_RIGHT = 1; public static final int TEXT_ALIGN_CENTER = 2; private static boolean _AntiAliasedFonts = true; public static Rectangle drawString(Graphics g, Font font, String text, Rectangle rect, int align) { return drawString(g, font, text, rect.x, rect.y, rect.width, rect.height, align); } public static Rectangle drawString(Graphics g, Font font, String text, int x, int y, int width, int height, int align) { return drawString(g, font, text, x, y, width, height, align, false); } public static Rectangle drawString(Graphics g, Font font, String text, int x, int y, int width, int height, int align, boolean wrap) { g.setFont(font); FontMetrics fm = g.getFontMetrics(font); setPreferredAliasingMode(g); Rectangle ret = new Rectangle(0, 0, 0, 0); if (text == null) { return ret; } String[] alines = text.split("\\n"); ArrayList<String> lines = new ArrayList<String>(); for (String s : alines) { if (wrap && fm.stringWidth(s) > width) { // need to split this up into multiple lines... List<String> splitLines = wrapString(s, fm, width); lines.addAll(splitLines); } else { lines.add(s); } } int numlines = lines.size(); while (fm.getHeight() * numlines > height) { numlines--; } if (numlines > 0) { int maxwidth = 0; int minxoffset = y + width; int totalheight = (numlines * fm.getHeight()); int linestart = ((height / 2) - (totalheight / 2)); if (!wrap) { ret.y = y + linestart; } else { ret.y = y; linestart = 0; } for (int idx = 0; idx < numlines; ++idx) { String line = lines.get(idx); int stringWidth = fm.stringWidth(line); // the width of the label depends on the font : // if the width of the label is larger than the item if (stringWidth > 0 && width < stringWidth) { // We have to truncate the label line = clipString(null, fm, line, width); stringWidth = fm.stringWidth(line); } int xoffset = 0; int yoffset = linestart + fm.getHeight() - fm.getDescent(); if (align == TEXT_ALIGN_RIGHT) { xoffset = (width - stringWidth); } else if (align == TEXT_ALIGN_CENTER) { xoffset = (int) Math.round((double) (width - stringWidth) / (double) 2); } if (xoffset < minxoffset) { minxoffset = xoffset; } g.drawString(line, x + xoffset, y + yoffset); if (stringWidth > maxwidth) { maxwidth = stringWidth; } linestart += fm.getHeight(); } ret.width = maxwidth; ret.height = totalheight; ret.x = x + minxoffset; // Debug only... if (DEBUG) { Graphics2D g2d = (Graphics2D) g; g2d.setStroke(new BasicStroke(1)); g.setColor(Color.blue); g.drawRect(ret.x, ret.y, ret.width, ret.height); g.setColor(Color.green); g.drawRect(x, y, width, height); } return ret; } return ret; } /** * Returns the FontMetrics for the current Font of the passed in Graphics. This method is used when a Graphics is available, typically when painting. If a Graphics is not available the JComponent method of the same name should be used. * <p> * Callers should pass in a non-null JComponent, the exception to this is if a JComponent is not readily available at the time of painting. * <p> * This does not necessarily return the FontMetrics from the Graphics. * * @param c * JComponent requesting FontMetrics, may be null * @param g * Graphics Graphics */ public static FontMetrics getFontMetrics(JComponent c, Graphics g) { return getFontMetrics(c, g, g.getFont()); } /** * Returns the FontMetrics for the specified Font. This method is used when a Graphics is available, typically when painting. If a Graphics is not available the JComponent method of the same name should be used. * <p> * Callers should pass in a non-null JComonent, the exception to this is if a JComponent is not readily available at the time of painting. * <p> * This does not necessarily return the FontMetrics from the Graphics. * * @param c * JComponent requesting FontMetrics, may be null * @param c * Graphics Graphics * @param font * Font to get FontMetrics for */ @SuppressWarnings("deprecation") public static FontMetrics getFontMetrics(JComponent c, Graphics g, Font font) { if (c != null) { // Note: We assume that we're using the FontMetrics // from the widget to layout out text, otherwise we can get // mismatches when printing. return c.getFontMetrics(font); } return Toolkit.getDefaultToolkit().getFontMetrics(font); } public static void setPreferredAliasingMode(Graphics g) { if (g instanceof Graphics2D) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, (_AntiAliasedFonts ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF)); } } /** * Returns the width of the passed in String. * * @param c * JComponent that will display the string, may be null * @param fm * FontMetrics used to measure the String width * @param string * String to get the width of */ public static int stringWidth(JComponent c, FontMetrics fm, String string) { return fm.stringWidth(string); } private static List<String> wrapString(String s, FontMetrics fm, int width) { List<String> lines = new ArrayList<String>(); StringBuilder line = new StringBuilder(); for (int i = 0; i < s.length(); ++i) { char ch = s.charAt(i); String test = line.toString() + ch; if (fm.stringWidth(test) > width) { if (test.length() > 1) { // Backtrack to look for a space... boolean breakFound = false; if (ch != ' ') { for (int j = line.length() - 1; j > 0; --j) { if (line.charAt(j) == ' ') { lines.add(line.substring(0, j)); line = new StringBuilder(line.substring(j + 1)); breakFound = true; break; } } } if (!breakFound) { lines.add(line.toString()); line = new StringBuilder(); } line.append(ch); } else { lines.add(test); line = new StringBuilder(); } } else { line.append(ch); } } if (line.length() > 0) { lines.add(line.toString()); } return lines; } /** * Clips the passed in String to the space provided. NOTE: this assumes the string does not fit in the available space. * * @param c * JComponent that will display the string, may be null * @param fm * FontMetrics used to measure the String width * @param string * String to display * @param availTextWidth * Amount of space that the string can be drawn in * @return Clipped string that can fit in the provided space. */ public static String clipString(JComponent c, FontMetrics fm, String string, int availTextWidth) { // c may be null here. String clipString = "..."; int width = stringWidth(c, fm, clipString); // NOTE: This does NOT work for surrogate pairs and other fun // stuff int nChars = 0; for (int max = string.length(); nChars < max; nChars++) { width += fm.charWidth(string.charAt(nChars)); if (width > availTextWidth) { break; } } string = string.substring(0, nChars) + clipString; return string; } }