1

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 の paperSize は通常の 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;
    }

}

イベントプリント.JAVA

public class EventPrint extends PrintableBase implements Printable {

    private Event event;

    public EventPrint(Event event) {
        this.event = event; 
    }

    @Override
    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;                 
}
4

2 に答える 2

3

あなたの問題は、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;                 
}

したがって、1 ページだけを印刷したい場合は、次のようなものを使用できます...

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は、本の各ページが 1 回だけ印刷され、すべてのページが印刷されるまで続くという点で、異なるアプローチを使用します。 Printable停止するまで印刷を続けます。

詳細については、基本的な印刷プログラムをご覧ください。

于 2015-02-12T21:51:08.733 に答える