Java 有人能解释一下iTexts帆布画的顺序吗?

Java 有人能解释一下iTexts帆布画的顺序吗?,java,pdf,canvas,itext,savestate,Java,Pdf,Canvas,Itext,Savestate,我尝试在iText中绘制一些嵌套表,因为我认为这是定位所有内容的最简单方法 因此,我在另一个表中有多个表,它们都有背景色和/或笔划(通过PdfPCellEvents)。不幸的是,外表的笔划与内表的背景重叠。 我假设这是由于应用的顺序错误,或者在我的PdfPCellEvents中设置了错误的saveState或restoreState 谁能给我解释一下saveState和restoreState的正确用法,并告诉我如何正确应用背景和笔划 下面是我添加条带化背景单元格的代码: PdfPCell s

我尝试在iText中绘制一些嵌套表,因为我认为这是定位所有内容的最简单方法

因此,我在另一个表中有多个表,它们都有背景色和/或笔划(通过PdfPCellEvents)。不幸的是,外表的笔划与内表的背景重叠。 我假设这是由于应用的顺序错误,或者在我的PdfPCellEvents中设置了错误的
saveState
restoreState

谁能给我解释一下
saveState
restoreState
的正确用法,并告诉我如何正确应用背景和笔划

下面是我添加条带化背景单元格的代码:

PdfPCell scaleBackground = new PdfPCell();
scaleBackground.setBorder(Rectangle.NO_BORDER);
scaleBackground.setVerticalAlignment(Element.ALIGN_TOP);
scaleBackground.setCellEvent(new StripedScaleBackground(max, scaleHeight));
条带缩放背景的单元布局方法:

public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
    PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
    float llx = rect.getLeft();
    float lly = rect.getBottom();
    float urx = rect.getRight();
    float ury = rect.getTop();

    // Light scale lines with padding from left
    canvas.setLineWidth(Constants.BORDER_WIDTH_THIN);
    canvas.setColorStroke(Colors.LIGHT_GRAY);

    float paddingLeft = 22f;
    for (int i = 0; i <= this.maxValue; i++)
    {
        canvas.moveTo(llx + paddingLeft, lly + (this.scaleHeight * (i + 1)));
        canvas.lineTo(urx, lly + (this.scaleHeight * (i + 1)));
    }

    // Vertical line
    canvas.moveTo(llx + (((urx - llx) + paddingLeft) / 2), ury);
    canvas.lineTo(llx + (((urx - llx) + paddingLeft) / 2), lly);
    canvas.stroke();

    // Fat line left and right
    canvas.moveTo(llx, ury);
    canvas.lineTo(llx, lly);
    canvas.moveTo(urx, ury);
    canvas.lineTo(urx, lly);

    canvas.setLineWidth(0.8f);
    canvas.setColorStroke(Colors.MEDIUM_GRAY);
    canvas.stroke();

    canvas.saveState();
    canvas.restoreState();
}

这是不同直接内容层的顺序:

  • PdfPtable.BASECANVAS
    -此处放置的任何内容都将位于表下
  • PdfPtable.BACKGROUNDCANVAS
    -这是背景所在的层 画
  • PdfPtable.LINECANVAS
    -这是绘制线条的图层
  • PdfPtable.TEXTCANVAS
    -这是文本所在的层。放置的任何东西 这是桌子
这是取自《iText行动-第二版》一书

您还询问了
saveState()
restoreState()
。下文对此进行了解释:

首先,我们使用
saveState()
方法保存当前图形状态,然后更改状态并绘制想要绘制的任何线条或形状,最后,我们使用
restoreState()
方法返回原始图形状态。我们在
saveState()
之后应用的所有更改都将撤消。如果更改多个值(线宽、颜色等)或难以计算反向更改(返回到原始坐标系),这一点尤其有趣

您的代码太长,我无法检查,但我非常怀疑
saveState()
/
restoreState()
是否是您出现问题的原因

我会尽量避免嵌套表格。使用colspan和rowspan通常更容易(也更有效)


如果这不能解决您的问题,请用一句话解释您的问题。

这是不同直接内容层的顺序:

  • PdfPtable.BASECANVAS
    -此处放置的任何内容都将位于表下
  • PdfPtable.BACKGROUNDCANVAS
    -这是背景所在的层 画
  • PdfPtable.LINECANVAS
    -这是绘制线条的图层
  • PdfPtable.TEXTCANVAS
    -这是文本所在的层。放置的任何东西 这是桌子
这是取自《iText行动-第二版》一书

您还询问了
saveState()
restoreState()
。下文对此进行了解释:

首先,我们使用
saveState()
方法保存当前图形状态,然后更改状态并绘制想要绘制的任何线条或形状,最后,我们使用
restoreState()
方法返回原始图形状态。我们在
saveState()
之后应用的所有更改都将撤消。如果更改多个值(线宽、颜色等)或难以计算反向更改(返回到原始坐标系),这一点尤其有趣

您的代码太长,我无法检查,但我非常怀疑
saveState()
/
restoreState()
是否是您出现问题的原因

我会尽量避免嵌套表格。使用colspan和rowspan通常更容易(也更有效)


如果这不能解决您的问题,请用一句话解释您的问题。

感谢您的快速回答!我的问题是,我将PdfPtable.LINECANVAS用作条带化背景,尽管它用作背景。我把它改为PdfPtable.BACKGROUNDCANVAS,现在它可以正常工作了!谢谢你的快速回答!我的问题是,我将PdfPtable.LINECANVAS用作条带化背景,尽管它用作背景。我把它改为PdfPtable.BACKGROUNDCANVAS,现在它可以正常工作了!
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
    PdfContentByte backgroundCanvas = canvases[PdfPTable.BACKGROUNDCANVAS];
    float llx = rect.getLeft();
    float lly = rect.getBottom();
    float urx = rect.getRight();
    float ury = rect.getTop();

    // Draw background

    // Define shading with direction and color
    PdfShading shading = PdfShading.simpleAxial(this.writer,
                    llx, ury,
                    llx, lly,
                    Colors.BAR_CHART_BLACK_LIGHT, Colors.BAR_CHART_BLACK_DARK);

    PdfShadingPattern pattern = new PdfShadingPattern(shading);
    backgroundCanvas.setShadingFill(pattern);

    // Draw shape with defined shading
    backgroundCanvas.moveTo(llx, ury);
    backgroundCanvas.lineTo(llx, lly);
    backgroundCanvas.lineTo(urx, lly);
    backgroundCanvas.lineTo(urx, ury);
    backgroundCanvas.lineTo(llx, ury);
    backgroundCanvas.fill();

    backgroundCanvas.saveState();
    backgroundCanvas.restoreState();

    // Draw border
    PdfContentByte lineCanvas = canvases[PdfPTable.LINECANVAS];

    float lineWidth = Constants.BORDER_WIDTH_THIN;
    lineCanvas.setLineWidth(lineWidth);
    lineCanvas.moveTo(llx, ury - lineWidth);
    lineCanvas.lineTo(llx, lly);
    lineCanvas.lineTo(urx, lly);
    lineCanvas.lineTo(urx, ury - lineWidth);

    lineCanvas.setColorStroke(BaseColor.BLACK);
    lineCanvas.stroke();

    lineCanvas.saveState();
    lineCanvas.restoreState();
}