|
|
||
Sergey Groznyh's BlogSwing ArchivesGenerating Print Preview of Swing Text ComponentsPosted by g_s_m on September 05, 2007 at 04:42 AM | Permalink | Comments (6)This question, “how to generate print preview of Java Swing
components,” is asked often on various discussion forums, because
currently (as of version 6) the Java SE doesn't have standard facilities for
building print previews. While working on the Swing Tutorial, I tried to address this issue under the topic “Using
There exist several resources on the Internet related to generating print previews in Java, but in most cases they are either commercial, or use an outdated API, or attempt to build some all-in-one custom dialog solution without paying much attention to details. In this issue I'll try to focus on how to create a print preview—what necessary parts are involved and how they do communicate. What to PrintThe Printable p = textComponent.getPrintable(); Page FormatNext thing we need to know is the parameters of the output media,
most important ones being the physical page dimensions. In real-life
situation the available page dimensions should be obtained by querying
some PageFormat f = new PageFormat(); int pageWidth = f.getWidth(); int pageHeight = f.getHeight(); Where to PrintThen we need a print destination that will receive the actual drawing commands. The destination should be an instance of
the
Image page = new BufferedImage(
pageWidth, pageHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = page.getGraphics();
How to PrintNow we are ready to generate page images. We need to repeatedly
invoke the
for (int n = 0; p.print(g, f, n) == Printable.PAGE_EXISTS; n++) {
// N-th page printed successfully
}
How to ScaleThe generated page image is usually too large for on-screen display, so we need to shrink the image for viewing. The following code creates an image with size reduced by two times on both dimensions.
double scaleFactor = 0.5;
int previewWidth = (int) (pageWidth * scaleFactor);
int previewHeight = (int) (pageHeight * scaleFactor);
Image preview = page.getScaledInstance(
previewWidth, previewHeight, SCALE_SMOOTH);
Back to SwingUntil now we dealt mostly with 2D and AWT parts of the Client Java API.
Now we need to place the generated preview image into some Swing
component. For this we'll create a subclass of the
JPanel previewPane = new JPanel() {
public void paintComponent(Graphics g) {
g.drawImage(preview, 0, 0, previewWidth, previewHeight, null);
}
public Dimension getPreferredSize() {
return new Dimension(previewWidth, previewHeight);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
}
The resulting print preview pane can then be added to Swing container, just like any other Swing component. Below are links to the example containing the complete print preview implementation as described in this issue. Using this implementation, the print preview functionality could be added to any text component in a couple lines of code. Please note that in order to run this demo, you'll need Java runtime version 1.6 (aka 6.0) or higher. The demo displays a chapter from “Alice in Wonderland” in the
Removing elements from Swing HTML in JDK6Posted by g_s_m on August 01, 2007 at 10:12 AM | Permalink | Comments (0)After I published the entry on removing elements from Swing HTMLDocument in JDK7, I got a question from a reader: but how to actually remove elements in JDK6? There's no easy way, but what is the hard way? Well, there exist a bunch of methods, to various degrees of ugliness, let's look at one of them. It's neither pretty nor effective, but has the advantage of being simple enough. The method is to serialize all the sibling elements
using The following code illustrates this approach.
void removeElement(HTMLDocument d, Element e) throws Exception {
Element p = e.getParentElement();
int n = p.getElementCount();
String s = "";
for (int i = 0; i < n; i++) {
Element c = p.getElement(i);
if (c != e) {
s += getElementText(d, c);
}
}
d.setInnerHTML(p, s);
}
The tricky thing is, how to serialize not the complete document but
a single element only. There exist a constructor in
the To overcome this, we need to override
the
String getElementText(HTMLDocument d, final Element e) throws Exception {
StringWriter sw = new StringWriter();
int p0 = e.getStartOffset();
int p1 = e.getEndOffset();
new HTMLWriter(sw, d, p0, p1 - p0) {
protected ElementIterator getElementIterator() {
return new ElementIterator(e);
}
}.write();
return sw.toString();
}
Note that if we try to remove the sole child element, the behavior
of this method differs from Removing elements from Swing HTMLDocumentPosted by g_s_m on June 18, 2007 at 08:36 AM | Permalink | Comments (2)Suppose you have an HTML document, like this:
<ul>
<li id="LI1">Item 1</li>
<li id="LI2">Item 2</li>
<li id="LI3">Item 3</li>
</ul>
And you want to programmatically remove one of the list items (say, the second one). For this, you load the document into Swing’s
JEditorPane p = new JEditorPane();
p.setContentType("text/html");
p.setText("HTML text from the above example");
As you know the HTML element’s ID, you can easily obtain
a reference to the corresponding
HTMLDocument d = (HTMLDocument) p.getDocument();
Element e = d.getElement("LI2");
But how to remove this element from the document? A quick
glance through the Except that it doesn’t work. The So how to actually remove an element from the document? Quite surprisingly, until recently there was no easy way of doing this. Starting with JDK7
build 10, the Swing Text subsystem provides the new public
method in the
d.removeElement(e);
Due to specifics of the default
| ||
|
|