打印到物理形式 - 需要基本的理解

时间:2014-10-23 15:24:45

标签: java printing

我不太确定我理解g.drawString。

我有一个写入预打印表单的程序。用户声称打印是不规则的...即,表单上的文本比先前的打印更高/更低。就我个人而言,我认为他们会错误地填写表单,但由于他们付我编写代码,我会测量表单并将尺寸转换为像素并重写处理打印的部分。

要正确打印表单,c.getCostAmount()必须打印一个像素ABOVE c.getAppraisersAmount(),使其在其下方显示一行。然而,每个后续行低于4mm(或大约15个像素)。

我的问题是我不了解垂直距离以及为什么必须将第3行放在上一行上方的像素中,以使其位于下方。

任何人都有快速简单的解释或教程/解释的链接?

非常感谢!

代码(h / t Alex,Java: Printing program output to a physical printer):

public int print(Graphics g, PageFormat pf, int page, Check c){
    final double MILLIMETER_IN_PIXELS = 3.779527559;
    DecimalFormat df = new DecimalFormat("$#.00");

    if (page > 0) {
        return NO_SUCH_PAGE;
    }

    Graphics2D g2d = (Graphics2D) g;
    int x = (int) pf.getImageableX();
    int y = (int) pf.getImageableY();
    g2d.translate(x, y + .5);

    Font font = new Font("Courier New", Font.PLAIN, 10);
    g2d.setFont(font);
    FontMetrics metrics = g.getFontMetrics(font);
    g.drawString("CHECK #" + c.getCheckNumber(), ((int) MILLIMETER_IN_PIXELS* 55),((int) MILLIMETER_IN_PIXELS*15));

    int strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getAppraisersAmount()));
    g.drawString(df.format(c.getAppraisersAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) MILLIMETER_IN_PIXELS*23));

    Date d = c.getJavaDate();
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
    g.drawString(sdf.format(d), ((int) MILLIMETER_IN_PIXELS*90), ((int) MILLIMETER_IN_PIXELS*24));

    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getCostAmount()));
    g.drawString(df.format(c.getCostAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*22)));

    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getRefundsAmount()));
    g.drawString(df.format(c.getRefundsAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*26)));        

    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getOfficersAmount()));
    g.drawString(df.format(c.getOfficersAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*30)));

    Double totalLeft = c.getAppraisersAmount() + c.getCostAmount() + c.getRefundsAmount() + c.getOfficersAmount();
    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(totalLeft));
    g.drawString(df.format(totalLeft), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*44)));

    return PAGE_EXISTS;
}

2 个答案:

答案 0 :(得分:0)

我自己也不擅长,但是在一本书中,我读到了有关tekst以及它在绘画时表现如何的非常好的探索。我搜索了一个熟悉的探索,我在Oracle找到了一个。这是:http://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html 它不是那么好但它是一些东西。 tekst的问题是你需要考虑提升下降和基线来正确绘制它。对不起,我无法提供更多帮助,我希望Oracles能够提供足够的帮助。

答案 1 :(得分:0)

我不确定你是如何确定MILLIMETER_IN_PIXELS价值的,这对我来说完全是可疑的。

但是,让您感到困惑的错误只是缺少大括号:

您使用以下字词:((int) MILLIMETER_IN_PIXELS*23)((int) MILLIMETER_IN_PIXELS*24)((int) (MILLIMETER_IN_PIXELS*22))

请注意,前两个术语缺少产品MILLIMETER_IN_PIXELS*…周围的大括号,这意味着您首先将MILLIMETER_IN_PIXELS投射到int,获取值3,然后乘以,而不是先执行double乘法,然后再投射到int

因此舍入误差不同。结果值为697283

请注意,缺少大括号的错误也出现在其他地方,水平位置也会受到影响。


作为附录,这里是你如何获得真正的DPI:

Point2D p = g2d.getDeviceConfiguration().getDefaultTransform()
    .transform(new Point2D.Float(72,72),null);
// normally, both are the same
int horizontalDPI=(int)p.getX(), verticalDPI=(int)p.getY();

说明:默认转换被指定为将72个用户空间像素转换为1英寸的转换,因此在将转换应用于72时,将导致设备像素的数量与1英寸匹配。