简体   繁体   English

尝试修改整数时,它会引发NullPointer异常

[英]Integer throws NullPointer exception when trying to modify it

I am trying to generate a PDF based on data passed in through an object using Apache PDFBox. 我正在尝试根据通过使用Apache PDFBox通过对象传递的数据生成PDF。 Since there's a variable amount of data I use a variable called volY to keep track of the y position to write the information. 由于数据量可变,因此我使用一个称为volY的变量来跟踪y位置以写入信息。 if volY is greater than 700, I close the Content stream I'm writing to, generate a new page and a new content stream, and start writing to a new page. 如果volY大于700,我将关闭正在写入的内容流,生成一个新页面和一个新的内容流,然后开始写入新页面。 The methods I use to write to the pdf return an integer which represents the height of the string, which I add to volY . 我用于写入pdf的方法返回一个整数,该整数表示字符串的高度,并将其添加到volY For some reason when I try to access volY when iterating through the elements I get a null pointer exception. 由于某些原因,当我尝试遍历元素时访问volY时,会得到一个空指针异常。

Here is my code to generate the PDF: 这是我生成PDF的代码:

public void generateSection(PDPage startingPage, PDPageContentStream cs, List<TestSection> sections) throws IOException {
    /*
     * TODO
     * verify list sequence integrity and reorder if not valid.
     */

    int volY = 350;
    PDPage page = startingPage;
    PDPageContentStream vcs = cs;
    // Iterate through sections
    for(int i = 0; i < sections.size(); i++) {
        if(volY > 700) {

            vcs.close();
            page = createPage();
            vcs = new PDPageContentStream(pd, page);
            volY = 50;
        }
        if(sections.get(i).isUrgent())
            cs.setNonStrokingColor(URGENT);

        drawString(sections.get(i).getType().getName(), 60, volY, vcs, page, 18);
        cs.setNonStrokingColor(REGULAR_TEXT);

        drawLine(vcs, 60, flipY(page, volY+8), 560);
        volY += 30;
        // Iterate through Items in section
        TestSection s = sections.get(i);
        for(int y = 0; y < s.getElements().size(); y++ ) {
            TestReportElement re = s.getElements().get(y);
            TestSubSection subSection = (TestSubSection)re;

            volY++;
            drawHeader(re.getTitle(), "a", volY, page, vcs);

            for(int z = 0; z < subSection.getItems().size(); z++) {
                //volY doesn't exist here for some reason?  At the very least it's not modifiable.


                if(vcs == null) {
                    System.err.println("VCS IS NULL");
                    System.exit(3);
                }
                TestInspectionItem ti = subSection.getItems().get(z);
                vcs.setNonStrokingColor(BOLD_TEXT);
                System.out.println(volY);
                drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z);
                vcs.setNonStrokingColor(REGULAR_TEXT);
                for(int z1 = 0; z1 < ti.getResponses().size(); z1++) {
                    if (volY > 700) {

                        vcs.close();
                        page = createPage();
                        vcs = new PDPageContentStream(pd, page);
                        volY = 50;
                    }
                    String text = ti.getResponses().get(z1);
                    drawMultipleStrings(text, volY+15, vcs, page, z1);
                }
                if (volY > 700) {

                    vcs.close();
                    page = createPage();
                    vcs = new PDPageContentStream(pd, page);
                    volY = 50;
                }
            }

            if (volY > 700) {

                vcs.close();
                page = createPage();
                vcs = new PDPageContentStream(pd, page);
                volY = 50;
            }

        }
        // Add 70 to account for a new section.
        volY += 70;
    }
    vcs.close();
}

Here is the code I'm using to draw multiple strings: 这是我用来绘制多个字符串的代码:

