ADDITIONAL SYSTEM INFORMATION :
Can be reproduced at least in Windows 64-bit and in Linux 64-bit
Can be reproduced at least in Java 10.0.2 and in Java 11.0.2
Can NOT be reproduced in Java 8
A DESCRIPTION OF THE PROBLEM :
When drawing text using background with alpha channel fontmetrics return invalid values, for example getStringBounds returns a zero rectangle and getAscent returns a negative value. So most applications will print such strings at wrong locations. Problem only occurs when printing, not when drawing in a panel.
JTable.print() is also broken when used with Nimbus L&F - I suppose this is the same problem
REGRESSION : Last worked in version 8u201
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run class SwingTextPrintBugFrame2 from test case in Java 10.0.2 or java 11.0.2
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Java version number should be shown as text 3 times side by side in JFrame and on printout
ACTUAL -
Java version number is shown as text 3 times side by side in JFrame but NOT on printout: printout is broken
---------- BEGIN SOURCE ----------
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);
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None known
FREQUENCY : always