[英]Printing a Multi-page JPanel
I'm nervous about asking this because I'm scared I'll get told off. 我很想问这个问题,因为我害怕我会被告知。 I am trying to print a JPanel that is about 4 pages long.
我正在尝试打印大约4页长的JPanel。 It could be more, the data is from a JDBC MySql query, that could end up being many more that 4. The JPanel I am trying to print is full of other JPanels (with competitors race details on them) that I have added via a ListArray..
可能更多,数据来自JDBC MySql查询,最终可能会比4多得多。我要打印的JPanel充满了我通过一个方式添加的其他JPanels(上面有竞争对手的比赛细节)。 ListArray ..
Anyway, I have scoured all day through stackoverflow and have found may examples of code that I have tried to implement. 无论如何,我整天都在stackoverflow上进行搜索,并且发现了可能尝试实现的代码示例。 The printable class only prints the first page, so I have tried to implement the pageable class, but I just can't seem to get it right.
可打印类仅打印第一页,因此我尝试实现可分页类,但似乎无法正确完成。 I have tried to implement the Book class but don't know how to add my JPanel to the book.
我尝试实现Book类,但不知道如何将JPanel添加到书中。 I have looked here , here and many more (I'm only allowed to post 2 links).
我看过这里 , 这里等等(只允许发布2个链接)。 Here is my current code (that I got off one of the answers that @madprogrammer gave) -
这是我当前的代码(我得到了@madprogrammer给出的答案之一)-
int printButton = JOptionPane.showOptionDialog(null, scrollPane, "Race Winners", JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE, // no Icon
null, //do not use a custom Icon
options, //the titles of buttons
options[0]); //default button title
if (printButton == 0) {
try {
printComponent(pane, true);
//printComponentToFile(pane, false);
} catch (PrinterException exp) {
exp.printStackTrace();
}
public static void printComponent(JComponent comp, boolean fill) throws PrinterException {
PrinterJob pjob = PrinterJob.getPrinterJob();
//pjob.setPageable(comp);
PageFormat pf = pjob.defaultPage();
pf.setOrientation(PageFormat.PORTRAIT);
PageFormat postformat = pjob.pageDialog(pf);
if (pf != postformat) {
//Set print component
//pjob.setPageable(comp);
pjob.setPrintable(new ComponentPrinter(comp, fill), postformat);
if (pjob.printDialog()) {
pjob.print();
}
}
}
public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72);
paper.setImageableArea(18, 18, 559, 783);
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.PORTRAIT);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()), (int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
ComponentPrinter cp = new ComponentPrinter(comp, fill);
try {
cp.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ComponentPrinter implements Printable, Pageable {
private Component comp;
private boolean fill;
int numPages;
PageFormat format;
public ComponentPrinter(Component comp, boolean fill) {
this.comp = comp;
this.fill = fill;
}
@Override
public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {
numPages = (int) Math.ceil(comp.getHeight() / format.getImageableY());
System.out.print(numPages);
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) g;
g2.translate(format.getImageableX(), format.getImageableY());
//g2.translate(format.getImageableX(), format.getImageableY()- page_index*comp.getPreferredSize().height);
double width = (int) Math.floor(format.getImageableWidth());
double height = (int) Math.floor(format.getImageableHeight());
if (!fill) {
width = Math.min(width, comp.getPreferredSize().width);
height = Math.min(height, comp.getPreferredSize().height);
}
comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
if (comp.getParent() == null) {
comp.addNotify();
}
comp.validate();
comp.doLayout();
comp.printAll(g2);
if (comp.getParent() != null) {
comp.removeNotify();
}
return Printable.PAGE_EXISTS;
}
@Override
public int getNumberOfPages() {
// TODO Auto-generated method stub
return numPages;
}
@Override
public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
return format;
}
@Override
public Printable getPrintable(int arg0) throws IndexOutOfBoundsException {
// TODO Auto-generated method stub
return this;
}
}
This all works, but only prints the first page. 所有这些都可以,但是仅打印第一页。 I would REALLY appreciate a nudge in the right direction with this as I'm stumped.
当我感到困惑时,我将非常感激朝着正确的方向前进。 TIA :-)
TIA :-)
This is how you print a Component
( JPanel
) on multiple pages: 这是在多页上打印
Component
( JPanel
)的方式:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.*;
import javax.swing.RepaintManager;
public class PrintMultiPageUtil implements Printable, Pageable {
private Component componentToBePrinted;
private PageFormat format;
private int numPages;
public PrintMultiPageUtil(Component componentToBePrinted) {
this.componentToBePrinted = componentToBePrinted;
// get total space from component
Dimension totalSpace = this.componentToBePrinted.getPreferredSize();
// calculate for DIN A4
format = PrinterJob.getPrinterJob().defaultPage();
numPages = (int) Math.ceil(totalSpace .height/format.getImageableHeight());
}
public void print() {
PrinterJob printJob = PrinterJob.getPrinterJob();
// show page-dialog with default DIN A4
format = printJob.pageDialog(printJob.defaultPage());
printJob.setPrintable(this);
printJob.setPageable(this);
if (printJob.printDialog())
try {
printJob.print();
} catch(PrinterException pe) {
System.out.println("Error printing: " + pe);
}
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
if ((pageIndex < 0) | (pageIndex >= numPages)) {
return(NO_SUCH_PAGE);
} else {
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
disableDoubleBuffering(componentToBePrinted);
componentToBePrinted.paint(g2d);
enableDoubleBuffering(componentToBePrinted);
return(PAGE_EXISTS);
}
}
public static void disableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
public static void enableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
@Override
public int getNumberOfPages() {
// TODO Auto-generated method stub
return numPages;
}
@Override
public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
return format;
}
@Override
public Printable getPrintable(int arg0) throws IndexOutOfBoundsException {
// TODO Auto-generated method stub
return this;
}
}
numPages NUMPAGES
I changed the expression for numPages
to: 我将
numPages
的表达式numPages
为:
(int) Math.ceil(page.height/format.getImageableHeight())
This divides the total height (height of the jpanel) through the height of one page, thus calculating the number of all pages. 这样会将总高度(jpanel的高度)除以一页的高度,从而计算出所有页面的数量。
g2d.translate g2d.translate
I did the following change: In this line: 我做了以下更改:在这一行:
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
Changed componentToBePrinted.getPreferredSize().height
to pageFormat.getImageableHeight()
. 将
componentToBePrinted.getPreferredSize().height
更改为pageFormat.getImageableHeight()
。 A positive value for the first or the second parameter of g2d.translate
moves the graphic to the right or down respectively. g2d.translate
的第一个或第二个参数的g2d.translate
将图形向右或向下移动。
.getImageableX()
and .getImageableY()
help position the graphic so that it doesn't overlap with the padding. .getImageableX()
和.getImageableY()
帮助定位图形,使其不与填充重叠。
For pageIndex
greater than 0
, - pageIndex * pageFormat.getImageableHeight()
moves the image pageIndex
-times the page-height to the top. 对于
pageIndex
大于0
, - pageIndex * pageFormat.getImageableHeight()
移动图像pageIndex
-times页面高度到顶部。 So the area, that the pageIndex
refers to is printed. 因此,将打印
pageIndex
所指的区域。
original broken source: : https://community.oracle.com 原始损坏的源 :: https://community.oracle.com
Here is my original answer . 这是我的原始答案 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.