Java Pagination and Printing

R

rj

Hi

I am presently making decisions regarding how to paginate on screen
reports to a printer using java. The on screen reports are shown in a
jedtiorpane, with the editorpane set to display an html file (which
contains the report). Is there any conceivable way to find the height
of the *contents* within the jeditorpane (ie the height of the html -
not the height of the jeditorpane itself)? If so, it would be possible
to determine if the length of content is greater than a imageable
page, and paginate accordingly, as opposed to attempting to count how
much room displayed html takes based on fonts etc (not lightweight!).

All help appreciated. Thanks in advance.

RJ
 
Joined
Aug 19, 2006
Messages
4
Reaction score
0
Solution for pagination / page layout in the JEditorPane.

import javax.swing.text.*;
import javax.swing.*;
import java.awt.*;

public class CetiEditorKit extends StyledEditorKit {
protected static final int PAGE_WIDTH = 612;
protected static final int PAGE_HEIGHT = 400;
protected static final int PAGE_INSET = 20;
protected static final Insets PAGE_MARGIN = new Insets(10, 10, 10, 10);
protected static final Color BACKGROUND = Color.GRAY;

private ViewFactory factory;


public static void main(String[] args) {
JTextPane pane = new JTextPane();
pane.setEditorKit(new CetiEditorKit());

JPanel jpan = new JPanel(new BorderLayout());
jpan.add(new JScrollPane(pane));

JFrame frame = new JFrame();
frame.getContentPane().add(jpan);

frame.setSize(1024, 800);
frame.show();
}

public CetiEditorKit() {
factory = new PagingViewFactory();
}

public ViewFactory getViewFactory() {
return factory;
}

protected int calculatePageBreak(int pageNumber) {
int pageBreak = (pageNumber * PAGE_HEIGHT) - PAGE_INSET - PAGE_MARGIN.bottom;
return pageBreak;
}

private class PagingViewFactory implements ViewFactory {
public View create(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new LabelView(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new PagingParagraphView(elem);
} else if (kind.equals(AbstractDocument.SectionElementName)) {
return new SectionView(elem, View.Y_AXIS);
} else if (kind.equals(StyleConstants.ComponentElementName)) {
return new ComponentView(elem);
} else if (kind.equals(StyleConstants.IconElementName)) {
return new IconView(elem);
}
}
// default to text display
return new LabelView(elem);
}
}

private class SectionView extends BoxView {
private int pageNumber;


/**
* Creates a view from an element that spans the supplied axis
* @param element
* @param axis
*/
public SectionView(Element element, int axis) {
super(element, axis);

// apply insets to width but not top/bottom as it distorts
// breaking calculations
setInsets((short) (0),
(short) (PAGE_INSET + PAGE_MARGIN.left),
(short) (0),
(short) (PAGE_INSET + PAGE_MARGIN.right));
}


protected void layout(int width, int height) {
width = PAGE_WIDTH - 2 * PAGE_INSET - PAGE_MARGIN.left - PAGE_MARGIN.right;
super.layout(width, height);
}


public float getPreferredSpan(int axis) {
float span = 0;
if (axis == View.X_AXIS) {
span = PAGE_WIDTH;
} else {
span = pageNumber * PAGE_HEIGHT;
}
return span;
}


public float getMinimumSpan(int axis) {
return getPreferredSpan(axis);
}


public float getMaximumSpan(int axis) {
return getPreferredSpan(axis);
}


protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
super.layoutMajorAxis(targetSpan, axis, offsets, spans);

int totalOffset = PAGE_INSET + PAGE_MARGIN.top;
int pageBreak;
pageNumber = 1;
PagingParagraphView view;

for (int i = 0; i < offsets.length; i++) {
offsets = totalOffset;
pageBreak = calculatePageBreak(pageNumber);

view = (PagingParagraphView) getView(i);
view.setPargraphOffset(totalOffset);
view.setStartPage(pageNumber);

if ((spans + offsets) > pageBreak) {
view.layout(view.getWidth(), getHeight());
pageNumber = view.getEndPage();
spans += view.getAdjustedSpan();
}

totalOffset = offsets + spans;
}
}


