Java printing stretched on Konica - Minolta PagePro printers - java

I am using JasperReports to print from my Java application. All the prints were OK for all costumers for quite a bit of time, but recently we have installed the software for couple of costumers that all have Konica Minolta PagePro 1200 or 1350W printers. And all those costumers get the same result - the printing is "stretched" - as if I printed A4 report on A5 paper. Except that I am printing A4 on A4 and on all other printers it works fine.
Does anyone have any idea what might be the cause?
This questions seems similar to https://stackoverflow.com/questions/15854722/jasper-report-printing-stretched but the workaround presented there (messing with printer paper size etc.) did not lead to desired result.
Here is an example of the print:
And this is what the print should look like (there are slighlty different data, but I guess the problem is clear)
Thanks for any suggestions.
EDIT:
The issue can be reproduced with a simple direct call to printing API:
import java.awt.*;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
/**
*
* #author MaCe
*/
public class PrintTest {
static Printable printable = new Printable() {
#Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
Graphics2D grx = (Graphics2D)graphics;
grx.drawLine(20,20, getPageWidth() / 2, 20);
return Printable.PAGE_EXISTS;
}
};
protected static int getPageWidth() {
//width of A4 in 1/72 of inches
return 595;
}
protected static int getPageHeight() {
//height of A4 in 1/72 of inches
return 842;
}
public static void main(String args[]) throws PrinterException {
Frame f = new Frame();
f.show();
//Build a buggy print job using PrinterJob class
PrinterJob printJob = PrinterJob.getPrinterJob();
/**
* Fix for bug ID 6255588 from Sun bug database
*/
try {
printJob.setPrintService(printJob.getPrintService());
} catch (PrinterException e) {
}
PageFormat pageFormat = printJob.defaultPage();
Paper paper = pageFormat.getPaper();
printJob.setJobName("Buggy output");
pageFormat.setOrientation(PageFormat.PORTRAIT);
paper.setSize(getPageWidth() , getPageHeight());
paper.setImageableArea(
0,
0, getPageWidth(), getPageHeight());
pageFormat.setPaper(paper);
Book book = new Book();
book.append(printable, pageFormat, 1);
printJob.setPageable(book);
if (printJob.printDialog()) {
printJob.print();
}
//Build a good print job using PrintJob class
PrintJob pjob = f.getToolkit().getPrintJob(f, "Good output", null);
if (pjob!=null) {
Graphics g = pjob.getGraphics();
g.drawLine(20, 20, pjob.getPageDimension().width / 2, 20);
pjob.end();
}
System.exit(0);
}
}
Now this code produces two prints that on most printers both print a line from the top left corner of the paper to the middle of the paper. However on the aforementioned printers the first print creates a thick line across the whole paper (200% scale) - the second variant is however OK even on Minolta printers.
Seems like a Java bug, since all other programs print normally with the printer. The bug was accepted by Sun, but closed as they could not get their hands on the correct printer (https://bugs.openjdk.java.net/browse/JDK-804159)

Is your platform windows/mac/linux?
I've had trouble with printing with label printers when the print job's media hint did not communicate fully through to the driver. Its actually very similar to your problem, stretched prints, skipped pages etc,.
I dont know if you have code to modify, but we had to switch to System Printing instead of Java Printing. Then with the System Printing settings, (windows spooler in my case), I had to create a printer with the exact driver settings needed to print properly. Its rarely anything you can really do in JasperReports other than specify the width/height/orientation.
I assume your report prints fine when saved to PDF, then print from a PDF Viewer.

I have found a workaround to the problem. The solution is to scale the graphics to half before printing. This is not easy to do with JasperReports, as the graphics object is not exposed anywhere. However, my app uses #AspectJ so I managed to fiddle with the graphics through a custom aspect:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class JRMinoltaAspect {
#Before("execution(int net.sf.jasperreports.engine.print.JRPrinterAWT.print(java.awt.Graphics, java.awt.print.PageFormat , int )) && args(g, pf, ..)")
public void scalePrint(Graphics g, PageFormat pf){
if(pf.getOrientation() == PageFormat.LANDSCAPE){
g.translate(0, (int)pf.getHeight() / 2 );
}
((Graphics2D)g).scale(0.5, 0.5);
}
}

