实现和使用 Printable 接口时的堆溢出问题
所以我写了下面的类,它可以工作,但是在使用它时我们遇到了一些堆溢出问题。每张图像限制为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在不了解代码细节的情况下,也许您确实需要更大的堆大小来完成此任务。您是否尝试过使用标志 -Xmx 来增加它?
例如:
将堆大小设置为 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?
For instance:
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.