Graphics2D in a DefaultStyleDocument

E

Elliot

Hi
I currently use a lot of code to parse and print a multi-page document
with a lot of Graphics2D objects. I need to display the same document
in a JTextPane. I would like to create a new class that could be used
by either the repaginate() and print() routines for the print job or
by a new paint() routine for the Swing components.

I would like to add the Graphics2D objects to a DefaultStyledDocument
and then add the styled document to a JTextPane. I think this would be
the fastest way to draw everything.
First, is it possible to add paint graphic 2d on a StyledDocument?

Second, I do not want to duplicate any of the existing complex parsing
code for the print job. I need to figure out how to create a new class
containing this logic that could be used by either the current
repaginate() and print() methods or new paint() method.

Any ideas would be really welcome.

Thanks

Elliot
 
J

John B. Matthews

Elliot said:
I currently use a lot of code to parse and print a multi-page
document with a lot of Graphics2D objects. I need to display the same
document in a JTextPane. I would like to create a new class that
could be used by either the repaginate() and print() routines for the
print job or by a new paint() routine for the Swing components.

I would like to add the Graphics2D objects to a DefaultStyledDocument
and then add the styled document to a JTextPane. I think this would
be the fastest way to draw everything. First, is it possible to add
paint graphic 2d on a StyledDocument?

Second, I do not want to duplicate any of the existing complex
parsing code for the print job. I need to figure out how to create a
new class containing this logic that could be used by either the
current repaginate() and print() methods or new paint() method.

Any ideas would be really welcome.

If a Graphics2D instance is associated with a Component you can use the
insertComponent() method of JTextPane:

<http://java.sun.com/javase/6/docs/api/javax/swing/JTextPane.html
#insertComponent(java.awt.Component)>

If it's a BufferedImage, you can wrap it in a JComponent and override
the paintComponent() method to call drawImage().
 
K

Knute Johnson

Hi
I currently use a lot of code to parse and print a multi-page document
with a lot of Graphics2D objects. I need to display the same document
in a JTextPane. I would like to create a new class that could be used
by either the repaginate() and print() routines for the print job or
by a new paint() routine for the Swing components.

I would like to add the Graphics2D objects to a DefaultStyledDocument
and then add the styled document to a JTextPane. I think this would be
the fastest way to draw everything.
First, is it possible to add paint graphic 2d on a StyledDocument?

Second, I do not want to duplicate any of the existing complex parsing
code for the print job. I need to figure out how to create a new class
containing this logic that could be used by either the current
repaginate() and print() methods or new paint() method.

Any ideas would be really welcome.

Thanks

Elliot

If you are already drawing it to print, just draw it on a JComponent of
some variety. I do that all the time for print preview only in reverse.
 
J

John B. Matthews

Daniel Pitts said:
Or use a JLabel with an ImageIcon, instead of writing custom
paintComponent :)

Even better!

Somewhere between the two approaches, I like to implement the Icon
interface. As an example, here's a handy component for seeing the
effect of various layout managers:

/**
* A label having an icon showing the icon's center.
* @author John B. Matthews
*/
private static class SizeLabel extends JLabel implements Icon {

private static final Font FONT =
new Font("Serif", Font.PLAIN, 16);
private static final int WIDE = 72;
private static final int HIGH = 24;

public SizeLabel() {
this.setHorizontalAlignment(JLabel.CENTER);
this.setVerticalAlignment(JLabel.CENTER);
this.setHorizontalTextPosition(JLabel.CENTER);
this.setVerticalTextPosition(JLabel.TOP);
this.setIconTextGap(0);
this.setFont(FONT);
this.setPreferredSize(
new Dimension(4 * WIDE / 3, 8 * HIGH / 3));
this.setMinimumSize(this.getPreferredSize());
this.setIcon(this);
}

public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.darkGray);
g.fillRect(x, y, WIDE, HIGH);
int x2 = x + WIDE / 2;
int y2 = y + HIGH / 2;
String s = "(" + x2 + ", " + y2 + ")";
int w2 = g.getFontMetrics().stringWidth(s) / 2;
int h2 = g.getFontMetrics().getDescent() + 1;
g.setColor(Color.white);
g.drawString(s, x2 - w2, y2 + h2);
}

public int getIconWidth() {
return WIDE;
}

public int getIconHeight() {
return HIGH;
}
}
 
E

Elliot

If you are already drawing it to print, just draw it on a JComponent of
some variety.  I do that all the time for print preview only in reverse..

Are you saying to extend JComponent in my print() method?
 
K

Knute Johnson

Are you saying to extend JComponent in my print() method?

No. What I'm saying is to use the code in your current print() method
to draw on a JComponent. In the example below, the method draw() is
used to draw on the JPanel as well as in the print() method to draw on
paper. Needless to say, I have left out printing margins and PageFormat
and all of that.

import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import javax.swing.*;

public class test4 extends JPanel implements Printable {
public test4() {
setPreferredSize(new Dimension(400,300));
}

public void paintComponent(Graphics g) {
draw(g);
}

public void draw(Graphics g) {
g.drawRect(20,20,360,260);
g.drawLine(20,20,380,280);
g.drawLine(20,280,380,20);
}

public int print(Graphics g, PageFormat pf, int index) {
if (index == 0) {
draw(g);
return Printable.PAGE_EXISTS;
} else
return Printable.NO_SUCH_PAGE;
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final test4 t4 = new test4();
f.add(t4,BorderLayout.CENTER);
JButton b = new JButton("Print");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(t4);
if (pj.printDialog())
try {
pj.print();
} catch (PrinterException pe) {
System.out.println(pe);
}
}
});
f.add(b,BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
});
}
}
 
K

Knute Johnson

Are you saying to extend JComponent in my print() method?

No. What I'm saying is to use the code in your current print() method to
draw on a JComponent. In the example below, the method draw() is used to
draw on the JPanel as well as in the print() method to draw on paper.
Needless to say, I have left out printing margins and PageFormat and all
of that.

import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import javax.swing.*;

public class test4 extends JPanel implements Printable {
public test4() {
setPreferredSize(new Dimension(400,300));
}

public void paintComponent(Graphics g) {
draw(g);
}

public void draw(Graphics g) {
g.drawRect(20,20,360,260);
g.drawLine(20,20,380,280);
g.drawLine(20,280,380,20);
}

public int print(Graphics g, PageFormat pf, int index) {
if (index == 0) {
draw(g);
return Printable.PAGE_EXISTS;
} else
return Printable.NO_SUCH_PAGE;
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final test4 t4 = new test4();
f.add(t4,BorderLayout.CENTER);
JButton b = new JButton("Print");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(t4);
if (pj.printDialog())
try {
pj.print();
} catch (PrinterException pe) {
System.out.println(pe);
}
}
});
f.add(b,BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
});
}
}

One job I did a while back we printed on 8.5 x 14 paper. I scaled the
print preview so that it would fit easily on the screen but would print
full size. There are lots of tricky things you can do but only write
the code once or most of it anyway.
 
E

Elliot

Thanks Knute for the very clear example.

Executing draw()from either print()or paintComponent() is the kind of
idea I was hoping to find in the forum. In my case there are will be
three calls to draw(). The first by a direct print to a default
printer and the next two as you have described, in the preview and the
preview's print action.

Thanks again.

Elliot
 

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

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top