Related

BufferedImage TYPE_BYTE_BINARY change color of pixel

I have been struggling to find and answer to this issue. I am trying to change the color of a pixel in a large BufferedImage with the imageType of TYPE_BYTE_BINARY. By default when I create the image it will create a black image which is fine but I cannot seem to be able to change pixel color to white.
This is the basic idea of what I want to do.
BufferedImage bi = new BufferedImage(dim[0], dim[1], BufferedImage.TYPE_BYTE_BINARY);
bi.setRBG(x, y, 255)
This seems weird to me as a TYPE_BYTE_BINARY image will not have RGB color, so I know that that is not the correct solution.
Another idea that I had was to create multiple bufferedImage TYPE_BYTE_BINARY with the createGraphics() method and then combine all of those buffered images into one large bufferedImage but I could not find any information about that when using the TYPE_BYTE_BINARY imageType.
When reading up on this I came across people saying that you need to use createGraphics() method on the BufferedImage but I don't want to do that as it will use up too much memory.
I came across this link http://docs.oracle.com/javase/7/docs/api/java/awt/image/Raster.html specifically for this method createPackedRaster()(the second one). This seems like it might be on the right track.
Are those the only options to be able to edit a TYPE_BYTE_BINARY image? Or is there another way that is similar to the way that python handles 1 bit depth images?
In python this is all that needs to be done.
im = Image.new("1", (imageDim, imageDim), "white")
picture = im.load()
picture[x, y] = 0 # 0 or 1 to change color black or white
All help or guidance is appreciated.
All works. I am able to get a white pixel on the image.
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.awt.Color;
import java.io.File;
public class MakeImage
{
public static void main(String[] args)
{
BufferedImage im = new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_BINARY);
im.setRGB(10, 10, Color.WHITE.getRGB());
try
{
ImageIO.write(im, "png", new File("image.png"));
}
catch (IOException e)
{
System.out.println("Some exception occured " + e);
}
}
}

Java. Estimation of total number of printing pages

I have question how to check how many pages will be printed when i use my own Printable class.
I need it, because i want to have "page_number/total_pages" in footer of each page.
In my case problem with estimation of rows is that rows are wrapped. Additionaly the are empty rows beetwen some of the lines of text and there are some other cases which can prevent regular spreading of text. Generally this is not uniform printing.
As you know, rendering process is done after calling all print dialog windows.
Is any way to deal with this issue or should i somehow launch printing simulation , to receieve real number of pages? Or maybe should i implement some other class?
Regards
You can use following to get no. of pages:
int linesPerPage; // No. of lines per Page to be drawn.
static int numPages; // No. of pages too be rendered.
public int getNumberOfPages() // Override method to get Number Of Pages.
{
return numPages;
}
in main..
linesPerPage = (int)Math.floor(format.getImageableHeight()/linespacing);
numPages = (DATA_to_Print.length - 1)/linesPerPage + 1;
in override print method..
if ((pagenum < 0) | (pagenum >= numPages))
{
return NO_SUCH_PAGE;
}
Each time when print method will be call, value of the numPages will increment.
I figured out how to do it. Maybe this is no elegant, but it works (i tested estimation with document with 1200 pages and estimation is accurate). I will show you rather concept supported with couple line of code because my Printable classes are complex.
This is class which calls all operations connected with printing:
package print_manager;
import icd_searcher.ResultContainer;
import java.awt.Point;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import others.MeasuredBox;
public class PrintManager
{
private PrinterJob printerJob;
private SimpleResultPrinter srp;
/**
* Print printable object.
*
* #param toPrint
*/
public void initPrint(ResultContainer resultToPrint)
{
printerJob = PrinterJob.getPrinterJob();
PageFormat selectedArea = printerJob.pageDialog(printerJob.defaultPage());
MeasuredBox margin = new MeasuredBox(new Point((int) selectedArea.getImageableX(), (int) selectedArea.getImageableY()), (int) selectedArea.getImageableWidth(), (int) selectedArea.getImageableHeight() - 72);
srp = new SimpleResultPrinter(resultToPrint, margin);
SimpleResultPrinterSimulator srpSimulation = new SimpleResultPrinterSimulator(resultToPrint, margin);
// total pages simulation
int totalPages = 0;
try
{
while (srpSimulation.print(selectedArea, totalPages) != Printable.NO_SUCH_PAGE)
{
totalPages++;
}
}
catch (PrinterException e)
{
e.printStackTrace();
}
printerJob.setPrintable(srp, widenedPage);
if (printerJob.printDialog())
{
try
{
printerJob.print();
}
catch (PrinterException exc)
{
System.out.println(exc);
}
}
}
}
Method print in SimpleResultPrinter
public int print(Graphics g, PageFormat page, int pageIndex) throws
PrinterException {...}
Method print in SimpleResultPrinterSimulator
public int print(PageFormat page, int pageIndex) throws PrinterException
{...}
You need to know about this:
MeasuredBox and ResultContainer are my custom classes that have no meaning in this conception - treat them as a "some classes".
Class SimpleResultPrinter which is Printable has method print(...) which is called by printerJob.print().
SimpleResultPrinterSimulator has the same method print(...) like SimpleResultPrinter except there is no draw actions in it for better performance and of course SimpleResultPrinterSimulator has only this method. Also SimpleResultPrinterSimulator extends Component because i need Graphics object to measure font height.
My solution is just to launch simulation of printing and print(...) makes the same actions like will be done soon during printing except of real drawing to any Graphics object. Finally i recieves total number of pages.
I know this is not elegant and i make the same action twice (lost of performance), but i don't see any other way to estimate number of pages in complex printing.

