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;
}
Related
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();
}
}
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.
This question already has answers here:
Connecting and printing to a printer in Java
(4 answers)
Closed 9 years ago.
Basically i m creating a java standalone application where a student first gives his entire details.
when the print button is clicked i want to print some of the data given by the student in a specified format
like:
//logo goes here
regn no:
regn date:
name:
phnno:
mail:
how to do it??
If you want to do printing with Java with any kind of formatting instead of plain text, you need to use javax.print. It is quite similar to the 2D graphics.
Have a look at the official tutorial at http://docs.oracle.com/javase/tutorial/2d/printing/ to learn how to do it.
From http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/2d/printing/examples/HelloWorldPrinter.java (untested):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.print.*;
public class HelloWorldPrinter implements Printable, ActionListener {
public int print(Graphics g, PageFormat pf, int page) throws
PrinterException {
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());
/* Now we perform our rendering */
g.drawString("Hello world!", 100, 100);
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
}
public static void main(String args[]) {
UIManager.put("swing.boldMetal", Boolean.FALSE);
JFrame f = new JFrame("Hello World Printer");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
JButton printButton = new JButton("Print Hello World");
printButton.addActionListener(new HelloWorldPrinter());
f.add("Center", printButton);
f.pack();
f.setVisible(true);
}
}
This question already has answers here:
How can I print a single JPanel's contents?
(3 answers)
Closed 9 years ago.
I have a JPanel, with some components like buttons, labels, table, etc.
What I want to do is to add a functionality (a jButton), that clicking on that button directs me to print the whole panel, along with labels and components.
Please help.
Just make a JButton that calls this code:
public void printComponent() {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setJobName(" Print Component ");
pj.setPrintable (new Printable() {
public int print(Graphics pg, PageFormat pf, int pageNum) {
if (pageNum > 0) return Printable.NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) pg;
g2.translate(pf.getImageableX(), pf.getImageableY());
componenet_name.paint(g2);
return Printable.PAGE_EXISTS;
}
});
if (pj.printDialog() == false) return;
try {
pj.print();
} catch (PrinterException ex) {
// handle exception
}
}
(taken from: How can I print a single JPanel's contents?)
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;
}
}