Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PrintJob到DocPrintJob不工作?_Java_Swing_Printing_Javafx_Java Print - Fatal编程技术网

Java 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

我有一个从Printable扩展而来的类,它使用标准的PrintJob可以很好地打印,但是我想转到DocPrintJob,这样我就可以监听打印的状态(成功打印等)

我当前的代码如下所示,用于创建打印作业并打印

// 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;                 
}