Drawing a tilted text in Swing

Main.java:

import javax.swing.event.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame { 
   JSlider hslider, vslider;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      hslider = new JSlider(JSlider.HORIZONTAL, 0, 20, 10);
      hslider.addChangeListener(new ChangeListener() {
         public void stateChanged(ChangeEvent ce) {
            repaint();
         }
      });
 
      vslider = new JSlider(JSlider.VERTICAL, 0, 20, 10);
      vslider.addChangeListener(new ChangeListener() {
         public void stateChanged(ChangeEvent ce) {
            repaint();
         }
      });
  
      hslider.setMajorTickSpacing(1);
      hslider.setPaintTicks(true);
      hslider.setPaintLabels(true);
 
      vslider.setMajorTickSpacing(1);
      vslider.setPaintTicks(true);
      vslider.setPaintLabels(true);
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.SOUTH, hslider);
      getContentPane().add(BorderLayout.WEST, vslider);
   }
  
   public void paint(Graphics g) {
      super.paint(g); 
  
      Graphics2D g2d = (Graphics2D) g;

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
  
      String text = "90% of all statistics are made up!";
 
      int w = getSize().width;
      int h = getSize().height;
 
      AffineTransform atShear = new AffineTransform();
      atShear.shear((hslider.getValue()-10)/10.0, -(vslider.getValue()-10)/10.0);
 
      FontRenderContext frc = g2d.getFontRenderContext();
      Font font = new Font("Serif", Font.BOLD, 24);
      Font derivedFont = font.deriveFont(atShear);
      TextLayout tl = new TextLayout(text, derivedFont, frc);
 
      AffineTransform at = new AffineTransform();
      at.setToTranslation(70, h/2);
      g2d.transform(at);
 
      g2d.setColor(Color.blue);
      tl.draw(g2d, 0f, 0f);
 
      g2d.setColor(Color.black);
      g2d.drawString("Shear x:" + (hslider.getValue()-10)/10.0, 60, 50-h/2);
      g2d.drawString("Shear y:" + -(vslider.getValue()-10)/10.0, 150, 50-h/2);
   }
   
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(550, 400);
      main.setVisible(true);
   }
}

Drawing a paragraph of text in Swing

Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;
import java.awt.*;
 
public class Main extends JFrame {
   private String text;
   LineBreakMeasurer lineMeasurer;
   int beginIndex, endIndex;
   
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });  
 
      text = "It is, in fact, nothing short of a miracle that the modern methods " +
             "of instruction have not yet entirely strangled the holy curiosity " +
             "of inquiry; for this delicate little plant, aside from stimulation, " +
             "stands mainly in need of freedom; without this it goes to wrack and " +
             "ruin without fail. It is a very grave mistake to think that the " +
             "enjoyment of seeing and searching can promoted by means of coercion " +
             "and sense of duty. To the contrary, I believe that it would be " +
             "possible to rob even a healthy beast of prey of its voraciousness, " +
             "if it were possible, with the aid of a whip, to force the beast to " +
             "devour continuously, even when not hungry,especiallyif the food, " +
             "handed out under such coercion, were to be selected accordingly." +
             "n" +
             "Albert Einstein";
 
      AttributedString as = new AttributedString(text);
      AttributedCharacterIterator aci = as.getIterator();
 
      FontRenderContext frc = new FontRenderContext(null, false, false);
 
      beginIndex = aci.getBeginIndex();
      endIndex = aci.getEndIndex();
 
      // Create a new LineBreakMeasurer from the paragraph.
      lineMeasurer = new LineBreakMeasurer(aci, frc);
   }
 
   public void paint(Graphics g) {
      super.paint(g);
 
      Graphics2D g2d = (Graphics2D) g;
 
      Dimension size = getSize();
      float width = (float) size.width - 40;
 
      float x=10, y=30;
 
      g2d.setFont(new Font("Serif", Font.PLAIN, 24));
      lineMeasurer.setPosition(beginIndex);
      while (lineMeasurer.getPosition() < endIndex) {
         TextLayout layout = lineMeasurer.nextLayout(width);
 
         x = 10;   
         y += layout.getAscent() + layout.getDescent() + layout.getLeading();
       
         layout.draw(g2d, x, y);
     }
   }
   
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(420, 230);
      main.setVisible(true);
   }
}

Drawing a strikethrough string in Swing

Use the class AttributedString as shown in following example.

Main.java:

import java.awt.event.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;
import java.awt.*;
 
public class Main extends JFrame {
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      AttributedString as = new AttributedString("Easter Island");
      as.addAttribute(TextAttribute.FONT, new Font("Helvetica", Font.PLAIN, 36));
      as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, 7, 13);
     
      g2d.drawString(as.getIterator(), 50, 100);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 150);
      main.setVisible(true);
   }
}

Drawing an underlined string in Swing

