I am currently using a JLayeredPane to display a bowling ball in the background and then put JTextField's on top of the image that represent certain measurements that a bowling pro-shop worker would use to drill the holes in bowling balls. I am trying to let the user print the bowling ball with the measurement fields on a piece of paper.
I am currently able to print just about any other component that has paint() and paintAll() functionality, usually inherited from a Component or JComponent class. When I print the JLayeredPane only the print button is printed, which is strange.
If anyone knows about issues printing JLayeredPane please let me know. Also, I have looked all over the internet searching for people who have this similar problem and no one seems to have found the solution and not many people have actually reported this problem (probably b/c not too many applications need to use a JLayeredPane).
I found this right from the Java website and just added a JFrame reference so that I could hide the main window so the modal print dialog window isn't hidden behind it, then I show the main window after printing (damn Java bug):
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import javax.swing.JFrame;
public class PrintUtilities implements Printable, ActionListener {
JFrame mainFrame;
Component componentToPrint;
public PrintUtilities(JFrame f, Component c) {
mainFrame = f;
componentToPrint = c;
}
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
if (page > 0) { /* We have only one page, and 'page' is zero-based */
return NO_SUCH_PAGE;
}
/* User (0,0) is typically outside the imageable area, so we must
* translate by the X and Y values in the PageFormat to avoid clipping
*/
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Now print the window and its visible contents */
componentToPrint.printAll(g);
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
// There is a known problem with some versions of the Java implementation
// of the print component dialog window because it is modal and somehow
// ends up behind your main window. This is a problem b/c you can't access
// the print dialog window and your main application is waiting for you to
// respond to the print dialog window. The user would then be stuck and
// would have to do some tricks to close the application abruptly.
//
// *Note: switching to a newer version of Java might solve this problem
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
mainFrame.setVisible(false); // hide main window
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
mainFrame.setVisible(true); // un-hide main window
}
}
And my code looks like this:
// This is just a code snippet and not the actual complete code because it is too long to post here
...
private JLayeredPane layeredPane;
...
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(300, 310));
...
JButton printButton = new JButton("Print");
int printButtonWidth = 110;
int printButtonHeight = 20;
printButton.setOpaque(false);
printButton.setBounds(x, y, printButtonWidth, printButtonHeight);
printButton.addActionListener(new PrintUtilities(catalog, layeredPane));
...
for(int i = 0; i < numLayers; i++)
{
layeredPane.add(label,new Integer(i));
layeredPane.add(textField, new Integer(i));
}
I think it might have to do with the amount of layers I have created, but I'm not sure. Any help on this would be greatly appreciated.