Ok, I heard that java doesn't really have any easy way to get it to say, call print on a JTable and a JTextArea and, even if there IS room, to put them on the same page. It always seems to go to a new page for each item, or so I've read that it will. I've found out a nice tutorial that shows me MOST of what I can do to get around this, it involved something called a BufferedImage, but they have something in there that can't compile and will throw a NullPointerException the only way I can think of it to run it.
I'm not sure how to DIRECTLY call the print method of a Printable subclass. I cannot get a Graphics object to go and getGraphics() is returning null.
I thought it would be PrinterJob, but that doesn't seem to be what they're hinting at. However, they kinda said that PrinterJob normally always will print it on two separate pages for each item. I DON'T want that.
I have tried to find a way to call the Printable.print() directly online, but it always keep suggesting that I use PrinterJob. I cannot deduce what the guy meant as he left no examples (nor was I the only one confused from the looks of the comments on the page.)
Here's his tutorial:
Hot Coding!: Printing multiple Printables in Java
He suggests this at the end for how to work it:
For each Printable, JTable.getPrintable(...), wrap it with MyPrintable object and then print the wrapper.
MyPrintable prt = new MyPrintable(table.getPrintable(...))
...
while (prt.print(graphics,pf,pageIndex) == PAGE_EXISTS){
if (prt.getSpaceLeft() < 100){
// create a new page or a new graphics
// reset page index to 0
}
pageIndex++;
}
// looping to the next Printable...
First off, table.getPrintable() isn't a no argument method. (However, I figured that out and got that to compile.)
However, I have no clue what he wanted me to do with his
......
The line: while (prt.print(graphics,pf,pageIndex) == PAGE_EXISTS)
Doesn't seem to work. He doesn't put the stuff in a method that is passed a Graphics object. I cannot get a Graphics object and getGraphics() is returning null so that can't be the way to do it.
I keep being told online that I should use a PrinterJob object. However, that returns void. His example seems to require an int.
The print method of Printable DOES return an int, but there is the issue of passing it a Graphics object that works.
Here is what my attempt at trying to get it to work. It will compile but will throw a NullPointerException because getGraphics() is null.
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package printer; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.awt.print.PageFormat; import java.awt.print.Paper; import java.awt.print.Printable; import java.awt.print.PrinterException; /** * * @author pballeux */ public class MyPrintable implements Printable { Printable delegate; double spaceLeft = 0; double minimumRequired = 72; static int debugindex = 0; public MyPrintable(Printable p) { this.delegate = p; } public MyPrintable(Printable p, double minimumHeight) { this.delegate = p; this.minimumRequired = minimumHeight; } public void setMinimumRequired(double height) { minimumRequired = height; } public double getMinimumRequired() { return minimumRequired; } public double getSpaceLeft() { return spaceLeft; } private int detectLastLine(BufferedImage img) { int lastIndex = 0; int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); for (int i = data.length - 1; i > 0; i--) { if (data[i] != 0) { lastIndex = i; break; } } return (lastIndex / img.getWidth()); } @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { BufferedImage img = new BufferedImage((int) pageFormat.getWidth(), (int) pageFormat.getHeight(), BufferedImage.TRANSLUCENT); Graphics2D g = img.createGraphics(); int retValue = delegate.print(g, pageFormat, pageIndex); if (retValue == PAGE_EXISTS) { //Find out bound of printing... //System.out.println("Last Line drawn is : " + detectLastLine(img)); // try { // ImageIO.write(img, "jpg", new File("img" + debugindex++ + ".jpg")); // } catch (IOException ex) { // } spaceLeft = (pageFormat.getImageableY() + pageFormat.getImageableHeight()) - detectLastLine(img); retValue = delegate.print(graphics, pageFormat, pageIndex); //Updating paper after the hardprint Paper paper = pageFormat.getPaper(); paper.setImageableArea(paper.getImageableX(), paper.getImageableY() + paper.getImageableHeight() - spaceLeft, paper.getImageableWidth(), spaceLeft); pageFormat.setPaper(paper); } return retValue; } // For each Printable, JTable.getPrintable(...), wrap it with MyPrintable object and then print the wrapper. public static void main(String[] args) { Object[][] rows = new Object[2][2]; for (int i =0; i < rows.length; i++) { for (int j=0; j < rows[i].length; j++) { rows[i][j] = i*j; } } Object[] data = new Object[2]; data[0] = "Mike"; data[1] = "Bob"; javax.swing.JTable table = new javax.swing.JTable(rows, data); MyPrintable prt = new MyPrintable(table.getPrintable(javax.swing.JTable.PrintMode.NORMAL, null, null)); int pageIndex = 0; try { while (prt.print(table.getGraphics(), new java.awt.print.PageFormat(),pageIndex) == PAGE_EXISTS){ if (prt.getSpaceLeft() < 100){ // create a new page or a new graphics // reset page index to 0 } pageIndex++; } // looping to the next Printable... } catch(PrinterException pe) { } }
I cannot figure out what he meant when he called the print() method from Printable directly.
There is nothing online that mentions what to do.
Note, I tried using PrinterJob with the MyPrintable object and that printed it out on TWO pages. That is NOT what I want.
I have just found that the guy who did the tutorial has a Google plus page. (I found that in the comments that it went there. So I've contacted him as well.
However, if you can tell me what he might have meant, that would be great.
(Originally, when I made this topic, I didn't see that the comments were through Google Pus and the guy hadn't responded on the tutorial page to a comment somebody else made asking for an example of how to use his class and what he meant. Someone made that comment 6 months ago and it still hasn't gotten a reply on the tutorial page. So, I thought I'd go here.
I was going back to the page to see, yet again, if I'd missed something in what he said. That's when I found a way to contact him on his Google Plus Account (which he last used three days ago).