Java AWT打印调用两次问题

3
我是Java打印的新手。我开始打印一页数据,一切正常。现在我开始测试如何分页我的数据。我有一个实现Printable接口的类,并且我有一个int变量(curLine)来保持我已经打印的行数,还有一个变量lines来保持我最终要打印的总数。在public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)方法中,当我使用graphics.drawString(...);方法绘制一行时,我增加度量值(curLine++),但在打印机上,我没有得到想要的结果。我认为print方法针对特定的indexPage被调用了两次,在这两次调用中,数据只打印了一次,但curLine变量在这两次调用中也增加了,导致输出“丢失”的行。

更具体地说,我的测试类是

public class PrintTest implements Printable {

private final int marginTop = 20;
private final int marginLeft = 10;
private Font mainFont = new Font("Verdana", Font.PLAIN, 10);
private Font bigFont = new Font("Verdana", Font.PLAIN, 14);
private int lines;
private int curLine;

private boolean finish = false;

public PrintTest() {
    curLine = 0;
    lines = 160;
}

public static void main(String[] args) {
    PrinterJob job = PrinterJob.getPrinterJob(); // Use default printer
    job.printDialog();
    PrintTest t = new PrintTest();
    job.setPrintable(t);
    try {
        job.print();
    } catch (PrinterException e) {
        e.printStackTrace();
    }

}

@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
        throws PrinterException {
    //if printed all rows then return no_such_page
    if (finish) {
        return NO_SUCH_PAGE;
    }

    Graphics2D g2 = (Graphics2D) graphics;

    double pageH = pageFormat.getImageableHeight();
    g2.setFont(mainFont);
    int t = g2.getFontMetrics().charWidth('T');
    int lineH = g2.getFontMetrics().getHeight();

    double curY;

    g2.translate(pageFormat.getImageableX() + marginLeft,
            curY = pageFormat.getImageableY() + marginTop);

    while ((curY < (pageH - lineH)) && (curLine < lines)) {
        g2.translate(0, lineH);
        g2.drawString("Print row number #" + curLine, 0, 0);
        curY += lineH;
        curLine++;
    }

    if (curLine >= lines) {
        finish = true;
    }

    return PAGE_EXISTS;

}

您可以在此处查看输出结果:https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0ByN6KrI39kzuMTRmZDA5NTMtOGJjZi00ZmRhLThlYWYtMzUwNzE0NTdkMjcz&hl=en&authkey=CLa-svAG

您可以看到它并没有从第0行开始。


你可以将你的解决方案发布为答案并接受它,这样就可以摆脱标题中的 [已解决]。 - Alberto Zaccagni
为了消除持久状态“未解决” - user unknown
@alberto-zaccagni 这就是我想做的,但我没有看到任何回复自己问题的选项,可能是我没有权限。所以我决定编辑我的问题,将其添加为评论。如果存在更好的发布解决方案的方法(以帮助其他遇到相同问题的用户),请告诉我。谢谢。 - javment
2个回答

1

注意:这个解决方案最初是由问题的提问者提供的。

public class PrintTest implements Printable {

    private final int marginTop = 20;
    private final int marginLeft = 10;
    private Font mainFont = new Font("Verdana", Font.PLAIN, 10);
    private Font bigFont = new Font("Verdana", Font.PLAIN, 14);
    private int lines;

    private int headerHeighInLines = 5;
    private int lineH = -1;
    private double pageH = -1;
    private int pages = -1;

    private boolean finish = false;

    public PrintTest() {

        lines = 30;// set the total number of rows we want to print
    }

    public static void main(String[] args) {
        PrinterJob job = PrinterJob.getPrinterJob(); // Use default printer
        job.printDialog();
        PrintTest t = new PrintTest();
        job.setPrintable(t);
        try {
            job.print();
        } catch (PrinterException e) {
            e.printStackTrace();
        }

    }

    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {

        // if printed all pages then no_such_page
        if (pageIndex >= getPages()) {
            return NO_SUCH_PAGE;
        }

        Graphics2D g2 = (Graphics2D) graphics;
        AffineTransform defaultTransform = g2.getTransform();
        if (pageH == -1) {

            pageH = pageFormat.getImageableHeight();

        }
        g2.setFont(mainFont);
        int charW = g2.getFontMetrics().charWidth('T');
        if (lineH == -1) {
            lineH = g2.getFontMetrics().getHeight();
        }

        double curY;

        g2.translate(pageFormat.getImageableX() + marginLeft, curY = pageFormat.getImageableY() + marginTop);

        // if we have the first page we can print a title
        // or a description
        if (pageIndex == 0) {
            g2.translate(0, lineH * headerHeighInLines);
        }

        int[] res = getNumLines(pageIndex);

        for (int i = res[0]; i < res[1]; i++) {
            g2.translate(0, lineH);
            g2.drawString("Print row number #" + i, 0, 0);
        }

        // code to add the page number at footer
        g2.setTransform(defaultTransform);
        g2.drawString("page #" + (pageIndex + 1), (int) (pageFormat.getImageableWidth() - charW * 9),
                (int) (pageFormat.getImageableHeight() - (double) lineH / 2));

        return PAGE_EXISTS;

    }

    /**
     * 
     * @param pageIndex
     * @return an int array with contains two values, the num of row to start
     *         printing and the num of row to finish the printing in the
     *         specific pageindex
     */
    public int[] getNumLines(int pageIndex) {

        int[] res = new int[2];

        if (pageIndex == 0) {
            res[0] = 0;
            res[1] = firstPageLines();
            return res;
        }
        double tmpH = pageH - 2 * marginTop;
        double numlines = (double) (tmpH / lineH);
        res[0] = (int) (firstPageLines() + (pageIndex - 1) * numlines);
        res[1] = (int) Math.min((res[0] + numlines), lines + 1);

        return res;
    }

    public int firstPageLines() {
        double tmpPageH = pageH - 2 * marginTop - lineH * headerHeighInLines;
        // return the minumum of expected lines to print and the total number of
        // lines
        return (int) Math.min((tmpPageH / lineH), lines + 1);
    }

    /**
     * 
     * @return int the total number of pages to print
     */
    public int getPages() {
        if (firstPageLines() >= lines) {
            return 1;
        }
        // we substract the lines in the first page
        // because may will be less than in the number of
        // line in the other pages
        // later we increase the total nubmer of pages with 1 for the first page
        int tmpLines = lines - firstPageLines();

        int[] tmp = getNumLines(1);
        int linePerPage = tmp[1] - tmp[0];
        pages = tmpLines / linePerPage;
        if (tmpLines % linePerPage > 0) {
            pages++;
        }
        pages++;

        return pages;
    }
}

0

现在我明白了为什么...问题在于,即使你让它在纸张的一侧打印,print中的每个pageIndex都会被使用两次。我有几行数据,我的程序每次进入print()时都会增加pageBreak(我们开始打印每一页的行索引),因此每页打印的内容都是错误的(pageBreak增加了两次)。这就是为什么在教程示例中,它使用一个数组来包含这些索引,并使用pageIndex作为索引,因为它确保程序每次进入循环时更改数组中的同一元素,因为pageIndex是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接