private int drawMultipleStrings(String text, int y, PDPageContentStream cs, PDPage page, int index) {
    // Page is 900 units wide
    // Assume font size is 13
    int strSize = text.length();
    int height = 0;
    String textVal = text;
    List<String> allText = new ArrayList<>();
    int xVal = index % 2 == 0 ? 60 : 300;
    if(strSize > 40) {
        while(textVal.length() > 40) {
            for (int i = 40; i > 0; i--) {
                if (textVal.charAt(i) == ' ') {
                    allText.add(textVal.substring(0, i));
                    textVal = textVal.substring(i);
                    break;
                }
            }
        }
        allText.add(textVal);
        for(int ind = 0; ind < allText.size(); ind++) {
            String s = allText.get(ind);
            if(s.charAt(0) == ' ') {
                s = s.substring(1);
                drawString(s, xVal, y+(13*ind), cs, page, 13);
            } else {
                // This should only trigger on the first iteration.
                drawString(s, xVal, y+(13*ind), cs, page, 13);
            }
            height += 13;
        }
        // Allows items to be displayed in 2 columns based on the index
        return index % 2 == 0 ? 0 : height + 32;
    } else {
        drawString(text, index % 2 == 0 ? 60: 300, y, cs, page, 13);
        return 13;
    }
}

This code works properly, but if I change drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z); 这段代码可以正常工作,但是如果我更改drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z); to volY += drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z); volY += drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z); It throws this exception: 它引发以下异常:

java.lang.NullPointerException
    at org.apache.pdfbox.pdmodel.PDPageContentStream.writeOperand(PDPageContentStream.java:2429)
    at org.apache.pdfbox.pdmodel.PDPageContentStream.setNonStrokingColor(PDPageContentStream.java:1316)
    at org.apache.pdfbox.pdmodel.PDPageContentStream.setNonStrokingColor(PDPageContentStream.java:1348)
    at compliancego.report.PdfService.generateSection(PdfService.java:206)
    at compliancego.report.PdfService.generateHeader(PdfService.java:176)
    at compliancego.report.PdfService.<init>(PdfService.java:97)
    at compliancego.report.PdfService.main(PdfService.java:73)

At first I thought this was because some of the data didn't exist to write but it works just fine if I don't update volY. 起初我以为这是因为不存在要写入的一些数据,但是如果我不更新volY,它就可以正常工作。 Then I thought it was an issue with the PDPageContentStream not being created when a new page is created but the stream exists. 然后,我认为这是创建新页面但流存在时未创建PDPageContentStream的问题。

Thanks in advance for any help! 在此先感谢您的帮助!

You initially create a local page content stream variable you initialize with the page content stream you received as a parameter: 最初,您创建一个本地页面内容流变量,并使用接收到的页面内容流作为参数进行初始化:

PDPageContentStream vcs = cs;

Upon page change you close the current page content stream in vcs and then set vcs to a new stream on a new page: 更改页面后,您将关闭vcs的当前页面内容流,然后将vcs设置为新页面上的新流:

if (volY > 700) {

    vcs.close();
    page = createPage();
    vcs = new PDPageContentStream(pd, page);
    volY = 50;
}

But in two code lines in your loop over the sections you draw on cs instead of vcs : 但是在循环的sections代码中,您使用的是cs而不是vcs

cs.setNonStrokingColor(URGENT);
...
cs.setNonStrokingColor(REGULAR_TEXT);

During the first page change you closed vcs which pointed to the same stream as cs . 在第一页更改期间,您关闭了vcs ,这些vcs指向与cs相同的流。 Thus, these color setting instructions are drawn on the closed stream cs which results in the observed NullPointerException . 因此,这些颜色设置指令绘制在封闭的流cs ,这导致观察到的NullPointerException

To fix this, use vcs here instead of cs , too. 要解决此问题,也可以在此处使用vcs而不是cs


The reason why this only occurred after you changed 仅在您更改后才发生这种情况的原因

drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z);

to

volY += drawMultipleStrings(ti.getPrompt(), volY, vcs, page, z);

most likely is that before that change volY never grew large enough to trigger a page change but thereafter it did. 最有可能的是,在此更改之前, volY从未增长到足以触发页面更改的大小,但此后确实如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM