So I’ve written the class below, and it works, but we are getting some heap overflow problems when using this. The images are limited to 5 mb each. Anyone have an idea on how to solve overflowing the heap when generating the printout?
import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class GeneratePrintout implements Printable { public static void main(String... args) { GeneratePrintout print = new GeneratePrintout("Path to image", "Description"); // print.setPath2("C:\images\house.jpeg"); print.setDesc1(""); print.setDesc2("A random house from the net"); // print.setPath3("C:\images\biltmore.jpg"); print.setDesc3("The Biltmore Again..."); // print.setPath4("C:\images\house.jpeg"); print.setDesc4("The random house again."); print.setType("JPG"); print.setComments("These are pictures of two houses and this text is really long because I am trying to wrap the words, and I really hope this works correctly!"); print.setPolNum("123456789"); print.setContNum("2564585"); print.setfName("John"); print.startPrint(print); } private String type; private String polNum; private String contNum; private String fName; private String lName; private String comments; private String path1; private String path2; private String path3; private String path4; private String desc1; private String desc2; private String desc3; private String desc4; /** * Default Constructor. */ public GeneratePrintout() { this.setType(""); this.setPolNum(""); this.setContNum(""); this.setfName(""); this.setlName(""); this.setComments(""); this.setPath1(""); this.setPath2(""); this.setPath3(""); this.setPath4(""); this.setDesc1(""); this.setDesc2(""); this.setDesc3(""); this.setDesc4(""); } /** * Constructor. * * @param path1 * The file path for the first image. * @param lName * String last name or business name. */ public GeneratePrintout(String path1, String lName) { this.setPath1(path1); this.setlName(lName); this.setPath2(""); this.setPath3(""); this.setPath4(""); this.setPolNum(""); this.setContNum(""); this.setfName(""); this.setComments(""); this.setDesc1(""); this.setDesc2(""); this.setDesc3(""); this.setDesc4(""); } /** * Constructor. * * @param type * image file type * @param polNum * Policy Number * @param contNum * Control Number. * @param fName * First Name * @param lName * Last Name * @param comments * Comments * @param path1 * File path to image 1 * @param path2 * File path to image 2 * @param path3 * File path to image 3 * @param path4 * File path to image 4 * @param desc1 * Description for image 1 * @param desc2 * Description for image 2 * @param desc3 * Description for image 3 * @param desc4 * Description for image 4 */ public GeneratePrintout(String type, String polNum, String contNum, String fName, String lName, String comments, String path1, String path2, String path3, String path4, String desc1, String desc2, String desc3, String desc4) { this.setType(type); this.setPolNum(polNum); this.setContNum(contNum); this.setfName(fName); this.setlName(lName); this.setComments(comments); this.setPath1(path1); this.setPath2(path2); this.setPath3(path3); this.setPath4(path4); this.setDesc1(desc1); this.setDesc2(desc2); this.setDesc3(desc3); this.setDesc4(desc4); } /** * This method is used to start the printing process. The print dialog box * pops up where the user can set printer settings and then select print or * cancel. * * @param printOut * GeneratedPrintout object which contains the locations of the * images. */ public void startPrint(GeneratePrintout printOut) { PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(printOut); // This pops up the print dialog box, this is not necessary. boolean doPrint = job.printDialog(); if(doPrint){ try{ job.print(); }catch(PrinterException e){ /* The job did not successfully complete */ } } } @Override public int print(Graphics g, PageFormat pf, int page) throws PrinterException { /* We have only one page, and 'page' is zero-based */ if(page > 0){ return NO_SUCH_PAGE; } // Find the printable area of the printer. /* * (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()); // Get default width, height, x and y values of the page. int width = (int) pf.getImageableWidth(); int height = (int) pf.getImageableHeight(); int x = (int) pf.getImageableX(); int y = (int) pf.getImageableY(); Image img1 = null; Image img2 = null; Image img3 = null; Image img4 = null; // Try to create the images from the specified filepaths. Image 1 throws // a NullPointerException if not found because it is required. try{ if(!"".equals(path1)){ File src1 = new File(path1); img1 = ImageIO.read(src1); }else{ throw new NullPointerException("File path 1 is required."); } if(!"".equals(path2)){ File src2 = new File(path2); img2 = ImageIO.read(src2); } if(!"".equals(path3)){ File src3 = new File(path3); img3 = ImageIO.read(src3); } if(!"".equals(path4)){ File src4 = new File(path4); img4 = ImageIO.read(src4); } }catch(IOException e){ e.printStackTrace(); } /* Now we perform our rendering */ // Note: Image 1 must exist before image 2, and image 2 must exist // before image 3 and so on. // Image 1 and its description. if(img1 != null){ img1 = img1.getScaledInstance(width / 2, height / 4, 0); g.drawImage(img1, x, y, null); g.drawString(desc1, x, y + img1.getHeight(null) + 10); } // Image 2 and its description. if(img1 != null && img2 != null){ img2 = img2.getScaledInstance(width / 2, height / 4, 0); g.drawImage(img2, x + img1.getWidth(null) + 10, y, null); g.drawString(desc2, x + (width / 2) + 10, y + img2.getHeight(null) + 10); } // Image 3 and its description. if(img1 != null && img2 != null && img3 != null){ img3 = img3.getScaledInstance(width / 2, height / 4, 0); g.drawImage(img3, x, y + img1.getHeight(null) + 20, null); g.drawString(desc3, x, y + img1.getHeight(null) + img3.getHeight(null) + 30); } // Image 4 and its description. if(img1 != null && img2 != null && img3 != null && img4 != null){ img4 = img4.getScaledInstance(width / 2, height / 4, 0); g.drawImage(img4, x + img3.getWidth(null) + 10, y + img2.getHeight(null) + 20, null); g.drawString(desc4, x + (width / 2) + 10, y + img1.getHeight(null) + img3.getHeight(null) + 30); } // This is used to draw the text at the bottom. int p1Height = height; if(img1 != null){ p1Height = y + img1.getHeight(null) + 50; } if(img3 != null){ p1Height = y + img1.getHeight(null) + img3.getHeight(null) + 50; } // Left panel g.drawString("Image Type: " + type, x, p1Height); //Wordwrap business name. String[] busArray = lName.split(" "); int addY = 20; int check = 0; for(int i = 0; i < busArray.length;){ String toAdd = ""; if(addY == 20) toAdd +="Last or Business Name: "; //Only allow a max of 45 characters per line. while(toAdd.length() <= 45 && i < busArray.length){ toAdd += busArray[i] + " "; i++; } g.drawString(toAdd, x, p1Height + addY); check = addY; addY += 13; toAdd = ""; } addY += 13; // Wordwrap the comments section String[] commentsArray = comments.split(" "); for(int i = 0; i < commentsArray.length;){ String toAdd = ""; if((addY - check) == 26) toAdd += "Comments: "; // Only allow a max of 45 characters per line. while(toAdd.length() <= 45 && i < commentsArray.length){ toAdd += commentsArray[i] + " "; i++; } g.drawString(toAdd, x, p1Height + addY); // Add 13 pixels to Y to create a new line. addY += 13; toAdd = ""; } // right Panel g.drawString("Policy #: " + polNum, width / 2, p1Height); g.drawString("Control #: " + contNum, width / 2, p1Height + 20); g.drawString("First Name: " + fName, width / 2, p1Height + 40); /* tell the caller that this page is part of the printed document */ return PAGE_EXISTS; } /** * @param type * the type to set */ public void setType(String type) { this.type = type; } /** * @return the type */ public String getType() { return type; } /** * @param polNum * the polNum to set */ public void setPolNum(String polNum) { this.polNum = polNum; } /** * @return the polNum */ public String getPolNum() { return polNum; } /** * @param contNum * the contNum to set */ public void setContNum(String contNum) { this.contNum = contNum; } /** * @return the contNum */ public String getContNum() { return contNum; } /** * @param fName * the fName to set */ public void setfName(String fName) { this.fName = fName; } /** * @return the fName */ public String getfName() { return fName; } /** * @param lName * the lName to set */ public void setlName(String lName) { this.lName = lName; } /** * @return the lName */ public String getlName() { return lName; } /** * @param comments * the comments to set */ public void setComments(String comments) { this.comments = comments; } /** * @return the comments */ public String getComments() { return comments; } /** * @param desc2 * the desc2 to set */ public void setDesc2(String desc2) { this.desc2 = desc2; } /** * @return the desc2 */ public String getDesc2() { return desc2; } /** * @param desc3 * the desc3 to set */ public void setDesc3(String desc3) { this.desc3 = desc3; } /** * @return the desc3 */ public String getDesc3() { return desc3; } /** * @param desc4 * the desc4 to set */ public void setDesc4(String desc4) { this.desc4 = desc4; } /** * @return the desc4 */ public String getDesc4() { return desc4; } /** * @param path1 * the path1 to set */ public void setPath1(String path1) { this.path1 = path1; } /** * @return the path1 */ public String getPath1() { return path1; } /** * @param path2 * the path2 to set */ public void setPath2(String path2) { this.path2 = path2; } /** * @return the path2 */ public String getPath2() { return path2; } /** * @param path3 * the path3 to set */ public void setPath3(String path3) { this.path3 = path3; } /** * @return the path3 */ public String getPath3() { return path3; } /** * @param path4 * the path4 to set */ public void setPath4(String path4) { this.path4 = path4; } /** * @return the path4 */ public String getPath4() { return path4; } /** * @param desc1 * the desc1 to set */ public void setDesc1(String desc1) { this.desc1 = desc1; } /** * @return the desc1 */ public String getDesc1() { return desc1; }
}
Advertisement
Answer
Without going in the specifics of your code, maybe you really need a bigger heap size to do this task. Have you tried increasing it with the flag -Xmx?
-Xmx<size> set maximum Java heap size
For instance:
java -Xmx360m ...
sets the heap size to 360 Mb.
Alternatively, you can use a profiler to understand where the memory is used. See this tutorial for Eclipse.