// package bugs.swing_text_print; 

import java.awt.*; 
import java.awt.font.*; 
import java.awt.geom.AffineTransform; 
import java.awt.print.*; 
import java.util.*; 
import javax.swing.*; 

/** 
 * 
 * @author werner 
 */ 
public class SwingTextPrintBugFrame2 extends JFrame 
{ 
  private final String TEXT = 
    "* " +System.getProperty("java.version")+" *"; 

  private javax.swing.JButton btPrint; 
   
  /** 
   * Creates new form SwingTextPrintBugFrame 
   */ 
  public SwingTextPrintBugFrame2() 
  { 
    initComponents(); 
    final JPanel pMain = 
      new JPanel() 
      { 
        @Override 
        public void paint(final Graphics g) 
        { 
          super.paint(g); 
          drawText((Graphics2D)g); 
        } 
      }; 
    pMain.setPreferredSize(new Dimension(360,100)); 
    getContentPane().add(pMain); 
    pack(); 
  } 
   
  private void initComponents() 
  { 

    btPrint = new javax.swing.JButton(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    btPrint.setText("Print"); 
    btPrint.addActionListener(new java.awt.event.ActionListener() 
    { 
      public void actionPerformed(java.awt.event.ActionEvent evt) 
      { 
        onPrint(evt); 
      } 
    }); 
    getContentPane().add(btPrint, java.awt.BorderLayout.PAGE_END); 

    pack(); 
  } 
  private void drawText(final Graphics2D g2) 
  { 
    final Map<java.text.AttributedCharacterIterator.Attribute,Object> 
      fontMap = new HashMap<>(); 
    fontMap.put(TextAttribute.FAMILY,"SansSerif"); 
    fontMap.put(TextAttribute.SIZE,17F+2F/3F); 
    fontMap.put(TextAttribute.FOREGROUND,Color.BLACK); 
    fontMap.put(TextAttribute.WEIGHT,TextAttribute.WEIGHT_BOLD); 

    //setRenderingHints(g2); 
    int baseX = 10, baseY = 50; 
    for (int i=0;i<3;i++) 
    { 
      if (i==2) // Bug only occurs if Text has background WITH ALPHA! 
        fontMap.put(TextAttribute.BACKGROUND, new Color(0,0,255,64)); 
      final Font font = new Font(fontMap); 
      final FontMetrics fontMetrics = g2.getFontMetrics(font); 
      final Rectangle rect = 
        fontMetrics.getStringBounds(TEXT, g2).getBounds(); 
      System.out.println("***** "+rect+" / "+fontMetrics.getAscent()); 
      final int 
        ascent = fontMetrics.getAscent(), // Bug: ascent gets negative! 
        width= rect.width; // Bug: width gets zero! 
      final TextLayout textLayout = 
        new TextLayout(TEXT, font, fontMetrics.getFontRenderContext()); 
      textLayout.getBounds(); 
       
      textLayout.draw(g2, baseX, baseY+ascent); 
      g2.drawRect(baseX, baseY, rect.width, rect.height); 
       
      baseX += width+10; 
    } 
  } 
   
  private Printable getPrintable() 
  { 
    return new Printable() 
    { 
      @Override 
      public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) 
        throws PrinterException 
      { 
        final Graphics2D g2 = (Graphics2D)graphics; 
        final AffineTransform at = g2.getTransform(); 
        at.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY()); 
        //at.scale(0.7, 0.7); 
        g2.setTransform(at); 
        drawText(g2); 
        return pageIndex==0 ? Printable.PAGE_EXISTS : Printable.NO_SUCH_PAGE; 
      } 
    }; 
  } 
   
  private void onPrint(java.awt.event.ActionEvent evt) 
  { 
    final PrinterJob pj = PrinterJob.getPrinterJob(); 
    if (!pj.printDialog()) 
      return; 
    pj.setPrintable(getPrintable(), pj.defaultPage()); 
    try 
    { 
      pj.print(); 
    } 
    catch (final Exception ex) 
    { 
      ex.printStackTrace(); 
    } 
  } 
   
  public static void main(String[] args) 
  { 
      java.awt.EventQueue.invokeLater(new Runnable() 
    { 
      @Override 
      public void run() 
      { 
        new SwingTextPrintBugFrame2().setVisible(true); 
      } 
    }); 
     
  } 
} 