Printing Mathematical Symbols in Java Gives Wrong Output

I am trying to print using the TextLayout class. When I print some mathematical symbols, I get odd behavior.
The image below shows the results from printing the strings "First + 2" and "First \u222A 2" to a PDF file. When the 'union' symbol (\u222A) is printed, it looks like characters following the symbol overwrite characters before the symbol.
Here is the test code that prints a string that does not contain \u222A and another string that does:
public class PrintTest {
public static void main(String[] args) {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new Printable() {
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex != 0) return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
Font font = new Font("SansSerif", Font.PLAIN, 10);
// Draw string with + char
TextLayout layout = new TextLayout("First + 2", font, g2
.getFontRenderContext());
layout.draw(g2, 40, 80);
// Draw string with union character
layout = new TextLayout("First \u222A 2", font, g2
.getFontRenderContext());
layout.draw(g2, 40, 100);
return PAGE_EXISTS;
}
});
if (pj.printDialog()) {
try {
pj.print();
} catch (PrinterException e) {
System.out.println(e.getMessage());
}
}
}
}
I am running java 1.7.0_17 on Windows 7 & 8, and have tested this on several printers, including printing to PDF. All tests show the same problem. I get the same results with 'union', 'intersection' and 'exclusion' symbols.
I am really stuck here. Any help would be greatly appreciated.
UPDATE: The problem seems to occur when using logical fonts. I tested with all of the installed logical fonts ('Dialog', 'DialogInput', 'Monospaced, 'SansSerif' and 'Serif') and got the same problem. When I tested with physical fonts that support these symbols ('Lucida Sans' and 'Arial Unicode MS') I got the desired output.
This resolves the immediate issue for me since I'm not tied to using logical fonts.
Actually, you are printing Unicode characters all the time; the title of your post suggests you are printing something other than Unicode. All the alphabetic characters that you print correctly are encoded in Unicode, since that is how Java encodes strings.
So you are trying to print the "Union" symbol, and it isn't working. What evidence do you have that it is supported on the printer you are printing on? It is quite possibly not supported on any printer you've tried, hence unpredictable behavior. It is the most obvious thing that could cause this.

how to create and print form using java

maybe someone can give hand of help and tell how to create and print form
like this:
using java.
Also, it should be filled with needed information.
java.awt.print - Java 2D printing, since JDK 1.2
javax.print - aka the Java Print Service (JPS) API, since JDK 1.4
from http://java.sun.com/javase/technologies/desktop/printing/
I think you need a bit of googling - it looks like a very trivial task.
If you are using Swing, the follow the procedure below:
For A4 setting:
Use a JFrame of approx. 750 px. X 960 px.
In the Window use JLabels, JTextFields and JTextAreas to Design the template.
Also do add a print button anywhere on the window (to initiate the print command).
Now when all designing is complete, in the code window of the button action event, simply
add:
<Button Name>.setVisible(false);
<PanelName>.print();
First one will hide the Button, second will actually present you with a print dialog.
Additionally, use Netbeans IDE to save time in designing. It is a great time saver in the designing, compiling and testing grounds.
Please revert back for any doubts, Hope the information is helpful.
If you need to do it in a web application, the printing should be done in javascript. But you may render the page using Java. http://shyarmal.blogspot.com/2011/08/printing-example-with-java-ee.html
If you are doing it using swing: http://shyarmal.blogspot.com/2011/08/printing-with-jeditorpane.html
A little late, but I'll leave this here for reference:
//pertinent code only
import java.awt.print
public void FilePrintClicked(){
PrinterJob job = PrinterJob.getPrinterJob();
PageFormat format = job.defaultPage();
format.setOrientation(PageFormat.LANDSCAPE);
job.setPrintable(this, format);
try{
if(job.printDialog()) job.print();
}
catch(Exception e){e.printStackTrace();}
}
public int print(Graphics g, PageFormat format, int pagenum) {
if (pagenum > 0){
return Printable.NO_SUCH_PAGE;
}
g.translate((int)format.getImageableX(), (int)format.getImageableY());
float pageWidth = (float)format.getImageableWidth();
float pageHeight = (float)format.getImageableHeight();
float imageHeight = (float)this.getHeight();
float imageWidth = (float)this.getWidth();
float scaleFactor = Math.min((float)pageWidth/(float)imageWidth, (float)pageHeight/(float)imageHeight);
int scaledWidth = (int)(((float)imageWidth)*scaleFactor);
int scaledHeight = (int)(((float)imageHeight)*scaleFactor);
BufferedImage canvas = new BufferedImage( this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D gg = canvas.createGraphics();
this.paint( gg );
Image img = canvas ;
g.drawImage(img, 0, 0, scaledWidth, scaledHeight, null );
return Printable.PAGE_EXISTS;
}
Note: Your class needs to implement Printable
It's a little dirty, but it's rather old code from when I was learning Java and I didn't double-check it as I posted it here, but it's working in my application so.....

Mouse shows color

i am trying to make an application which would show which color my mouse is pointing to, i dont mean in my own application but anywhere in windows on any screen, kind of like a tag beside my mouse pointer which shows the exact color.
I am a Java developer but i dont think this could be done in java i am thinking maybe i need some sort of script but i have no idea any help would be really appriciated
The solution consists of two parts:
Part 1: Retrieving the color:
Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
Color color = new Robot().getPixelColor(mouseLocation.x, mouseLocation.y);
Part 2: Getting the color name:
You can get a list of many colors and their names from Wikipedia's List of colors. You can create a mapping in Java given the data on Wikipedia.
Perhaps you can start with a few colors, and provide a generic hex representation for unknown colors, for example #rrggbb.
Here is the runnable example,
import java.awt.AWTException;
import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
public class Main {
public static String getHexString(int rgb) {
String hexString = Integer.toHexString(rgb);
hexString = hexString.length() > 1 ? hexString : "0" + hexString;
return hexString;
}
public static void main(String[] a) throws AWTException {
Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
Color color = new Robot().getPixelColor(mouseLocation.x,
mouseLocation.y);
System.out.println(getHexString(color.getRed())
+ getHexString(color.getGreen())
+ getHexString(color.getBlue()));
}
}
Take your pick: http://rosettacode.org/wiki/Color_of_a_screen_pixel
There is a Java/AWT example, an AutoHotKey is a simple scripted option.
The second C example shows the 3 API calls you need GetDC/GetCursorPos/GetPixel and their support code, these can be used from most languages that compile for windows.

Categories