Zebra GK420T打印JPanel仅显示一半,如何适配不同纸张尺寸?
解决Zebra GK420T打印机JPanel打印不全及自适应纸张问题
问题分析
当前代码存在几个关键问题导致打印不全:
- 硬编码纸张尺寸可能与实际使用的纸张不匹配
- 组件尺寸获取时机不准确,导致缩放计算偏差
- 打印时的坐标变换与缩放逻辑需要调整,确保内容完整适配可打印区域
解决方案
1. 动态适配纸张尺寸,避免硬编码
移除硬编码的纸张尺寸设置,让打印对话框自动适配所选打印机的纸张,或允许用户选择合适尺寸:
// 替换原硬编码部分 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); aset.add(OrientationRequested.PORTRAIT); // 移除硬编码MediaSize,让用户在打印对话框选择或使用打印机默认
若需要指定Zebra常用的热敏纸尺寸(如4x6英寸),可明确匹配对应型号:
// 指定4x6英寸纸张 aset.add(MediaSize.findMedia(MediaSizeName.NA_LETTER, 4, 6, Size2DSyntax.INCH));
2. 确保获取组件实际渲染尺寸
组件的getWidth()/getHeight()可能在未完全渲染时返回错误值,改用getPreferredSize()获取最佳尺寸:
private double calculateScaleFactor(PageFormat pageFormat) { Dimension panelSize = jPanel3.getPreferredSize(); double panelWidth = panelSize.getWidth(); double panelHeight = panelSize.getHeight(); double paperWidth = pageFormat.getImageableWidth(); double paperHeight = pageFormat.getImageableHeight(); // 计算缩放比例,确保内容完整适配纸张 double scaleX = paperWidth / panelWidth; double scaleY = paperHeight / panelHeight; return Math.min(scaleX, scaleY); }
3. 优化打印坐标变换与缩放逻辑
调整缩放和平移顺序,同时添加居中对齐,确保内容在可打印区域内完整显示:
@Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) { if (pageIndex > 0) { return Printable.NO_SUCH_PAGE; } Graphics2D g2 = (Graphics2D) graphics; Dimension panelSize = jPanel3.getPreferredSize(); double scaleFactor = calculateScaleFactor(pageFormat); // 先缩放,再计算居中偏移量并平移到可打印区域 g2.scale(scaleFactor, scaleFactor); double xOffset = (pageFormat.getImageableWidth() / scaleFactor - panelSize.getWidth()) / 2; double yOffset = (pageFormat.getImageableHeight() / scaleFactor - panelSize.getHeight()) / 2; g2.translate(pageFormat.getImageableX() / scaleFactor + xOffset, pageFormat.getImageableY() / scaleFactor + yOffset); jPanel3.printAll(g2); return Printable.PAGE_EXISTS; }
4. 确保打印属性正确生效
打印前根据设置的属性获取正确的PageFormat,避免使用默认格式:
boolean ok = job.printDialog(aset); // 将属性传递给打印对话框 if (ok) { try { PageFormat pageFormat = job.getPageFormat(aset); job.setPrintable(new Printable() { @Override public int print(Graphics graphics, PageFormat pf, int pageIndex) { // 使用用户选择后的格式进行打印 // ... 上述打印逻辑 } }, pageFormat); job.print(aset); dispose(); } catch (PrinterException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } }
完整修改后的打印方法示例
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { PrinterJob job = PrinterJob.getPrinterJob(); PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); aset.add(OrientationRequested.PORTRAIT); boolean ok = job.printDialog(aset); if (ok) { try { PageFormat pageFormat = job.getPageFormat(aset); job.setPrintable(new Printable() { @Override public int print(Graphics graphics, PageFormat pf, int pageIndex) { if (pageIndex > 0) { return Printable.NO_SUCH_PAGE; } Graphics2D g2 = (Graphics2D) graphics; Dimension panelSize = jPanel3.getPreferredSize(); double scaleFactor = calculateScaleFactor(pf); g2.scale(scaleFactor, scaleFactor); // 计算居中偏移量 double xOffset = (pf.getImageableWidth() / scaleFactor - panelSize.getWidth()) / 2; double yOffset = (pf.getImageableHeight() / scaleFactor - panelSize.getHeight()) / 2; // 平移到正确位置 g2.translate(pf.getImageableX() / scaleFactor + xOffset, pf.getImageableY() / scaleFactor + yOffset); jPanel3.printAll(g2); return Printable.PAGE_EXISTS; } }, pageFormat); job.print(aset); dispose(); } catch (PrinterException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } } private double calculateScaleFactor(PageFormat pageFormat) { Dimension panelSize = jPanel3.getPreferredSize(); double panelWidth = panelSize.getWidth(); double panelHeight = panelSize.getHeight(); double paperWidth = pageFormat.getImageableWidth(); double paperHeight = pageFormat.getImageableHeight(); double scaleX = paperWidth / panelWidth; double scaleY = paperHeight / panelHeight; return Math.min(scaleX, scaleY); }
额外注意事项
- 确保JPanel完成布局后再打印,可在打印前调用
jPanel3.doLayout()确保尺寸正确 - Zebra GK420T为热敏打印机,需在打印设置中选择对应驱动和纸张类型,避免驱动导致的尺寸偏差
内容的提问来源于stack exchange,提问作者AHMED
相关产品推荐
相关产品推荐

