【问题标题】:Printing to a physical form -- need basic understanding打印到物理形式 - 需要基本了解
【发布时间】:2014-12-19 07:52:22
【问题描述】:

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

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

要正确打印表单,必须将 c.getCostAmount() 打印在 c.getAppraisersAmount() 上方一个像素处,才能在其下方显示一行。然而,随后的每条线都比它低 4 毫米(或大约 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;
}

【问题讨论】:

  • 就我个人而言,我不知道,但我很想知道答案是什么!来自我的明星,为你欢呼!

标签: java printing


【解决方案1】:

我自己也不是很擅长,但是在我读过的一本书中,对 tekst 以及它在绘制时的行为方式进行了非常好的解释。我搜索了一个类似的解释,我从 Oracle 找到了一个。这是:http://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html 它不是那么好,但它是一些东西。 tekst 的问题是您需要考虑上升下降和基线才能正确绘制它。抱歉,我无法提供更多帮助,我希望 Oracles 页面对它有足够的帮助。

【讨论】:

  • 我之前读过那个链接...实际上它帮助我达到了现在的目的。如果你记得这本书的名字,请告诉我。我老婆什么都不做,她可以跑去书店。 :)
  • 嗯,这本书实际上是一个安卓数字应用程序,我被称为“Java 编程入门”,它是由 thu gian viet 编写的。这是我的第一本书,我相信关于字体的部分已经接近尾声。我不知道它是否涵盖更多。顺便说一句,该应用程序是免费的。
  • 顺便说一下这里有本书的网络版:math.hws.edu/javanotes
  • 我在网上找到了书中的章节:math.hws.edu/eck/cs124/javanotes7/c13/s2.html我认为你的问题与领先的财产有关。
  • 优秀!谢谢!
【解决方案2】:

我不确定你是如何确定 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 个用户空间像素转换为一英寸的转换,因此在将转换应用于72 时,将导致设备像素数与一英寸匹配。

【讨论】:

  • 这就是问题所在。感谢您解决了这个问题并加强了我对 Java 理解的信念。
  • 括号的优先级高于强制转换,但强制转换优先于乘法(指数在这里不适用,因为 Java 中没有这样的运算符)。顺便说一句,如果有疑问,您可以在任何内容周围加上括号,然后在 Eclipse 中按 CTRL+1,然后从弹出菜单中选择“删除多余的括号”,这将删除所有过时的括号,但保留所有必要的括号。
猜你喜欢
  • 1970-01-01
  • 2011-04-29
  • 2013-06-09
  • 2017-12-31
  • 2021-10-09
  • 1970-01-01
  • 2013-03-28
  • 2021-11-29
  • 1970-01-01
相关资源
最近更新 更多