?
Solved

Why does printing a StyledDocument produce misaligned text in Java 1.6 but not 1.5?

Posted on 2009-04-06
5
Medium Priority
?
1,276 Views
Last Modified: 2013-11-23
The issue we are seeing is that text displayed onscreen looks different when printed in Java 1.6.  In particular, we are seeing text that is replaced within a StyledDocument is loosing it's whitespace when printed.  However the text looks fine onscreen.

For example:
EXPECTED - Note:  The underscores are really whitespaces.
Page_1_of_2

ACTUAL
Page_1_of2

On Java 1.5 everything looks fine.  We have narrowed down that passing in null for the ((AbstractDocument)document).replace(5, 1, "1", null); and ((AbstractDocument)document).replace(10, 1, "2", null); makes this issue go away but that is not an acceptable solution.

We have tried Java 1.6.0_11, 1.6.0_12, 1.6.0_13, and 1.7.0-ea but all versions produce the same problem.  Any ideas on what we're doing wrong?
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
 
import javax.swing.AbstractButton;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
 
public final class PrintingDemo implements Printable {
 
	private final JTextPane textPane;
	private static final String TEXT = "Page   of  " + '\n';
 
	public static void main(String[] args) {
        new PrintingDemo();
    }
 
	public PrintingDemo() {
        textPane = new JTextPane();
		textPane.setText(TEXT);
        final StyledDocument document = textPane.getStyledDocument();
 
		final MutableAttributeSet attributeSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attributeSet, "Tahoma");
		StyleConstants.setFontSize(attributeSet, 12);
		document.setParagraphAttributes(0, TEXT.length(), attributeSet, true);
 
		try {
			((AbstractDocument)document).replace(5, 1, "1", attributeSet);
			((AbstractDocument)document).replace(10, 1, "2", attributeSet);
		} catch (BadLocationException ex) {
			throw new RuntimeException(ex);
		}
 
		final AbstractButton printContextButton = new JButton("Print Context");
		printContextButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				final PrinterJob job = PrinterJob.getPrinterJob();
				job.setPrintable(PrintingDemo.this);
				try {
					job.print();
				} catch (PrinterException ex) {
					throw new RuntimeException("Printing Failed.", ex);
				}
			}
		});
 
		final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
		final Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
		contentPane.add(printContextButton);
		contentPane.add(new JScrollPane(textPane));
        frame.setSize(400, 200);
 
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				frame.setVisible(true);
			};
		});
    }
 
	public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
		if (pageIndex >= 1) return Printable.NO_SUCH_PAGE;
		final Graphics2D graphics2D = (Graphics2D)graphics;
		graphics2D.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
		textPane.print(graphics);
		return Printable.PAGE_EXISTS;
	}
}

Open in new window

0
Comment
Question by:dlotts
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 20

Expert Comment

by:Venabili
ID: 24082054
Sounds like a bug to me - especially considering that it works in Java 5. Had you tried to submit it to Sun?
0
 
LVL 1

Author Comment

by:dlotts
ID: 24082522
Yep, we're waiting to hear back.

-----Original Message-----
From: IncidentDaemon@sun.com [mailto:IncidentDaemon@sun.com]
Sent: Thursday, April 02, 2009 2:39 PM
Subject: Your Report (Review ID: 1490132) - Printing a StyledDocument produces misaligned text

************************************************
Dear Java Developer,

Thank you for your interest in improving the quality of Java Technology.

Your report has been assigned an internal review ID of 1490132, which is NOT visible on the Sun Developer Network (SDN).

Please be aware that the large volume of reports we receive sometimes prevents us from responding individually to each message.

If the information is determined to be a new Bug or RFE, or a duplicate of a known Bug or RFE, you will receive a followup email containing a seven digit bug number.  You may search for, view, or vote for this bug in the Bug Database at http://bugs.sun.com/.

If you just reported an issue that could have a major impact on your project and require a timely response, please consider purchasing one of the support offerings described at http://developers.sun.com/services/.

