实现和使用 Printable 接口时的堆溢出问题

发布于 2024-12-08 19:45:56 字数 12172 浏览 0 评论 0原文

所以我写了下面的类,它可以工作,但是在使用它时我们遇到了一些堆溢出问题。每张图像限制为 5 mb。有人知道如何解决生成打印输出时堆溢出的问题吗?

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;
}

}

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;
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴情换悲伤 2024-12-15 19:45:56

在不了解代码细节的情况下,也许您确实需要更大的堆大小来完成此任务。您是否尝试过使用标志 -Xmx 来增加它?

-Xmx<size>        set maximum Java heap size

例如:

java -Xmx360m ...

将堆大小设置为 360 Mb。

或者,您可以使用探查器来了解内存的使用情况。请参阅此 Eclipse 教程

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文