Java Printable多页打印异常:第二页空白问题求助
解决Java Printable多页打印第二页空白的问题
我来帮你搞定这个第二页空白的问题,核心问题出在你对全局任务索引i的处理上——既没结合页码计算页内的相对位置,还错误地用全局索引计算绘制坐标,导致第二页的内容要么没进入绘制分支,要么画到了页面可见区域之外。
问题拆解
- 全局索引未转换为页内相对索引:你原来的
if ((i < 9) || ((i>=3*9) && (i<4*9)))这类判断,只对第一页的任务(i=0~26)有效。第二页的任务i=27~53完全不满足这些条件,自然不会执行任何绘制代码。 - 坐标计算错误:就算第二页的任务进入了分支,你用
i * 90计算y坐标,i=27时y值会达到10+27*90=2440,远远超出了打印页面的可打印区域,内容根本看不到。
修复后的代码
我调整了逻辑,先把全局索引转换为当前页内的相对索引,再基于这个索引计算任务在页面的列和行位置,确保每一页的内容都能正确绘制:
public class Printer implements Printable { private ArrayList<Task> dataTasks; private ArrayList<Tag> dataTags; private int tasksPerPage = 27; // 每页3列,每列9个任务 private final int tasksPerCol = 9; // 三列的x偏移量 private final int[] colXOffsets = {10, 202, 392}; public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { // 计算当前页的起始和结束索引 int startIndex = pageIndex * tasksPerPage; if (startIndex >= dataTasks.size()) { return NO_SUCH_PAGE; } int endIndex = Math.min(startIndex + tasksPerPage, dataTasks.size()); Graphics2D g2d = (Graphics2D) g; g2d.translate(pf.getImageableX(), pf.getImageableY()); Font titleFont = new Font("Courier New", Font.PLAIN, 12); g2d.setFont(titleFont); for (int i = startIndex; i < endIndex; i++){ // 计算当前任务在当前页内的相对索引(0~26) int pageRelativeIndex = i - startIndex; // 计算属于哪一列(0=第一列,1=第二列,2=第三列) int col = pageRelativeIndex / tasksPerCol; // 计算在当前列的第几行(0~8) int rowInCol = pageRelativeIndex % tasksPerCol; // 当前列的x坐标 int x = colXOffsets[col]; // 当前任务的基础y坐标 int baseY = 10 + rowInCol * 90; // 绘制任务基本信息 g.drawString("Task: " + dataTasks.get(i).getName(), x, baseY); g.drawString("Created: " + dataTasks.get(i).getCreationDate().toString(true,false), x, baseY + 12); g.drawString("Deadline: " + dataTasks.get(i).getDeadline().toString(true,true), x, baseY + 24); g.drawString("Compl.: " + dataTasks.get(i).getCompletionDate().toString(true,true), x, baseY + 36); // 绘制标签 List<Integer> tagIds = dataTasks.get(i).gettagIdList(); if (tagIds.isEmpty()){ g.drawString("Tags: ", x, baseY + 48); } else { int tagY = baseY + 48; for (int j = 0; j < tagIds.size(); j++) { for (int k = 0; k < dataTags.size(); k++) { if (tagIds.get(j) == dataTags.get(k).getId()){ if (j == 0){ g.drawString("Tags: " + dataTags.get(k).getName(), x, tagY); } else { g.drawString(" " + dataTags.get(k).getName(), x, tagY); } tagY += 10; // 下一个标签往下偏移10 break; // 找到对应标签后跳出内层循环 } } } } } return PAGE_EXISTS; } }
关键修改点
- 页内相对索引:通过
pageRelativeIndex = i - startIndex把全局索引转换成当前页的0~26范围,确保每一页的任务位置计算逻辑一致。 - 行列划分:用
col = pageRelativeIndex / 9和rowInCol = pageRelativeIndex % 9清晰划分任务在页面的列和行,替代原来复杂且错误的全局索引判断。 - 坐标统一计算:用
baseY = 10 + rowInCol * 90确保每列的任务从上到下依次排列,不会出现第二页y坐标溢出的问题。 - 优化标签循环:添加
break减少不必要的循环,同时统一标签的y偏移逻辑。
这样修改后,不管是第1页还是第N页,任务都会按照3行9列的布局正确绘制在页面可见区域内,不会再出现空白页的问题。
内容的提问来源于stack exchange,提问作者Nikola Petkovic
相关产品推荐
相关产品推荐

