You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Print Service LANDSCAPE模式下含半透明色打印异常求助

问题分析与结论

这是代码实现有误,并非JVM或Java Print Service的问题。核心错误出在对页面方向转换后的坐标系统理解偏差,以及错误依赖静态纸张参数。

关键错误点

  1. 误用静态paper对象而非动态pageFormat参数
    页面设置为LANDSCAPE后,PageFormat会自动调整用户空间的坐标映射,其getImageableWidth()和getImageableHeight()会返回旋转后的可打印区域尺寸。但你在print方法中直接使用静态paper的物理尺寸,完全忽略了页面方向带来的坐标转换。

  2. 横向模式下坐标计算错误
    LANDSCAPE模式下,Java Print Service已经对Graphics2D的坐标系统做了顺时针90度旋转的适配。你绘制底部线条时,用paper.getImageableWidth()作为Y坐标,再叠加translate(0, -15)的偏移,导致线条位置超出了横向模式下的用户空间可见范围。

  3. 未利用pageFormat的标准坐标信息
    正确的做法是在print方法中通过pageFormat.getImageableX()、getImageableY()、getImageableWidth()、getImageableHeight()获取当前页面的可打印区域参数,而非依赖初始化时的静态纸张对象。

修复后的代码示例

import java.awt.*;
import java.awt.print.*;

public class Printing implements Printable {
    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        if (Thread.interrupted()) {
            throw new PrinterException("Current thread interrupted.");
        }

        Graphics2D g2d = (Graphics2D) graphics;
        Stroke oldStroke = g2d.getStroke();
        g2d.setStroke(new BasicStroke(10));

        // 获取当前页面的可打印区域参数(已适配页面方向)
        double imgX = pageFormat.getImageableX();
        double imgY = pageFormat.getImageableY();
        double imgWidth = pageFormat.getImageableWidth();
        double imgHeight = pageFormat.getImageableHeight();

        // 绘制左侧边距线
        g2d.translate(imgX + 15, imgY);
        g2d.drawLine(0, 0, 0, (int) imgHeight);
        g2d.translate(-(imgX + 15), -imgY);

        // 绘制底部边距线
        g2d.translate(imgX, imgY + imgHeight - 15);
        g2d.drawLine(0, 0, (int) imgWidth, 0);
        g2d.translate(-imgX, -(imgY + imgHeight - 15));

        g2d.setStroke(oldStroke);

        // 绘制半透明矩形
        g2d.setPaint(new Color(0, 0, 0, 100));
        g2d.fill(new Rectangle((int) imgX, (int) imgY, 200, 200));

        return Printable.PAGE_EXISTS;
    }

    public static void main(String[] argv) {
        Printing printer = new Printing();
        PrinterJob printJob = PrinterJob.getPrinterJob();
        PageFormat pageFormat = printJob.defaultPage();
        Paper paper = pageFormat.getPaper();
        paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
        pageFormat.setOrientation(PageFormat.LANDSCAPE);
        pageFormat.setPaper(paper);

        Book book = new Book();
        book.append(printer, pageFormat, 1);
        printJob.setPageable(book);
        try {
            printJob.print();
        } catch (PrinterException e) {
            e.printStackTrace();
        }
    }
}

关于“移除填充代码后线条正常显示”的原因

当不使用带Alpha通道的颜色时,Java Print Service的渲染器会对超出可打印区域的内容做宽松兼容(比如自动调整位置);但启用Alpha合成后,渲染逻辑更严格,超出区域的内容会被直接裁剪,因此线条不可见。

内容的提问来源于stack exchange,提问作者vtsty.dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:35:14