> Is it possible to create off-screen images that render HTML pages? In other
> words, can I feed an HTML page to some text.swing object, and have it save
> out a JPEG for me?
Sure it's possible. I just copied the following code from Design-a-
Course Developer, which should give the basic idea:
Image offscreen = createImage(width, height);
Graphics g2 = offscreen.getGraphics();
editorPane.paint(g2);
g2.dispose();
previewImage = offscreen.getScaledInstance(
viewWidth, viewHeight, Image.SCALE_SMOOTH);
offscreen.flush();
That creates a temporary image to be drawn onto a component. Instead of
using Component.createImage, you'll want to create a BufferedImage, then
use ImageIO to save it as a JPEG file.
One thing I didn't show there is that I use a custom subclass of
HTMLEditorKit, which in turn uses a custom ViewFactory, which calls
setLoadsSynchronously on ImageView instances to ensure that the
resulting image doesn't exclude images in the page. I think that's the
only major change I made, but I don't recall everything. You may have
to dink around with things to get the whole page. As a worst-case hack,
you could simply add a Thread.sleep to give the page time to load
completely.

Signature
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Lukas Bradley - 05 Dec 2003 23:42 GMT
> One thing I didn't show there is that I use a custom subclass of
> HTMLEditorKit, which in turn uses a custom ViewFactory, which calls
[quoted text clipped - 4 lines]
> you could simply add a Thread.sleep to give the page time to load
> completely.
Would you mind sharing that code? It would keep me from dinking, and
removes the worst-case hack scenario.
Lukas
Chris Smith - 06 Dec 2003 00:48 GMT
> Would you mind sharing that code? It would keep me from dinking, and
> removes the worst-case hack scenario.
Unfortunately, the custom HTMLEditorKit subclass does a lot of other
things as well... and I don't have time to separate the parts that
matter from the parts that don't. I described the basic steps to
implementing the synchronous image loading, which is the biggest deal.
Other problems may come from background images and the like.
It would look something like this (entirely from memory, so let me know
if you can't fix the mistakes I'm sure to make):
class SyncEditorKit extends HTMLEditorKit
{
public ViewFactory getViewFactory()
{
final ViewFactory superFactory = super.getViewFactory();
return new ViewFactory() {
public View getView(Element e)
{
View v = superFactory.getView(e);
if (v instanceof ImageView)
{
((ImageView) v).setLoadsSynchronously(true);
}
return v;
}
};
}
}
You'd then have to do the following to the JEditorPane:
editorPane.setEditorKitForContentType(
"text/html",
new SyncEditorKit());

Signature
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Lukas Bradley - 06 Dec 2003 00:11 GMT
> Image offscreen = createImage(width, height);
> Graphics g2 = offscreen.getGraphics();
[quoted text clipped - 5 lines]
> viewWidth, viewHeight, Image.SCALE_SMOOTH);
> offscreen.flush();
To be more specific, you say you use a custom extended HTMLEditorKit. So, I
assume this code is within that class. However, createImage() is not
available there.
So what type of object is this code from?
Lukas
Chris Smith - 06 Dec 2003 00:43 GMT
> > Image offscreen = createImage(width, height);
> > Graphics g2 = offscreen.getGraphics();
[quoted text clipped - 11 lines]
>
> So what type of object is this code from?
Oh, no! This is actually defined from within a Component subclass. In
my specific application, the Component will later be drawing the image
to the screen, so that makes sense. I thought I mentioned that you'd
want to use "new BufferedImage(width, height)" instead.

Signature
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation