Удалите свойства первой и последней строк в документе Itext7

Мне нужно удалить свойство в Text(setRise) , если t.setRise(+-) выходит за пределы поля paper. Удалите свойства первой и последней строк в документе Itext7

    PdfDocument pdfDoc = new PdfDocument(pdfWriter);
    Document doc = new Document(pdfDoc, PageSize.A5);
    doc.setMargins(0,0,0,36);
    for (int i = 0; i <50 ; i++) {
        Text t = new Text("hello " + i);
        if (i ==0){
            t.setTextRise(7);
        }
        if (i==31){
            t.setTextRise(-35);
        }
    Paragraph p = new Paragraph(t);
    p.setNextRenderer(new ParagraphRen(p,doc));
    p.setFixedLeading(fixedLeading);

     doc.add(p);
    }
    doc.close();
}

class ParagraphRen extends ParagraphRenderer{
private float heightDoc;
private float marginTop;
private float marginBot;



public ParagraphRen(Paragraph modelElement, Document doc) {
    super(modelElement);
    this.heightDoc =doc.getPdfDocument().getDefaultPageSize().getHeight();
    this.marginTop = doc.getTopMargin();
   this.marginBot = doc.getBottomMargin();


}

@Override
public void drawChildren(DrawContext drawContext) {
    super.drawChildren(drawContext);
    Rectangle rect = this.getOccupiedAreaBBox();
    List<IRenderer> childRenderers = this.getChildRenderers();
    //check first line
    if (rect.getTop()<=heightDoc- marginTop) {
        for (IRenderer iRenderer : childRenderers) {
            if (iRenderer.getModelElement().hasProperty(72)) {
            Object property = iRenderer.getModelElement().getProperty(72);
            float v = (Float) property + rect.getTop();
            //check text  more AreaPage
            if (v >heightDoc){
                iRenderer.getModelElement().deleteOwnProperty(72);
            }

        }
    }
    }
    //check last line
      if (rect.getBottom()-marginBot-rect.getHeight()*2<0){
        for (IRenderer iRenderer : childRenderers) {


            if (iRenderer.getModelElement().hasProperty(72)) {
                Object property = iRenderer.getModelElement().getProperty(72);


                      //if setRise(-..) more margin bottom  setRise remove
                if (rect.getBottom()-marginBot-rect.getHeight()+(Float) property<0)
                    iRenderer.getModelElement().deleteOwnProperty(72);
                }

            }
        }

    }

}

Здесь я проверяю, если первые строки с setRise больше площади бумаги, я удаляю свойство setRise.

И если последние строки с serRise(-35) больше чем нижняя граница, я удаляю это.

Но это не работает. Свойства не удаляются.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
288
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша проблема заключается в следующем: метод drawChildren вызывается после завершения рендеринга. На этом этапе iText обычно не учитывает свойства каких-либо элементов: он просто помещает элемент в его занятую область, которая была рассчитана ранее, на этапе layout().

Вы можете преодолеть это с помощью эмуляции макета.

Давайте добавим все ваши абзацы в div, а не прямо в документ. Затем эмулируйте добавление этого div в документ:

LayoutResult result = div.createRendererSubTree().setParent(doc.getRenderer()).layout(new LayoutContext(new LayoutArea(0, PageSize.A5)));

В приведенном выше фрагменте я попытался разместить наш div в документе формата A5.

Теперь вы можете рассмотреть результат макета и изменить некоторые элементы, которые затем будут обработаны по-настоящему с помощью Document#add. Например, чтобы получить 30-й макетный абзац, можно использовать:

((DivRenderer)result.getSplitRenderer()).getChildRenderers().get(30);

Еще несколько советов: раздельный рендерер представляет часть содержимого, которое iText может разместить в области, переполнение - содержимое, которое выходит за пределы.

но я не могу получить getOccupiedAreaBBox(); и я не могу вычислить, где последняя и первая строка.

heavywar 29.05.2019 14:03

если сделать это в макете Rectangle rect = this.getOccupiedAreaBBox(); Я получаю исключение NullPointerException

heavywar 29.05.2019 14:08

Вот что я вижу при отладке: pasteboard.co/IgWjLWF.png Не могли бы вы указать, где именно вы вызываете метод getOccupiedAreaBBox?

Uladzimir Asipchuk 29.05.2019 14:26

Первая строка в области представлена ​​первым дочерним элементом splitRenderer, а последняя — последним дочерним элементом splitRenderer.

Uladzimir Asipchuk 29.05.2019 14:27
stackoverflow.com/questions/56365855/…
heavywar 29.05.2019 19:36

Другие вопросы по теме