Use the class AttributedString as shown in following example.

Main.java:

import java.awt.event.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;
import java.awt.*;
 
public class Main extends JFrame {
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      AttributedString as = new AttributedString("Easter Island");
      as.addAttribute(TextAttribute.FONT, new Font("Helvetica", Font.PLAIN, 36));
      as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 0, 6);
     
      g2d.drawString(as.getIterator(), 50, 100);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 150);
      main.setVisible(true);
   }
}

Drawing an attributed string in Swing

Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;
import java.awt.*;
 
public class Main extends JFrame {
   private Image img;
  
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      }); 
 
      img = new javax.swing.ImageIcon("per.gif").getImage(); 
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
  
      String text = "90% of all statistics are made up!";
 
      Font font = new Font("Serif", Font.PLAIN, 24);
      AttributedString as = new AttributedString(text);
      as.addAttribute(TextAttribute.FONT, font, 0, 11);
 
      // image in between the text
      ImageGraphicAttribute iga = new ImageGraphicAttribute(img, (int) 
                                               GraphicAttribute.TOP_ALIGNMENT);
      as.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga, 2, 3);
 
      // shape in between the text
      Shape s1 = new Rectangle2D.Double(10, 0, 5, 15);
      Shape s2 = new Rectangle2D.Double(10, 18, 5, 5);
      Area a1 = new Area(s1);
      Area a2 = new Area(s2);
      a1.add(a2);
      ShapeGraphicAttribute sga = new ShapeGraphicAttribute(a1,
                                               GraphicAttribute.TOP_ALIGNMENT, false);
      as.addAttribute(TextAttribute.CHAR_REPLACEMENT, sga, 33, 34);
 
      // set the background of the first 3 characters to red
      as.addAttribute(TextAttribute.BACKGROUND, Color.red, 0, 3);
 
      // set the foreground of the word "are" to blue
      as.addAttribute(TextAttribute.FOREGROUND, Color.blue, 22, 25);
 
      // underline the word "all"
      as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 7, 10);
 
      // change fontsize and weight for word "statistics"
      as.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 11, 21);
      as.addAttribute(TextAttribute.SIZE, new Float(14f), 11, 21);
 
      // make the words "made up" italic
      as.addAttribute(TextAttribute.POSTURE,TextAttribute.POSTURE_OBLIQUE,25,text.length());
 
      g2d.drawString(as.getIterator(), 20, 100);
   }
   
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(420, 200);
      main.setVisible(true);
   }
}

Image used:

Rotating text in Swing

You could apply AffineTransform on the graphics context directly or you can use the TextLayout class as shown here.

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private int degrees = 0;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      JButton button = new JButton("Rotate 10 degrees");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            degrees += 10;
            repaint();
         }
      });
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.SOUTH, button);
   }
 
   public void paint(Graphics g) {
      super.paint(g);
 
      Graphics2D g2d = (Graphics2D) g;
 
      g2d.drawString("Java and...", 80, 50);
     
      double radians = degrees * (Math.PI / 180);
      AffineTransform at = new AffineTransform();
      at.setToRotation(radians);
 
      FontRenderContext frc = g2d.getFontRenderContext();
      Font font = new Font("Times", Font.PLAIN, 20);
      Font derivedFont = font.deriveFont(at);
      TextLayout textLayout = new TextLayout("Alicia", derivedFont, frc);
      textLayout.draw(g2d, getSize().width/2, getSize().height/2);
 
      g2d.drawString("all I need ;)", 330, 180);
   }
  
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(480, 240);
      main.setVisible(true);
   }
}

Drawing a texture-filled text in Swing

Result:

Texture:

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private BufferedImage image; 
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = toBufferedImage(new javax.swing.ImageIcon("djkrush.jpg").getImage());
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
       
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
 
      Font font = new Font("Serif", Font.PLAIN, 140);
      g2d.setFont(font);
 
      Rectangle2D tr = new Rectangle2D.Double(0, 0, image.getWidth(), image.getHeight());
      TexturePaint tp = new TexturePaint(image, tr);
      g2d.setPaint(tp);
      g2d.drawString("Alicia", 30, 150);
   }
 
   public BufferedImage toBufferedImage(Image image) {
      BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), 
                                           BufferedImage.TYPE_INT_RGB); 
 
      // copy the original image
      Graphics g = bi.createGraphics();
    
      g.drawImage(image, 0, 0, null);
      g.dispose();
 
      return bi;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(410, 180);
      main.setVisible(true);
   }
}

