1 package jimm.datavision.layout; 2 import jimm.datavision.*; 3 import jimm.datavision.field.Field; 4 import jimm.datavision.field.ImageField; 5 import java.io.PrintWriter ; 6 import java.util.*; 7 8 16 public abstract class LayoutEngine { 17 18 19 public static final int POINTS_PER_INCH = 72; 20 21 protected static final int SECT_REPORT_HEADER = 0; 22 protected static final int SECT_REPORT_FOOTER = 1; 23 protected static final int SECT_PAGE_HEADER = 2; 24 protected static final int SECT_PAGE_FOOTER = 3; 25 protected static final int SECT_GROUP_HEADER = 4; 26 protected static final int SECT_GROUP_FOOTER = 5; 27 protected static final int SECT_DETAIL = 6; 28 29 30 protected Report report; 31 protected int pageNumber; 32 protected PrintWriter out; 33 protected boolean newPage; 34 protected double pageHeight; 35 protected double pageWidth; 36 protected double pageHeightUsed; 37 protected Section currentSection; 38 protected boolean wantsMoreData; 39 protected int previousSectionArea; 40 41 44 public LayoutEngine() { 45 this(null); 46 } 47 48 53 public LayoutEngine(PrintWriter out) { 54 report = null; 55 this.out = out; 56 wantsMoreData = true; 57 previousSectionArea = -1; 58 } 59 60 public void setReport(Report r) { report = r; } 61 62 68 public double pageWidth() { return pageWidth; } 69 70 76 public double pageHeight() { return pageHeight; } 77 78 86 public boolean wantsMoreData() { return wantsMoreData; } 87 88 92 public void cancel() { 93 closeOutput(); 94 } 95 96 103 public void start() { 104 newPage = true; 105 pageHeightUsed = 0; 106 pageNumber = 0; 107 pageHeight = report.getPaperFormat().getHeight(); 108 pageWidth = report.getPaperFormat().getWidth(); 109 if (wantsMoreData) { 110 doStart(); 111 startPage(); 112 } 113 } 114 115 119 protected void doStart() { } 120 121 124 public void end() { 125 if (wantsMoreData) { 126 for (Iterator iter = report.footers().iterator(); iter.hasNext(); ) 127 outputSection((Section)iter.next(), SECT_REPORT_FOOTER); 128 endPage(true); 129 doEnd(); 130 } 131 closeOutput(); 132 } 133 134 138 protected void doEnd() {} 139 140 141 144 protected void closeOutput() { 145 if (out != null) { 146 out.flush(); 147 out.close(); 148 out = null; 149 } 150 } 151 152 163 public void groupHeaders(boolean isLastRow) { 164 if (!wantsMoreData) 165 return; 166 167 boolean headerWasOutput = false; 168 for (Iterator iter = report.groups(); iter.hasNext(); ) { 169 Group g = (Group)iter.next(); 170 if (headerWasOutput || g.isNewValue()) { 171 for (Iterator i2 = g.headers().iterator(); i2.hasNext(); ) 172 ((Section)i2.next()).evaluateFormulas(); 173 headerWasOutput = true; 174 } 175 } 176 178 checkRemainingPageLength(isLastRow, true); 179 180 headerWasOutput = false; 181 for (Iterator iter = report.groups(); iter.hasNext(); ) { 182 Group g = (Group)iter.next(); 183 if (headerWasOutput || g.isNewValue()) { 184 for (Iterator i2 = g.headers().iterator(); i2.hasNext(); ) 185 outputSection((Section)i2.next(), SECT_GROUP_HEADER); 186 headerWasOutput = true; 187 } 188 } 189 } 190 191 196 public void detail(boolean isLastRow) { 197 if (!wantsMoreData) 198 return; 199 200 checkRemainingPageLength(isLastRow, true); 201 for (Iterator iter = report.details().iterator(); iter.hasNext(); ) 202 outputSection((Section)iter.next(), SECT_DETAIL); 203 } 204 205 212 public void groupFooters(boolean isLastRow) { 213 if (!wantsMoreData) 214 return; 215 216 checkRemainingPageLength(isLastRow, false); 217 218 boolean footerWasOutput = false; 224 ArrayList groupsToOutput = new ArrayList(); 225 for (Iterator iter = report.groups(); iter.hasNext(); ) { 226 Group g = (Group)iter.next(); 227 if (footerWasOutput || g.isNewValue() || isLastRow) { 228 if (footerWasOutput) g.forceFooterOutput(); 229 groupsToOutput.add(g); 230 footerWasOutput = true; 231 } 232 } 233 234 Collections.reverse(groupsToOutput); 236 for (Iterator iter = groupsToOutput.iterator(); iter.hasNext(); ) { 237 Group g = (Group)iter.next(); 238 for (Iterator i2 = g.footers().iterator(); i2.hasNext(); ) 239 outputSection((Section)i2.next(), SECT_GROUP_FOOTER); 240 } 241 } 242 243 251 protected void checkRemainingPageLength(boolean isLastRow, 252 boolean includeDetail) 253 { 254 double detailHeight = includeDetail ? calcDetailHeight() : 0; 258 double footerHeight = calcPageFooterHeight(); 259 if (isLastRow) footerHeight += calcReportFooterHeight(); 260 261 if ((pageHeightUsed + footerHeight + detailHeight) > pageHeight()) 262 endPage(isLastRow); 263 264 if (newPage) startPage(); 265 } 266 267 272 public int pageNumber() { return pageNumber; } 273 274 277 protected void startPage() { 278 if (!wantsMoreData) 279 return; 280 281 pageNumber += 1; 282 pageHeightUsed = 0; 283 newPage = false; 284 285 doStartPage(); 286 if (pageNumber == 1) { 287 for (Iterator iter = report.headers().iterator(); iter.hasNext(); ) 288 outputSection((Section)iter.next(), SECT_REPORT_HEADER); 289 } 290 for (Iterator iter = report.pageHeaders().iterator(); iter.hasNext(); ) 291 outputSection((Section)iter.next(), SECT_PAGE_HEADER); 292 } 293 294 298 protected void doStartPage() { } 299 300 305 protected void endPage(boolean isLastPage) { 306 if (!wantsMoreData) 307 return; 308 309 for (Iterator iter = report.pageFooters().iterator(); iter.hasNext(); ) 310 outputSection((Section)iter.next(), SECT_PAGE_FOOTER); 311 312 newPage = true; 313 doEndPage(); 314 } 315 316 320 protected void doEndPage() { } 321 322 329 protected void outputSection(Section sect, int which) { 330 if (!wantsMoreData) 331 return; 332 333 if (sect.isVisibleForCurrentRow()) { 334 if (sect.hasPageBreak() 336 && previousSectionArea != SECT_PAGE_HEADER) 337 { 338 endPage(false); 339 startPage(); 340 } 341 342 currentSection = sect; 345 report.evaluateFormulasIn(currentSection); 346 doOutputSection(currentSection); 347 348 pageHeightUsed += sect.getOutputHeight(); 349 previousSectionArea = which; 350 } 351 else { 352 report.evaluateFormulasIn(sect); 354 } 355 } 356 357 363 protected void doOutputSection(Section sect) { 364 for (Iterator iter = sect.fields(); iter.hasNext(); ) { 366 Field f = (Field)iter.next(); 367 if (f.isVisible()) { 368 if (f instanceof ImageField) 369 outputImage((ImageField)f); 370 else 371 outputField(f); 372 } 373 } 374 for (Iterator iter = sect.lines(); iter.hasNext(); ) { 376 Line l = (Line)iter.next(); 377 if (l.isVisible()) outputLine(l); 378 } 379 } 380 381 386 protected void outputField(Field field) { 387 if (wantsMoreData) doOutputField(field); 389 } 390 391 397 protected abstract void doOutputField(Field field); 398 399 404 protected void outputImage(ImageField image) { 405 if (wantsMoreData) doOutputImage(image); 407 } 408 409 415 protected abstract void doOutputImage(ImageField image); 416 417 422 protected void outputLine(Line line) { 423 if (wantsMoreData) 424 doOutputLine(line); 425 } 426 427 433 protected abstract void doOutputLine(Line line); 434 435 440 protected String currentSectionTypeAsString() { 441 switch (currentSection.getArea().getArea()) { 442 case SectionArea.REPORT_HEADER: return "report header"; 443 case SectionArea.REPORT_FOOTER: return "report footer"; 444 case SectionArea.PAGE_HEADER: return "page header"; 445 case SectionArea.PAGE_FOOTER: return "page footer"; 446 case SectionArea.GROUP_HEADER: return "group header"; 447 case SectionArea.GROUP_FOOTER: return "group footer"; 448 case SectionArea.DETAIL: return "detail"; 449 default: return "unknown"; } 451 } 452 453 459 protected double calcSectionHeights(SectionArea area) { 460 double sum = 0; 461 for (Iterator iter = area.iterator(); iter.hasNext(); ) { 462 Section s = (Section)iter.next(); 463 if (s.isVisibleForCurrentRow()) 464 sum += s.getOutputHeight(); 465 } 466 return sum; 467 } 468 469 474 protected double calcDetailHeight() { 475 return calcSectionHeights(report.details()); 476 } 477 478 483 protected double calcPageFooterHeight() { 484 return calcSectionHeights(report.pageFooters()); 485 } 486 487 492 protected double calcReportFooterHeight() { 493 return calcSectionHeights(report.footers()); 494 } 495 496 } 497 | Popular Tags |