java - 打印成物理形式——需要基本的理解

标签 java printing

我不太确定我理解 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;
}

最佳答案

我不确定你是如何确定 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 - 打印成物理形式——需要基本的理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26531595/

相关文章:

java - 如何在Eclipse中使用Admob?

c# - 在 .网

php - Google 云打印和功能 PPD

java - 无法从 AlarmManager 取消警报

java - java 'class' 文字如何为同一类返回 Class 对象的不同实例?

java - @RequestParam不同的URI

windows - v4 打印驱动器的虚拟打印机驱动程序 INF 配置

python - 如何打印具有用户定义属性的类的实例?

PDFBox 无法识别 pdf 为不可打印

java - 为什么我有来自 repo spring 的 HTTP 403?