The Sun Developer Network (http://developers.sun.com) is a free service that Sun offers. To join, visit http://developers.sun.com/global/join_sdn.html.

For a limited time, SDN members can obtain fully licensed Java IDEs for web and enterprise development.  More information is at http://developers.sun.com/prodtech/javatools/free/.

Thank you for using our bug submit page.

Regards,
Java Developer Bug Report Review Team



---------------------------------------------------------------


Date Created: Thu Apr 02 12:38:28 MST 2009
Type:        bug
SDN ID:      
status:      Waiting
Category:    java
Subcategory: classes_beans
release:     6u10
hardware:    x86
OSversion:   win_xp
priority:    4
Synopsis:    Printing a StyledDocument produces misaligned text
Description:
 FULL PRODUCT VERSION :
java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP
Professional
Version 2002
Service Pack 2

A DESCRIPTION OF THE PROBLEM :
The issue we are seeing is that text displayed onscreen looks different when printed.  In particular, we are seeing that text that is replace within a StyledDocument is loosing it's whitespace when printed but looks fine onscreen.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the following code example.  Notice that the text displayed in the JTextPane is "Page 1 of 2".  Click the print button.  Look at the printed document and notice that the text is now "Page 1 of2".

This only seems to happen when replacing text around whitespace with at least two text replacements.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
With the example, we expect the following below to be printed.  Note:  The underscores are really whitespaces.

Page_1_of_2
ACTUAL -
Page_1_of2

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.AbstractButton;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public final class PrintingDemo implements Printable {

      private final JTextPane textPane;
      private static final String TEXT = "Page   of  " + '\n';

      public static void main(String[] args) {
        new PrintingDemo();
    }

      public PrintingDemo() {
        textPane = new JTextPane();
            textPane.setText(TEXT);
        final StyledDocument document = textPane.getStyledDocument();

            final MutableAttributeSet attributeSet = new SimpleAttributeSet();
            StyleConstants.setFontFamily(attributeSet, "Tahoma");
            StyleConstants.setFontSize(attributeSet, 12);
            document.setParagraphAttributes(0, TEXT.length(), attributeSet, true);

            try {
                  ((AbstractDocument)document).replace(5, 1, "1", attributeSet);
                  ((AbstractDocument)document).replace(10, 1, "2", attributeSet);
            } catch (BadLocationException ex) {
                  throw new RuntimeException(ex);
            }

            final AbstractButton printContextButton = new JButton("Print Context");
            printContextButton.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        final PrinterJob job = PrinterJob.getPrinterJob();
                        job.setPrintable(PrintingDemo.this);
                        try {
                              job.print();
                        } catch (PrinterException ex) {
                              throw new RuntimeException("Printing Failed.", ex);
                        }
                  }
            });

            final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            final Container contentPane = frame.getContentPane();
            contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
            contentPane.add(printContextButton);
            contentPane.add(new JScrollPane(textPane));
        frame.setSize(400, 200);

            SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                        frame.setVisible(true);
                  }
            });
    }

      public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            if (pageIndex >= 1) return Printable.NO_SUCH_PAGE;
            final Graphics2D graphics2D = (Graphics2D)graphics;
            graphics2D.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
            textPane.print(graphics);
            return Printable.PAGE_EXISTS;
      }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Instead of passing in an AttributeSet to the replace() methods on AbstractDocument, pass null.
workaround:  
0
 
LVL 20

Expert Comment

by:Venabili
ID: 24082572
Well - you have a workaround - as stupid as it is so it is the waiting game now I think.

Hm. Can you try something? Do the replacement in the opposite order - first the one later in the line? I recall something from the 1.4 days but had not touched printing for a while and might be ways off
0
 
LVL 1

Author Comment

by:dlotts
ID: 24102270
Well I tried switch the order of the two replace statements but that did not fix this issue.
0
 
LVL 1

Accepted Solution

by:
dlotts earned 0 total points
ID: 24102333
What we have found is that printing has changed for JTextComponents.  It appears that now user are supposed to use the following methods:

public boolean print()
public boolean print(MessageFormat headerFormat, MessageFormat footerFormat)
public boolean print(MessageFormat headerFormat, MessageFormat footerFormat, boolean showPrintDialog, PrintService service, PrintRequestAttributeSet attributes, boolean interactive)
public Printable getPrintable(MessageFormat headerFormat, MessageFormat footerFormat)

For the code snippet above, the ActionListener.actionPerformed(ActionEvent) method code can be replace with two possible solutions:

Solution 1:
try {
    textPane.print();
} catch (PrinterException ex) {
    throw new RuntimeException("Printing Failed.", ex);
}

Solution 2:
final Printable printable = textPane.getPrintable(null, null);
final PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(printable);
try {
    job.print();
} catch (PrinterException ex) {
    throw new RuntimeException("Printing Failed.", ex);
}
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question