JDK-4776296 : Right justified text in JLabel prints badly aligned
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0,1.4.1
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_98
  • CPU: x86
  • Submitted: 2002-11-08
  • Updated: 2004-02-10
  • Resolved: 2004-02-10
Related Reports
Duplicate :  
Description

Name: jk109818			Date: 11/08/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

AND

java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

FULL OPERATING SYSTEM VERSION :
Windows 98 [Version 4.10.2222]


A DESCRIPTION OF THE PROBLEM :
A JLabel with multiple lines of right-justified text
generally displays OK (I wouldn't say perfect, but errors
are only a fraction of a character).  But when the same
JLabel is printed the alignment goes very wrong in multiple
ways:

1) The right ends of the lines become misaligned, varying by
2-3 character positions over the different lines
2) Some lines overshoot the reported right edge of JLabel by
as much as two or three characters.
3) Some lines undershoot the right edge by two or three
characters and in a few cases by much more than that.

The undershooting and right end misalignment look amaturish
but at least you can still read things.  But the
overshooting is a major problem.  It means you can't rely on
Java to stay within the bounds it reports and can't ensure
that adjacent components don't overlap and become
unreadable.  This is a showstopper for trying to print
acceptible forms and reports!

The problem is primarily at small point sizes, the error is
reduced or disappears for larger sizes.

The results vary greatly depending upon the font:
  - SansSerif tends to overshoot by up to 2-3 characters and
right ends of lines are uneven by the same amount
  - Serif is the best, never seem to overshoot, alignment
isn't perfect but is usually off by < 1 character.
  - Monospaced usually undershoot by up to 2-3 characters
and lines are uneven by that much
  - Symbol font is the worst, undershoot errors of 10-20
characters (!) are common with right ends differing by
similar amounts.  Try the code below, you won't believe it.

I get identical results on HP printers and PostScript
printers, so it appears to be a Java 2D problem not a
printer imaging or font mismatch problem.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile and run the attached program and print
2. Notice the displayed JLabels
3. Notice the printed JLabels

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: When printed all lines of text should be evenly
aligned and (most importantly) stay within the JLabel

Actual: Right ends of lines vary by multiple characters when
printed, lines overshoot and undershoot the right bounds of
the JLabel by multiple characters

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.print.*;
import javax.swing.*;

public class Test{
	static public void main(String args[]) {
	    JFrame f = new JFrame("Test");
        f.getContentPane().setLayout(new FlowLayout());
        
	    String str1 = "Here are";
	    String str2 = "Several lines of right justified text in a JLabel";
	    String str3 = "Seems to me we might have cummulative rendering errors";
	    String str4 = "No two lines are the same";
	    String str5 = "No two fonts have the same right justification";
	    String str6 = "And text sometimes extends past the right edge of the JLabel";
	    String str7 = "Or falls short of the right edge";
	    JLabel lab1 = new JLabel("<html><p align=right><font face=SansSerif size='-3'>"
	        + str1 + "<br>" + str2 + "<br>" + str3 + "<br>" + str4 + "<br>" + str5
	        + "<br>" + str6 + "<br>" + str7 + "<br></font></p></html>", JLabel.RIGHT);
        lab1.setOpaque(true);
        lab1.setBackground(Color.pink);
        f.getContentPane().add(lab1);
        
	    JLabel lab2 = new JLabel("<html><p align=right><font face=Serif size='-3'>"
	        + str1 + "<br>" + str2 + "<br>" + str3 + "<br>" + str4 + "<br>" + str5
	        + "<br>" + str6 + "<br>" + str7 + "<br></font></p></html>", JLabel.RIGHT);
        lab2.setOpaque(true);
        lab2.setBackground(Color.pink);
        f.getContentPane().add(lab2);
        
	    JLabel lab3 = new JLabel("<html><p align=right><font face=Monospaced
size='-3'>"
	        + str1 + "<br>" + str2 + "<br>" + str3 + "<br>" + str4 + "<br>" + str5
	        + "<br>" + str6 + "<br>" + str7 + "<br></font></p></html>", JLabel.RIGHT);
        lab3.setOpaque(true);
        lab3.setBackground(Color.pink);
        f.getContentPane().add(lab3);
         
	    JLabel lab4 = new JLabel("<html><p align=right><font face=Symbol size='-3'>"
	        + str1 + "<br>" + str2 + "<br>" + str3 + "<br>" + str4 + "<br>" + str5
	        + "<br>" + str6 + "<br>" + str7 + "<br></font></p></html>", JLabel.RIGHT);
        lab4.setOpaque(true);
        lab4.setBackground(Color.pink);
        f.getContentPane().add(lab4);
        
        f.setBounds(10,10,400,500);
        f.setVisible(true);
        
        f.addWindowListener( new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent e)
                 {System.exit(0); }  }  );

		PrinterJob pj = PrinterJob.getPrinterJob();
		PageFormat pf = pj.defaultPage();
		pj.setPrintable(new Content(lab1,lab2,lab3,lab4), pf);
		try { if (pj.printDialog()) pj.print(); } catch (Exception e) {}
	}
}

class Content implements Printable {
    JLabel lab1, lab2, lab3, lab4;
    Content(JLabel lab1, JLabel lab2, JLabel lab3, JLabel lab4) {
        this.lab1 = lab1; this.lab2 = lab2; this.lab3 = lab3; this.lab4 = lab4;
    }
    public int print(Graphics g, PageFormat pf, int pageIndex) {
        if (pageIndex>0) return Printable.NO_SUCH_PAGE;
        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());
        lab1.print(g2d);
        g2d.translate(0,150);
        lab2.print(g2d);
        g2d.translate(0,150);
        lab3.print(g2d);
        g2d.translate(0,150);
        lab4.print(g2d);
        return Printable.PAGE_EXISTS;
    }
}

    

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Some fonts are better than others.  Lucida Sans does better
than SansSerif, Helvetica, Arial, Gill Sans....
(Review ID: 165021) 
======================================================================

Comments
EVALUATION The fact that this happens in JLabels is significant. Swing doesn't measure text in a way that's adjusted for printer resolution. Swing already has a bug on this and this should be a duplicate of that bug. ###@###.### 2002-11-08 ============================
08-11-2002