private void cmdprintActionPerformed(java.awt.event.ActionEvent evt) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setJobName("Outside Processing System");
job.setPrintable (new Printable() {
#Override
public int print(Graphics pg, PageFormat pf, int pageNum){
if (pageNum > 0){
return Printable.NO_SUCH_PAGE;
}
OPSPrintPanel panel = new OPSPrintPanel();
Graphics2D g2 =(Graphics2D)pg;
g2.translate(pf.getImageableX(), pf.getImageableY());
panel.paint(pg);
return Printable.PAGE_EXISTS;
}
});
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
}
I'm trying to print a panel and the codes seems okay but when I click print and view it to pdf its only a blank page. I tried so many codes that can print panel but it doesn't print. Even I reinstall my NetBeans and install an updated jdk it won't work.
Blank page
You didn't dispose object g2 and use try catch block when you print as pdf. First you have to print the image as it is and then try to translate it.
Try this, i hope it would works.
OPSPrintPanel panel = new OPSPrintPanel();
//print the panel to pdf
Document document = new Document();
try {
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\temp\\test.pdf"));
document.open();
// PdfContentByte is an object containing the user positioned text and
// graphic contents of a page. It knows how to apply the proper font encoding.
PdfContentByte contentByte = writer.getDirectContent();
PdfTemplate template = contentByte.createTemplate(500, 500);
Graphics2D g2 = template.createGraphics(500, 500);
// First print the panel as it is and then try to translate it by removing comments
// g2.translate(pf.getImageableX(), pf.getImageableY());
panel.print(g2);
g2.dispose();
// Adds a template to this content.
contentByte.addTemplate(template, 30, 300);
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
if(document.isOpen())
{
document.close();
}
}
Related
I am developing a desktop app in Java for my project work. I need to print an invoice with sub total and total fields along with tabular data from JTable. I am able to print the table but not in the same page. i.e JTable prints in first page and subtotal, total prints in next page. Is there a way to print both data in the same page. I dont want to use reporting engines. Just use the inbuilt java printing services. Please guide me.
Print Format as I want:
Following figure shows the GUI
And following figure shows the report i am getting till now. Its not in correct format. Please help
Code is as follows
JLabel title = new JLabel();
title.setText("Invoice");
title.setBounds(300, 200, 80, 30);
JTextField subTotal = new JTextField();
subTotal.setText("Sub Total : Rs. " + SubTotal.getText());
subTotal.setBounds(400, 200, 150, 30);
MyPrintable prt = new MyPrintable();
prt.addComponent(title);
prt.addComponent(billTable); //billTable is the JTable
prt.addComponent(subTotal);
prt.printIt();
And below is the My Printable class
class MyPrintable implements Printable
{
private ArrayList<JComponent> items;
public MyPrintable()
{
items = new ArrayList<>();
}
#Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException
{
if(page > 0) return Printable.NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D)g;
g2.translate(pf.getImageableX(), pf.getImageableY());
for(JComponent item : items)
{
item.setLayout(null);
// item.setBounds(500, 500, 200, 200);
item.printAll(g);
g2.translate(0, item.getHeight());
}
return Printable.PAGE_EXISTS;
}
public void printIt()
{
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();;
PrinterJob job = PrinterJob.getPrinterJob();
try
{
job.setPrintable(this);
if(job.printDialog(attributes))
job.print(attributes);
}
catch (PrinterException e)
{
JOptionPane.showMessageDialog(null, e);
}
}
public void addComponent(JComponent component) { items.add(component); }
}
If you want to print all your stuff at the coordinates you've set, you either need to create a new panel, lay out all your component to print in this panel, and than print this panel or you need to translate all the components in your print method to the correct coordinates.
the second way will look like
public int print(Graphics g, PageFormat pf, int page) throws PrinterException
{
if(page > 0) return Printable.NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D)g;
g2.translate(pf.getImageableX(), pf.getImageableY());
for(JComponent item : items)
{
g2.translate(item.getX(), item.getY());
item.printAll(g);
g2.translate(-item.getX(), -item.getY()); // bring all back to default coordinates
}
return Printable.PAGE_EXISTS;
}
I am facing an issue that I am not able to draw an png image into my swing GUI into JPanel (which I am adding into JScrollPane after).
Here is my code I am trying to use for this.
if(processCreated == true){
System.out.println("updating tree of organisms");
processCreated = false;
updateTree();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Svet.class.getName()).log(Level.SEVERE, null, ex);
}
tree = new File(path+"/out.png"); //File
try {
treeImage = ImageIO.read(tree); //BufferedImage
tp = new TreePane(treeImage.getScaledInstance( 500, 500 ,treeImage.SCALE_SMOOTH)); // my class, implementation below
treeOutput.add(tp); //adding "JPanel" with picture into GUI
treeOutput.repaint();
} catch (IOException ex) {
Logger.getLogger(Svet.class.getName()).log(Level.SEVERE, null, ex);
}
}
After this the JScrollPane remains empty. Is there anything wrong with my code? You can find what is what in comments.
Here is my TreePane class
public class TreePane extends JPanel{
Image img;
public TreePane( Image img ){
this.img = img;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int imgX = 0;
int imgY = 0;
g.drawImage(img, imgX, imgY, this);
}
}
Very likely your TreePane is layed out to size 0,0 and therefore you'll never see anything. Try adding a breakpoint and inspecting in paintComponent - it might not even ever get called.
To fix, you should explicitly set the size of your TreePane before adding it to the JScrollPane.
tp = new TreePane(treeImage.getScaledInstance( 500, 500 ,treeImage.SCALE_SMOOTH)); // my class, implementation below
tp.setSize(myWidth, myHeight);
treeOutput.add(tp); //adding "JPanel" with picture into GUI
treeOutput.repaint();
I'm trying to print the content of JFrame but, by looking at different tutorials, I still din't have any luck... Currently Parts of code for printing are
public class View_Check extends javax.swing.JFrame implements Printable{
JFrame frameToPrint;
public int print(Graphics g, PageFormat pf, int page) throws
PrinterException {
if (page > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
frameToPrint.printAll(g);
return PAGE_EXISTS;
}
and on the click of the button (jButton2)
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
}
}
}
Im Sure something is missing, but by trying to add "JFrame f" to View_Check didn't help... and new (View_Check(f)) either as f couldn't be found ant NetBeans was turning into a christmas tree with red lines
just in case here is a
public View_Check( Model_Customer cust) {
initComponents();
lblinfo1.setVisible(false);
customer = cust;
lblname.setText(customer.GetFName());
lblsurname.setText(customer.GetLName());
lblMake.setText(customer.GetMake());
lblModel.setText(customer.GetModel());
lblEngine.setText(customer.GetEngine());
lblRegistration.setText(customer.GetRegistration());
lblMileage.setText(customer.GetMileage());
String date = new SimpleDateFormat("dd-MM-yyyy").format(new Date());
lblDate.setText(date);
lblPostcode.setText(customer.GetPostcode());
lblNumber.setText(customer.GetNumber());
}
Changed frameToPrint.printAll(g); to this.printAll(g); and worked Like a charm :) Thanks for your help
try making the JFrame frameToPrint static
See if it solves the problem.
So im writing a java program for my dad to print out receipts and stuff. My original intention was to print out to his Receipt Printer some info regarding each transaction he made. However, the printer has some trouble printing what i send without clipping it to an extreme point.
My next idea, which worked out quite well, was to save the "receipt" into an XPS file and then print the XPS, which would not clip it and would make everything nice. Now, i can print into an XPS file using Microsoft's XPS Document Writer PrintService. The problem is, when i do it, it always pop's up a box asking for the file name and location to save it into.
Is there anyway to set it so as to not show that pop-up at all?
Current code:
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
try {
job.print();
} catch (PrinterException ex) {
// The job did not successfully complete
}
-
#Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
String temp;
if (page > 0) { /* We have only one page, and 'page' is zero-based */
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
int lineSize=20;
Font testFont=new Font("Lucida Console", 0, 20);
g.setFont(testFont);
g.drawString(" Fatura/Recibo nº"+nmrRec+" ", 5, 20);
return PAGE_EXISTS;
}
You should be able to do it by setting the Destination attribute:
static void print(Printable printable, PrintService service)
throws PrintException,
IOException {
Path outputFile = Files.createTempFile(
Paths.get(System.getProperty("user.home")), null, ".xps");
Doc doc = new SimpleDoc(printable,
DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);
PrintRequestAttributeSet attributes =
new HashPrintRequestAttributeSet();
attributes.add(new Destination(outputFile.toUri()));
DocPrintJob job = service.createPrintJob();
job.print(doc, attributes);
}
So i followed VGR's advice and i got it working. This was my final code, in case anyone runs into the same problem:
Date data = new Date(); //Data
DateFormat dataform = new SimpleDateFormat("dd-MM-yyyy"); //Data
PrintService service=getPrinterService("Microsoft XPS Document Writer");
if(service!=null){
try{
File outputFile = new File(dataform.format(data)+"-Recibo"+nmrRec+".xps");
Doc doc = new SimpleDoc(new myReceipt(), DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
attributes.add(new Destination(outputFile.toURI()));
DocPrintJob job = service.createPrintJob();
job.print(doc, attributes);
} catch(Exception e){
System.out.println("kaboom"+e);
}
}
else{
System.out.println("XPS Printer not found");
}
And there's my receipt class:
class myReceipt implements Printable{
#Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
String temp;
if (page > 0) { /* We have only one page, and 'page' is zero-based */
return NO_SUCH_PAGE;
}
/* User (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());
int lineSize=20;
Font testFont=new Font("Lucida Console", Font.BOLD, 20);
// font name, style (0 for Plain), font size
g.setFont(testFont);
int line=20;
g.drawString(" Fatura/Recibo nº"+nmrRec+" ", 5, line);
return PAGE_EXISTS;
}
}
I have a Print Button in my SWT TitleAreaDialog.
viewPDFButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
try {
startPdfPrintOperation();
}
catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
I am getting a existing PDF filename and path from a user selection from a table.
I am then wantinf to print the pdf file out to a local printer. The user needs to be allowed to select the local printer of choice.
public void startPdfPrintOperation() throws Exception {
File file = new File(getPDFFileName());
RandomAccessFile raf;
raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
pdfFile = new PDFFile(buf);
PDFPrintPage pages = new PDFPrintPage(pdfFile);
// Create Print Job
pjob = PrinterJob.getPrinterJob();
pjob.setPrintable(new MyPrintable());
final HashPrintRequestAttributeSet attset;
attset = new HashPrintRequestAttributeSet ();
attset.add (new PageRanges (1, pdfFile.getNumPages ()));
if (pjob.printDialog (attset)) {
try {
pjob.print (attset);
}
catch (PrinterException e) {
e.printStackTrace();
}
}
}
class MyPrintable implements Printable {
public int print (Graphics g, PageFormat format, int index) throws PrinterException {
int pagenum = index+1;
if (pagenum < 1 || pagenum > pdfFile.getNumPages ())
return NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) g;
AffineTransform at = g2d.getTransform ();
PDFPage pdfPage = pdfFile.getPage (pagenum);
Dimension dim;
dim = pdfPage.getUnstretchedSize ((int) format.getImageableWidth (),
(int) format.getImageableHeight (),
pdfPage.getBBox ());
Rectangle bounds = new Rectangle ((int) format.getImageableX (),
(int) format.getImageableY (),
dim.width,
dim.height);
PDFRenderer rend = new PDFRenderer (pdfPage, (Graphics2D) g, bounds, null, null);
try
{
pdfPage.waitForFinish ();
rend.run ();
}
catch (InterruptedException ie)
{
MessageDialog.openError(null, "PDF Error Message", "Needs");
}
g2d.setTransform (at);
g2d.draw (new Rectangle2D.Double (format.getImageableX (),
format.getImageableY (),
format.getImageableWidth (),
format.getImageableHeight ()));
return PAGE_EXISTS;
}
}
I am getting the above error from line 315
if (pjob.printDialog (attset)) {
The printer dialog opens the entire application is frozen and goes unresponsive. Then in about 30 secs, I get the above error.
I have tried to use Display.getDefault().asyncExec(new Runnable() ) in multiple spots but that did not help.
Could it be because the base dialog is SWT and the printer dialog is AWT?
Since you didn't define "in multiple spots", I would suggest you refactor the print job in its own class, extends Thread and implement starting the print job in the run method.
I'm not familiar with all classes in above code, you can try simply starting this thread and it will run in parallel with the SWT thread. Try avoiding shared ressources, this may help resolving your deadlock. If you want to have a UI response from this thread, you can wrap e.g. the SWT messagebox ("Printing done!") in a call to Display.getDefault().asyncExec(new Runnable() { ... }.
Furthermore, please test if the printing code without UI code produces the same exception. If it does, the environment may be misconfigured.