Using javax.print classes to print text/file

  • Thread starter Arun Kumar Srinivasan
  • Start date
A

Arun Kumar Srinivasan

Hi,
I am trying to use the javax.print classes to print some text
(currently as String, but can be modified to read it from a text
file). I am having trouble because it appears as if the printer (HP
LaserJet) doesnt seem to support printing text. I tried to use
DocFlavor.STRING.TEXT_PLAIN as well as
DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST but I got a flavor not
supported error. So, I took the selected printer and asked to display
its supported flavors (Mime type and representation class name) and
this is the result I got:

image/jpeg-->[B
image/jpeg-->java.io.InputStream
image/jpeg-->java.net.URL
image/png-->[B
image/png-->java.io.InputStream
image/png-->java.net.URL
application/x-java-jvm-local-objectref-->java.awt.print.Pageable
application/x-java-jvm-local-objectref-->java.awt.print.Printable
application/octet-stream-->[B
application/octet-stream-->java.net.URL
application/octet-stream-->java.io.InputStream

The code snippet I am using is:
try
{
PrintService
defaultService=PrintServiceLookup.lookupDefaultPrintService();
javax.print.attribute.PrintRequestAttributeSet attributes
= new javax.print.attribute.HashPrintRequestAttributeSet();
DocFlavor flavDoc=DocFlavor.STRING.TEXT_PLAIN;
PrintService[]
services=PrintServiceLookup.lookupPrintServices(null, null);
PrintService service = ServiceUI.printDialog(null, 50, 50,
services, defaultService, null, attributes);
if (service!=null)
{
DocFlavor[] flavs=service.getSupportedDocFlavors();
if (flavs.length==0)
System.out.println("No Flavors supported!!!");
for (int i=0; i<flavs.length; i++)
{
System.out.println(flavs.getMimeType() + "-->"
+ flavs.getRepresentationClassName());
}
String toPrint=txtResults.getText();
SimpleDoc prnDoc=new SimpleDoc(toPrint, flavDoc,
null);
DocPrintJob prnJob=service.createPrintJob();
prnJob.print(prnDoc, attributes);
}
}
catch (Exception e)
{
e.printStackTrace();
javax.swing.JOptionPane.showMessageDialog(this,
e.toString());
}

When I run the program, it runs until the last command (prnJob.print)
and there it crashes. I first tried to use the flavor as a filter for
the printservices, but found that none were returned.

Does this mean I cannot print text on my printer? Is there another
representation class/Mime Type that I can use? Or is there another way
to print text files or large strings (possibly spanning many pages of
A4 sheets) in Java?
Please let me know. I have searched the internet but have not found
much to lead me...

Thanking you in advance,
Arun Kumar Srinivasan.
 
G

Gregory A. Swarthout

Hi,
I am trying to use the javax.print classes to print some text
(currently as String, but can be modified to read it from a text
file). I am having trouble because it appears as if the printer (HP
LaserJet) doesnt seem to support printing text. I tried to use
DocFlavor.STRING.TEXT_PLAIN as well as
DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST but I got a flavor not
supported error. So, I took the selected printer and asked to display
its supported flavors (Mime type and representation class name) and
this is the result I got:

image/jpeg-->[B
image/jpeg-->java.io.InputStream
image/jpeg-->java.net.URL
image/png-->[B
image/png-->java.io.InputStream
image/png-->java.net.URL
application/x-java-jvm-local-objectref-->java.awt.print.Pageable
application/x-java-jvm-local-objectref-->java.awt.print.Printable
application/octet-stream-->[B
application/octet-stream-->java.net.URL
application/octet-stream-->java.io.InputStream

The code snippet I am using is:
try
{
PrintService
defaultService=PrintServiceLookup.lookupDefaultPrintService();
javax.print.attribute.PrintRequestAttributeSet attributes
= new javax.print.attribute.HashPrintRequestAttributeSet();
DocFlavor flavDoc=DocFlavor.STRING.TEXT_PLAIN;
PrintService[]
services=PrintServiceLookup.lookupPrintServices(null, null);
PrintService service = ServiceUI.printDialog(null, 50, 50,
services, defaultService, null, attributes);
if (service!=null)
{
DocFlavor[] flavs=service.getSupportedDocFlavors();
if (flavs.length==0)
System.out.println("No Flavors supported!!!");
for (int i=0; i<flavs.length; i++)
{
System.out.println(flavs.getMimeType() + "-->"
+ flavs.getRepresentationClassName());
}
String toPrint=txtResults.getText();
SimpleDoc prnDoc=new SimpleDoc(toPrint, flavDoc,
null);
DocPrintJob prnJob=service.createPrintJob();
prnJob.print(prnDoc, attributes);
}
}
catch (Exception e)
{
e.printStackTrace();
javax.swing.JOptionPane.showMessageDialog(this,
e.toString());
}

When I run the program, it runs until the last command (prnJob.print)
and there it crashes. I first tried to use the flavor as a filter for
the printservices, but found that none were returned.

Does this mean I cannot print text on my printer? Is there another
representation class/Mime Type that I can use? Or is there another way
to print text files or large strings (possibly spanning many pages of
A4 sheets) in Java?
Please let me know. I have searched the internet but have not found
much to lead me...

Thanking you in advance,
Arun Kumar Srinivasan.


Here is a method that will print text (and perform line-wrap on long
lines):

public static void printString(String text) {
PageFormat pageFormat = new PageFormat();
PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setPrintable(new Printable() {
public int print(Graphics graphics, PageFormat pageFormat,
int pageIndex) {
Graphics2D graphics2D = (Graphics2D)graphics;
graphics2D.translate(pageFormat.getImageableX(),
pageFormat.getImageableY());
StringTokenizer stringTokenizer = new
StringTokenizer(text, "\n\r");
Font font = new Font("Monospaced", Font.BOLD, 10);
graphics2D.setFont(font);
int pageWidth = graphics2D.getClipBounds().width;
FontMetrics fontMetrics =
graphics2D.getFontMetrics(font);
int position = fontMetrics.getHeight();
int height = fontMetrics.getAscent();
while (stringTokenizer.hasMoreTokens()) {
String line = stringTokenizer.nextToken().trim();
int lineWidth = fontMetrics.stringWidth(line);
while (lineWidth > pageWidth) {
String lineCopy = line;
String firstPart = "";
while (lineWidth > pageWidth) {
int index = lineCopy.lastIndexOf(' ');
firstPart = lineCopy.substring(0, index);
lineWidth =
fontMetrics.stringWidth(firstPart);
lineCopy = firstPart;
}
graphics2D.drawString(firstPart, 0, position);
position += height;
line = line.substring(firstPart.length(),
line.length()).trim();
lineWidth = fontMetrics.stringWidth(line);
}
graphics2D.drawString(line, 0, position);
position += height;
}
return (pageIndex == 0 ? PAGE_EXISTS : NO_SUCH_PAGE);
}
}, pageFormat);
if (printerJob.printDialog()) {
try {
printerJob.print();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
System.exit(0);
}
 
N

nos

Arun Kumar Srinivasan said:
Hi,
I am trying to use the javax.print classes to print some text
(currently as String, but can be modified to read it from a text
file). I am having trouble because it appears as if the printer (HP
LaserJet) doesnt seem to support printing text. I tried to use

Did you try (in console window or unix screen) "print abc" where abc is a
text file.
DocFlavor.STRING.TEXT_PLAIN as well as
DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST but I got a flavor not
supported error. So, I took the selected printer and asked to display
its supported flavors (Mime type and representation class name) and
this is the result I got:

image/jpeg-->[B
image/jpeg-->java.io.InputStream
image/jpeg-->java.net.URL
image/png-->[B
image/png-->java.io.InputStream
image/png-->java.net.URL
application/x-java-jvm-local-objectref-->java.awt.print.Pageable
application/x-java-jvm-local-objectref-->java.awt.print.Printable
application/octet-stream-->[B
application/octet-stream-->java.net.URL
application/octet-stream-->java.io.InputStream

The code snippet I am using is:
try
{
PrintService
defaultService=PrintServiceLookup.lookupDefaultPrintService();
javax.print.attribute.PrintRequestAttributeSet attributes
= new javax.print.attribute.HashPrintRequestAttributeSet();
DocFlavor flavDoc=DocFlavor.STRING.TEXT_PLAIN;
PrintService[]
services=PrintServiceLookup.lookupPrintServices(null, null);
PrintService service = ServiceUI.printDialog(null, 50, 50,
services, defaultService, null, attributes);
if (service!=null)
{
DocFlavor[] flavs=service.getSupportedDocFlavors();
if (flavs.length==0)
System.out.println("No Flavors supported!!!");
for (int i=0; i<flavs.length; i++)
{
System.out.println(flavs.getMimeType() + "-->"
+ flavs.getRepresentationClassName());
}
String toPrint=txtResults.getText();
SimpleDoc prnDoc=new SimpleDoc(toPrint, flavDoc,
null);
DocPrintJob prnJob=service.createPrintJob();
prnJob.print(prnDoc, attributes);
}
}
catch (Exception e)
{
e.printStackTrace();
javax.swing.JOptionPane.showMessageDialog(this,
e.toString());
}

When I run the program, it runs until the last command (prnJob.print)
and there it crashes. I first tried to use the flavor as a filter for
the printservices, but found that none were returned.

Does this mean I cannot print text on my printer? Is there another
representation class/Mime Type that I can use? Or is there another way
to print text files or large strings (possibly spanning many pages of
A4 sheets) in Java?
Please let me know. I have searched the internet but have not found
much to lead me...

Thanking you in advance,
Arun Kumar Srinivasan.
 
A

Arun Kumar Srinivasan

I tried what you said but I ran into a few problems...
1. The compiler said that the inner class (new Printable) cannot
access variable text unless text is declared final. So, instead, I
created a class ClsPrintable which implements Printable, created a
constructor that took the string (stored as a private variable) and
moved the print routine to this class.
Therefore, the statement setPrintable had arguments:
(new ClsPrintable(text), pageFormat)
After doing this, the program compiled and printed "Testing
1.2..3.." correctly.
2. In general, I have a string that has \n characters. These get
clipped because of the trim commands. I know that I cannot simply
remove the trim statement (position+=height will have to take the
number of '\n's trimmed). Is there any way to do this?
3. I am not very clear on how exactly the print method of the
Printable interface works. If someone could explain, I would be
grateful. Also, if someone can give code for doing this with
javax.print classes I would be grateful (javax classes have uniform
look and feel across platforms).
4. The reports I create generally run a few pages. Depending on
whether I am using a brief report or a detailed report generation, the
reports can run from about 3-5 pages to more than 10 pages. When I run
the code, the program prints only the first page. How can I rectify
this?
I tried the following, but printer gave 1 empty page when I run the
code:
a. Before the while (stringTokenizer.hasMoreTokens()) statment, I
added a if statement that checks if there are any more tokens and if
not, returns NO_SUCH_PAGE
b. In the while condition, I added a constrain to check if the
position is less than the page height.
c. After the while condition, I remove the ternary operator and
return PAGE_EXISTS
The Print method Code:
public int print(Graphics graphics, PageFormat pageFormat, int
pageIndex)
{
Graphics2D graphics2D = (Graphics2D)graphics;
graphics2D.translate(pageFormat.getImageableX(),
pageFormat.getImageableY());
Font font = new Font("Monospaced", Font.BOLD, 10);
graphics2D.setFont(font);
int pageWidth = graphics2D.getClipBounds().width;
int pageHeight = graphics2D.getClipBounds().height;
FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
int position = 0;
int height = fontMetrics.getAscent();
if (!stringTokenizer.hasMoreTokens())
return this.NO_SUCH_PAGE;
while (stringTokenizer.hasMoreTokens() &&
position<=pageHeight) {
position = fontMetrics.getHeight();
String line = stringTokenizer.nextToken().trim();
int lineWidth = fontMetrics.stringWidth(line);
while (lineWidth > pageWidth) {
String lineCopy = line;
String firstPart = "";
while (lineWidth > pageWidth) {
int index = lineCopy.lastIndexOf(' ');
firstPart = lineCopy.substring(0, index);
lineWidth = fontMetrics.stringWidth(firstPart);
lineCopy = firstPart;
}
graphics2D.drawString(firstPart, 0, position);
position += height;
line = line.substring(firstPart.length(),
line.length()).trim();
lineWidth = fontMetrics.stringWidth(line);
}
graphics2D.drawString(line, 0, position);
position += height;
}
return PAGE_EXISTS;
}

Thanks in advance,
Arun Kumar Srinivasan

(e-mail address removed) (Gregory A. Swarthout) wrote in message (Deleted by me to reduce message length - View thread)
 
A

Andrew Thompson

message .....
| 2. In general, I have a string that has \n characters. These
get
| clipped because of the trim commands.
.....
| String line = stringTokenizer.nextToken();
| int lineWidth =
fontMetrics.stringWidth(line.trim());

Try moving the 'trim' to the next line,
that way it is only trimmed for the
measurement, AFAIU your snippet.

HTH
 
G

Gregory A. Swarthout

I tried what you said but I ran into a few problems...
1. The compiler said that the inner class (new Printable) cannot
access variable text unless text is declared final. So, instead, I
created a class ClsPrintable which implements Printable, created a
constructor that took the string (stored as a private variable) and
moved the print routine to this class.

Sorry about that. I did a quick clean-up of a routine I use that printed
the text of the system clipboard and it got that text from within the
method, so it didn't have to be final.
Therefore, the statement setPrintable had arguments:
(new ClsPrintable(text), pageFormat)
After doing this, the program compiled and printed "Testing
1.2..3.." correctly.
2. In general, I have a string that has \n characters. These get
clipped because of the trim commands. I know that I cannot simply
remove the trim statement (position+=height will have to take the
number of '\n's trimmed). Is there any way to do this?

I'm not sure what you are asking here.
3. I am not very clear on how exactly the print method of the
Printable interface works. If someone could explain, I would be
grateful. Also, if someone can give code for doing this with
javax.print classes I would be grateful (javax classes have uniform
look and feel across platforms).
4. The reports I create generally run a few pages. Depending on
whether I am using a brief report or a detailed report generation, the
reports can run from about 3-5 pages to more than 10 pages. When I run
the code, the program prints only the first page. How can I rectify
this?

Sorry, again. I knew the system clipboard would never have more than
a page of text, so I didn't put anything in the method to print
multiple pages.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,835
Latest member
KetoRushACVBuy

Latest Threads

Top