Drawing a gradient-filled text in Swing

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private BufferedImage image; 
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = toBufferedImage(new javax.swing.ImageIcon("djkrush.jpg").getImage());
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
       
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
 
      Font font = new Font("Serif", Font.PLAIN, 140);
      g2d.setFont(font);
      FontMetrics fm = g2d.getFontMetrics();
 
      GradientPaint gp = new GradientPaint(30, 150-fm.getAscent(), Color.red, 
                                           390, 150, Color.blue, true);
      g2d.setPaint(gp);
      g2d.drawString("Alicia", 30, 150);
   }
 
   public BufferedImage toBufferedImage(Image image) {
      BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), 
                                           BufferedImage.TYPE_INT_RGB); 
 
      // copy the original image
      Graphics g = bi.createGraphics();
    
      g.drawImage(image, 0, 0, null);
      g.dispose();
 
      return bi;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(410, 180);
      main.setVisible(true);
   }
}

Drawing italic/bold text in Swing

You can call the method setFont on the graphics context, or if you want to associate the font with the String, you can use the AttributedString class.

Main.java:

import java.awt.event.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;
import java.awt.*;
 
public class Main extends JFrame {
   private boolean antiAliasing = false;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      }); 
   }
  
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
       
      g2d.setFont(new Font("Helvetica", Font.PLAIN, 24));
      g2d.drawString("Gyros (setFont)", 10, 70);
 
      g2d.setFont(new Font("Helvetica", Font.BOLD, 24));
      g2d.drawString("Gyros (setFont)", 10, 100);
 
      g2d.setFont(new Font("Helvetica", Font.ITALIC, 24));
      g2d.drawString("Gyros (setFont)", 10, 130);
 
      AttributedString as = new AttributedString("Gyros (AttributedString)");
      as.addAttribute(TextAttribute.FONT, new Font("Helvetica", Font.PLAIN, 24));
      g2d.drawString(as.getIterator(), 10, 170);
 
      as = new AttributedString("Gyros (AttributedString)");
      as.addAttribute(TextAttribute.FONT, new Font("Helvetica", Font.BOLD, 24));
      g2d.drawString(as.getIterator(), 10, 200);
 
      as = new AttributedString("Gyros (AttributedString)");
      as.addAttribute(TextAttribute.FONT, new Font("Helvetica", Font.ITALIC, 24));
      g2d.drawString(as.getIterator(), 10, 230);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 250);
      main.setVisible(true);
   }
}

Getting the FontMetrics of all available fonts on your system?

This code will display some FontMetrics information about the font you select.

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame {
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      getContentPane().setLayout(new BorderLayout());
      FontRendering fr = new FontRendering();
      getContentPane().add(BorderLayout.CENTER, fr);
      getContentPane().add(BorderLayout.NORTH, new FontRenderingControls(fr));
   } 
 
   public static class FontRenderingControls extends JPanel implements ActionListener {
      FontRendering fr;
 
      public FontRenderingControls(FontRendering fr) {
         this.fr = fr;
 
         Vector v = new Vector();
         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
         Font f[] = ge.getAllFonts();
         for (int i = 0; i < f.length; i++) {
            if (f[i].canDisplayUpTo(f[i].getName()) > 0) {
               v.addElement(f[i].getName());
            }
         }      
 
         final JComboBox fontCombo = new JComboBox(v);
         add(fontCombo);
         fontCombo.addActionListener(this);
      }
 
      public void actionPerformed(ActionEvent e) {
         JComboBox fontCombo = (JComboBox) e.getSource();
         fr.font = (String) fontCombo.getSelectedItem();
         fr.repaint();
      }
   }
 
   public static class FontRendering extends JPanel {
      public String text = "Easter Island";
      public String font = "Helvetica";
 
      public void paint(Graphics g) {
         Graphics2D g2d = (Graphics2D) g;
 
         Font f = g2d.getFont();
  
         g2d.setFont(new Font(font, Font.BOLD, 36));
         g2d.drawString(text, 10, 40); 
 
         FontMetrics fm = g2d.getFontMetrics();
    
         g2d.setFont(f);
         FontMetrics fm2 = g2d.getFontMetrics();
         g2d.drawString("FontMetrics:", 10, 60);
         g2d.drawString("Ascent: "      + 
                          fm.getAscent(), 50, 60 + fm2.getHeight());
         g2d.drawString("Descent: "     + 
                          fm.getDescent(), 50, 60 + fm2.getHeight() * 2);
         g2d.drawString("Height: "      + 
                          fm.getHeight(), 50, 60 + fm2.getHeight() * 3);
         g2d.drawString("Leading: "     + 
                          fm.getLeading(), 50, 60 + fm2.getHeight() * 4);
         g2d.drawString("MaxAdvance: "  + 
                          fm.getMaxAdvance(), 50, 60 + fm2.getHeight() * 5);
         g2d.drawString("MaxAscent: "   + 
                          fm.getMaxAscent(), 50, 60 + fm2.getHeight() * 6);
         g2d.drawString("MaxDescent: "  + 
                          fm.getMaxDescent(), 50, 60 + fm2.getHeight() * 7);
      }
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
      main.setSize(300, 300);
   }
}