Java AWT FontMetrics multiple line text alignment
// Demonstrate text alignment. import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.StringTokenizer; import javax.swing.JFrame; import javax.swing.JPanel; class Demo extends JPanel { final int LEFT = 0; final int RIGHT = 1; final int CENTER = 2; final int LEFTRIGHT = 3; int align;/*from w w w . j a v a2s .com*/ Dimension d; Font f; FontMetrics fm; int fontSize; int fh, bl; int space; String text; public Demo() { setBackground(Color.white); text = "demo2s.com <p> demo2s.com this is a test <p> demo2s.com <p> demo2s.com <p>"; fontSize = 14; align = LEFT; addMouseListener(new MyMouseAdapter(this)); } public void paint(Graphics g) { update(g); } public void update(Graphics g) { d = getSize(); g.setColor(getBackground()); g.fillRect(0, 0, d.width, d.height); if (f == null) f = new Font("New Roman", Font.PLAIN, fontSize); g.setFont(f); if (fm == null) { fm = g.getFontMetrics(); bl = fm.getAscent(); fh = bl + fm.getDescent(); space = fm.stringWidth(" "); } g.setColor(Color.black); StringTokenizer st = new StringTokenizer(text); int x = 0; int nextx; int y = 0; String word, sp; int wordCount = 0; String line = ""; while (st.hasMoreTokens()) { word = st.nextToken(); if (word.equals("<P>")) { drawString(g, line, wordCount, fm.stringWidth(line), y + bl); line = ""; wordCount = 0; x = 0; y = y + (fh * 2); } else { int w = fm.stringWidth(word); if ((nextx = (x + space + w)) > d.width) { drawString(g, line, wordCount, fm.stringWidth(line), y + bl); line = ""; wordCount = 0; x = 0; y = y + fh; } if (x != 0) { sp = " "; } else { sp = ""; } line = line + sp + word; x = x + space + w; wordCount++; } } drawString(g, line, wordCount, fm.stringWidth(line), y + bl); } public void drawString(Graphics g, String line, int wc, int lineW, int y) { switch (align) { case LEFT: g.drawString(line, 0, y); break; case RIGHT: g.drawString(line, d.width - lineW, y); break; case CENTER: g.drawString(line, (d.width - lineW) / 2, y); break; case LEFTRIGHT: if (lineW < (int) (d.width * .75)) { g.drawString(line, 0, y); } else { int toFill = (int) ((d.width - lineW) / wc); int nudge = d.width - lineW - (toFill * wc); int s = fm.stringWidth(" "); StringTokenizer st = new StringTokenizer(line); int x = 0; while (st.hasMoreTokens()) { String word = st.nextToken(); g.drawString(word, x, y); if (nudge > 0) { x = x + fm.stringWidth(word) + space + toFill + 1; nudge--; } else { x = x + fm.stringWidth(word) + space + toFill; } } } break; } } } class MyMouseAdapter extends MouseAdapter { Demo tl; public MyMouseAdapter(Demo tl) { this.tl = tl; } public void mouseClicked(MouseEvent me) { tl.align = (tl.align + 1) % 4; tl.repaint(); } } public class Main { public static void main(String[] args) { Demo panel = new Demo(); JFrame application = new JFrame(); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); application.add(panel); application.setSize(250, 250); application.setVisible(true); } }