Java/2D Graphics GUI/Text Layout
Содержание
- 1 A display of text, formatted by us instead of by AWT/Swing
- 2 Another Line Break Demo
- 3 Caret action
- 4 Caret and TextLayout
- 5 Drawing a Paragraph of Text
- 6 Drawing multi-line text with AttributedString and LineBreakMeasurer
- 7 Drawing Text with Mixed Styles
- 8 Draws the string at the specified location underlining the specified character
- 9 Draw text with TextLayout
- 10 Getting the Shape from the Outline of Text
- 11 Hightlight text by drag and selection
- 12 JFreeChart: Draw String Demo
- 13 Line break for textlayout
- 14 LineMetrics: the metrics to layout characters along a line
- 15 Mouse hit and textlayout
- 16 Paragraph Layout
- 17 Renders a paragraph of text (line breaks ignored) to an image (created and returned).
- 18 TextAttribute: color and font
- 19 TextAttribute: Underline and strike through
- 20 TextHitInfo Demo: tell you which is the letter you are clicking
- 21 TextLayout demo
- 22 Unicode display
- 23 Unicode: test layout
A display of text, formatted by us instead of by AWT/Swing
<source lang="java"> /*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.ruponent; import java.awt.Container; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedString; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.JFrame; /**
* A display of text, formatted by us instead of by AWT/Swing.*
* This program is distributed under the terms of the accompanying COPYRIGHT.txt * file (which is NOT the GNU General Public License). Please read it. Your use * of the software constitutes acceptance of the terms in the COPYRIGHT.txt * file. * * @author Ian F. Darwin * @version $Id: TextFormat.java,v 1.3 2004/03/26 03:34:30 ian Exp $ */ public class TextFormat extends Component { /** The text of this line */ protected String text; /** The Font */ protected Font font; /** The TextLayouts corresponding to "text" */ List layouts; public Font getFont() { return font; } public void setFont(Font f) { font = f; } public String getText() { return text; } public void setText(String t) { text = t; } public void paint(Graphics g) { if (text == null || text.length() == 0) return; if (layouts == null) getLayouts(g); Point pen = new Point(0, 0); Graphics2D g2d = (Graphics2D) g; g2d.setColor(java.awt.Color.black); // or a property g2d.setFont(font); Iterator it = layouts.iterator(); while (it.hasNext()) { TextLayout layout = (TextLayout) it.next(); pen.y += (layout.getAscent()); g2d.setFont(font); layout.draw(g2d, pen.x, pen.y); pen.y += layout.getDescent(); //pen.y += leading; } } /** * Lazy evaluation of the List of TextLayout objects corresponding to this * MText. Some things are approximations! */ private void getLayouts(Graphics g) { layouts = new ArrayList(); Point pen = new Point(10, 20); Graphics2D g2d = (Graphics2D) g; FontRenderContext frc = g2d.getFontRenderContext(); AttributedString attrStr = new AttributedString(text); attrStr.addAttribute(TextAttribute.FONT, font, 0, text.length()); LineBreakMeasurer measurer = new LineBreakMeasurer(attrStr .getIterator(), frc); float wrappingWidth; wrappingWidth = getSize().width - 15; while (measurer.getPosition() < text.length()) { TextLayout layout = measurer.nextLayout(wrappingWidth); layouts.add(layout); } } public static void main(String[] args) { JFrame jf = new JFrame("Demo"); Container cp = jf.getContentPane(); TextFormat tl = new TextFormat(); tl.setFont(new Font("SansSerif", Font.BOLD, 42)); tl.setText("The quick brown fox jumped over the lazy cow"); cp.add(tl); jf.setSize(300, 200); jf.setVisible(true); } } </source>
Another Line Break Demo
<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JPanel; public class Main extends JPanel {
String text = "this is a test. This is a test. This is a test. This is a test"; AttributedString attribString = new AttributedString(text); AttributedCharacterIterator attribCharIterator; public Main() { setSize(350, 400); attribString.addAttribute(TextAttribute.FOREGROUND, Color.blue, 0, text .length()); attribString.addAttribute(TextAttribute.FONT, new Font("sanserif", Font.ITALIC, 20), 0, text.length()); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; attribCharIterator = attribString.getIterator(); FontRenderContext frc = new FontRenderContext(null, false, false); LineBreakMeasurer lbm = new LineBreakMeasurer(attribCharIterator, frc); int x = 10, y = 20; int w = getWidth(); float wrappingWidth = w - 15; while (lbm.getPosition() < text.length()) { TextLayout layout = lbm.nextLayout(wrappingWidth); y += layout.getAscent(); layout.draw(g2, x, y); y += layout.getDescent() + layout.getLeading(); } } public static void main(String arg[]) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add("Center", new Main()); frame.pack(); frame.setSize(new Dimension(350, 400)); frame.setVisible(true); }
}
</source>
Caret action
<source lang="java"> import java.awt.BasicStroke; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JLabel; public class TextLayoutWithCarets extends JLabel {
private TextHitInfo mHit; private TextLayout mLayout; private boolean mInitialized = false; public TextLayoutWithCarets() { addKeyListener(new KeyListener() { public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_RIGHT) { mHit = mLayout.getNextRightHit(mHit.getInsertionIndex()); if (mHit == null) mHit = mLayout.getNextLeftHit(1); repaint(); } else if (ke.getKeyCode() == KeyEvent.VK_LEFT) { mHit = mLayout.getNextLeftHit(mHit.getInsertionIndex()); if (mHit == null) mHit = mLayout.getNextRightHit(mLayout .getCharacterCount() - 1); repaint(); } } public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub } }); } private void initialize(Graphics2D g2) { String s = "Java Source and Support."; // Create a plain and italic font. int fontSize = 32; Font font = new Font("Lucida Sans Regular", Font.PLAIN, fontSize); Font italicFont = new Font("Lucida Sans Oblique", Font.ITALIC, fontSize); // Create an Attributed String AttributedString as = new AttributedString(s); as.addAttribute(TextAttribute.FONT, font); as.addAttribute(TextAttribute.FONT, italicFont, 2, 5); // Get the iterator. AttributedCharacterIterator iterator = as.getIterator(); // Create a TextLayout. FontRenderContext frc = g2.getFontRenderContext(); mLayout = new TextLayout(iterator, frc); mHit = mLayout.getNextLeftHit(1); // Respond to left and right arrow keys. mInitialized = true; } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); if (mInitialized == false) initialize(g2); float x = 20, y = 80; mLayout.draw(g2, x, y); // Create a plain stroke and a dashed stroke. Stroke[] caretStrokes = new Stroke[2]; caretStrokes[0] = new BasicStroke(); caretStrokes[1] = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0, new float[] { 4, 4 }, 0); // Now draw the carets Shape[] carets = mLayout.getCaretShapes(mHit.getInsertionIndex()); for (int i = 0; i < carets.length; i++) { if (carets[i] != null) { AffineTransform at = AffineTransform.getTranslateInstance(x, y); Shape shape = at.createTransformedShape(carets[i]); g2.setStroke(caretStrokes[i]); g2.draw(shape); } } } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new TextLayoutWithCarets()); f.setSize(350, 250); f.setVisible(true); }
}
</source>
Caret and TextLayout
<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.font.FontRenderContext; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; public class TextLayoutPanel extends JPanel {
TextLayout layout; FontRenderContext frc; Font font; Rectangle2D rect; float rx, ry, rw, rh; TextHitInfo hitInfo; Color caretColor; int hit1, hit2; int w, h; public TextLayoutPanel() { setBackground(Color.white); setForeground(Color.black); setSize(400, 200); addMouseListener(new MouseHandler()); addMouseMotionListener(new MouseMotionHandler()); w = getWidth(); h = getHeight(); String text = "Java Source and Support"; font = new Font("Arial", Font.PLAIN, 36); frc = new FontRenderContext(null, false, false); layout = new TextLayout(text, font, frc); rx = (float) (w / 2 - layout.getBounds().getWidth() / 2); ry = (float) 3 * h / 4; rw = (float) (layout.getBounds().getWidth()); rh = (float) (layout.getBounds().getHeight()); rect = new Rectangle2D.Float(rx, ry, rw, rh); caretColor = getForeground(); } public void update(Graphics g) { g.clearRect(0, 0, getWidth(), getHeight()); paintComponent(g); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; AffineTransform at = AffineTransform.getTranslateInstance(rx, ry); Shape hilight = layout.getLogicalHighlightShape(hit1, hit2); hilight = at.createTransformedShape(hilight); g2.setColor(Color.lightGray); g2.fill(hilight); g2.setColor(Color.black); layout.draw(g2, rx, ry); // Draw caret Shape[] caretShapes = layout.getCaretShapes(hit1); Shape caret = at.createTransformedShape(caretShapes[0]); g2.setColor(caretColor); g2.draw(caret); } public int getHitLocation(int mouseX, int mouseY) { hitInfo = layout.hitTestChar(mouseX, mouseY, rect); return hitInfo.getInsertionIndex(); } class MouseHandler extends MouseAdapter { public void mouseClicked(MouseEvent e) { caretColor = getForeground(); hit1 = getHitLocation(e.getX(), e.getY()); hit2 = hit1; repaint(); } public void mousePressed(MouseEvent e) { caretColor = getForeground(); hit1 = getHitLocation(e.getX(), e.getY()); hit2 = hit1; repaint(); } public void mouseReleased(MouseEvent e) { hit2 = getHitLocation(e.getX(), e.getY()); repaint(); } } class MouseMotionHandler extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { caretColor = getBackground(); hit2 = getHitLocation(e.getX(), e.getY()); repaint(); } } public static void main(String arg[]) { JFrame frame = new JFrame(); frame.setBackground(Color.white); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.getContentPane().add("Center", new TextLayoutPanel()); frame.pack(); frame.setSize(new Dimension(400, 300)); frame.setVisible(true); }
}
</source>
Drawing a Paragraph of Text
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextLayout; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JPanel; public class Main extends JPanel {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; drawParagraph(g2d, "adfasdfaf", 20); } void drawParagraph(Graphics2D g, String paragraph, float width) { LineBreakMeasurer linebreaker = new LineBreakMeasurer(new AttributedString(paragraph) .getIterator(), g.getFontRenderContext()); int y = 0; while (linebreaker.getPosition() < paragraph.length()) { TextLayout textLayout = linebreaker.nextLayout(width); y += textLayout.getAscent(); textLayout.draw(g, 0, y); y += textLayout.getDescent() + textLayout.getLeading(); } } public static void main(String[] args) { JFrame frame = new JFrame("Basic Shapes"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Main()); frame.setSize(350, 250); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}
</source>
Drawing multi-line text with AttributedString and LineBreakMeasurer
<source lang="java"> import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.UIManager; public class Main extends JFrame {
public void paint(Graphics g) { String input = "this is a test.this is a test.this is a test.this is a test."; AttributedString attributedString = new AttributedString(input); attributedString.addAttribute(TextAttribute.FONT, (Font) UIManager .get("Label.font")); Color color = (Color) UIManager.get("Label.foreground"); attributedString.addAttribute(TextAttribute.FOREGROUND, color); super.paint(g); Graphics2D g2d = (Graphics2D) g; int width = getSize().width; int x = 10; int y = 30; AttributedCharacterIterator characterIterator = attributedString .getIterator(); FontRenderContext fontRenderContext = g2d.getFontRenderContext(); LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator, fontRenderContext); while (measurer.getPosition() < characterIterator.getEndIndex()) { TextLayout textLayout = measurer.nextLayout(width); y += textLayout.getAscent(); textLayout.draw(g2d, x, y); y += textLayout.getDescent() + textLayout.getLeading(); } } public static void main(String args[]) { JFrame frame = new Main(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setSize(20, 200); frame.setVisible(true); }
}
</source>
Drawing Text with Mixed Styles
<source lang="java"> import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JPanel; public class Main extends JPanel {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AttributedString astr = new AttributedString("aString"); astr.addAttribute(TextAttribute.FONT, new Font("", 1, 30), 1, 2); astr.addAttribute(TextAttribute.BACKGROUND, Color.red, 2, 3); TextLayout tl = new TextLayout(astr.getIterator(), g2d.getFontRenderContext()); tl.draw(g2d, 10, 20); } public static void main(String[] args) { JFrame frame = new JFrame("Basic Shapes"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Main()); frame.setSize(350, 250); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}
</source>
Draws the string at the specified location underlining the specified character
<source lang="java"> /*
* Copyright (c) 2001-2009 JGoodies Karsten Lentzsch. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * o Neither the name of JGoodies Karsten Lentzsch nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import java.awt.*; import java.awt.print.PrinterGraphics; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.JComponent; import javax.swing.plaf.basic.BasicGraphicsUtils;
/**
* Provides convenience behavior used by the JGoodies Looks.<p> * * Note: This class is not part of the public Looks API. * It should be treated as library internal and should not be used by * API users. It may be removed or changed with the Looks version * without further notice. * * @author Karsten Lentzsch * @author Andrej Golovnin * @version $Revision: 1.12 $ * * @since 2.0 */
public final class RenderingUtils {
private static final String PROP_DESKTOPHINTS = "awt.font.desktophints";
private static final String SWING_UTILITIES2_NAME ="sun.swing.SwingUtilities2";
/**
* In Java 5 or later, this field holds the public static method
* SwingUtilities2#drawStringUnderlinedAt
that has been added
* for Java 5.
*/
private static Method drawStringUnderlineCharAtMethod = null;
static {
drawStringUnderlineCharAtMethod = getMethodDrawStringUnderlineCharAt();
}
private RenderingUtils() { // Overrides default constructor; prevents instantiation. } /** * Draws the string at the specified location underlining the specified * character. * * @param c JComponent that will display the string, may be null * @param g Graphics to draw the text to * @param text String to display * @param underlinedIndex Index of a character in the string to underline * @param x X coordinate to draw the text at * @param y Y coordinate to draw the text at */ public static void drawStringUnderlineCharAt(JComponent c,Graphics g, String text, int underlinedIndex, int x,int y) { if (drawStringUnderlineCharAtMethod != null) { try { drawStringUnderlineCharAtMethod.invoke(null, new Object[] {c, g, text, new Integer(underlinedIndex), new Integer(x), new Integer(y)}); return; } catch (IllegalArgumentException e) { // Use the BasicGraphicsUtils as fallback } catch (IllegalAccessException e) { // Use the BasicGraphicsUtils as fallback } catch (InvocationTargetException e) { // Use the BasicGraphicsUtils as fallback } } Graphics2D g2 = (Graphics2D) g; Map oldRenderingHints = installDesktopHints(g2); BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, underlinedIndex, x, y); if (oldRenderingHints != null) { g2.addRenderingHints(oldRenderingHints); } return; BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, underlinedIndex, x, y); }
// Private Helper Code ****************************************************
private static Method getMethodDrawStringUnderlineCharAt() { try { Class clazz = Class.forName(SWING_UTILITIES2_NAME); return clazz.getMethod( "drawStringUnderlineCharAt", new Class[] {JComponent.class, Graphics.class, String.class, Integer.TYPE, Integer.TYPE, Integer.TYPE} ); } catch (ClassNotFoundException e) { // returns null } catch (SecurityException e) { // returns null } catch (NoSuchMethodException e) { // returns null } return null; }
private static Map installDesktopHints(Graphics2D g2) { Map oldRenderingHints = null; Map desktopHints = desktopHints(g2); if (desktopHints != null && !desktopHints.isEmpty()) { oldRenderingHints = new HashMap(desktopHints.size()); RenderingHints.Key key; for (Iterator i = desktopHints.keySet().iterator(); i.hasNext();) { key = (RenderingHints.Key) i.next(); oldRenderingHints.put(key, g2.getRenderingHint(key)); } g2.addRenderingHints(desktopHints); } return oldRenderingHints; }
private static Map desktopHints(Graphics2D g2) { if (isPrinting(g2)) { return null; } Toolkit toolkit = Toolkit.getDefaultToolkit(); GraphicsDevice device = g2.getDeviceConfiguration().getDevice(); Map desktopHints = (Map) toolkit.getDesktopProperty( PROP_DESKTOPHINTS + "." + device.getIDstring()); if (desktopHints == null) { desktopHints = (Map) toolkit.getDesktopProperty(PROP_DESKTOPHINTS); } // It is possible to get a non-empty map but with disabled AA. if (desktopHints != null) { Object aaHint = desktopHints.get(RenderingHints.KEY_TEXT_ANTIALIASING); if ((aaHint == RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) || (aaHint == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) { desktopHints = null; } } return desktopHints; }
private static boolean isPrinting(Graphics g) { return g instanceof PrintGraphics || g instanceof PrinterGraphics; }
}
</source>
Draw text with TextLayout
<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import javax.swing.JFrame; import javax.swing.JPanel; public class Main extends JPanel {
public Main() { setBackground(Color.white); } public void paint(Graphics g) { Graphics2D g2D; g2D = (Graphics2D) g; g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); FontRenderContext frc = g2D.getFontRenderContext(); Font font1 = new Font("Courier", Font.BOLD, 24); String str1 = new String("Java"); TextLayout tl = new TextLayout(str1, font1, frc); g2D.setColor(Color.gray); tl.draw(g2D, 50, 150); } public static void main(String s[]) { JFrame frame1 = new JFrame("2D Text"); frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame1.getContentPane().add("Center", new Main()); frame1.pack(); frame1.setSize(new Dimension(500, 300)); frame1.setVisible(true); }
}
</source>
Getting the Shape from the Outline of Text
<source lang="java"> import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import javax.swing.JFrame; import javax.swing.JPanel; public class Main extends JPanel {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.draw(getTextShape(g2d, "asdf", new Font("", 1, 30))); } public Shape getTextShape(Graphics2D g2d, String str, Font font) { FontRenderContext frc = g2d.getFontRenderContext(); TextLayout tl = new TextLayout(str, font, frc); return tl.getOutline(null); } public static void main(String[] args) { JFrame frame = new JFrame("Basic Shapes"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Main()); frame.setSize(350, 250); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}
</source>
Hightlight text by drag and selection
<source lang="java"> import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.font.FontRenderContext; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import javax.swing.JFrame; import javax.swing.JPanel; public class Highlights extends JPanel {
private TextLayout textLayout; private TextHitInfo firstHit, secondHit; private int x = 40, y = 80; public Highlights(){ addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { firstHit = textLayout.hitTestChar(me.getX() - x, me.getY() - y); secondHit = null; } public void mouseReleased(MouseEvent me) { secondHit = textLayout.hitTestChar(me.getX() - x, me.getY() - y); repaint(); } }); addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent me) { secondHit = textLayout.hitTestChar(me.getX() - x, me.getY() - y); repaint(); } }); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); String s = "Drag the text to highlight Java Source and Support."; Font font = new Font("Serif", Font.PLAIN, 32); if (textLayout == null) { FontRenderContext frc = g2.getFontRenderContext(); textLayout = new TextLayout(s, font, frc); } // Draw the highlight. if (firstHit != null && secondHit != null) { Shape base = textLayout.getLogicalHighlightShape(firstHit .getInsertionIndex(), secondHit.getInsertionIndex()); AffineTransform at = AffineTransform.getTranslateInstance(x, y); Shape highlight = at.createTransformedShape(base); g2.setPaint(Color.white); g2.fill(highlight); } g2.setPaint(Color.black); textLayout.draw(g2, x, y); } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new Highlights()); f.setSize(850, 250); f.show(); }
}
</source>
JFreeChart: Draw String Demo
<source lang="java"> /* ========================================================================
* JCommon : a free general purpose class library for the Java(tm) platform * ======================================================================== * * (C) Copyright 2000-2004, 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.] * * ------------------- * DrawStringDemo.java * ------------------- * (C) Copyright 2003, 2004, by Object Refinery Limited. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; * * $Id: DrawStringDemo.java,v 1.3 2005/06/01 14:12:28 taqua Exp $ * * Changes * ------- * 10-Jun-2003 : Version 1; * */
package org.jfree.demo; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTabbedPane; import org.jfree.ui.ApplicationFrame; import org.jfree.ui.FontChooserPanel; import org.jfree.ui.RefineryUtilities; import org.jfree.ui.Spinner; import org.jfree.ui.TextAnchor; /**
* A demo of some of the string drawing methods in the JCommon class library. * * @author David Gilbert */
public class DrawStringDemo extends ApplicationFrame
implements ActionListener, PropertyChangeListener { /** The alignment anchor for the first panel. */ private JComboBox combo1; /** The alignment anchor for the second panel. */ private JComboBox combo2; /** The rotation anchor for the second panel. */ private JComboBox combo3; /** A spinner for the second panel. */ private Spinner spinner; /** String panel 1. */ private DrawStringPanel drawStringPanel1; /** String panel 2. */ private DrawStringPanel drawStringPanel2; /** * Creates a new demo instance. * * @param title the frame title. */ public DrawStringDemo(final String title) { super(title); setContentPane(createContentPane()); } /** * Receives action events. * * @param event the event. */ public void actionPerformed(final ActionEvent event) { if (event.getActionCommand().equals("fontButton.clicked")) { displayFontDialog(); } if (event.getActionCommand().equals("combo1.changed")) { handleCombo1Change(); } if (event.getActionCommand().equals("combo2.changed")) { handleCombo2Change(); } if (event.getActionCommand().equals("combo3.changed")) { handleCombo3Change(); } } /** * Receives property change events. * * @param event the event. */ public void propertyChange(final PropertyChangeEvent event) { final int r = this.spinner.getValue(); final double angle = Math.PI * 2.0 * (r / 360.0); this.drawStringPanel2.setAngle(angle); this.drawStringPanel2.invalidate(); this.drawStringPanel2.repaint(); } /** * Updates the display when combo 1 is updated. */ private void handleCombo1Change() { final String text = this.rubo1.getSelectedItem().toString(); this.drawStringPanel1.setAnchor(convertStringToAnchor(text)); this.drawStringPanel1.invalidate(); this.drawStringPanel1.repaint(); } /** * Updates the display when combo 2 is updated. */ private void handleCombo2Change() { final String text = this.rubo2.getSelectedItem().toString(); this.drawStringPanel2.setAnchor(convertStringToAnchor(text)); this.drawStringPanel2.invalidate(); this.drawStringPanel2.repaint(); } /** * Updates the display when combo 3 is updated. */ private void handleCombo3Change() { final String text = this.rubo3.getSelectedItem().toString(); this.drawStringPanel2.setRotationAnchor(convertStringToAnchor(text)); this.drawStringPanel2.invalidate(); this.drawStringPanel2.repaint(); } /** * Creates the content pane for the demo frame. * * @return The content pane. */ private JPanel createContentPane() { final JPanel content = new JPanel(new BorderLayout()); final JTabbedPane tabs = new JTabbedPane(); tabs.add("Alignment", createTab1Content()); tabs.add("Rotation", createTab2Content()); content.add(tabs); return content; } /** * Creates the content for tab 1. * * @return The content panel. */ private JPanel createTab1Content() { final JPanel content = new JPanel(new BorderLayout()); this.rubo1 = new JComboBox(); this.rubo1.setActionCommand("combo1.changed"); populateTextAnchorCombo(this.rubo1); this.rubo1.addActionListener(this); final JPanel controls = new JPanel(); controls.add(this.rubo1); final JButton fontButton = new JButton("Select Font..."); fontButton.setActionCommand("fontButton.clicked"); fontButton.addActionListener(this); controls.add(fontButton); content.add(controls, BorderLayout.NORTH); this.drawStringPanel1 = new DrawStringPanel("0123456789", false); content.add(this.drawStringPanel1); return content; } /** * Creates the content for tab 2. * * @return The content panel. */ private JPanel createTab2Content() { final JPanel content = new JPanel(new BorderLayout()); final JPanel controls = new JPanel(); controls.add(new JLabel("Text anchor: ")); this.rubo2 = new JComboBox(); populateTextAnchorCombo(this.rubo2); this.rubo2.setActionCommand("combo2.changed"); this.rubo2.addActionListener(this); controls.add(this.rubo2); controls.add(new JLabel("Rotation anchor: ")); this.rubo3 = new JComboBox(); populateTextAnchorCombo(this.rubo3); this.rubo3.setActionCommand("combo3.changed"); this.rubo3.addActionListener(this); controls.add(this.rubo3); this.spinner = new Spinner(0); this.spinner.addPropertyChangeListener(this); controls.add(this.spinner); content.add(controls, BorderLayout.NORTH); this.drawStringPanel2 = new DrawStringPanel("Rotated Text", true); content.add(this.drawStringPanel2); return content; } /** * Displays a primitive font chooser dialog to allow the user to change the font. */ private void displayFontDialog() { final FontChooserPanel panel = new FontChooserPanel(this.drawStringPanel1.getFont()); final int result = JOptionPane.showConfirmDialog(this, panel, "Font Selection", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (result == JOptionPane.OK_OPTION) { this.drawStringPanel1.setFont(panel.getSelectedFont()); this.drawStringPanel2.setFont(panel.getSelectedFont()); } } /** * Populates a combo box with the available {@link TextAnchor} options. * * @param combo the combo box. */ private void populateTextAnchorCombo(final JComboBox combo) { combo.addItem("TextAnchor.TOP_LEFT"); combo.addItem("TextAnchor.TOP_CENTER"); combo.addItem("TextAnchor.TOP_RIGHT"); combo.addItem("TextAnchor.HALF_ASCENT_LEFT"); combo.addItem("TextAnchor.HALF_ASCENT_CENTER"); combo.addItem("TextAnchor.HALF_ASCENT_RIGHT"); combo.addItem("TextAnchor.CENTER_LEFT"); combo.addItem("TextAnchor.CENTER"); combo.addItem("TextAnchor.CENTER_RIGHT"); combo.addItem("TextAnchor.BASELINE_LEFT"); combo.addItem("TextAnchor.BASELINE_CENTER"); combo.addItem("TextAnchor.BASELINE_RIGHT"); combo.addItem("TextAnchor.BOTTOM_LEFT"); combo.addItem("TextAnchor.BOTTOM_CENTER"); combo.addItem("TextAnchor.BOTTOM_RIGHT"); } /** * Converts a string to a corresponding {@link TextAnchor} instance. * * @param text the text. * * @return The anchor. */ private TextAnchor convertStringToAnchor(final String text) { if (text.equals("TextAnchor.TOP_LEFT")) { return TextAnchor.TOP_LEFT; } else if (text.equals("TextAnchor.TOP_CENTER")) { return TextAnchor.TOP_CENTER; } else if (text.equals("TextAnchor.TOP_RIGHT")) { return TextAnchor.TOP_RIGHT; } else if (text.equals("TextAnchor.CENTER_LEFT")) { return TextAnchor.CENTER_LEFT; } else if (text.equals("TextAnchor.CENTER")) { return TextAnchor.CENTER; } else if (text.equals("TextAnchor.CENTER_RIGHT")) { return TextAnchor.CENTER_RIGHT; } else if (text.equals("TextAnchor.HALF_ASCENT_LEFT")) { return TextAnchor.HALF_ASCENT_LEFT; } else if (text.equals("TextAnchor.HALF_ASCENT_CENTER")) { return TextAnchor.HALF_ASCENT_CENTER; } else if (text.equals("TextAnchor.HALF_ASCENT_RIGHT")) { return TextAnchor.HALF_ASCENT_RIGHT; } else if (text.equals("TextAnchor.BASELINE_LEFT")) { return TextAnchor.BASELINE_LEFT; } else if (text.equals("TextAnchor.BASELINE_CENTER")) { return TextAnchor.BASELINE_CENTER; } else if (text.equals("TextAnchor.BASELINE_RIGHT")) { return TextAnchor.BASELINE_RIGHT; } else if (text.equals("TextAnchor.BOTTOM_LEFT")) { return TextAnchor.BOTTOM_LEFT; } else if (text.equals("TextAnchor.BOTTOM_CENTER")) { return TextAnchor.BOTTOM_CENTER; } else if (text.equals("TextAnchor.BOTTOM_RIGHT")) { return TextAnchor.BOTTOM_RIGHT; } else { return null; } } /** * The starting point for the demo. * * @param args ignored. */ public static void main(final String[] args) { final DrawStringDemo demo = new DrawStringDemo("DrawString Demo"); demo.pack(); RefineryUtilities.centerFrameOnScreen(demo); demo.setVisible(true); }
}
</source>
Line break for textlayout
<source lang="java"> import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.util.Hashtable; import javax.swing.JApplet; import javax.swing.JFrame; import javax.swing.JPanel; public class LineBreakSample extends JPanel {
private LineBreakMeasurer lineMeasurer; // the first character in the paragraph. private int paragraphStart; // the first character after the end of the paragraph. private int paragraphEnd; private static final Hashtable map = new Hashtable(); static { map.put(TextAttribute.SIZE, new Float(18.0)); } private static AttributedString vanGogh = new AttributedString( "Many people believe that Vincent van Gogh painted his best works " + "during the two-year period he spent in Provence. Here is where he " + "painted The Starry Night--which some consider to be his greatest " + "work of all. However, as his artistic brilliance reached new heights " + "in Provence, his physical and mental health plummeted. ", map); public LineBreakSample() { AttributedCharacterIterator paragraph = vanGogh.getIterator(); paragraphStart = paragraph.getBeginIndex(); paragraphEnd = paragraph.getEndIndex(); // Create a new LineBreakMeasurer from the paragraph. lineMeasurer = new LineBreakMeasurer(paragraph, new FontRenderContext(null, false, false)); } public void paintComponent(Graphics g) { super.paintComponent(g); setBackground(Color.white); Graphics2D graphics2D = (Graphics2D) g; // Set formatting width to width of Component. Dimension size = getSize(); float formatWidth = (float) size.width; float drawPosY = 0; lineMeasurer.setPosition(paragraphStart); // Get lines from lineMeasurer until the entire // paragraph has been displayed. while (lineMeasurer.getPosition() < paragraphEnd) { // Retrieve next layout. TextLayout layout = lineMeasurer.nextLayout(formatWidth); // Move y-coordinate by the ascent of the layout. drawPosY += layout.getAscent(); // Compute pen x position. If the paragraph is // right-to-left, we want to align the TextLayouts // to the right edge of the panel. float drawPosX; if (layout.isLeftToRight()) { drawPosX = 0; } else { drawPosX = formatWidth - layout.getAdvance(); } // Draw the TextLayout at (drawPosX, drawPosY). layout.draw(graphics2D, drawPosX, drawPosY); // Move y-coordinate in preparation for next layout. drawPosY += layout.getDescent() + layout.getLeading(); } } public static void main(String[] args) { JFrame f = new JFrame(""); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); LineBreakSample controller = new LineBreakSample(); f.getContentPane().add(controller,"Center"); f.setSize(new Dimension(400, 250)); f.setVisible(true); }
}
</source>
LineMetrics: the metrics to layout characters along a line
<source lang="java"> import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.font.LineMetrics; import java.awt.geom.Line2D; import javax.swing.JFrame; import javax.swing.JPanel; public class LineMetricsIllustration extends JPanel{
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Font font = new Font("Serif", Font.PLAIN, 72); g2.setFont(font); String s = "Java Source and Support"; float x = 50, y = 150; // Draw the baseline. FontRenderContext frc = g2.getFontRenderContext(); float width = (float) font.getStringBounds(s, frc).getWidth(); Line2D baseline = new Line2D.Float(x, y, x + width, y); g2.setPaint(Color.red); g2.draw(baseline); // Draw the ascent. LineMetrics lm = font.getLineMetrics(s, frc); Line2D ascent = new Line2D.Float(x, y - lm.getAscent(), x + width, y - lm.getAscent()); g2.draw(ascent); // Draw the descent. Line2D descent = new Line2D.Float(x, y + lm.getDescent(), x + width, y + lm.getDescent()); g2.draw(descent); // Draw the leading. Line2D leading = new Line2D.Float(x, y + lm.getDescent() + lm.getLeading(), x + width, y + lm.getDescent() + lm.getLeading()); g2.draw(leading); // Render the string. g2.setPaint(Color.black); g2.drawString(s, x, y); } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new LineMetricsIllustration()); f.setSize(850, 250); f.show(); }
}
</source>
Mouse hit and textlayout
<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.awt.geom.Point2D; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.util.Hashtable; import javax.swing.JFrame; import javax.swing.JPanel; public class HitTestSample extends JPanel {
private static final Color STRONG_CARET_COLOR = Color.red; private static final Color WEAK_CARET_COLOR = Color.black; private TextLayout textLayout; private int insertionIndex; private static final FontRenderContext DEFAULT_FRC = new FontRenderContext( null, false, false); private static final Hashtable map = new Hashtable(); static { map.put(TextAttribute.SIZE, new Float(18.0)); } private static AttributedString helloWorld = new AttributedString( "Java Source and Support.", map); public HitTestSample() { AttributedCharacterIterator text = helloWorld.getIterator(); // Create a new TextLayout from the given text. textLayout = new TextLayout(text, DEFAULT_FRC); // Initilize insertionIndex. insertionIndex = 0; addMouseListener(new HitTestMouseListener()); } public Dimension getPreferredSize() { return new Dimension(400, 250); } private Point2D computeLayoutOrigin() { Dimension size = getPreferredSize(); Point2D.Float origin = new Point2D.Float(); origin.x = (float) (size.width - textLayout.getAdvance()) / 2; origin.y = (float) (size.height - textLayout.getDescent() + textLayout .getAscent()) / 2; return origin; } public void paintComponent(Graphics g) { super.paintComponent(g); setBackground(Color.white); Graphics2D graphics2D = (Graphics2D) g; Point2D origin = computeLayoutOrigin(); graphics2D.translate(origin.getX(), origin.getY()); // Draw textLayout. textLayout.draw(graphics2D, 0, 0); // Retrieve caret Shapes for insertionIndex. Shape[] carets = textLayout.getCaretShapes(insertionIndex); graphics2D.setColor(STRONG_CARET_COLOR); graphics2D.draw(carets[0]); if (carets[1] != null) { graphics2D.setColor(WEAK_CARET_COLOR); graphics2D.draw(carets[1]); } } private class HitTestMouseListener extends MouseAdapter { public void mouseClicked(MouseEvent e) { Point2D origin = computeLayoutOrigin(); // Compute the mouse click location relative to // textLayout"s origin. float clickX = (float) (e.getX() - origin.getX()); float clickY = (float) (e.getY() - origin.getY()); // Get the character position of the mouse click. TextHitInfo currentHit = textLayout.hitTestChar(clickX, clickY); insertionIndex = currentHit.getInsertionIndex(); // Repaint the Component so the new caret(s) will be displayed. repaint(); } } public static void main(String[] args) { JFrame f = new JFrame("HitTestSample"); HitTestSample demo = new HitTestSample(); f.getContentPane().add(demo, "Center"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(new Dimension(400, 250)); f.setVisible(true); }
}
</source>
Paragraph Layout
<source lang="java"> import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JPanel; public class ParagraphLayout extends JPanel {
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); String s = "Java components and products Directory for Java components " + "and applications.Hundreds of Java components and applications " + "are organized by topic. You can find what you need easily. " + "You may also compare your product with others. If your component " + "is not listed, just send your url to jexp@jexp.ru. " + "http://www.jexp.ru"; Font font = new Font("Serif", Font.PLAIN, 24); AttributedString as = new AttributedString(s); as.addAttribute(TextAttribute.FONT, font); AttributedCharacterIterator aci = as.getIterator(); FontRenderContext frc = g2.getFontRenderContext(); LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); Insets insets = getInsets(); float wrappingWidth = getSize().width - insets.left - insets.right; float x = insets.left; float y = insets.top; while (lbm.getPosition() < aci.getEndIndex()) { TextLayout textLayout = lbm.nextLayout(wrappingWidth); y += textLayout.getAscent(); textLayout.draw(g2, x, y); y += textLayout.getDescent() + textLayout.getLeading(); x = insets.left; } } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new ParagraphLayout()); f.setSize(350, 250); f.show(); }
}
</source>
Renders a paragraph of text (line breaks ignored) to an image (created and returned).
<source lang="java"> /*
* * Created on March 16, 2007, 4:34 PM * * Copyright 2006-2007 Nigel Hughes * * Licensed 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. */
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.RenderingHints; import java.awt.Transparency; import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.awt.image.BufferedImage; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.util.Hashtable; /**
* @author nigel */
public class Utils {
/** * Renders a paragraph of text (line breaks ignored) to an image (created and returned). * * @param font The font to use * @param textColor The color of the text * @param text The message * @param width The width the text should be limited to * @return An image with the text rendered into it */ public static BufferedImage renderTextToImage(Font font, Color textColor, String text, int width){ Hashtable map = new Hashtable(); map.put(TextAttribute.FONT, font); AttributedString attributedString = new AttributedString(text,map); AttributedCharacterIterator paragraph = attributedString.getIterator(); FontRenderContext frc = new FontRenderContext(null, false, false); int paragraphStart = paragraph.getBeginIndex(); int paragraphEnd = paragraph.getEndIndex(); LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc); float drawPosY=0; //First time around, just determine the height while (lineMeasurer.getPosition() < paragraphEnd) { TextLayout layout = lineMeasurer.nextLayout(width); // Move it down drawPosY += layout.getAscent() + layout.getDescent() + layout.getLeading(); } BufferedImage image = createCompatibleImage(width,(int) drawPosY); Graphics2D graphics = (Graphics2D) image.getGraphics(); graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); drawPosY=0; lineMeasurer.setPosition(paragraphStart); while (lineMeasurer.getPosition() < paragraphEnd) { TextLayout layout = lineMeasurer.nextLayout(width); // Move y-coordinate by the ascent of the layout. drawPosY += layout.getAscent(); /* Compute pen x position. If the paragraph is right-to-left, we want to align the TextLayouts to the right edge of the panel. */ float drawPosX; if (layout.isLeftToRight()) { drawPosX = 0; } else { drawPosX = width - layout.getAdvance(); } // Draw the TextLayout at (drawPosX, drawPosY). layout.draw(graphics, drawPosX, drawPosY); // Move y-coordinate in preparation for next layout. drawPosY += layout.getDescent() + layout.getLeading(); } graphics.dispose(); return image; } /** * Creates an image compatible with the current display * * @return A BufferedImage with the appropriate color model */ public static BufferedImage createCompatibleImage(int width, int height) { GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice().getDefaultConfiguration(); return configuration.createCompatibleImage(width, height, Transparency.TRANSLUCENT); }
}
</source>
TextAttribute: color and font
<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.TextAttribute; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JPanel; public class IteratorTest extends JPanel {
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; String s = "Java Source and Support"; Dimension d = getSize(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Font serifFont = new Font("Serif", Font.PLAIN, 48); Font sansSerifFont = new Font("Monospaced", Font.PLAIN, 48); AttributedString as = new AttributedString(s); as.addAttribute(TextAttribute.FONT, serifFont); as.addAttribute(TextAttribute.FONT, sansSerifFont, 2, 5); as.addAttribute(TextAttribute.FOREGROUND, Color.red, 5, 6); as.addAttribute(TextAttribute.FOREGROUND, Color.red, 16, 17); g2.drawString(as.getIterator(), 40, 80); } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new IteratorTest()); f.setSize(850, 250); f.show(); }
}
</source>
TextAttribute: Underline and strike through
<source lang="java"> import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.TextAttribute; import java.text.AttributedString; import javax.swing.JFrame; import javax.swing.JPanel; public class IteratorUnderStrike extends JPanel{
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; String s = "\"www.jexp.ru\" is great."; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Font plainFont = new Font("Times New Roman", Font.PLAIN, 24); AttributedString as = new AttributedString(s); as.addAttribute(TextAttribute.FONT, plainFont); as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 1, 15); as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, 18, 25); g2.drawString(as.getIterator(), 24, 70); } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new IteratorUnderStrike()); f.setSize(850, 250); f.show(); }
}
</source>
TextHitInfo Demo: tell you which is the letter you are clicking
<source lang="java"> import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.FontRenderContext; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import javax.swing.JFrame; import javax.swing.JPanel; public class TextHitInfoDemo extends JPanel {
private TextLayout mTextLayout; private int mX = 40, mY = 80; public TextHitInfoDemo() { addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { TextHitInfo hit = mTextLayout.hitTestChar(me.getX() - mX, me .getY() - mY); System.out.println(hit); } }); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); String s = "Java Source and Support"; Font font = new Font("Serif", Font.PLAIN, 32); if (mTextLayout == null) { FontRenderContext frc = g2.getFontRenderContext(); mTextLayout = new TextLayout(s, font, frc); } mTextLayout.draw(g2, mX, mY); } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new TextHitInfoDemo()); f.setSize(200, 200); f.show(); }
}
</source>
TextLayout demo
<source lang="java"> import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.TextLayout; import javax.swing.JFrame; import javax.swing.JPanel; public class TextLayoutOne extends JPanel {
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); String s = "Java Source and Support."; Font font = new Font("Serif", Font.PLAIN, 32); TextLayout textLayout = new TextLayout(s, font, g2 .getFontRenderContext()); textLayout.draw(g2, 40, 80); } public static void main(String[] args) { JFrame f = new JFrame(); f.getContentPane().add(new TextLayoutOne()); f.setSize(300, 200); f.setVisible(true); }
}
</source>
Unicode display
<source lang="java"> import java.awt.Font; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class HelloInJapanese extends JPanel {
static JFrame frame; static String helloInJapanese = "Hello in Japanese is konnichi wa, \u4eca\u65e5\u306f."; public HelloInJapanese(String characters) { Font theFont = new Font("Bitstream Cyberbit", Font.PLAIN, 20); JTextArea area = new JTextArea(characters, 2, 30); area.setFont(theFont); area.setLineWrap(true); JScrollPane scrollpane = new JScrollPane(area); add(scrollpane); } public static void main(String argv[]) { HelloInJapanese japanesePanel = new HelloInJapanese(helloInJapanese); frame = new JFrame("Hello in Japanese"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.getContentPane().add("Center", japanesePanel); frame.pack(); frame.setVisible(true); }
}
</source>
Unicode: test layout
<source lang="java"> /* Java Internationalization By Andy Deitsch, David Czarnecki ISBN: 0-596-00019-7 O"Reilly
- /
import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.text.*; import javax.swing.*; public class TextLayoutDemo extends JFrame {
String davidMessage = "David says, \"\u05E9\u05DC\u05D5\u05DD \u05E2\u05D5\u05DC\u05DD\" "; String andyMessage = "Andy also says, \"\u05E9\u05DC\u05D5\u05DD \u05E2\u05D5\u05DC\u05DD\" "; String textMessage = davidMessage + andyMessage + davidMessage + andyMessage + davidMessage + andyMessage + davidMessage + andyMessage + davidMessage + andyMessage + davidMessage + andyMessage + davidMessage + andyMessage + davidMessage + andyMessage; public TextLayoutDemo() { super("TextLayoutDemo"); } public void paint(Graphics g) { Graphics2D graphics2D = (Graphics2D)g; GraphicsEnvironment.getLocalGraphicsEnvironment(); Font font = new Font("LucidaSans", Font.PLAIN, 14); AttributedString messageAS = new AttributedString(textMessage); messageAS.addAttribute(TextAttribute.FONT, font); AttributedCharacterIterator messageIterator = messageAS.getIterator(); FontRenderContext messageFRC = graphics2D.getFontRenderContext(); LineBreakMeasurer messageLBM = new LineBreakMeasurer(messageIterator, messageFRC); Insets insets = getInsets(); float wrappingWidth = getSize().width - insets.left - insets.right; float x = insets.left; float y = insets.top; while (messageLBM.getPosition() < messageIterator.getEndIndex()) { TextLayout textLayout = messageLBM.nextLayout(wrappingWidth); y += textLayout.getAscent(); textLayout.draw(graphics2D, x, y); y += textLayout.getDescent() + textLayout.getLeading(); x = insets.left; } } public static void main(String[] args) { JFrame frame = new TextLayoutDemo(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.pack(); frame.setVisible(true); }
}