1
24 package net.sf.jasperreports.engine.fill;
25
26 import org.apache.commons.javaflow.api.continuable;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 import net.sf.jasperreports.engine.JRException;
31 import net.sf.jasperreports.engine.JRExpression;
32 import net.sf.jasperreports.engine.JRGroup;
33 import net.sf.jasperreports.engine.JRRuntimeException;
34 import net.sf.jasperreports.engine.JasperReport;
35 import net.sf.jasperreports.engine.JasperReportsContext;
36 import net.sf.jasperreports.engine.type.FooterPositionEnum;
37 import net.sf.jasperreports.engine.type.IncrementTypeEnum;
38 import net.sf.jasperreports.engine.type.ResetTypeEnum;
39 import net.sf.jasperreports.engine.type.RunDirectionEnum;
40
41
42
45 public class JRVerticalFiller extends JRBaseFiller
46 {
47
48 private static final Log log = LogFactory.getLog(JRVerticalFiller.class);
49
50 protected boolean hasDetailOnPage;
51
52
53
56 protected JRVerticalFiller(
57 JasperReportsContext jasperReportsContext,
58 JasperReport jasperReport
59 ) throws JRException
60 {
61 this(jasperReportsContext, jasperReport, null);
62 }
63
64
67 public JRVerticalFiller(
68 JasperReportsContext jasperReportsContext,
69 JasperReport jasperReport,
70 BandReportFillerParent parent
71 ) throws JRException
72 {
73 this(jasperReportsContext, SimpleJasperReportSource.from(jasperReport), parent);
74 }
75
76 public JRVerticalFiller(
77 JasperReportsContext jasperReportsContext,
78 JasperReportSource reportSource,
79 BandReportFillerParent parent
80 ) throws JRException
81 {
82 super(jasperReportsContext, reportSource, parent);
83
84 setPageHeight(pageHeight);
85 }
86
87
88 public boolean hasDetailOnPage()
89 {
90 return hasDetailOnPage;
91 }
92
93
94 @Override
95 protected void setPageHeight(int pageHeight)
96 {
97 this.pageHeight = pageHeight;
98
99 columnFooterOffsetY = pageHeight - bottomMargin - pageFooter.getHeight() - columnFooter.getHeight();
100 lastPageColumnFooterOffsetY = pageHeight - bottomMargin - lastPageFooter.getHeight() - columnFooter.getHeight();
101
102 if (log.isDebugEnabled())
103 {
104 log.debug("Filler " + fillerId + " - pageHeight: " + pageHeight
105 + ", columnFooterOffsetY: " + columnFooterOffsetY
106 + ", lastPageColumnFooterOffsetY: " + lastPageColumnFooterOffsetY);
107 }
108 }
109
110
111 @Override
112 @continuable
113 protected synchronized void fillReport() throws JRException
114 {
115 setLastPageFooter(false);
116
117 if (next())
118 {
119 fillReportStart();
120
121 while (next())
122 {
123 fillReportContent();
124 }
125
126 fillReportEnd();
127 }
128 else
129 {
130 if (log.isDebugEnabled())
131 {
132 log.debug("Fill " + fillerId + ": no data");
133 }
134
135 switch (getWhenNoDataType())
136 {
137 case ALL_SECTIONS_NO_DETAIL :
138 {
139 if (log.isDebugEnabled())
140 {
141 log.debug("Fill " + fillerId + ": all sections");
142 }
143
144 scriptlet.callBeforeReportInit();
145 calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT);
146 scriptlet.callAfterReportInit();
147
148 printPage = newPage();
149 printPageContentsWidth = 0;
150 addPage(printPage);
151 setFirstColumn();
152 offsetY = topMargin;
153 isFirstPageBand = true;
154 isFirstColumnBand = true;
155 isCrtRecordOnPage = false;
156 isCrtRecordOnColumn = false;
157
158 fillBackground();
159
160 fillTitle();
161
162 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
163
164 fillColumnHeader(JRExpression.EVALUATION_DEFAULT);
165
166 fillGroupHeaders(true);
167
168 fillGroupFooters(true);
169
170 fillSummary();
171
172 break;
173 }
174 case BLANK_PAGE :
175 {
176 if (log.isDebugEnabled())
177 {
178 log.debug("Fill " + fillerId + ": blank page");
179 }
180
181 printPage = newPage();
182 addPage(printPage);
183 break;
184 }
185 case NO_DATA_SECTION:
186 {
187 if (log.isDebugEnabled())
188 {
189 log.debug("Fill " + fillerId + ": all sections");
190 }
191
192 scriptlet.callBeforeReportInit();
193 calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT);
194 scriptlet.callAfterReportInit();
195
196 printPage = newPage();
197 addPage(printPage);
198 setFirstColumn();
199 offsetY = topMargin;
200 isFirstPageBand = true;
201 isFirstColumnBand = true;
202 isCrtRecordOnPage = false;
203 isCrtRecordOnColumn = false;
204
205 fillBackground();
206
207 fillNoData();
208
209 break;
210
211 }
212 case NO_PAGES :
213 default :
214 {
215 if (log.isDebugEnabled())
216 {
217 log.debug("Fill " + fillerId + ": no pages");
218 }
219 }
220 }
221 }
222
223 recordUsedPageHeight(offsetY + bottomMargin);
224 if (ignorePagination)
225 {
226 jasperPrint.setPageHeight(usedPageHeight);
227 }
228
229 if (isSubreport())
230 {
231 addPageToParent(true);
232 }
233 else
234 {
235 addLastPageBookmarks();
236 }
237
238 if (bookmarkHelper != null)
239 {
240 jasperPrint.setBookmarks(bookmarkHelper.getRootBookmarks());
241 }
242 }
243
244
245
248 @continuable
249 private void fillReportStart() throws JRException
250 {
251 scriptlet.callBeforeReportInit();
252 calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT);
253 scriptlet.callAfterReportInit();
254
255 printPage = newPage();
256 printPageContentsWidth = 0;
257 addPage(printPage);
258 setFirstColumn();
259 offsetY = topMargin;
260 isFirstPageBand = true;
261 isFirstColumnBand = true;
262 isCrtRecordOnPage = false;
263 isCrtRecordOnColumn = false;
264
265 fillBackground();
266
267 fillTitle();
268
269 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
270
271 fillColumnHeader(JRExpression.EVALUATION_DEFAULT);
272
273 fillGroupHeaders(true);
274
275 fillDetail();
276 }
277
278
279
282 @continuable
283 private void fillReportContent() throws JRException
284 {
285 calculator.estimateGroupRuptures();
286
287 fillGroupFooters(false);
288
289 resolveGroupBoundElements(JRExpression.EVALUATION_OLD, false);
290 scriptlet.callBeforeGroupInit();
291 calculator.initializeVariables(ResetTypeEnum.GROUP, IncrementTypeEnum.GROUP);
292 scriptlet.callAfterGroupInit();
293
294 fillGroupHeaders(false);
295
296 fillDetail();
297 }
298
299
300
303 @continuable
304 private void fillReportEnd() throws JRException
305 {
306 fillGroupFooters(true);
307
308 fillSummary();
309 }
310
311
312
315 @continuable
316 private void fillTitle() throws JRException
317 {
318 if (log.isDebugEnabled() && !title.isEmpty())
319 {
320 log.debug("Fill " + fillerId + ": title at " + offsetY);
321 }
322
323 title.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
324
325 if (title.isToPrint())
326 {
327 while (
328 title.getBreakHeight() > pageHeight - bottomMargin - offsetY
329 )
330 {
331 addPage(false);
332 }
333
334 title.evaluate(JRExpression.EVALUATION_DEFAULT);
335
336 JRPrintBand printBand = title.fill(pageHeight - bottomMargin - offsetY);
337
338 if (title.willOverflow() && title.isSplitPrevented() && !title.isSplitTypePreventInhibited())
339 {
340 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
341 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
342 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
343 scriptlet.callBeforePageInit();
344 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
345 scriptlet.callAfterPageInit();
346
347 addPage(false);
348
349 printBand =
350 title.refill(
351 JRExpression.EVALUATION_DEFAULT,
352 pageHeight - bottomMargin - offsetY
353 );
354 }
355
356 fillBand(printBand);
357 offsetY += printBand.getHeight();
358 isCrtRecordOnPage = true;
359 isCrtRecordOnColumn = true;
360
361 while (title.willOverflow())
362 {
363 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
364 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
365 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
366 scriptlet.callBeforePageInit();
367 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
368 scriptlet.callAfterPageInit();
369
370 addPage(false);
371
372 printBand = title.fill(pageHeight - bottomMargin - offsetY);
373
374 fillBand(printBand);
375 offsetY += printBand.getHeight();
376 isCrtRecordOnPage = true;
377 isCrtRecordOnColumn = true;
378 }
379
380 resolveBandBoundElements(title, JRExpression.EVALUATION_DEFAULT);
381
382 if (isTitleNewPage)
383 {
384 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
385 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
386 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
387 scriptlet.callBeforePageInit();
388 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
389 scriptlet.callAfterPageInit();
390
391 addPage(false);
392 }
393 }
394 }
395
396
397
400 @continuable
401 private void fillPageHeader(byte evaluation) throws JRException
402 {
403 if (log.isDebugEnabled() && !pageHeader.isEmpty())
404 {
405 log.debug("Fill " + fillerId + ": page header at " + offsetY);
406 }
407
408 setNewPageColumnInBands();
409
410 pageHeader.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
411
412 if (pageHeader.isToPrint())
413 {
414 int reattempts = getMasterColumnCount();
415 if (isCreatingNewPage)
416 {
417 --reattempts;
418 }
419
420 boolean filled = fillBandNoOverflow(pageHeader, evaluation);
421
422 for (int i = 0; !filled && i < reattempts; ++i)
423 {
424 resolveGroupBoundElements(evaluation, false);
425 resolveColumnBoundElements(evaluation);
426 resolvePageBoundElements(evaluation);
427 scriptlet.callBeforePageInit();
428 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
429 scriptlet.callAfterPageInit();
430
431 addPage(false);
432
433 filled = fillBandNoOverflow(pageHeader, evaluation);
434 }
435
436 if (!filled)
437 {
438 throw
439 new JRRuntimeException(
440 EXCEPTION_MESSAGE_KEY_PAGE_HEADER_OVERFLOW_INFINITE_LOOP,
441 (Object[])null);
442 }
443 }
444
445 columnHeaderOffsetY = offsetY;
446
447 hasDetailOnPage = false;
448
449 isNewPage = true;
450 }
451
452
453 private boolean fillBandNoOverflow(JRFillBand band, byte evaluation) throws JRException
454 {
455 int availableHeight = columnFooterOffsetY - offsetY;
456 boolean overflow = availableHeight < band.getHeight();
457
458 if (!overflow)
459 {
460 band.evaluate(evaluation);
461 JRPrintBand printBand = band.fill(availableHeight);
462
463 overflow = band.willOverflow();
464 if (overflow)
465 {
466 band.rewind();
467 }
468 else
469 {
470 fillBand(printBand);
471 offsetY += printBand.getHeight();
472 isCrtRecordOnPage = evaluation == JRExpression.EVALUATION_DEFAULT;
473 isCrtRecordOnColumn = isCrtRecordOnPage;
474
475 resolveBandBoundElements(band, evaluation);
476 }
477 }
478
479 return !overflow;
480 }
481
482
483
486 @continuable
487 private void fillColumnHeader(byte evaluation) throws JRException
488 {
489 if (log.isDebugEnabled() && !columnHeader.isEmpty())
490 {
491 log.debug("Fill " + fillerId + ": column header at " + offsetY);
492 }
493
494 setNewPageColumnInBands();
495 isFirstColumnBand = true;
496
497 columnHeader.evaluatePrintWhenExpression(evaluation);
498
499 if (columnHeader.isToPrint())
500 {
501 int reattempts = getMasterColumnCount();
502 if (isCreatingNewPage)
503 {
504 --reattempts;
505 }
506
507 setOffsetX();
508
509 boolean filled = fillBandNoOverflow(columnHeader, evaluation);
510
511 for (int i = 0; !filled && i < reattempts; ++i)
512 {
513 while (columnIndex < columnCount - 1)
514 {
515 resolveGroupBoundElements(evaluation, false);
516 resolveColumnBoundElements(evaluation);
517 scriptlet.callBeforeColumnInit();
518 calculator.initializeVariables(ResetTypeEnum.COLUMN, IncrementTypeEnum.COLUMN);
519 scriptlet.callAfterColumnInit();
520
521 columnIndex += 1;
522 setOffsetX();
523 offsetY = columnHeaderOffsetY;
524 isCrtRecordOnColumn = false;
525
526 setColumnNumberVar();
527 }
528
529 fillPageFooter(evaluation);
530
531 resolveGroupBoundElements(evaluation, false);
532 resolveColumnBoundElements(evaluation);
533 resolvePageBoundElements(evaluation);
534 scriptlet.callBeforePageInit();
535 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
536 scriptlet.callAfterPageInit();
537
538 addPage(false);
539
540 fillPageHeader(evaluation);
541
542 filled = fillBandNoOverflow(columnHeader, evaluation);
543 }
544
545 if (!filled)
546 {
547 throw new JRRuntimeException(EXCEPTION_MESSAGE_KEY_COLUMN_HEADER_OVERFLOW_INFINITE_LOOP, (Object[]) null);
548 }
549 }
550
551 isNewColumn = true;
552 }
553
554
555
558 @continuable
559 private void fillGroupHeaders(boolean isFillAll) throws JRException
560 {
561 if (groups != null && groups.length > 0)
562 {
563 for (int i = 0; i < groups.length; i++)
564 {
565 JRFillGroup group = groups[i];
566
567 if (isFillAll || group.hasChanged())
568 {
569 fillGroupHeader(group);
570 }
571 }
572 }
573 }
574
575
576
579 @continuable
580 private void fillGroupHeader(JRFillGroup group) throws JRException
581 {
582 JRFillSection groupHeaderSection = (JRFillSection)group.getGroupHeaderSection();
583
584 if (log.isDebugEnabled() && !groupHeaderSection.isEmpty())
585 {
586 log.debug("Fill " + fillerId + ": " + group.getName() + " header at " + offsetY);
587 }
588
589
590
591 if ( (group.isStartNewPage() || group.isResetPageNumber()) && !isNewPage )
592 {
593 fillPageBreak(
594 group.isResetPageNumber(),
595 isCrtRecordOnPage ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD,
596 JRExpression.EVALUATION_DEFAULT,
597 true
598 );
599 }
600 else if ( group.isStartNewColumn() && !isNewColumn )
601 {
602 fillColumnBreak(
603 isCrtRecordOnColumn ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD,
604 JRExpression.EVALUATION_DEFAULT
605 );
606 }
607
608 boolean isFirstHeaderBandToPrint = true;
609 boolean isGroupReset = false;
610
611 JRFillBand[] groupHeaderBands = groupHeaderSection.getFillBands();
612 for (int i = 0; i < groupHeaderBands.length; i++)
613 {
614 JRFillBand groupHeaderBand = groupHeaderBands[i];
615
616 groupHeaderBand.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
617
618 if (groupHeaderBand.isToPrint())
619 {
620 while (
621 groupHeaderBand.getBreakHeight() > columnFooterOffsetY - offsetY ||
622 (isFirstHeaderBandToPrint && group.getMinHeightToStartNewPage() > columnFooterOffsetY - offsetY)
623 )
624 {
625 fillColumnBreak(
626 isCrtRecordOnColumn ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD,
627 JRExpression.EVALUATION_DEFAULT
628 );
629 }
630 }
631
632 if (!isGroupReset && (isFirstHeaderBandToPrint || i == groupHeaderBands.length - 1))
633 {
634
635
636 setNewGroupInBands(group);
637
638 group.setFooterPrinted(false);
639 group.resetDetailsCount();
640
641 isGroupReset = true;
642 }
643
644 ElementRange elementRange = null;
645
646 if (
647 (group.isKeepTogether() && !isNewColumn)
648 || group.getMinDetailsToStartFromTop() > 0
649 )
650 {
651 elementRange = group.getKeepTogetherElementRange();
652
653 if (elementRange == null)
654 {
655
656
657
658 elementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
659
660 group.setKeepTogetherElementRange(elementRange);
661
662
663
664
665
666
667
668 }
669 }
670
671 if (groupHeaderBand.isToPrint())
672 {
673 fillColumnBand(groupHeaderBand, JRExpression.EVALUATION_DEFAULT, false);
674
675 ElementRange newElementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
676
677
678
679
680
681 ElementRangeUtil.expandOrIgnore(elementRange, newElementRange);
682
683 isFirstPageBand = false;
684 isFirstColumnBand = false;
685
686 isFirstHeaderBandToPrint = false;
687 }
688 }
689
690 group.setHeaderPrinted(true);
691 }
692
693
694
697 @continuable
698 private void fillGroupHeadersReprint(byte evaluation, boolean isPageBreak) throws JRException
699 {
700 if (groups != null && groups.length > 0)
701 {
702 for (int i = 0; i < groups.length; i++)
703 {
704 JRFillGroup group = groups[i];
705
706 if (
707 group.getKeepTogetherElementRange() != null
708 && (group.isKeepTogether() || !group.hasMinDetails())
709 )
710 {
711
712
713 break;
714 }
715
716 if (
717 (group.isReprintHeaderOnEachColumn() || (group.isReprintHeaderOnEachPage() && isPageBreak))
718 && (!group.hasChanged() || (group.hasChanged() && group.isHeaderPrinted()))
719 )
720 {
721 fillGroupHeaderReprint(groups[i], evaluation);
722 }
723 }
724 }
725 }
726
727
728
731 @continuable
732 private void fillGroupHeaderReprint(JRFillGroup group, byte evaluation) throws JRException
733 {
734 JRFillSection groupHeaderSection = (JRFillSection)group.getGroupHeaderSection();
735
736 JRFillBand[] groupHeaderBands = groupHeaderSection.getFillBands();
737 for (int i = 0; i < groupHeaderBands.length; i++)
738 {
739 JRFillBand groupHeaderBand = groupHeaderBands[i];
740
741 groupHeaderBand.evaluatePrintWhenExpression(evaluation);
742
743 if (groupHeaderBand.isToPrint())
744 {
745 while (groupHeaderBand.getBreakHeight() > columnFooterOffsetY - offsetY)
746 {
747 fillColumnBreak(evaluation, evaluation);
748 }
749
750 fillColumnBand(groupHeaderBand, evaluation, false);
751
752
753 if (columnCount > 1)
754 {
755 isFirstColumnBand = false;
756 }
757 }
758 }
759 }
760
761
762
765 @continuable
766 private void fillDetail() throws JRException
767 {
768 if (log.isDebugEnabled() && !detailSection.isEmpty())
769 {
770 log.debug("Fill " + fillerId + ": detail at " + offsetY);
771 }
772
773 if (!detailSection.areAllPrintWhenExpressionsNull())
774 {
775 calculator.estimateVariables();
776 }
777
778 JRFillBand[] detailBands = detailSection.getFillBands();
779 for (int i = 0; i < detailBands.length; i++)
780 {
781 JRFillBand detailBand = detailBands[i];
782
783 detailBand.evaluatePrintWhenExpression(JRExpression.EVALUATION_ESTIMATED);
784
785 if (detailBand.isToPrint())
786 {
787 while (
788 detailBand.getBreakHeight() > columnFooterOffsetY - offsetY
789 )
790 {
791 fillColumnBreak(
792 isCrtRecordOnColumn ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD,
793 JRExpression.EVALUATION_DEFAULT
794 );
795 }
796
797 break;
798 }
799 }
800
801 scriptlet.callBeforeDetailEval();
802 calculator.calculateVariables(true);
803 scriptlet.callAfterDetailEval();
804
805 detailElementRange = null;
806
807 boolean keepDetailElementRangeForOrphanFooter = true;
808 boolean atLeastOneDetailBandPrinted = false;
809
810 for (int i = 0; i < detailBands.length; i++)
811 {
812 JRFillBand detailBand = detailBands[i];
813
814 detailBand.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
815
816 if (detailBand.isToPrint())
817 {
818 while (
819 detailBand.getBreakHeight() > columnFooterOffsetY - offsetY
820 )
821 {
822 fillColumnBreak(
823 isCrtRecordOnColumn ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD,
824 JRExpression.EVALUATION_DEFAULT
825 );
826 }
827
828 if (
829 keepDetailElementRangeForOrphanFooter
830 && detailElementRange == null
831 )
832 {
833 detailElementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
834 }
835
836 fillColumnBand(detailBand, JRExpression.EVALUATION_DEFAULT, !atLeastOneDetailBandPrinted);
837
838 if (detailElementRange == null)
839 {
840
841
842
843
844
845
846 keepDetailElementRangeForOrphanFooter = false;
847 }
848 else
849 {
850
851
852 ElementRange newElementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
853
854 ElementRangeUtil.expandOrIgnore(detailElementRange, newElementRange);
855 }
856
857 atLeastOneDetailBandPrinted = true;
858
859 isFirstPageBand = false;
860 isFirstColumnBand = false;
861 }
862 }
863
864 if (atLeastOneDetailBandPrinted)
865 {
866 if (groups != null)
867 {
868 for (JRFillGroup group : groups)
869 {
870 group.incrementDetailsCount();
871 }
872 }
873 }
874
875 hasDetailOnPage = atLeastOneDetailBandPrinted;
876
877 isNewPage = false;
878 isNewColumn = false;
879 }
880
881
882
885 @continuable
886 private void fillGroupFooters(boolean isFillAll) throws JRException
887 {
888 if (groups != null && groups.length > 0)
889 {
890 byte evaluation = (isFillAll)?JRExpression.EVALUATION_DEFAULT:JRExpression.EVALUATION_OLD;
891
892 preventOrphanFootersMinLevel = null;
893 for (int i = groups.length - 1; i >= 0; i--)
894 {
895 JRFillGroup group = groups[i];
896
897 if (
898 (isFillAll || group.hasChanged())
899 && group.isPreventOrphanFooter()
900 )
901 {
902
903
904 preventOrphanFootersMinLevel = i;
905 break;
906 }
907 }
908
909 for (int i = groups.length - 1; i >= 0; i--)
910 {
911 JRFillGroup group = groups[i];
912
913 crtGroupFootersLevel = i;
914 if (
915 preventOrphanFootersMinLevel != null
916 && crtGroupFootersLevel < preventOrphanFootersMinLevel
917 )
918 {
919
920
921
922 orphanGroupFooterDetailElementRange = null;
923 orphanGroupFooterElementRange = null;
924 detailElementRange = null;
925 }
926
927 if (isFillAll || group.hasChanged())
928 {
929 fillGroupFooter(group, evaluation);
930
931
932
933 group.setKeepTogetherElementRange(null);
934 }
935 }
936
937
938 orphanGroupFooterDetailElementRange = null;
939 orphanGroupFooterElementRange = null;
940 detailElementRange = null;
941
942
943
944
945
946
947 if (
948 !isFillAll
949 && groupFooterPositionElementRange != null
950 )
951 {
952 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
953 groupFooterPositionElementRange = null;
954
955 offsetY = columnFooterOffsetY;
956 }
957 }
958 }
959
960
961
964 @continuable
965 private void fillGroupFooter(JRFillGroup group, byte evaluation) throws JRException
966 {
967 JRFillSection groupFooterSection = (JRFillSection)group.getGroupFooterSection();
968
969 if (log.isDebugEnabled() && !groupFooterSection.isEmpty())
970 {
971 log.debug("Fill " + fillerId + ": " + group.getName() + " footer at " + offsetY);
972 }
973
974 JRFillBand[] groupFooterBands = groupFooterSection.getFillBands();
975 for (int i = 0; i < groupFooterBands.length; i++)
976 {
977 JRFillBand groupFooterBand = groupFooterBands[i];
978
979 groupFooterBand.evaluatePrintWhenExpression(evaluation);
980
981 if (groupFooterBand.isToPrint())
982 {
983 if (
984 preventOrphanFootersMinLevel != null
985 && crtGroupFootersLevel >= preventOrphanFootersMinLevel
986 && orphanGroupFooterDetailElementRange == null
987 )
988 {
989
990
991
992 orphanGroupFooterDetailElementRange = detailElementRange;
993 }
994
995 if (
996 groupFooterBand.getBreakHeight() > columnFooterOffsetY - offsetY
997 )
998 {
999 fillColumnBreak(evaluation, evaluation);
1000 }
1001
1002 if (
1003 groupFooterPositionElementRange == null
1004 && group.getFooterPositionValue() != FooterPositionEnum.NORMAL
1005 )
1006 {
1007 groupFooterPositionElementRange =
1008 new SimpleGroupFooterElementRange(
1009 new SimpleElementRange(getCurrentPage(), columnIndex, offsetY),
1010 group.getFooterPositionValue()
1011 );
1012 }
1013
1014 if (groupFooterPositionElementRange != null)
1015 {
1016
1017
1018
1019 groupFooterPositionElementRange.setCurrentFooterPosition(group.getFooterPositionValue());
1020 }
1021
1022 if (orphanGroupFooterDetailElementRange != null)
1023 {
1024 ElementRange newElementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
1025 if (orphanGroupFooterElementRange == null)
1026 {
1027 orphanGroupFooterElementRange = newElementRange;
1028 }
1029 else
1030 {
1031 ElementRangeUtil.expandOrIgnore(orphanGroupFooterElementRange, newElementRange);
1032 }
1033 }
1034
1035 fillColumnBand(groupFooterBand, evaluation, false);
1036
1037 ElementRange newElementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
1038
1039 if (groupFooterPositionElementRange != null)
1040 {
1041 ElementRangeUtil.expandOrIgnore(groupFooterPositionElementRange.getElementRange(), newElementRange);
1042
1043 switch (group.getFooterPositionValue())
1044 {
1045 case STACK_AT_BOTTOM :
1046 {
1047 groupFooterPositionElementRange.setMasterFooterPosition(FooterPositionEnum.STACK_AT_BOTTOM);
1048 break;
1049 }
1050 case FORCE_AT_BOTTOM :
1051 {
1052 groupFooterPositionElementRange.setMasterFooterPosition(FooterPositionEnum.FORCE_AT_BOTTOM);
1053 break;
1054 }
1055 case COLLATE_AT_BOTTOM :
1056 {
1057 break;
1058 }
1059 case NORMAL :
1060 default :
1061 {
1062
1063 if (groupFooterPositionElementRange.getMasterFooterPosition() == FooterPositionEnum.COLLATE_AT_BOTTOM)
1064 {
1065 groupFooterPositionElementRange = null;
1066 }
1067 break;
1068 }
1069 }
1070 }
1071
1072 isFirstPageBand = false;
1073 isFirstColumnBand = false;
1074 }
1075 }
1076
1077
1078
1079
1080
1081 if (
1082 groupFooterPositionElementRange != null
1083 && groupFooterPositionElementRange.getMasterFooterPosition() == FooterPositionEnum.FORCE_AT_BOTTOM
1084 )
1085 {
1086 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
1087 groupFooterPositionElementRange = null;
1088
1089 offsetY = columnFooterOffsetY;
1090 }
1091
1092 isNewPage = false;
1093 isNewColumn = false;
1094
1095 group.setHeaderPrinted(false);
1096 group.setFooterPrinted(true);
1097 }
1098
1099
1100
1103 private void fillColumnFooter(byte evaluation) throws JRException
1104 {
1105 if (log.isDebugEnabled() && !columnFooter.isEmpty())
1106 {
1107 log.debug("Fill " + fillerId + ": column footer at " + offsetY);
1108 }
1109
1110 setOffsetX();
1111
1112
1118
1119 if (isSubreport() && !isSubreportRunToBottom() && columnIndex == 0)
1120 {
1121 columnFooterOffsetY = offsetY;
1122 }
1123
1124 int oldOffsetY = offsetY;
1125 if (!isFloatColumnFooter && !ignorePagination)
1126 {
1127 offsetY = columnFooterOffsetY;
1128 }
1129
1130
1131
1132 if (groupFooterPositionElementRange != null)
1133 {
1134
1135
1136
1137
1138 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
1139 groupFooterPositionElementRange = null;
1140
1141 }
1142
1143 columnFooter.evaluatePrintWhenExpression(evaluation);
1144
1145 if (columnFooter.isToPrint())
1146 {
1147 if (isFloatColumnFooter && !ignorePagination)
1148 {
1149 floatColumnFooterElementRange = new SimpleElementRange(getCurrentPage(), columnIndex, offsetY);
1150 }
1151
1152 fillFixedBand(columnFooter, evaluation);
1153
1154 if (floatColumnFooterElementRange != null)
1155 {
1156 floatColumnFooterElementRange.expand(offsetY);
1157 }
1158 }
1159
1160 if (isFloatColumnFooter && !ignorePagination)
1161 {
1162 offsetY += columnFooterOffsetY - oldOffsetY;
1163 }
1164 }
1165
1166
1167
1170 private void fillPageFooter(byte evaluation) throws JRException
1171 {
1172 JRFillBand crtPageFooter = getCurrentPageFooter();
1173
1174 if (log.isDebugEnabled() && !crtPageFooter.isEmpty())
1175 {
1176 log.debug("Fill " + fillerId + ": " + (isLastPageFooter ? "last " : "") + "page footer at " + offsetY);
1177 }
1178
1179 offsetX = leftMargin;
1180
1181 if ((!isSubreport() || isSubreportRunToBottom()) && !ignorePagination)
1182 {
1183 offsetY = pageHeight - crtPageFooter.getHeight() - bottomMargin;
1184 }
1185
1186 crtPageFooter.evaluatePrintWhenExpression(evaluation);
1187
1188 if (crtPageFooter.isToPrint())
1189 {
1190 fillFixedBand(crtPageFooter, evaluation);
1191 }
1192 }
1193
1194
1195
1198 @continuable
1199 private void fillSummary() throws JRException
1200 {
1201 if (log.isDebugEnabled() && !summary.isEmpty())
1202 {
1203 log.debug("Fill " + fillerId + ": summary at " + offsetY);
1204 }
1205
1206 offsetX = leftMargin;
1207
1208 if (lastPageFooter == missingFillBand)
1209 {
1210 if (
1211 !isSummaryNewPage
1212 && columnIndex == 0
1213 && summary.getBreakHeight() <= columnFooterOffsetY - offsetY
1214 )
1215 {
1216 fillSummaryNoLastFooterSamePage();
1217 }
1218 else
1219 {
1220 fillSummaryNoLastFooterNewPage();
1221 }
1222 }
1223 else
1224 {
1225 if (isSummaryWithPageHeaderAndFooter)
1226 {
1227 fillSummaryWithLastFooterAndPageBands();
1228 }
1229 else
1230 {
1231 fillSummaryWithLastFooterNoPageBands();
1232 }
1233 }
1234
1235 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1236 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1237 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1238 resolveReportBoundElements();
1239 if (isMasterReport())
1240 {
1241 resolveMasterBoundElements();
1242 }
1243 }
1244
1245
1246
1249 @continuable
1250 private void fillSummaryNoLastFooterSamePage() throws JRException
1251 {
1252 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1253
1254 if (summary.isToPrint())
1255 {
1256
1257 if (groupFooterPositionElementRange != null)
1258 {
1259 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
1260 offsetY = columnFooterOffsetY;
1261
1262 groupFooterPositionElementRange = null;
1263 }
1264
1265 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1266
1267 JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY);
1268
1269 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1270 {
1271 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1272
1273 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1274
1275 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1276 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1277 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1278 scriptlet.callBeforePageInit();
1279 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1280 scriptlet.callAfterPageInit();
1281
1282 addPage(false);
1283
1284 if (isSummaryWithPageHeaderAndFooter)
1285 {
1286 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1287 }
1288
1289 printBand =
1290 summary.refill(
1291 JRExpression.EVALUATION_DEFAULT,
1292 pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)
1293 );
1294
1295 fillBand(printBand);
1296 offsetY += printBand.getHeight();
1297 isCrtRecordOnPage = true;
1298 isCrtRecordOnColumn = true;
1299
1300
1301 fillSummaryOverflow();
1302
1303
1304 }
1305 else
1306 {
1307
1308
1309 fillBand(printBand);
1310 offsetY += printBand.getHeight();
1311 isCrtRecordOnPage = true;
1312 isCrtRecordOnColumn = true;
1313
1314 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1315
1316 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1317
1318 if (summary.willOverflow())
1319 {
1320 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1321 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1322 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1323 scriptlet.callBeforePageInit();
1324 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1325 scriptlet.callAfterPageInit();
1326
1327 addPage(false);
1328
1329 if (isSummaryWithPageHeaderAndFooter)
1330 {
1331 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1332 }
1333
1334 printBand = summary.fill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0));
1335
1336 fillBand(printBand);
1337 offsetY += printBand.getHeight();
1338 isCrtRecordOnPage = true;
1339 isCrtRecordOnColumn = true;
1340
1341
1342 fillSummaryOverflow();
1343
1344
1345 }
1346 else
1347 {
1348 resolveBandBoundElements(summary, JRExpression.EVALUATION_DEFAULT);
1349
1350
1351 }
1352 }
1353 }
1354 else
1355 {
1356
1357
1358
1359
1360 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1361
1362 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1363
1364
1365 }
1366 }
1367
1368
1369
1372 @continuable
1373 private void fillSummaryNoLastFooterNewPage() throws JRException
1374 {
1375
1376
1377
1378
1379 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1380
1381 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1382
1383 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1384
1385 if (summary.isToPrint())
1386 {
1387 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1388 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1389 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1390 scriptlet.callBeforePageInit();
1391 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1392 scriptlet.callAfterPageInit();
1393
1394 addPage(false);
1395
1396 if (isSummaryWithPageHeaderAndFooter)
1397 {
1398 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1399 }
1400
1401 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1402
1403 JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0));
1404
1405 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1406 {
1407 if (isSummaryWithPageHeaderAndFooter)
1408 {
1409 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1410 }
1411
1412 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1413 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1414 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1415 scriptlet.callBeforePageInit();
1416 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1417 scriptlet.callAfterPageInit();
1418
1419 addPage(false);
1420
1421 if (isSummaryWithPageHeaderAndFooter)
1422 {
1423 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1424 }
1425
1426 printBand =
1427 summary.refill(
1428 JRExpression.EVALUATION_DEFAULT,
1429 pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)
1430 );
1431 }
1432
1433 fillBand(printBand);
1434 offsetY += printBand.getHeight();
1435 isCrtRecordOnPage = true;
1436 isCrtRecordOnColumn = true;
1437
1438
1439 fillSummaryOverflow();
1440 }
1441
1442
1443 }
1444
1445
1446
1449 @continuable
1450 private void fillSummaryWithLastFooterAndPageBands() throws JRException
1451 {
1452 if (
1453 !isSummaryNewPage
1454 && columnIndex == 0
1455 && summary.getBreakHeight() <= columnFooterOffsetY - offsetY
1456 )
1457 {
1458 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1459
1460 if (summary.isToPrint())
1461 {
1462
1463 if (groupFooterPositionElementRange != null)
1464 {
1465 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
1466 offsetY = columnFooterOffsetY;
1467
1468 groupFooterPositionElementRange = null;
1469 }
1470
1471 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1472
1473 JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY);
1474
1475 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1476 {
1477 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1478
1479 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1480
1481 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1482 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1483 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1484 scriptlet.callBeforePageInit();
1485 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1486 scriptlet.callAfterPageInit();
1487
1488 addPage(false);
1489
1490 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1491
1492 printBand =
1493 summary.refill(
1494 JRExpression.EVALUATION_DEFAULT,
1495 pageHeight - bottomMargin - offsetY - pageFooter.getHeight()
1496 );
1497
1498 fillBand(printBand);
1499 offsetY += printBand.getHeight();
1500 isCrtRecordOnPage = true;
1501 isCrtRecordOnColumn = true;
1502 }
1503 else
1504 {
1505
1506
1507 fillBand(printBand);
1508 offsetY += printBand.getHeight();
1509 isCrtRecordOnPage = true;
1510 isCrtRecordOnColumn = true;
1511
1512 if (
1513 !summary.willOverflow()
1514 && offsetY <= lastPageColumnFooterOffsetY
1515 )
1516 {
1517 setLastPageFooter(true);
1518 }
1519
1520 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1521 }
1522
1523
1524 fillSummaryOverflow();
1525
1526
1527 }
1528 else
1529 {
1530
1531
1532
1533
1534 setLastPageFooter(true);
1535
1536 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1537
1538 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1539
1540
1541 }
1542 }
1543 else if (columnIndex == 0 && offsetY <= lastPageColumnFooterOffsetY)
1544 {
1545 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1546
1547 if (summary.isToPrint())
1548 {
1549
1550
1551
1552
1553 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1554
1555 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1556
1557 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1558 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1559 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1560 scriptlet.callBeforePageInit();
1561 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1562 scriptlet.callAfterPageInit();
1563
1564 addPage(false);
1565
1566 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1567
1568 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1569
1570 JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight());
1571
1572 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1573 {
1574 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1575
1576 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1577 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1578 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1579 scriptlet.callBeforePageInit();
1580 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1581 scriptlet.callAfterPageInit();
1582
1583 addPage(false);
1584
1585 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1586
1587 printBand =
1588 summary.refill(
1589 JRExpression.EVALUATION_DEFAULT,
1590 pageHeight - bottomMargin - offsetY - pageFooter.getHeight()
1591 );
1592 }
1593
1594 fillBand(printBand);
1595 offsetY += printBand.getHeight();
1596 isCrtRecordOnPage = true;
1597 isCrtRecordOnColumn = true;
1598
1599
1600 fillSummaryOverflow();
1601
1602
1603 }
1604 else
1605 {
1606
1607
1608
1609
1610 setLastPageFooter(true);
1611
1612 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1613
1614 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1615
1616
1617 }
1618 }
1619 else
1620 {
1621
1622
1623 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1624
1625 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1626
1627 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
1628 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1629 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1630 scriptlet.callBeforePageInit();
1631 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1632 scriptlet.callAfterPageInit();
1633
1634 addPage(false);
1635
1636 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1637
1638 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1639
1640 if (summary.isToPrint())
1641 {
1642
1643
1644 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1645
1646 JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight());
1647
1648 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1649 {
1650 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1651
1652 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1653 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1654 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1655 scriptlet.callBeforePageInit();
1656 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1657 scriptlet.callAfterPageInit();
1658
1659 addPage(false);
1660
1661 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1662
1663 printBand =
1664 summary.refill(
1665 JRExpression.EVALUATION_DEFAULT,
1666 pageHeight - bottomMargin - offsetY - pageFooter.getHeight()
1667 );
1668 }
1669
1670 fillBand(printBand);
1671 offsetY += printBand.getHeight();
1672 isCrtRecordOnPage = true;
1673 isCrtRecordOnColumn = true;
1674 }
1675 else
1676 {
1677
1678 }
1679
1680
1681 fillSummaryOverflow();
1682
1683
1684 }
1685 }
1686
1687
1688
1691 @continuable
1692 private void fillSummaryWithLastFooterNoPageBands() throws JRException
1693 {
1694 if (
1695 !isSummaryNewPage
1696 && columnIndex == 0
1697 && summary.getBreakHeight() <= lastPageColumnFooterOffsetY - offsetY
1698 )
1699 {
1700 setLastPageFooter(true);
1701
1702 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1703
1704 if (summary.isToPrint())
1705 {
1706
1707 if (groupFooterPositionElementRange != null)
1708 {
1709 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
1710 offsetY = columnFooterOffsetY;
1711
1712 groupFooterPositionElementRange = null;
1713 }
1714
1715 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1716
1717 JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY);
1718
1719 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1720 {
1721 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1722
1723 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1724
1725 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1726 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1727 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1728 scriptlet.callBeforePageInit();
1729 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1730 scriptlet.callAfterPageInit();
1731
1732 addPage(false);
1733
1734 printBand =
1735 summary.refill(
1736 JRExpression.EVALUATION_DEFAULT,
1737 pageHeight - bottomMargin - offsetY
1738 );
1739
1740 fillBand(printBand);
1741 offsetY += printBand.getHeight();
1742 isCrtRecordOnPage = true;
1743 isCrtRecordOnColumn = true;
1744 }
1745 else
1746 {
1747
1748
1749 fillBand(printBand);
1750 offsetY += printBand.getHeight();
1751 isCrtRecordOnPage = true;
1752 isCrtRecordOnColumn = true;
1753
1754 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1755
1756 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1757 }
1758
1759
1760 fillSummaryOverflow();
1761
1762
1763 }
1764 else
1765 {
1766
1767
1768
1769
1770 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1771
1772 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1773
1774
1775 }
1776 }
1777 else if (
1778 !isSummaryNewPage
1779 && columnIndex == 0
1780 && summary.getBreakHeight() <= columnFooterOffsetY - offsetY
1781 )
1782 {
1783 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1784
1785 if (summary.isToPrint())
1786 {
1787
1788 if (groupFooterPositionElementRange != null)
1789 {
1790 ElementRangeUtil.moveContent(groupFooterPositionElementRange, columnFooterOffsetY);
1791 offsetY = columnFooterOffsetY;
1792
1793 groupFooterPositionElementRange = null;
1794 }
1795
1796 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1797
1798 JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY);
1799
1800 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1801 {
1802 if (offsetY <= lastPageColumnFooterOffsetY)
1803 {
1804 setLastPageFooter(true);
1805
1806 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1807
1808 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1809
1810 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1811 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1812 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1813 scriptlet.callBeforePageInit();
1814 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1815 scriptlet.callAfterPageInit();
1816
1817 addPage(false);
1818
1819 printBand =
1820 summary.refill(
1821 JRExpression.EVALUATION_DEFAULT,
1822 pageHeight - bottomMargin - offsetY
1823 );
1824
1825 fillBand(printBand);
1826 offsetY += printBand.getHeight();
1827 isCrtRecordOnPage = true;
1828 isCrtRecordOnColumn = true;
1829 }
1830 else
1831 {
1832 fillPageBreak(false, JRExpression.EVALUATION_DEFAULT, JRExpression.EVALUATION_DEFAULT, false);
1833
1834 setLastPageFooter(true);
1835
1836 printBand =
1837 summary.refill(
1838 JRExpression.EVALUATION_DEFAULT,
1839 lastPageColumnFooterOffsetY - offsetY
1840 );
1841
1842 fillBand(printBand);
1843 offsetY += printBand.getHeight();
1844 isCrtRecordOnPage = true;
1845 isCrtRecordOnColumn = true;
1846
1847 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1848
1849 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1850 }
1851 }
1852 else
1853 {
1854
1855
1856 fillBand(printBand);
1857 offsetY += printBand.getHeight();
1858 isCrtRecordOnPage = true;
1859 isCrtRecordOnColumn = true;
1860
1861 fillPageBreak(false, JRExpression.EVALUATION_DEFAULT, JRExpression.EVALUATION_DEFAULT, false);
1862
1863 setLastPageFooter(true);
1864
1865 if (summary.willOverflow())
1866 {
1867 printBand = summary.fill(lastPageColumnFooterOffsetY - offsetY);
1868
1869 fillBand(printBand);
1870 offsetY += printBand.getHeight();
1871 isCrtRecordOnPage = true;
1872 isCrtRecordOnColumn = true;
1873 }
1874
1875 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1876
1877 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1878 }
1879
1880
1881 fillSummaryOverflow();
1882
1883
1884 }
1885 else
1886 {
1887
1888
1889
1890 if (offsetY > lastPageColumnFooterOffsetY)
1891 {
1892
1893 fillPageBreak(false, JRExpression.EVALUATION_DEFAULT, JRExpression.EVALUATION_DEFAULT, false);
1894 }
1895 else
1896 {
1897
1898 }
1899
1900 setLastPageFooter(true);
1901
1902 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1903
1904 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1905
1906
1907 }
1908 }
1909 else if (columnIndex == 0 && offsetY <= lastPageColumnFooterOffsetY)
1910 {
1911
1912
1913
1914
1915 setLastPageFooter(true);
1916
1917 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1918
1919 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1920
1921 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1922
1923 if (summary.isToPrint())
1924 {
1925 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1926 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1927 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1928 scriptlet.callBeforePageInit();
1929 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1930 scriptlet.callAfterPageInit();
1931
1932 addPage(false);
1933
1934 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
1935
1936 JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY);
1937
1938 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
1939 {
1940 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
1941 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1942 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1943 scriptlet.callBeforePageInit();
1944 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1945 scriptlet.callAfterPageInit();
1946
1947 addPage(false);
1948
1949 printBand =
1950 summary.refill(
1951 JRExpression.EVALUATION_DEFAULT,
1952 pageHeight - bottomMargin - offsetY
1953 );
1954 }
1955
1956 fillBand(printBand);
1957 offsetY += printBand.getHeight();
1958 isCrtRecordOnPage = true;
1959 isCrtRecordOnColumn = true;
1960
1961
1962 fillSummaryOverflow();
1963 }
1964
1965
1966 }
1967 else
1968 {
1969
1970
1971
1972
1973 fillColumnFooter(JRExpression.EVALUATION_DEFAULT);
1974
1975 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1976
1977 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
1978 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
1979 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
1980 scriptlet.callBeforePageInit();
1981 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
1982 scriptlet.callAfterPageInit();
1983
1984 addPage(false);
1985
1986 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
1987
1988
1989
1990 setLastPageFooter(true);
1991
1992 if (isSummaryNewPage)
1993 {
1994 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
1995
1996 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
1997
1998 if (summary.isToPrint())
1999 {
2000 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
2001 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2002 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2003 scriptlet.callBeforePageInit();
2004 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2005 scriptlet.callAfterPageInit();
2006
2007 addPage(false);
2008
2009 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
2010
2011 JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY);
2012
2013 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
2014 {
2015 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
2016 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2017 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2018 scriptlet.callBeforePageInit();
2019 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2020 scriptlet.callAfterPageInit();
2021
2022 addPage(false);
2023
2024 printBand =
2025 summary.refill(
2026 JRExpression.EVALUATION_DEFAULT,
2027 pageHeight - bottomMargin - offsetY
2028 );
2029 }
2030
2031 fillBand(printBand);
2032 offsetY += printBand.getHeight();
2033 isCrtRecordOnPage = true;
2034 isCrtRecordOnColumn = true;
2035
2036
2037 fillSummaryOverflow();
2038 }
2039
2040
2041 }
2042 else
2043 {
2044 summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
2045
2046 if (summary.isToPrint())
2047 {
2048 summary.evaluate(JRExpression.EVALUATION_DEFAULT);
2049
2050 JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY);
2051
2052 if (summary.willOverflow() && summary.isSplitPrevented() && !summary.isSplitTypePreventInhibited())
2053 {
2054 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
2055
2056 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
2057 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2058 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2059 scriptlet.callBeforePageInit();
2060 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2061 scriptlet.callAfterPageInit();
2062
2063 addPage(false);
2064
2065 printBand =
2066 summary.refill(
2067 JRExpression.EVALUATION_DEFAULT,
2068 pageHeight - bottomMargin - offsetY
2069 );
2070
2071 fillBand(printBand);
2072 offsetY += printBand.getHeight();
2073 isCrtRecordOnPage = true;
2074 isCrtRecordOnColumn = true;
2075 }
2076 else
2077 {
2078 fillBand(printBand);
2079 offsetY += printBand.getHeight();
2080 isCrtRecordOnPage = true;
2081 isCrtRecordOnColumn = true;
2082
2083 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
2084 }
2085
2086
2087 fillSummaryOverflow();
2088 }
2089 else
2090 {
2091 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
2092 }
2093
2094
2095 }
2096 }
2097 }
2098
2099
2100
2103 @continuable
2104 private void fillSummaryOverflow() throws JRException
2105 {
2106 while (summary.willOverflow())
2107 {
2108 if (isSummaryWithPageHeaderAndFooter)
2109 {
2110 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
2111 }
2112
2113 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
2114 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2115 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2116 scriptlet.callBeforePageInit();
2117 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2118 scriptlet.callAfterPageInit();
2119
2120 addPage(false);
2121
2122 if (isSummaryWithPageHeaderAndFooter)
2123 {
2124 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
2125 }
2126
2127 JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0));
2128
2129 fillBand(printBand);
2130 offsetY += printBand.getHeight();
2131 isCrtRecordOnPage = true;
2132 isCrtRecordOnColumn = true;
2133 }
2134
2135 resolveBandBoundElements(summary, JRExpression.EVALUATION_DEFAULT);
2136
2137 if (isSummaryWithPageHeaderAndFooter)
2138 {
2139 if (offsetY > pageHeight - bottomMargin - lastPageFooter.getHeight())
2140 {
2141 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
2142
2143 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true);
2144 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2145 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2146 scriptlet.callBeforePageInit();
2147 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2148 scriptlet.callAfterPageInit();
2149
2150 addPage(false);
2151
2152 fillPageHeader(JRExpression.EVALUATION_DEFAULT);
2153 }
2154
2155 if (lastPageFooter != missingFillBand)
2156 {
2157 setLastPageFooter(true);
2158 }
2159
2160 fillPageFooter(JRExpression.EVALUATION_DEFAULT);
2161 }
2162 }
2163
2164
2165
2168 private void fillBackground() throws JRException
2169 {
2170 if (log.isDebugEnabled() && !background.isEmpty())
2171 {
2172 log.debug("Fill " + fillerId + ": background at " + offsetY);
2173 }
2174
2175
2176
2177
2178
2179
2180
2181
2182 if (background.getHeight() <= pageHeight - bottomMargin - offsetY)
2183 {
2184 background.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
2185
2186 if (background.isToPrint())
2187 {
2188 background.evaluate(JRExpression.EVALUATION_DEFAULT);
2189
2190 JRPrintBand printBand = background.fill(pageHeight - bottomMargin - offsetY);
2191
2192 fillBand(printBand);
2193
2194 isCrtRecordOnPage = true;
2195 isCrtRecordOnColumn = true;
2196
2197
2198 }
2199 }
2200 }
2201
2202
2203
2206 @continuable
2207 private void addPage(boolean isResetPageNumber) throws JRException
2208 {
2209 if (isSubreport())
2210 {
2211 addPageToParent(false);
2212 }
2213
2214 if (printPage != null)
2215 {
2216 recordUsedPageHeight(offsetY + bottomMargin);
2217 }
2218
2219 printPage = newPage();
2220 printPageContentsWidth = 0;
2221
2222 JRFillVariable pageNumberVar = calculator.getPageNumber();
2223 if (isResetPageNumber)
2224 {
2225 pageNumberVar.setValue(1);
2226 }
2227 else
2228 {
2229 pageNumberVar.setValue(
2230 ((Number)pageNumberVar.getValue()).intValue() + 1
2231 );
2232 }
2233 pageNumberVar.setOldValue(pageNumberVar.getValue());
2234
2235 addPage(printPage);
2236
2237 setFirstColumn();
2238 offsetY = topMargin;
2239 isFirstPageBand = true;
2240 isFirstColumnBand = true;
2241 isCrtRecordOnPage = false;
2242 isCrtRecordOnColumn = false;
2243
2244 fillBackground();
2245 }
2246
2247 private void setFirstColumn()
2248 {
2249 columnIndex = 0;
2250 offsetX = leftMargin;
2251 setColumnNumberVar();
2252 }
2253
2254 private void setColumnNumberVar()
2255 {
2256 JRFillVariable columnNumber = calculator.getColumnNumber();
2257 columnNumber.setValue(columnIndex + 1);
2258 columnNumber.setOldValue(columnNumber.getValue());
2259 }
2260
2261
2264 @continuable
2265 private void fillPageBreak(
2266 boolean isResetPageNumber,
2267 byte evalPrevPage,
2268 byte evalNextPage,
2269 boolean isReprintGroupHeaders
2270 ) throws JRException
2271 {
2272 if (isCreatingNewPage)
2273 {
2274 throw
2275 new JRException(
2276 EXCEPTION_MESSAGE_KEY_INFINITE_LOOP_CREATING_NEW_PAGE,
2277 (Object[])null
2278 );
2279 }
2280
2281 if (groups != null)
2282 {
2283 for (JRFillGroup group : groups)
2284 {
2285 if (group.getKeepTogetherElementRange() != null)
2286 {
2287 group.getKeepTogetherElementRange().expand(offsetY);
2288 }
2289 }
2290 }
2291
2292 FooterPositionEnum groupFooterPositionForOverflow = null;
2293 if (groupFooterPositionElementRange != null)
2294 {
2295 groupFooterPositionForOverflow = groupFooterPositionElementRange.getCurrentFooterPosition();
2296
2297
2298 groupFooterPositionElementRange.getElementRange().expand(offsetY);
2299 }
2300
2301 if (orphanGroupFooterElementRange != null)
2302 {
2303
2304
2305 orphanGroupFooterElementRange.expand(offsetY);
2306 }
2307 else if (orphanGroupFooterDetailElementRange != null)
2308 {
2309
2310
2311 orphanGroupFooterDetailElementRange.expand(offsetY);
2312 }
2313
2314 isCreatingNewPage = true;
2315
2316 fillColumnFooter(evalPrevPage);
2317
2318 fillPageFooter(evalPrevPage);
2319
2320 resolveGroupBoundElements(evalPrevPage, false);
2321 resolveColumnBoundElements(evalPrevPage);
2322 resolvePageBoundElements(evalPrevPage);
2323 scriptlet.callBeforePageInit();
2324 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2325 scriptlet.callAfterPageInit();
2326
2327 JRFillGroup keepTogetherGroup = getKeepTogetherGroup();
2328
2329 ElementRange elementRangeToMove = null;
2330 ElementRange elementRangeToMove2 = null;
2331 if (keepTogetherGroup != null)
2332 {
2333 elementRangeToMove = keepTogetherGroup.getKeepTogetherElementRange();
2334 }
2335 else if (orphanGroupFooterDetailElementRange != null)
2336 {
2337 elementRangeToMove = orphanGroupFooterDetailElementRange;
2338 elementRangeToMove2 = orphanGroupFooterElementRange;
2339 }
2340
2341 if (floatColumnFooterElementRange != null && elementRangeToMove != null)
2342 {
2343 ElementRangeUtil.moveContent(floatColumnFooterElementRange, elementRangeToMove.getTopY());
2344 }
2345
2346
2347 ElementRangeContents elementsToMove2 = null;
2348 if (elementRangeToMove2 != null)
2349 {
2350 elementsToMove2 = ElementRangeUtil.removeContent(elementRangeToMove2, delayedActions);
2351 }
2352 ElementRangeContents elementsToMove = null;
2353 if (elementRangeToMove != null)
2354 {
2355 elementsToMove = ElementRangeUtil.removeContent(elementRangeToMove, delayedActions);
2356 }
2357
2358 addPage(isResetPageNumber);
2359
2360 fillPageHeader(evalNextPage);
2361
2362 fillColumnHeader(evalNextPage);
2363
2364 if (isReprintGroupHeaders)
2365 {
2366 fillGroupHeadersReprint(evalNextPage, true);
2367
2368 ElementRange keepTogetherElementRange = keepTogetherGroup == null ? null : keepTogetherGroup.getKeepTogetherElementRange();
2369
2370 if (
2371 keepTogetherElementRange != null
2372 && offsetY > keepTogetherElementRange.getTopY()
2373 )
2374 {
2375 throw new JRException(EXCEPTION_MESSAGE_KEY_KEEP_TOGETHER_CONTENT_DOES_NOT_FIT, (Object[]) null);
2376 }
2377 }
2378
2379
2380 orphanGroupFooterDetailElementRange = null;
2381 orphanGroupFooterElementRange = null;
2382 detailElementRange = null;
2383 if (keepTogetherGroup != null)
2384 {
2385 keepTogetherGroup.setKeepTogetherElementRange(null);
2386 }
2387
2388 if (elementRangeToMove != null)
2389 {
2390 ElementRangeUtil.addContent(
2391 printPage,
2392 currentPageIndex(),
2393 elementsToMove,
2394
2395 (columnIndex - elementRangeToMove.getColumnIndex()) * (columnSpacing + columnWidth),
2396 offsetY - elementRangeToMove.getTopY(),
2397 delayedActions
2398 );
2399
2400 offsetY = offsetY + elementRangeToMove.getBottomY() - elementRangeToMove.getTopY();
2401
2402 if (elementRangeToMove2 != null)
2403 {
2404 ElementRangeUtil.addContent(
2405 printPage,
2406 currentPageIndex(),
2407 elementsToMove2,
2408
2409 (columnIndex - elementRangeToMove2.getColumnIndex()) * (columnSpacing + columnWidth),
2410 offsetY - elementRangeToMove2.getTopY(),
2411 delayedActions
2412 );
2413
2414 offsetY = offsetY + elementRangeToMove2.getBottomY() - elementRangeToMove2.getTopY();
2415 }
2416
2417 isFirstPageBand = false;
2418 isFirstColumnBand = false;
2419 }
2420 else if (
2421 groupFooterPositionForOverflow != null
2422 && groupFooterPositionForOverflow != FooterPositionEnum.NORMAL
2423 )
2424 {
2425
2426
2427 groupFooterPositionElementRange =
2428 new SimpleGroupFooterElementRange(
2429 new SimpleElementRange(getCurrentPage(), columnIndex, offsetY),
2430 groupFooterPositionForOverflow
2431 );
2432 }
2433
2434 isCreatingNewPage = false;
2435 }
2436
2437
2438
2441 @continuable
2442 private void fillColumnBreak(
2443 byte evalPrevPage,
2444 byte evalNextPage
2445 ) throws JRException
2446 {
2447 if (columnIndex == columnCount - 1)
2448 {
2449 fillPageBreak(false, evalPrevPage, evalNextPage, true);
2450 }
2451 else
2452 {
2453 if (groups != null)
2454 {
2455 for (JRFillGroup group : groups)
2456 {
2457 if (group.getKeepTogetherElementRange() != null)
2458 {
2459 group.getKeepTogetherElementRange().expand(offsetY);
2460 }
2461 }
2462 }
2463
2464 FooterPositionEnum groupFooterPositionForOverflow = null;
2465 if (groupFooterPositionElementRange != null)
2466 {
2467 groupFooterPositionForOverflow = groupFooterPositionElementRange.getCurrentFooterPosition();
2468
2469
2470 groupFooterPositionElementRange.getElementRange().expand(offsetY);
2471 }
2472
2473 if (orphanGroupFooterElementRange != null)
2474 {
2475
2476
2477 orphanGroupFooterElementRange.expand(offsetY);
2478 }
2479 else if (orphanGroupFooterDetailElementRange != null)
2480 {
2481
2482
2483 orphanGroupFooterDetailElementRange.expand(offsetY);
2484 }
2485
2486 fillColumnFooter(evalPrevPage);
2487
2488 resolveGroupBoundElements(evalPrevPage, false);
2489 resolveColumnBoundElements(evalPrevPage);
2490 scriptlet.callBeforeColumnInit();
2491 calculator.initializeVariables(ResetTypeEnum.COLUMN, IncrementTypeEnum.COLUMN);
2492 scriptlet.callAfterColumnInit();
2493
2494 JRFillGroup keepTogetherGroup = getKeepTogetherGroup();
2495
2496 ElementRange elementRangeToMove = null;
2497 ElementRange elementRangeToMove2 = null;
2498 if (keepTogetherGroup != null)
2499 {
2500 elementRangeToMove = keepTogetherGroup.getKeepTogetherElementRange();
2501 }
2502 else if (orphanGroupFooterDetailElementRange != null)
2503 {
2504 elementRangeToMove = orphanGroupFooterDetailElementRange;
2505 elementRangeToMove2 = orphanGroupFooterElementRange;
2506 }
2507
2508 if (floatColumnFooterElementRange != null && elementRangeToMove != null)
2509 {
2510 ElementRangeUtil.moveContent(floatColumnFooterElementRange, elementRangeToMove.getTopY());
2511 }
2512
2513
2514 ElementRangeContents elementsToMove2 = null;
2515 if (elementRangeToMove2 != null)
2516 {
2517 elementsToMove2 = ElementRangeUtil.removeContent(elementRangeToMove2, delayedActions);
2518 }
2519 ElementRangeContents elementsToMove = null;
2520 if (elementRangeToMove != null)
2521 {
2522 elementsToMove = ElementRangeUtil.removeContent(elementRangeToMove, null);
2523 }
2524
2525 columnIndex += 1;
2526 setOffsetX();
2527 offsetY = columnHeaderOffsetY;
2528 isCrtRecordOnColumn = false;
2529
2530 setColumnNumberVar();
2531
2532 fillColumnHeader(evalNextPage);
2533
2534
2535 {
2536 fillGroupHeadersReprint(evalNextPage, false);
2537
2538 ElementRange keepTogetherElementRange = keepTogetherGroup == null ? null : keepTogetherGroup.getKeepTogetherElementRange();
2539
2540 if (
2541 keepTogetherElementRange != null
2542 && offsetY > keepTogetherElementRange.getTopY()
2543 )
2544 {
2545 throw new JRException(EXCEPTION_MESSAGE_KEY_KEEP_TOGETHER_CONTENT_DOES_NOT_FIT, (Object[]) null);
2546 }
2547 }
2548
2549
2550 orphanGroupFooterDetailElementRange = null;
2551 orphanGroupFooterElementRange = null;
2552 detailElementRange = null;
2553 if (keepTogetherGroup != null)
2554 {
2555 keepTogetherGroup.setKeepTogetherElementRange(null);
2556 }
2557
2558 if (elementRangeToMove != null)
2559 {
2560 ElementRangeUtil.addContent(
2561 printPage,
2562 currentPageIndex(),
2563 elementsToMove,
2564
2565 (columnIndex - elementRangeToMove.getColumnIndex()) * (columnSpacing + columnWidth),
2566 offsetY - elementRangeToMove.getTopY(),
2567 delayedActions
2568 );
2569
2570 offsetY = offsetY + elementRangeToMove.getBottomY() - elementRangeToMove.getTopY();
2571
2572 if (elementRangeToMove2 != null)
2573 {
2574 ElementRangeUtil.addContent(
2575 printPage,
2576 currentPageIndex(),
2577 elementsToMove2,
2578
2579 (columnIndex - elementRangeToMove2.getColumnIndex()) * (columnSpacing + columnWidth),
2580 offsetY - elementRangeToMove2.getTopY(),
2581 delayedActions
2582 );
2583
2584 offsetY = offsetY + elementRangeToMove2.getBottomY() - elementRangeToMove2.getTopY();
2585 }
2586
2587 isFirstPageBand = false;
2588 isFirstColumnBand = false;
2589 }
2590 else if (
2591 groupFooterPositionForOverflow != null
2592 && groupFooterPositionForOverflow != FooterPositionEnum.NORMAL
2593 )
2594 {
2595
2596
2597 groupFooterPositionElementRange =
2598 new SimpleGroupFooterElementRange(
2599 new SimpleElementRange(getCurrentPage(), columnIndex, offsetY),
2600 groupFooterPositionForOverflow
2601 );
2602 }
2603 }
2604 }
2605
2606
2607
2610 @continuable
2611 protected void fillColumnBand(JRFillBand band, byte evaluation, boolean recalculateVariables) throws JRException
2612 {
2613 band.evaluate(evaluation);
2614
2615 JRPrintBand printBand = band.fill(columnFooterOffsetY - offsetY);
2616
2617 if (band.willOverflow())
2618 {
2619 boolean toRefill = band.isSplitPrevented() && !band.isSplitTypePreventInhibited();
2620
2621 if (!toRefill)
2622 {
2623 if (groups != null)
2624 {
2625
2626
2627
2628
2629 for (JRFillGroup group : groups)
2630 {
2631 if (
2632 group.getKeepTogetherElementRange() != null
2633 && (group.isKeepTogether() || !group.hasMinDetails())
2634 )
2635 {
2636 toRefill = true;
2637 break;
2638 }
2639 }
2640 }
2641 }
2642
2643 if (!toRefill)
2644 {
2645 if (orphanGroupFooterDetailElementRange != null)
2646 {
2647 toRefill = true;
2648 }
2649 }
2650
2651 if (toRefill)
2652 {
2653 fillColumnBreak(
2654 evaluation == JRExpression.EVALUATION_DEFAULT
2655 ? (isCrtRecordOnColumn ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD)
2656 : evaluation,
2657 evaluation
2658 );
2659
2660 if (recalculateVariables)
2661 {
2662 @SuppressWarnings("deprecation")
2663 boolean isLegacyBandEvaluationEnabled = getFillContext().isLegacyBandEvaluationEnabled();
2664 if (!isLegacyBandEvaluationEnabled)
2665 {
2666 mainDataset.revertVariablesToOldValues();
2667
2668 calculator.recalculateVariables();
2669 }
2670 }
2671
2672 printBand = band.refill(evaluation, columnFooterOffsetY - offsetY);
2673 }
2674 }
2675
2676 fillBand(printBand);
2677 offsetY += printBand.getHeight();
2678 isCrtRecordOnPage = evaluation == JRExpression.EVALUATION_DEFAULT;
2679 isCrtRecordOnColumn = isCrtRecordOnPage;
2680
2681 while (band.willOverflow())
2682 {
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695 if (band.willOverflowWithElements())
2696 {
2697 fillColumnBreak(
2698 evaluation == JRExpression.EVALUATION_DEFAULT
2699 ? (isCrtRecordOnColumn ? JRExpression.EVALUATION_DEFAULT : JRExpression.EVALUATION_OLD)
2700 : evaluation,
2701 evaluation
2702 );
2703 }
2704
2705
2706
2707
2708
2709 printBand = band.fill(columnFooterOffsetY - offsetY);
2710
2711 fillBand(printBand);
2712 offsetY += printBand.getHeight();
2713 isCrtRecordOnPage = evaluation == JRExpression.EVALUATION_DEFAULT;
2714 isCrtRecordOnColumn = isCrtRecordOnPage;
2715 }
2716
2717 resolveBandBoundElements(band, evaluation);
2718 }
2719
2720
2721
2724 protected void fillFixedBand(JRFillBand band, byte evaluation) throws JRException
2725 {
2726 band.evaluate(evaluation);
2727
2728 JRPrintBand printBand = band.fill();
2729
2730 fillBand(printBand);
2731 offsetY += printBand.getHeight();
2732 isCrtRecordOnPage = evaluation == JRExpression.EVALUATION_DEFAULT;
2733 isCrtRecordOnColumn = isCrtRecordOnPage;
2734
2735 resolveBandBoundElements(band, evaluation);
2736 }
2737
2738
2739
2742 private void setNewPageColumnInBands()
2743 {
2744 title.setNewPageColumn(true);
2745 pageHeader.setNewPageColumn(true);
2746 columnHeader.setNewPageColumn(true);
2747 detailSection.setNewPageColumn(true);
2748 columnFooter.setNewPageColumn(true);
2749 pageFooter.setNewPageColumn(true);
2750 lastPageFooter.setNewPageColumn(true);
2751 summary.setNewPageColumn(true);
2752 noData.setNewPageColumn(true);
2753
2754 if (groups != null && groups.length > 0)
2755 {
2756 for(int i = 0; i < groups.length; i++)
2757 {
2758 ((JRFillSection)groups[i].getGroupHeaderSection()).setNewPageColumn(true);
2759 ((JRFillSection)groups[i].getGroupFooterSection()).setNewPageColumn(true);
2760 }
2761 }
2762 }
2763
2764
2765
2768 private void setNewGroupInBands(JRGroup group)
2769 {
2770 title.setNewGroup(group, true);
2771 pageHeader.setNewGroup(group, true);
2772 columnHeader.setNewGroup(group, true);
2773 detailSection.setNewGroup(group, true);
2774 columnFooter.setNewGroup(group, true);
2775 pageFooter.setNewGroup(group, true);
2776 lastPageFooter.setNewGroup(group, true);
2777 summary.setNewGroup(group, true);
2778 noData.setNewGroup(group, true);
2779
2780 if (groups != null && groups.length > 0)
2781 {
2782 for(int i = 0; i < groups.length; i++)
2783 {
2784 ((JRFillSection)groups[i].getGroupHeaderSection()).setNewGroup(group, true);
2785 ((JRFillSection)groups[i].getGroupFooterSection()).setNewGroup(group, true);
2786 }
2787 }
2788 }
2789
2790
2791
2794 private JRFillBand getCurrentPageFooter()
2795 {
2796 return isLastPageFooter ? lastPageFooter : pageFooter;
2797 }
2798
2799
2800
2803 private void setLastPageFooter(boolean isLastPageFooter)
2804 {
2805 this.isLastPageFooter = isLastPageFooter;
2806
2807 if (isLastPageFooter)
2808 {
2809 columnFooterOffsetY = lastPageColumnFooterOffsetY;
2810 }
2811 }
2812
2813
2814
2817 @continuable
2818 private void fillNoData() throws JRException
2819 {
2820 if (log.isDebugEnabled() && !noData.isEmpty())
2821 {
2822 log.debug("Fill " + fillerId + ": noData at " + offsetY);
2823 }
2824
2825 noData.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
2826
2827 if (noData.isToPrint())
2828 {
2829 while (noData.getBreakHeight() > pageHeight - bottomMargin - offsetY)
2830 {
2831 addPage(false);
2832 }
2833
2834 noData.evaluate(JRExpression.EVALUATION_DEFAULT);
2835
2836 JRPrintBand printBand = noData.fill(pageHeight - bottomMargin - offsetY);
2837
2838 if (noData.willOverflow() && noData.isSplitPrevented() && !noData.isSplitTypePreventInhibited())
2839 {
2840 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
2841 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2842 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2843 scriptlet.callBeforePageInit();
2844 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2845 scriptlet.callAfterPageInit();
2846
2847 addPage(false);
2848
2849 printBand =
2850 noData.refill(
2851 JRExpression.EVALUATION_DEFAULT,
2852 pageHeight - bottomMargin - offsetY
2853 );
2854 }
2855
2856 fillBand(printBand);
2857 offsetY += printBand.getHeight();
2858 isCrtRecordOnPage = true;
2859 isCrtRecordOnColumn = true;
2860
2861 while (noData.willOverflow())
2862 {
2863 resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false);
2864 resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT);
2865 resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT);
2866 scriptlet.callBeforePageInit();
2867 calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE);
2868 scriptlet.callAfterPageInit();
2869
2870 addPage(false);
2871
2872 printBand = noData.fill(pageHeight - bottomMargin - offsetY);
2873
2874 fillBand(printBand);
2875 offsetY += printBand.getHeight();
2876 isCrtRecordOnPage = true;
2877 isCrtRecordOnColumn = true;
2878 }
2879
2880 resolveBandBoundElements(noData, JRExpression.EVALUATION_DEFAULT);
2881 }
2882 }
2883
2884
2885
2888 private void setOffsetX()
2889 {
2890 if (columnDirection == RunDirectionEnum.RTL)
2891 {
2892 offsetX = pageWidth - rightMargin - columnWidth - columnIndex * (columnSpacing + columnWidth);
2893 }
2894 else
2895 {
2896 offsetX = leftMargin + columnIndex * (columnSpacing + columnWidth);
2897 }
2898 }
2899
2900
2901 }
2902