Source Code Cross Referenced for SVGButtonRenderer.java in  » Workflow-Engines » osbl-1_0 » org » osbl » client » wings » shell » 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 » Workflow Engines » osbl 1_0 » org.osbl.client.wings.shell 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.osbl.client.wings.shell;
002:
003:        import java.awt.event.ActionEvent;
004:        import javax.swing.JFileChooser;
005:        import javax.swing.JProgressBar;
006:        import org.apache.batik.bridge.*;
007:        import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
008:        import org.apache.batik.dom.svg.SVGDocumentFactory;
009:        import org.apache.batik.gvt.GraphicsNode;
010:        import org.apache.batik.gvt.renderer.StaticRenderer;
011:        import org.apache.batik.util.XMLResourceDescriptor;
012:        import org.apache.commons.logging.Log;
013:        import org.apache.commons.logging.LogFactory;
014:        import org.w3c.dom.Document;
015:        import org.w3c.dom.Element;
016:        import org.w3c.dom.svg.SVGDocument;
017:        import org.wings.*;
018:        import org.wings.session.BrowserType;
019:        import org.wings.session.SessionManager;
020:        import org.wings.util.SessionLocal;
021:
022:        import java.awt.*;
023:        import java.awt.image.BufferedImage;
024:        import java.io.BufferedReader;
025:        import java.io.ByteArrayInputStream;
026:        import java.io.File;
027:        import java.io.IOException;
028:        import java.io.InputStream;
029:        import java.io.InputStreamReader;
030:        import java.util.*;
031:        import javax.swing.AbstractAction;
032:        import javax.swing.ImageIcon;
033:        import javax.swing.JButton;
034:        import javax.swing.JFrame;
035:        import javax.swing.JLabel;
036:        import javax.swing.JPanel;
037:        import javax.swing.SwingUtilities;
038:        import javax.swing.filechooser.FileFilter;
039:
040:        public class SVGButtonRenderer {
041:            private static final transient Log log = LogFactory
042:                    .getLog(SVGButtonRenderer.class);
043:
044:            SessionLocal iconCaches = new SessionLocal() {
045:                protected Object initialValue() {
046:                    return Collections
047:                            .synchronizedMap(new HashMap<BufferedImage, SIcon>());
048:                }
049:            };
050:            protected static final Map<String, BufferedImage> renderedImageCache = Collections
051:                    .synchronizedMap(new HashMap<String, BufferedImage>());
052:
053:            /**
054:             * The returned width of the textwidths somehow does not fit the real life. This correcture factor can be used to adjust.
055:             */
056:            protected static final double TEXTWIDTH_CORRECTURE_FACTOR = 1.0;
057:
058:            private static SVGButtonRenderer instance = null;
059:
060:            private SVGButtonRenderer() {
061:            }
062:
063:            /**
064:             * This method provides dynamical rendered buttons ....
065:             *
066:             * @param buttonText        The text which should appear inside the button
067:             * @param buttonTemplateUri The template file for the button
068:             */
069:            public SIcon retrieveRenderedButtonIcon(String buttonText,
070:                    String buttonTemplateUri, Dimension imageSize) {
071:                BufferedImage bufferedImage = retrieveRenderedButtonImage(
072:                        buttonText, buttonTemplateUri, imageSize);
073:                Map<BufferedImage, SIcon> renderedIconCache = (Map<BufferedImage, SIcon>) iconCaches
074:                        .get();
075:                SIcon icon = renderedIconCache.get(bufferedImage);
076:                if (icon == null) {
077:                    icon = new SImageIcon(bufferedImage, isIE() ? "image/gif"
078:                            : "image/png");
079:                    renderedIconCache.put(bufferedImage, icon);
080:                }
081:                return icon;
082:            }
083:
084:            private boolean isIE() {
085:                return BrowserType.IE.equals(SessionManager.getSession()
086:                        .getUserAgent().getBrowserType());
087:            }
088:
089:            /**
090:             * This method provides dynamical rendered buttons ....
091:             *
092:             * @param buttonText        The text which should appear inside the button
093:             * @param buttonTemplateUri The template file for the button
094:             */
095:            public BufferedImage retrieveRenderedButtonImage(String buttonText,
096:                    String buttonTemplateUri, Dimension imageSize) {
097:                if (buttonText == null) {
098:                    buttonText = "";
099:                }
100:
101:                // Cached version available?!
102:                String cacheKey = buttonTemplateUri + buttonText;
103:                BufferedImage cachedVersion = renderedImageCache.get(cacheKey);
104:                if (cachedVersion != null
105:                        && imageSize.width == cachedVersion.getWidth()
106:                        && imageSize.height == cachedVersion.getHeight()) {
107:                    log
108:                            .debug("Returning CACHED version of ButtonImage for button '"
109:                                    + buttonText
110:                                    + "' with template '"
111:                                    + buttonTemplateUri + "'");
112:                    return cachedVersion;
113:                }
114:
115:                if (imageSize == null) {
116:                    imageSize = calculateButtonImageSize(buttonText);
117:                }
118:
119:                return renderAndCacheNewButton(buttonText, buttonTemplateUri,
120:                        imageSize);
121:            }
122:
123:            private synchronized BufferedImage renderAndCacheNewButton(
124:                    String buttonText, String buttonTemplateURI,
125:                    Dimension imageSize) {
126:                if (buttonText == null) {
127:                    buttonText = "";
128:                }
129:                log.debug("Rendering unknown image button for button '"
130:                        + buttonText + "'");
131:                String cacheLookupKey = buttonTemplateURI.concat(buttonText);
132:
133:                // Recheck if cached version is available, perhaps other thread already generated this button?
134:                BufferedImage cachedVersion = renderedImageCache
135:                        .get(cacheLookupKey);
136:                if (cachedVersion != null
137:                        && imageSize.width == cachedVersion.getWidth()
138:                        && imageSize.height == cachedVersion.getHeight()) {
139:                    log
140:                            .warn("Concurrent thread seems to have already rendered button'"
141:                                    + buttonText
142:                                    + "'. Returning existing instance.");
143:                    return (BufferedImage) renderedImageCache
144:                            .get(cacheLookupKey);
145:                }
146:
147:                // Render button
148:                long renderingTime = System.currentTimeMillis();
149:                BufferedImage img = renderButton(buttonText, buttonTemplateURI,
150:                        imageSize);
151:                renderingTime = System.currentTimeMillis() - renderingTime;
152:                log.debug("Finished rendering button in " + renderingTime
153:                        + " ms. Caching and returning result.");
154:                renderedImageCache.put(cacheLookupKey, img);
155:                return img;
156:            }
157:
158:            /**
159:             * This method takes the given button text, inserts it into a SVG template document retrieved via the classpath, renders
160:             * the resulting SVG image into an image and returns this Image
161:             *
162:             * @param buttonText The text which should appear inside the button.
163:             */
164:            private BufferedImage renderButton(String buttonText,
165:                    String buttonTemplateURI, Dimension buttonImageSize) {
166:                GVTBuilder builder = new GVTBuilder();
167:                UserAgent userAgent = new Log4jUserAgentAdapter();
168:                DocumentLoader loader = new DocumentLoader(userAgent);
169:                BridgeContext ctx = new BridgeContext(userAgent, loader);
170:                StaticRenderer renderer = new StaticRenderer();
171:                GraphicsNode gvtRoot = null;
172:                BufferedImage image = null;
173:
174:                try {
175:                    // create according svg document
176:                    Document svgDoc = createButtonDocument(buttonText,
177:                            buttonImageSize, buttonTemplateURI);
178:                    log.debug("Building GVT Tree");
179:                    gvtRoot = builder.build(ctx, svgDoc);
180:                    log.debug("Populating GVT tree rood node to renderer ["
181:                            + gvtRoot + "]");
182:                    renderer.setTree(gvtRoot);
183:
184:                    // Allocate according image
185:                    BufferedImage display = new BufferedImage(
186:                            (int) buttonImageSize.getWidth(),
187:                            (int) buttonImageSize.getHeight(),
188:                            BufferedImage.TYPE_INT_BGR);
189:
190:                    // Set Transform (?!)
191:                    Element elt = ((SVGDocument) svgDoc).getRootElement();
192:                    renderer.setTransform(ViewBox.getViewTransform(null, elt,
193:                            display.getWidth(), display.getHeight()));
194:
195:                    // Cacluculate offscreen Image
196:                    renderer.updateOffScreen(display.getWidth(), display
197:                            .getHeight());
198:
199:                    //Repaint whole image
200:                    Rectangle r = new Rectangle(0, 0, display.getWidth(),
201:                            display.getHeight());
202:                    renderer.repaint(r);
203:
204:                    // Return resulting image
205:                    image = renderer.getOffScreen();
206:                } catch (Exception e) {
207:                    log.fatal("Uncaught Exception", e);
208:                }
209:                return image;
210:            }
211:
212:            public static SVGButtonRenderer getInstance() {
213:                if (instance == null) {
214:                    synchronized (SVGButtonRenderer.class) {
215:                        if (instance == null)
216:                            instance = new SVGButtonRenderer();
217:                    }
218:                }
219:                return instance;
220:            }
221:
222:            /**
223:             * Calls the method which creates a String with the SVG XML Document and parses it into an XML SVGDocument.
224:             */
225:            private SVGDocument createButtonDocument(String buttonText,
226:                    Dimension buttonImageSize, String buttonTemplateURI) {
227:                log.debug("Creating SVG template document");
228:                try {
229:                    String templateDocument = prepareTemplateDocument(
230:                            buttonText, buttonImageSize, buttonTemplateURI);
231:
232:                    log
233:                            .debug("Parsing resulting Document String to an SVGDocument");
234:                    ByteArrayInputStream istream = new ByteArrayInputStream(
235:                            templateDocument.getBytes("UTF-8"));
236:                    SVGDocumentFactory svgDocumentFactory = new SAXSVGDocumentFactory(
237:                            XMLResourceDescriptor.getXMLParserClassName());
238:                    return svgDocumentFactory.createSVGDocument(null, istream);
239:                } catch (Exception e) {
240:                    log.fatal("Uncaught Exception", e);
241:                }
242:                return null;
243:            }
244:
245:            /**
246:             * Calculates the estimated size for the button immage.
247:             */
248:            public Dimension calculateButtonImageSize(String buttonText) {
249:                if (buttonText == null) {
250:                    buttonText = "";
251:                }
252:                log.debug("Estimating image size for button with label '"
253:                        + buttonText + "'");
254:                Font font = new Font("sans-serif", Font.BOLD, 10);
255:                // XXX - Hack
256:                // This was previously new Label(), and this threw a HeadLessException.
257:                // Heavyweight components DON'T concern in headless environments
258:                // It's still pretty stupid to use JLabel, but we need a quick fix
259:                FontMetrics fm = new JLabel().getFontMetrics(font);
260:
261:                Dimension maxSize = new Dimension(Integer.MAX_VALUE,
262:                        Integer.MAX_VALUE);
263:                Dimension minSize = new Dimension(0, 0);
264:
265:                //Calculate the approximate space for the text
266:                int textWidth = fm.stringWidth(buttonText);
267:                int height = 20;
268:                int horizontalBorder = 21; // BSC: orig "20" but due to wrong font width with short texts (i.e. Ok) expanded.
269:                int width = ((int) (textWidth * TEXTWIDTH_CORRECTURE_FACTOR))
270:                        + horizontalBorder; // Apply lenght calculation correction factor.
271:
272:                // Adjust size to min/max requirements
273:                if (width > maxSize.width)
274:                    width = maxSize.width;
275:                else if (width < minSize.width)
276:                    width = minSize.width;
277:                if (height > maxSize.height)
278:                    height = maxSize.height;
279:                else if (height < minSize.height)
280:                    height = minSize.height;
281:
282:                return new Dimension(width, height);
283:            }
284:
285:            /**
286:             * The platform-specific implementation of how to retrieve the actual button template document. This implementation
287:             * differs for servlet/wings/swing applications.
288:             */
289:            private InputStream getTemplateDocument(String templateFileURI) {
290:                InputStream templateDocument = Thread.currentThread()
291:                        .getContextClassLoader().getResourceAsStream(
292:                                templateFileURI);
293:                if (templateDocument == null)
294:                    log.warn("Failed to retrieve template document +'"
295:                            + templateFileURI + "'. Check URI/implementation!");
296:                return templateDocument;
297:            }
298:
299:            /**
300:             * Reads the template document from the given URI and resolves the included tags.
301:             */
302:            private String prepareTemplateDocument(String templateText,
303:                    Dimension buttonSize, String templateFileURI) {
304:                InputStream templateFileStream = null;
305:                InputStreamReader streamReader = null;
306:                BufferedReader r = null;
307:                try {
308:                    templateFileStream = getTemplateDocument(templateFileURI);
309:                    streamReader = new InputStreamReader(templateFileStream,
310:                            "ISO-8859-1");
311:                    r = new BufferedReader(streamReader);
312:                    StringBuffer templateDocumentString = new StringBuffer();
313:                    String line = "";
314:
315:                    log.debug("Reading template file " + templateFileURI);
316:                    while (line != null) {
317:                        templateDocumentString.append(line);
318:                        line = r.readLine();
319:                    }
320:
321:                    //templateDocumentString.append("\n");
322:                    log.debug("Replacing tokens.");
323:                    String template = replaceTokens(templateDocumentString
324:                            .toString(), templateText, (int) buttonSize
325:                            .getWidth(), (int) buttonSize.getHeight());
326:
327:                    log.debug("Returning resulting document " + template);
328:                    return template;
329:                } catch (Exception ex) {
330:                    log.fatal("Uncatched Exception", ex);
331:                } finally {
332:                    try {
333:                        if (r != null)
334:                            r.close();
335:                        if (streamReader != null)
336:                            streamReader.close();
337:                        if (templateFileStream != null)
338:                            templateFileStream.close();
339:                    } catch (IOException e) {
340:                        log.error("Unexpected error", e);
341:                    }
342:                }
343:                return null;
344:            }
345:
346:            /**
347:             * Recursive method to replace all occurrences of template snippets like "@width@" ...
348:             */
349:            private String replaceTokens(String template, String buttonText,
350:                    int width, int height) {
351:                // replace the text element
352:                if (template.indexOf("@text@") >= 0)
353:                    template = template
354:                            .substring(0, template.indexOf("@text@"))
355:                            + buttonText
356:                            + template
357:                                    .substring(template.indexOf("@text@") + 6);
358:
359:                // find parse and replace the width element
360:                if (template.indexOf("@width") >= 0) {
361:                    template = replaceSizeToken(template, "@width", width);
362:                    return replaceTokens(template, buttonText, width, height);
363:                } else if (template.indexOf("@height") >= 0) {
364:                    template = replaceSizeToken(template, "@height", height);
365:                    return replaceTokens(template, buttonText, width, height);
366:                } else
367:                    return template;
368:            }
369:
370:            /**
371:             * Special methode to replace the token with pixel information.
372:             * Such a token can look like this: @width-5@ This means we have to insert the width of the button minus 5 pixels.
373:             * The optional number within the token can be "+" or "-"
374:             */
375:            private String replaceSizeToken(String template, String tokenName,
376:                    int value) {
377:                int index = template.indexOf(tokenName);
378:                if (index < 0)
379:                    return template;
380:
381:                String element = template.substring(index, template.indexOf(
382:                        "@", index + 1));
383:
384:                // parse if value has to be adjusted.. (example: @width-4@)
385:                int diff = 0;
386:                if (element.indexOf("-") >= 0)
387:                    diff = Integer.parseInt(element.substring(tokenName
388:                            .length()));
389:                else if (element.indexOf("+") >= 0)
390:                    diff = Integer.parseInt(element.substring(tokenName
391:                            .length() + 1));
392:
393:                //replace the element:
394:                template = template.substring(0, index) + (value + diff)
395:                        + template.substring(index + element.length() + 1);
396:
397:                return template;
398:            }
399:
400:            /**
401:             * Pipes all apache-bastik message output for the user agent to log4j
402:             */
403:            static class Log4jUserAgentAdapter extends UserAgentAdapter {
404:                public void displayMessage(String message) {
405:                    log.info(message);
406:                }
407:            }
408:
409:            public static void main(String[] args) {
410:                SwingUtilities.invokeLater(new Runnable() {
411:                    public void run() {
412:                        startApp();
413:                    }
414:                });
415:            }
416:
417:            public static void startApp() {
418:                final JFrame frWindow = new JFrame();
419:                frWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
420:                final JPanel paMain = new JPanel();
421:                final JProgressBar progressBar = new JProgressBar();
422:                final SVGButtonRenderer brImageCreator = new SVGButtonRenderer();
423:                progressBar.setVisible(false);
424:                paMain.setLayout(new BorderLayout());
425:
426:                JButton btLoadFile = new JButton(new AbstractAction(
427:                        "Load SVG file") {
428:                    public void actionPerformed(ActionEvent e) {
429:                        JFileChooser fcOpenSVGFile = new JFileChooser(
430:                                "/home/hengels/jdevel/osb3/osbuild/openshop/modules/core/src/web/WEB-INF/classes/svg/");
431:                        fcOpenSVGFile.setDialogTitle("Load SVG File");
432:                        fcOpenSVGFile.setMultiSelectionEnabled(false);
433:                        fcOpenSVGFile.addChoosableFileFilter(new FileFilter() {
434:                            public boolean accept(File pathname) {
435:                                return pathname.isFile()
436:                                        && (pathname.getAbsolutePath()
437:                                                .endsWith(".svg") || pathname
438:                                                .getAbsolutePath().endsWith(
439:                                                        ".SVG"));
440:                            }
441:
442:                            public String getDescription() {
443:                                return "SVG Files";
444:                            }
445:                        });
446:                        if (fcOpenSVGFile.showOpenDialog(frWindow) == JFileChooser.APPROVE_OPTION) {
447:                            final File fSelectedFile = fcOpenSVGFile
448:                                    .getSelectedFile();
449:                            //String filePath = selectedFile.getAbsolutePath();
450:                            //String normalizedPath = filePath.replace('\\', '/');
451:                            //String fileURI = "file://" + normalizedPath;
452:                            progressBar.setVisible(true);
453:                            progressBar.setIndeterminate(true);
454:                            //thread
455:                            Thread t = new Thread(new Runnable() {
456:                                public void run() {
457:                                    //Dimension dim = brImageCreator.calculateButtonImageSize("Aufgaben");
458:                                    Dimension dim = new Dimension(20, 100);
459:                                    final BufferedImage biImageButton = brImageCreator
460:                                            .retrieveRenderedButtonImage(
461:                                                    "Aufgaben", fSelectedFile
462:                                                            .getName(), dim);
463:                                    SwingUtilities.invokeLater(new Runnable() {
464:                                        public void run() {
465:                                            Component c = ((BorderLayout) paMain
466:                                                    .getLayout())
467:                                                    .getLayoutComponent(BorderLayout.CENTER);
468:                                            if (c != null) {
469:                                                paMain.remove(c);
470:                                            }
471:                                            paMain.add(
472:                                                    new JButton(new ImageIcon(
473:                                                            biImageButton)),
474:                                                    BorderLayout.CENTER);
475:                                            //paMain.setBackground(Color.YELLOW);
476:                                            paMain.validate();
477:
478:                                            //thread end
479:                                            progressBar.setVisible(false);
480:                                        }
481:                                    });
482:                                }
483:                            });
484:                            t.start();
485:                        }
486:                    }
487:                });
488:                JButton btClean = new JButton(new AbstractAction("Clean") {
489:                    public void actionPerformed(ActionEvent e) {
490:                        Component c = ((BorderLayout) paMain.getLayout())
491:                                .getLayoutComponent(BorderLayout.CENTER);
492:                        if (c != null) {
493:                            paMain.remove(c);
494:                        }
495:                        paMain.validate();
496:                    }
497:                });
498:                JPanel paButtons = new JPanel();
499:                paButtons.setLayout(new FlowLayout());
500:                paButtons.add(btLoadFile);
501:                paButtons.add(btClean);
502:                paMain.add(paButtons, BorderLayout.NORTH);
503:                paMain.add(progressBar, BorderLayout.SOUTH);
504:                frWindow.setContentPane(paMain);
505:                frWindow.setSize(new Dimension(640, 480));
506:                //window.pack();
507:                frWindow.setVisible(true);
508:            }
509:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.