ในกระบวนการ Fill Stage ตัวประมวลผล JRVerticalFiller ทำหน้าที่เรนเดอร์เอกสารทีละ Element ตามระนาบดิ่ง เมื่อกล่องข้อความถูกอนุญาตให้ขยายตัวเกิน Design Height เครื่องยนต์จะคำนวณระยะขยายตัวสะสม (ΔY) และแปลงพิกัดของ Element ด้านล่างด้วยระบบ Relative Y-Offset
หัวใจทางเทคนิคของสถาปัตยกรรม 7.0.x:
<element kind="..."> ปลดระวางแท็กแยกย่อยโบราณ เพื่อลดจำนวนคลาสใน Metaspace และช่วยให้ JIT Compiler สร้าง Native Bytecode ได้เร็วขึ้นY ของ Element ด้านล่างที่มี positionType="Float" จะถูกคำนวณใหม่เสมอ:
Y_final = Y_design + Total_Stretch_Delta_Above
isStretchWithOverflow โบราณ และบังคับใช้ textAdjust="StretchHeight" เพื่อกระตุ้นให้เครื่องยนต์จัดสรรพื้นที่แนวตั้งตามเนื้อหาจริง| แอตทริบิวต์ | พฤติกรรมทางวิศวกรรมระดับ JVM |
|---|---|
positionType="Float" |
เลื่อนตำแหน่งลงตามระยะยืดสะสมของทุก Element ที่วางอยู่เหนือมันตามแนวตั้ง |
textAdjust="StretchHeight" |
ขยายความสูงของกรอบข้อความลงมาในแนวตั้งเมื่อข้อความล้น Design Height |
stretchType="ElementGroupHeight" |
ปรับความสูงของ Element (เช่น เส้นแบ่งตาราง) ให้เท่ากับสมาชิกที่สูงที่สุดใน <elementGroup> |
stretchType="ContainerHeight" |
ยืดความสูงเต็มระนาบสุทธิของ Container แม่ (เช่น <frame> หรือ Band) |
positionType="FixRelativeToTop" เครื่องยนต์จะวาดข้อความตัวล่างทับซ้อนลงไปบนข้อความตัวบนทันที ส่งผลให้เอกสารบน Production กลายเป็นข้อความขยะที่อ่านไม่ออก และทำให้ตารางบน Excel แตกเป็น Merged Cells กระจายจนไม่สามารถนำข้อมูลไปคำนวณต่อได้
<!-- Detail Band: ป้องกันการชนและซิงโครไนซ์ตาราง (7.0.x Schema) -->
<detail>
<band height="65" splitType="Prevent">
<elementGroup>
<!-- กล่องรายละเอียดสินค้า: ยืดตามเนื้อหาจริง -->
<element kind="textField" x="0" y="5" width="280" height="20"
textAdjust="StretchHeight" blankWhenNull="true">
<expression><![CDATA[$F{item_description}]]></expression>
</element>
<!-- เส้นแบ่งตารางแนวตั้ง: ยืดเท่ากับความสูงของกลุ่มสินค้า -->
<element kind="line" x="290" y="0" width="1" height="30"
stretchType="ElementGroupHeight"/>
<!-- ช่องราคา: ตรึงพิกัดขอบบน -->
<element kind="textField" x="300" y="5" width="100" height="20">
<expression><![CDATA[$F{unit_price}]]></expression>
</element>
</elementGroup>
<!-- กล่องข้อความหมายเหตุ: หลบลงมาอัตโนมัติตาม Relative Y-Offset -->
<element kind="textField" x="0" y="32" width="280" height="18"
positionType="Float" blankWhenNull="true">
<expression><![CDATA[$F{item_notes}]]></expression>
</element>
<!-- คอนเทนเนอร์สถานะ: กักกันพิกัด Local Coordinates (0,0) -->
<element kind="frame" x="410" y="5" width="145" height="30"
positionType="Float">
<element kind="rectangle" x="0" y="0" width="145" height="30"
stretchType="ContainerHeight"/>
<element kind="staticText" x="5" y="5" width="135" height="20">
<text><![CDATA[VERIFIED]]></text>
</element>
</element>
</band>
</detail>
กลไกการทำงานของโค้ด:
• blankWhenNull="true": ดักจับข้อมูลว่าง ไม่ให้เรนเดอร์คำว่า "null" บนรายงาน
• <elementGroup>: นิยามขอบเขตความสูงร่วม เพื่อให้เส้นแบ่งคอลัมน์ยืดลงมาบรรจบพอดีกับบรรทัดสุดท้ายของคำอธิบายสินค้า
เงื่อนไขทางเทคนิค (Full-Coverage 100%):
1. แปลงแท็กโบราณเป็น 7.0.x Unified Element Model (<element kind="textField" ...>)
2. กำหนดให้ฟิลด์ $F{item_description} ขยายตัวอัตโนมัติตามข้อความจริงด้วย textAdjust="StretchHeight"
3. ป้องกันปัญหา Overlapping Collision โดยกำหนดให้กล่องหมายเหตุ $F{item_note} ด้านล่างมี positionType="Float"
4. ใส่ blankWhenNull="true" บนทุกฟิลด์เพื่อป้องกันข้อความ "null" หลุดไปบน Production
5. กำหนด splitType="Prevent" ที่ Detail Band เพื่อป้องกันแถวข้อมูลฉีกขาดระหว่างหน้า
เงื่อนไขทางเทคนิค (Full-Coverage 100%):
1. ครอบฟิลด์ข้อความยาว $F{cluster_specification} และเส้นแบ่งคอลัมน์ด้วย <elementGroup>
2. กำหนดเส้นคั่นแนวตั้ง <element kind="line" ...> ให้ยืดความสูงเท่ากับกลุ่มข้อมูลด้วย stretchType="ElementGroupHeight"
3. กักกันพิกัด Local Coordinates ของกล่องสถานะด้วยคอนเทนเนอร์ <element kind="frame" ...> โดยตั้งค่า positionType="Float"
4. กำหนดให้รูปทรงสี่เหลี่ยมผืนผ้าภายใน Frame ขยายตัวเต็มกรอบคอนเทนเนอร์ด้วย stretchType="ContainerHeight"
5. ตรวจสอบให้แน่ใจว่าไม่มีการวางคอลัมน์เหลื่อมล้ำทับซ้อนกันในแนวนอน (Zero Horizontal Overlap)
แบบทดสอบ 15 ข้อเชิงลึก อ้างอิงจากหลักการ Dynamic Sizing, Coordinate Calculations และกลไกหลบการชนบน Production: