Java Print Service LANDSCAPE模式下含半透明色打印异常求助
这是代码实现有误,并非JVM或Java Print Service的问题。核心错误出在对页面方向转换后的坐标系统理解偏差,以及错误依赖静态纸张参数。
关键错误点
误用静态
paper对象而非动态pageFormat参数
页面设置为LANDSCAPE后,PageFormat会自动调整用户空间的坐标映射,其getImageableWidth()和getImageableHeight()会返回旋转后的可打印区域尺寸。但你在print方法中直接使用静态paper的物理尺寸,完全忽略了页面方向带来的坐标转换。横向模式下坐标计算错误
LANDSCAPE模式下,Java Print Service已经对Graphics2D的坐标系统做了顺时针90度旋转的适配。你绘制底部线条时,用paper.getImageableWidth()作为Y坐标,再叠加translate(0, -15)的偏移,导致线条位置超出了横向模式下的用户空间可见范围。未利用
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

