Java PrintJob到DocPrintJob不工作?
我有一个从Printable扩展而来的类,它使用标准的PrintJob可以很好地打印,但是我想转到DocPrintJob,这样我就可以监听打印的状态(成功打印等) 我当前的代码如下所示,用于创建打印作业并打印Java PrintJob到DocPrintJob不工作?,java,swing,printing,javafx,java-print,Java,Swing,Printing,Javafx,Java Print,我有一个从Printable扩展而来的类,它使用标准的PrintJob可以很好地打印,但是我想转到DocPrintJob,这样我就可以监听打印的状态(成功打印等) 我当前的代码如下所示,用于创建打印作业并打印 // define printer AttributeSet attributes = new HashAttributeSet(); attributes.add(new Copies(1)); // get printerJob PrinterJob printJob = Print
// define printer
AttributeSet attributes = new HashAttributeSet();
attributes.add(new Copies(1));
// get printerJob
PrinterJob printJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = printJob.defaultPage();
// sizing (standard is 72dpi, so multiple inches by this)
Double height = 8d * 72d;
Double width = 3d * 72d;
Double margin = 0.1d * 72d;
// set page size
Paper paper = pageFormat.getPaper();
paper.setSize(width, height);
paper.setImageableArea(margin, margin, width - (margin * 2), height - (margin * 2));
// set orientation and paper
pageFormat.setOrientation(PageFormat.PORTRAIT);
pageFormat.setPaper(paper);
// create a book for printing
Book book = new Book();
book.append(new EventPrint(args.getEvent()), pageFormat);
// set book to what we are printing
printJob.setPageable(book);
// set print request attributes
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(OrientationRequested.PORTRAIT);
// now print
try {
printJob.print();
} catch (PrinterException e) {
e.printStackTrace();
}
现在要将其转换为DocPrintJob,我遵循了链接,该链接告诉我如何从PrintJob转换为DocPrintJob。所以现在我的代码变成了这个
PrintService[] services = PrinterJob.lookupPrintServices(); //list of printers
PrintService printService = services[0];
DocFlavor[] flavours = printService.getSupportedDocFlavors();
// may need to determine which printer to use
DocPrintJob printJob = printService.createPrintJob();
// get out printable
EventPrint eventPrint = new EventPrint(args.getEvent());
// convert printable to doc
Doc doc = new SimpleDoc(eventPrint, DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);
// add eventlistener to printJob
printJob.addPrintJobListener(new PrintJobListener() {
@Override
public void printDataTransferCompleted(PrintJobEvent pje) {
Console.Log("Print data sent successfully");
}
@Override
public void printJobCompleted(PrintJobEvent pje) {
Console.Log("Print successful");
}
@Override
public void printJobFailed(PrintJobEvent pje) {
Console.Log("Print failed");
}
@Override
public void printJobCanceled(PrintJobEvent pje) {
Console.Log("Print cancelled");
}
@Override
public void printJobNoMoreEvents(PrintJobEvent pje) {
Console.Log("No more printJob events");
}
@Override
public void printJobRequiresAttention(PrintJobEvent pje) {
Console.Log("printJob requires attention");
}
});
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Copies(1));
try {
printJob.print(doc, aset);
} catch (Exception e) {
}
现在由于某种原因,我的打印一直在执行(400多次,直到我关闭应用程序)。我不确定这是否是因为我可能没有像使用PrintJob时那样设置纸张大小?这会导致它吗?如果是这样,我如何设置DocPrintJob的纸张大小,因为它没有普通printJob的方法
以前还有其他人面临过这个问题吗
编辑:这是我的eventPrint类及其继承的类
PRINTABLEBASE.JAVA
public class PrintableBase {
public Graphics2D g2d;
public float x, y, imageHeight, imageWidth, maxY;
public enum Alignment { LEFT, RIGHT, CENTER };
public void printSetup(Graphics graphics, PageFormat pageFormat) {
// 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
g2d = (Graphics2D) graphics;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
// get starter X and Y
x = 0;//(float)pageFormat.getImageableX();
// do not offset vertical as pushes ticket down too much
y = 0;//(float)pageFormat.getImageableY();
// get height and width of the printable image
imageWidth = (float)pageFormat.getImageableWidth();
imageHeight = (float)pageFormat.getImageableHeight();
// maximum that we can go vertically
maxY = y;
Console.Log("imageWidth:" + imageWidth);
Console.Log("imageHeight: " + imageHeight);
Console.Log("X: " + x);
Console.Log("Y: " + y);
}
public void setFont(Font font) {
g2d.setFont(font);
}
public float addSeparatorLine(float y, float imageWidth) {
String fontName = g2d.getFont().getName();
int fontStyle = g2d.getFont().getStyle();
int fontSize = g2d.getFont().getSize();
g2d.setFont(new Font("Arial", Font.PLAIN, 10));
y = drawFirstLine(g2d, "---------------------------------------------------------------------------------------", imageWidth, 0, y, Alignment.LEFT);
// revery font
g2d.setFont(new Font(fontName, fontStyle, fontSize));
return y + 5;
}
public BufferedImage scaleImage(BufferedImage sbi, int dWidth, int dHeight) {
BufferedImage dbi = null;
if(sbi != null) {
// calculate ratio between standard size and scaled
double wRatio = (double)dWidth / (double)sbi.getWidth();
double hRatio = (double)dHeight / (double)sbi.getHeight();
// use wRatio by default
double sWidth = (double)sbi.getWidth() * wRatio;
double sHeight = (double)sbi.getHeight() * wRatio;
// if hRation is small, use that, as image will be reduced by more
if (hRatio < wRatio) {
sWidth = (double)sbi.getWidth() * hRatio;
sHeight = (double)sbi.getHeight() * hRatio;
}
double sRatio = (wRatio < hRatio) ? wRatio : hRatio;
// now create graphic, of new size
dbi = new BufferedImage((int)sWidth, (int)sHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = dbi.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(sRatio, sRatio);
g.drawRenderedImage(sbi, at);
}
return dbi;
}
// This function will only add the first line of text and will not wrap
// useful for adding the ticket title.
// Returns the height of the text
public float drawFirstLine(Graphics2D g2, String text, float width, float x, float y, Alignment alignment) {
AttributedString attstring = new AttributedString(text);
attstring.addAttribute(TextAttribute.FONT, g2.getFont());
AttributedCharacterIterator paragraph = attstring.getIterator();
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g2.getFontRenderContext();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
// Set break width to width of Component.
float breakWidth = width;
float drawPosY = y;
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
// Get lines until the entire paragraph has been displayed.
if (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout. A cleverer program would also cache
// these layouts until the component is re-sized.
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position.
float drawPosX;
switch (alignment){
case RIGHT:
drawPosX = (float) x + breakWidth - layout.getAdvance();
break;
case CENTER:
drawPosX = (float) x + (breakWidth - layout.getAdvance())/2;
break;
default:
drawPosX = (float) x;
}
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g2, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
return drawPosY;
}
/**
* Draw paragraph.
*
* @param g2 Drawing graphic.
* @param text String to draw.
* @param width Paragraph's desired width.
* @param x Start paragraph's X-Position.
* @param y Start paragraph's Y-Position.
* @param dir Paragraph's alignment.
* @return Next line Y-position to write to.
*/
protected float drawParagraph (String text, float width, float x, float y, Alignment alignment){
AttributedString attstring = new AttributedString(text);
attstring.addAttribute(TextAttribute.FONT, g2d.getFont());
AttributedCharacterIterator paragraph = attstring.getIterator();
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g2d.getFontRenderContext();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
// Set break width to width of Component.
float breakWidth = width;
float drawPosY = y;
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
// Get lines until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout. A cleverer program would also cache
// these layouts until the component is re-sized.
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position.
float drawPosX;
switch (alignment){
case RIGHT:
drawPosX = (float) x + breakWidth - layout.getAdvance();
break;
case CENTER:
drawPosX = (float) x + (breakWidth - layout.getAdvance())/2;
break;
default:
drawPosX = (float) x;
}
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g2d, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
return drawPosY;
}
}
从
PrinterJob
切换到DocPrintJob
时,我也遇到了一些问题。您的代码对我来说似乎很好,所以您的页面大小可能是正确的。您可以按如下方式设置页面大小:
aset.add(new MediaPrintableArea(0, 0, width, height, MediaPrintableArea.MM));
但这取决于可打印对象的设置方式。我用iText创建了一个bytearray(PDF),并在那里设置了页面大小。然后,我将上述代码中的宽度和高度设置为Integer.MAX\u VALUE
我可以在回家后把我的全部密码都发出去。希望有帮助 我想说,您的问题是,您从未告诉API不再有页面
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
// setup
super.printSetup(graphics, pageFormat);
// title
super.setFont(new Font("Tahoma", Font.BOLD, 16));
y = super.drawParagraph(event.getTitle(), imageWidth, x, y, Alignment.LEFT);
RETURN PAGE_EXISTS;
}
所以,假设你只想打印一页,你可以使用像
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
int result = NO_SUCH_PAGE;
if (pageIndex == 0) {
// setup
super.printSetup(graphics, pageFormat);
// title
super.setFont(new Font("Tahoma", Font.BOLD, 16));
y = super.drawParagraph(event.getTitle(), imageWidth, x, y, Alignment.LEFT);
result = PAGE_EXISTS;
}
RETURN result;
}
否则API不知道何时停止打印
Bookable
使用了一种不同的方法,即每本书的每一页只打印一次,并将继续打印,直到打印完所有页面<代码>可打印不同,它将继续打印,直到您告诉它停止为止
查看更多详细信息您在哪里
EventPrint
class?现在已经包括EventPrint类对不起,attrs是aset。编辑了我的答案。谢谢你的关注!添加了这个,但仍然不起作用。虽然打印现在是正确的,但它只是保持打印和打印,打印很好,听到打印更好。你能告诉我你的输入是什么样的吗?我现在已经添加了eventPrint类以及伟大的回答狂程序员,我同意你的看法!
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
int result = NO_SUCH_PAGE;
if (pageIndex == 0) {
// setup
super.printSetup(graphics, pageFormat);
// title
super.setFont(new Font("Tahoma", Font.BOLD, 16));
y = super.drawParagraph(event.getTitle(), imageWidth, x, y, Alignment.LEFT);
result = PAGE_EXISTS;
}
RETURN result;
}