public void paint(Graphics g, Shape a) {
super.paint(g, a);

Rectangle alloc = (a instanceof Rectangle) ? (Rectangle) a : a.getBounds();
Rectangle page = new Rectangle(alloc.x, alloc.y, PAGE_WIDTH, PAGE_HEIGHT);

for (int i = 0; i < pageNumber; i++) {
page.y = alloc.y + PAGE_HEIGHT * i;
if (page.intersects(alloc))
paintPageFrame(g, page);
}

// Fills in any unpainted areas
if ((alloc.y + alloc.height) > (page.y + page.height)) {
g.setColor(BACKGROUND);
g.fillRect(page.x, page.y + page.height, page.width, alloc.height - page.height);
}
}


private void paintPageFrame(Graphics g, Rectangle page) {
Color oldColor = g.getColor();

//borders
g.setColor(BACKGROUND);
g.fillRect(page.x, page.y, page.width, PAGE_INSET);
g.fillRect(page.x, page.y, PAGE_INSET, page.height);
g.fillRect(page.x, page.y + page.height - PAGE_INSET, page.width, PAGE_INSET);
g.fillRect(page.x + page.width - PAGE_INSET, page.y, PAGE_INSET, page.height);

//frame
g.setColor(Color.black);
g.drawRect(page.x + PAGE_INSET,
page.y + PAGE_INSET,
page.width - 2 * PAGE_INSET,
page.height - 2 * PAGE_INSET);

//shadow
g.fillRect(page.x + page.width - PAGE_INSET,
page.y + PAGE_INSET + 4,
4,
page.height - 2 * PAGE_INSET);
g.fillRect(page.x + PAGE_INSET + 4,
page.y + page.height - PAGE_INSET,
page.width - 2 * PAGE_INSET,
4);

g.setColor(oldColor);
}
}


private class PagingParagraphView extends ParagraphView {
private int startPage, endPage;
private int adjustedSpan;
private int paragraphOffset;

public PagingParagraphView(Element elem) {
super(elem);

startPage = 1;
endPage = 1;
adjustedSpan = 0;
paragraphOffset = 0;
}


public void setStartPage(int sp) {
startPage = sp;
}


public int getEndPage() {
return endPage;
}


public int getAdjustedSpan() {
return adjustedSpan;
}


public void setPargraphOffset(int po) {
paragraphOffset = po;
}


public void layout(int width, int height) {
super.layout(width, height);
}


protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
super.layoutMajorAxis(targetSpan, axis, offsets, spans);

if (paragraphOffset != 0) {
endPage = startPage;
int relativeBreak = calculatePageBreak(endPage) - paragraphOffset;
int correctedOffset;
adjustedSpan = 0;

for (int i = 0; i < offsets.length; i++) {
// determine the location of the page break

if (offsets + spans > relativeBreak) {
correctedOffset = relativeBreak
+ PAGE_MARGIN.bottom + (2 * PAGE_INSET) + PAGE_MARGIN.top
- offsets;

for (int j = i; j < offsets.length; j++) {
offsets[j] += correctedOffset;
}

adjustedSpan += correctedOffset;
endPage++;
relativeBreak = calculatePageBreak(endPage) - paragraphOffset;
}
}
}
}
}
}

Thanx
Samir
(e-mail address removed)
 
Joined
Dec 23, 2010
Messages
1
Reaction score
0
this is an old thread, yes, but im hoping ksamir2004 will be able to read this

. your code is great. it works perfectly. however, i want to use it using htmleditorkit (and even rtfeditorkit) does not work

the code works correctly if it inherits from stylededitorkit. any ideas?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top