Source Code Cross Referenced for cHTMLPart.java in  » Mail-Clients » columba-1.4 » org » columba » core » print » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Mail Clients » columba 1.4 » org.columba.core.print 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //The contents of this file are subject to the Mozilla Public License Version 1.1
002:        //(the "License"); you may not use this file except in compliance with the
003:        //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004:        //
005:        //Software distributed under the License is distributed on an "AS IS" basis,
006:        //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007:        //for the specific language governing rights and
008:        //limitations under the License.
009:        //
010:        //The Original Code is "The Columba Project"
011:        //
012:        //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013:        //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014:        //
015:        //All Rights Reserved.
016:        //
017:        package org.columba.core.print;
018:
019:        import java.awt.Graphics2D;
020:        import java.awt.Rectangle;
021:        import java.awt.Shape;
022:        import java.awt.geom.Point2D;
023:        import java.io.IOException;
024:        import java.net.URL;
025:        import java.util.logging.Logger;
026:
027:        import javax.swing.JTextPane;
028:        import javax.swing.text.Document;
029:        import javax.swing.text.View;
030:        import javax.swing.text.html.HTMLDocument;
031:        import javax.swing.text.html.HTMLEditorKit;
032:
033:        /**
034:         * Class for representing a HTML print object. Objects of this
035:         * type is intended for inclusion in cDocument objects for printing.
036:         * Division into multiple pages represented by cPage is supported.
037:         *
038:         * @author Karl Peder Olesen (karlpeder), 20030601
039:         *
040:         */
041:        public class cHTMLPart extends cPrintObject {
042:
043:            private static final Logger LOG = Logger
044:                    .getLogger("org.columba.core.print");
045:
046:            /** IContainer holding the HTML to be printed (used to control layout etc. */
047:            private JTextPane mPane = null;
048:
049:            /** Y-coordinate in mPane to start printing at */
050:            private cUnit mStartY = new cCmUnit(0.0);
051:
052:            /** Flag indicating whether scaling of the print is allowed (default is no) */
053:            private boolean mScaleAllowed;
054:
055:            /**
056:             * Creates a new empty HTML print object.
057:             * As default, scaling the print to fit is not allowed
058:             */
059:            public cHTMLPart() {
060:                this (false);
061:            }
062:
063:            /**
064:             * Creates a new empty HTML print object and sets whether scaling is allowed
065:             * @param scaleAllowed        If true, the print is allowed to "scale to fit"
066:             */
067:            public cHTMLPart(boolean scaleAllowed) {
068:                super ();
069:                mScaleAllowed = scaleAllowed;
070:            }
071:
072:            /**
073:             * Sets the HTML document to be printed.
074:             * @param        html        HTML document to be printed
075:             */
076:            public void setHTML(HTMLDocument html) {
077:                mPane = new JTextPane();
078:                mPane.setDoubleBuffered(false);
079:                mPane.setContentType("text/html");
080:                mPane.setDocument(html); // "store" html in jTextPane container
081:                mStartY = new cCmUnit(0.0); // reset starting position in y-direction
082:            }
083:
084:            /**
085:             * Sets the HTML document to be printed.
086:             * Precondition: The URL given contains a HTML document
087:             * @param         url                url to file with HTML document
088:             * @throws        IOException if errors occur while reading HTML document from file
089:             */
090:            public void setHTML(URL url) throws IOException {
091:                /*
092:                 * By using an instance of SyncHTMLEditorKit, the html should load
093:                 * synchroniously - so everything is loaded before printing starts
094:                 */
095:                mPane = new JTextPane();
096:                mPane.setDoubleBuffered(false);
097:                mPane.setEditorKit(new SyncHTMLEditorKit());
098:                mPane.setContentType("text/html");
099:                mPane.setPage(url);
100:                mStartY = new cCmUnit(0.0); // reset starting position in y-direction
101:            }
102:
103:            /**
104:             * Sets the starting position in y-direction. A starting position != 0 is used
105:             * when printing anything but the first page. This bookkeeping is usually done
106:             * internally when creating pagebreaks using the method breakBlock.
107:             * Therefore this method has not been made public.
108:             * @param        y                Starting position in y-direction
109:             */
110:            protected void setStartY(cUnit y) {
111:                mStartY = new cCmUnit(y);
112:            }
113:
114:            /**
115:             * Prints the contents of this HTML print object using the supplied
116:             * Graphics2D object.
117:             * @param        g        Used for rendering (i.e. printing) this HTML print object
118:             * @see org.columba.core.print.cPrintObject#print(java.awt.Graphics2D)
119:             */
120:            public void print(Graphics2D g) {
121:                /*
122:                 * *20030609, karlpeder* Introduced scaling
123:                 */
124:                computePositionAndSize();
125:
126:                // get origin & size information (height as "total" height minus current pos.)
127:                cPoint origin = getDrawingOrigin();
128:                double width = getDrawingSize().getWidth().getPoints();
129:                double height = getPage().getPrintableAreaSize().getHeight()
130:                        .sub(getLocation().getY()).getPoints();
131:
132:                /*
133:                 * TODO (@author karlpeder): Guess that right thing to do is to get height as getDrawingSize().getHeight(),
134:                 * since this should take top- and bottom margin of this print
135:                 * object into account. But the height seems not to be set
136:                 * correctly in computePositionAndSize() (*20030604, karlpeder*)
137:                 */
138:                // set size of mPane according to the available width
139:                // and fetch root view
140:                mPane.setSize((int) width, Integer.MAX_VALUE);
141:                mPane.validate();
142:
143:                View rootView = mPane.getUI().getRootView(mPane);
144:
145:                // scale the graphics
146:                double scale = scaleFactor(new cPointUnit(width));
147:                g.scale(scale, scale);
148:
149:                // set clipping for the graphics object
150:                Shape oldClip = g.getClip();
151:                g.setClip((int) (origin.getX().getPoints() / scale),
152:                        (int) (origin.getY().getPoints() / scale),
153:                        (int) (width / scale), (int) (height / scale));
154:
155:                // translate g to line up with origin of print area (trans 1)
156:                Point2D.Double trans = new Point2D.Double(g.getClipBounds()
157:                        .getX(), g.getClipBounds().getY());
158:                g.translate(trans.getX(), trans.getY());
159:
160:                // set allocation (defines print area together with the clipping
161:                // and translation made above), and print...
162:                Rectangle allocation = new Rectangle(0, (int) -mStartY
163:                        .getPoints(), (int) mPane.getMinimumSize().getWidth(),
164:                        (int) mPane.getPreferredSize().getHeight());
165:                printView(g, rootView, allocation, height / scale);
166:
167:                // translate graphics object back to original position and reset clip and scaling
168:                g.translate(-trans.getX(), -trans.getY());
169:                g.scale(1 / scale, 1 / scale);
170:                g.setClip(oldClip);
171:            }
172:
173:            /**
174:             * Private utility to print a view (called from the print method).<br>
175:             * The traversal through views and their children is the same as in
176:             * calcBreakHeightForView.
177:             *
178:             * @param        g                                Graphics object to print on
179:             * @param        view                        The View object to operate on
180:             * @param        allocation                Allocation for the view (where to render)
181:             * @param        maxHeight                Views starting after maxHeight is not printed
182:             */
183:            private void printView(Graphics2D g, View view, Shape allocation,
184:                    double maxHeight) {
185:                if (view.getViewCount() > 0) {
186:                    // child views exist - operate recursively on these
187:                    Shape childAllocation;
188:                    View childView;
189:
190:                    for (int i = 0; i < view.getViewCount(); i++) {
191:                        childAllocation = view
192:                                .getChildAllocation(i, allocation);
193:
194:                        if (childAllocation != null) {
195:                            childView = view.getView(i);
196:
197:                            // handle child view by recursive call
198:                            printView(g, childView, childAllocation, maxHeight);
199:                        }
200:                    }
201:                } else {
202:                    // no childs - we have a leaf view (i.e. with contents)
203:                    double viewStartY = allocation.getBounds().getY();
204:
205:                    if ((viewStartY >= 0) && (viewStartY < maxHeight)) {
206:                        // view starts on page - print it
207:                        view.paint(g, allocation);
208:                    }
209:                }
210:            }
211:
212:            /**
213:             * Returns the size of this HTML print object subject to the
214:             * given width.<br>
215:             * If scaling is allowed, and the contents can not be fitted inside
216:             * the given width, the content is scaled to fit before the size is
217:             * returned, i.e. the scaled size is returned.<br>
218:             * NB: The height returned will always be from the starting point
219:             * (which could be different from the top) to the end of the current
220:             * content, independent on whether everything will or can be printed
221:             * on onto one page.
222:             *
223:             * @param        maxWidth                Max. allowable width this print object can occupy
224:             *
225:             * @see org.columba.core.print.cPrintObject#getSize(org.columba.core.print.cUnit)
226:             */
227:            public cSize getSize(cUnit maxWidth) {
228:                /*
229:                 * *20030609, karlpeder* Introduced scaling
230:                 */
231:
232:                // resize jTextPane component to calculate height and get it
233:                double width = maxWidth.sub(leftMargin).sub(rightMargin)
234:                        .getPoints();
235:                mPane.setSize((int) width, Integer.MAX_VALUE);
236:                mPane.validate();
237:
238:                double height = mPane.getPreferredSize().getHeight();
239:
240:                // correct for starting position if printing should not start at the top
241:                height = height - mStartY.getPoints();
242:
243:                // calculate size and return it
244:                double scale = scaleFactor(new cPointUnit(width));
245:                cUnit w = new cCmUnit(maxWidth); // width unchanged
246:                cUnit h = new cCmUnit();
247:                h.setPoints(height); // height of content
248:                h.addI(topMargin); // + top margin
249:                h.addI(bottomMargin); // + bottom margin
250:                h.setPoints(h.getPoints() * scale); // height corrected for scaling
251:
252:                return new cSize(w, h);
253:            }
254:
255:            /**
256:             * Returns the scale, which should be applied to the content to make it
257:             * fit inside the given width.<br>
258:             * If scaling is not allowed, 1.0 will be returned.<br>
259:             * If the content fits inside the given width, or is smaller, 1.0 will
260:             * be returned.
261:             * @author  Karl Peder Olesen (karlpeder), 20030609
262:             * @param        maxWidth                Max. allowable width this print object can occupy
263:             * @return  scale to be applied to make the contents fit inside the given width
264:             */
265:            private double scaleFactor(cUnit maxWidth) {
266:                mPane.validate(); // ensure contents is layed out properly
267:
268:                if (!mScaleAllowed) {
269:                    LOG.info("Scaling not active - returning scale=1.0");
270:
271:                    return 1.0;
272:                } else {
273:                    // calculate scaling and return it
274:                    double width = maxWidth.sub(leftMargin).sub(rightMargin)
275:                            .getPoints();
276:                    double scale;
277:
278:                    if (mPane.getMinimumSize().getWidth() > width) {
279:                        scale = width / mPane.getMinimumSize().getWidth();
280:                    } else {
281:                        scale = 1.0; // do not scale up, i.e. no scale factor above 1.0
282:                    }
283:
284:                    LOG.info("Returning scale=" + scale);
285:
286:                    return scale;
287:                }
288:            }
289:
290:            /**
291:             * Divides (breaks) this HTML print object into a remainder (which fits
292:             * inside the given max height) and the rest. The remainder is returned and
293:             * "the rest" is stored by modifying this object.
294:             *
295:             * @param        w                        Max. allowable width this print object can occupy
296:             * @param        maxHeight        Max. allowable height before breaking
297:             * @return        The part of the print object, which fits inside the given max height
298:             *
299:             * @see org.columba.core.print.cPrintObject#breakBlock(org.columba.core.print.cUnit, org.columba.core.print.cUnit)
300:             */
301:            public cPrintObject breakBlock(cUnit w, cUnit maxHeight) {
302:                /*
303:                 * *20030609, karlpeder* Introduced scaling
304:                 */
305:
306:                // get size of content (width, height is size without scaling)
307:                cSize contentSize = this .getSize(w); // scaled size
308:                double scale = scaleFactor(w);
309:                int width = (int) (contentSize.getWidth().getPoints() / scale);
310:                int height = (int) (contentSize.getHeight().getPoints() / scale);
311:                int startY = (int) mStartY.getPoints();
312:
313:                // define allocation rectangle (startY is used to compensate for
314:                // different start point if printing shall not start from the top)
315:                Rectangle allocation = new Rectangle(0, -startY, width, height
316:                        + startY);
317:
318:                // set initial value for height where this print object should be broken
319:                double breakHeight = maxHeight.getPoints() / scale; // in points, without scale
320:
321:                /*
322:                 * calculate a new break height according to the contents, possibly
323:                 * smaller to break before some content (i.e. not to break in the
324:                 * middle of something
325:                 */
326:                View rootView = mPane.getUI().getRootView(mPane);
327:                breakHeight = calcBreakHeightFromView(rootView, allocation,
328:                        breakHeight);
329:
330:                // create remainder
331:                cHTMLPart remainder = new cHTMLPart(mScaleAllowed);
332:                remainder.setHTML((HTMLDocument) mPane.getDocument());
333:                remainder.setStartY(mStartY);
334:
335:                // modify "this" to start where remainder ends
336:                cUnit newStartY = new cCmUnit();
337:
338:                if (breakHeight < height) {
339:                    newStartY.setPoints(mStartY.getPoints() + breakHeight);
340:                } else { // this happends if there's nothing left for the next page
341:                    newStartY = mStartY.add(contentSize.getHeight());
342:                }
343:
344:                this .setStartY(newStartY);
345:
346:                return remainder;
347:            }
348:
349:            /**
350:             * Private utility to calculate break height based on the contents
351:             * of a view. If the break height calculated is not smaller than the
352:             * actual break height, actBreakHeight is returned unchanged.
353:             * @param        view                        The View object to operate on
354:             * @param        allocation                Allocation for the view (where to render)
355:             * @param        actBreakHeight         Actual break height
356:             */
357:            private double calcBreakHeightFromView(View view, Shape allocation,
358:                    double actBreakHeight) {
359:                if (view.getViewCount() > 0) {
360:                    // child views exist - operate recursively on these
361:                    double breakHeight = actBreakHeight;
362:                    Shape childAllocation;
363:                    View childView;
364:
365:                    for (int i = 0; i < view.getViewCount(); i++) {
366:                        childAllocation = view
367:                                .getChildAllocation(i, allocation);
368:
369:                        if (childAllocation != null) {
370:                            childView = view.getView(i);
371:
372:                            // calculate break height for child, and use updated
373:                            // value in the further processing
374:                            breakHeight = calcBreakHeightFromView(childView,
375:                                    childAllocation, breakHeight);
376:                        }
377:                    }
378:
379:                    return breakHeight; // return (possibly) updated value
380:                } else {
381:                    // no childs - we have a leaf view (i.e. with contents)
382:                    double allocY = allocation.getBounds().getY();
383:                    double allocMaxY = allocation.getBounds().getMaxY();
384:                    if ((allocY >= 0) && (allocY < actBreakHeight)
385:                            && (allocMaxY > actBreakHeight)) {
386:                        // view starts on page and exceeds it
387:
388:                        /*
389:                         * If the height of a view exceeds the paperheight, there should
390:                         * be no break before (since it will be impossible to fit it in
391:                         * anywhere => an infinite loop). We don't have access to the
392:                         * pageheight here, therefore an "educated guess" is made:
393:                         * No breaks are inserted before views starting within the first
394:                         * 1% (chosen to avoid round-off errors) of the available space
395:                         * given by actBreakHeight. If the view starts after the first 1%,
396:                         * a break is inserted and the view will start at the top of the
397:                         * next page (i.e. withing the first 1% this time).
398:                         */
399:                        if (allocY < (actBreakHeight * 0.01)) {
400:                            return actBreakHeight; // unchanged, i.e. no breaks before this view
401:                        } else {
402:                            // view can be broken
403:                            if (allocY < actBreakHeight) {
404:                                return allocY; // break before start of view
405:                            } else {
406:                                return actBreakHeight; // unchanged
407:                            }
408:                        }
409:                    } else {
410:                        return actBreakHeight; // unchanged
411:                    }
412:                }
413:            }
414:        }
415:
416:        /**
417:         * Utility class used for loading html synchroniously into a jTextPane
418:         * @author        Karl Peder Olesen (karlpeder), 20030604
419:         */
420:        class SyncHTMLEditorKit extends HTMLEditorKit {
421:            /**
422:             * Create an uninitialized text storage model that is appropriate for
423:             * this type of editor.<br>
424:             * The document returned will load synchroniously.
425:             *
426:             * @see javax.swing.text.EditorKit#createDefaultDocument()
427:             */
428:            public Document createDefaultDocument() {
429:                Document doc = super .createDefaultDocument();
430:                ((HTMLDocument) doc).setAsynchronousLoadPriority(-1);
431:
432:                return doc;
433:            }
434:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.