14 Replies Latest reply on Dec 21, 2007 3:37 PM by ericjava

    A customer JSF tag to display Graphics2D in Seam PDF output

      I posted a long blog entry, along with source code, about how to create a custom JSF tag to do more in Seam PDF: http://chiralsoftware.com/blog/JBoss-Seam-iText-PDF-custom-JSF-4642a90cb4d7412d.html

      The motivation: I wanted to be able to include arbitrary java.awt.Component s in the output, so I could do whatever I wanted with Graphics2D. I ended up writing a custom JSF tag to do that. All the source is there, along with a tour of how I did it.[/url]

        • 1. Re: A customer JSF tag to display Graphics2D in Seam PDF out
          damianharvey

          Pretty cool.

          However, you can currently include jFreecharts into your pdf using the existing <p:image> tag eg:

          <p:image width="300" height="200" value="#{myBean.myChartImage}" />

          Where you encode your chart as an image and store as a byte array:
          private byte[] myChartImage;
          
          myChartImage = ChartUtilities.encodeAsPNG(myChart.createBufferedImage(300, 200));
          


          Cheers,

          Damian.

          • 2. Re: A customer JSF tag to display Graphics2D in Seam PDF out

            Right, I mentioned that: "Before we go any further: why don't we use the Seam pdf:image tag, instead of writing a new tag? " The problem is that that will result in PDFs that don't look so good and can't be accessed by search engines (yes, I might want search engines to read my chart legend and labels). When I rendered simple JButtons into the PDF, it was cool to see how good they looked, even when zooming in.

            • 3. Re: A customer JSF tag to display Graphics2D in Seam PDF out
              damianharvey

              My mistake, I thought you were referring to the built in pdf chart tags.

              • 4. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                That's very nice. If you'd like to contribute this back to Seam, I'd be happy to include it in the next release.

                • 5. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                   

                  "norman.richards@jboss.com" wrote:
                  That's very nice. If you'd like to contribute this back to Seam, I'd be happy to include it in the next release.


                  Certainly! I would be honored. I hereby release copyright for that code. Contact me: eric *at* chiralsoftware d0t net if you need something more formal. And a link to chiralsoftware.com would be cool!

                  Think of the possibilities. You can now layout your PDF, or bits of your PDF, using Matisse!

                  • 6. Re: A customer JSF tag to display Graphics2D in Seam PDF out
                    • 7. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                       

                      "norman.richards@jboss.com" wrote:
                      http://jira.jboss.com/jira/browse/JBSEAM-2414


                      Thanks Norman!

                      I made another blog post on it:

                      http://chiralsoftware.com/blog/JFreeCharts-in-PDF-with-JSF-and-c47ae72d938fe060.html

                      This post discusses using the tag to put JFreeChart charts into a PDF. Bottom line: you would think that the JFreeChart ChartPanel class would do the trick, but actually you get the right result by writing a very simple extension of java.awt.Component, and it is a good candidate for using as an anonymous inner class. I show some examples of charts rendered into PDFs to show what the results are.


                      • 8. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                        I had a similar problem when doing the charting. I was rather disappointed with the results of putting charts in PDFs until I discovered Graphics2D. What a difference.

                        • 9. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                          BTW - I didn't quite follow why you had a problem with rendering your charts with the built-in charting. Just looking at the code, I see no reason why your charting subclass wouldn't have been rendered in the Graphics2D context that I use for our charts.

                          • 10. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                            Ok, I've adapted your code and checked in the results. Take a look and tell me what you think. Right now it would look like:

                            <p:swing width="310" height="120" component="#{sampleButton}" />


                            The only problem I'm having is that I have to explicitly set the look and feel. On the mac, the default look and feel does not seem to render to anything useful. If I set the look and feel to something neutral, it works fine.

                            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());


                            Did you run into this problem?





                            • 11. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                              Yes indeed! In my blog post, I wrote:

                              One interesting thing to notice is that this button is using the Linux look-and-feel, because, in this case, the server was running Linux. If this server had been running on some other operating system, the button would, by default, take that other operating system's look-and-feel. This is something to be aware of when using Swing components. All Swing components have system-dependent look-and-feel.


                              By the way, before you get everyone set on it, you might want to call the tag something other than "swing". I set it up to use java.awt.Component as an argument, not a JComponent. All Swing components are sub-classes of java.awt.Component, so you get them all for free. But Component is simpler, with no complications from look-and-feel considerations, and more inclusive, than JComponent. Here's a very simple Component I wrote to display a JFreeChart, for example, without Swing involved:

                              public final class ChartComponent extends Component {
                              
                               public ChartComponent(JFreeChart chart) { this.chart = chart; }
                               private final JFreeChart chart;
                              
                               @Override public void paint(Graphics g) {
                               chart.draw((Graphics2D)g, new Rectangle(getWidth(), getHeight()));
                               }
                              
                              }




                              • 12. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                                 

                                "norman.richards@jboss.com" wrote:
                                BTW - I didn't quite follow why you had a problem with rendering your charts with the built-in charting. Just looking at the code, I see no reason why your charting subclass wouldn't have been rendered in the Graphics2D context that I use for our charts.


                                I'm not following. Simple pie charts, bar charts, etc, yes, the built-in charting can do all that. I needed to do some other stuff that the built-in Seam charting couldn't do.

                                Do you mean why I wrote my own ChartComponent class? I initially tried to show my charts like: new ChartPanel(chart), using the JFree ChartPanel class. For whatever reason, that rendered as a bitmap. They probably have some buffering or whatever in there. So I just wrote a tiny java.awt.Component class.


                                • 13. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                                  I couldn't think of a good name. Component is too generic. JSF component. AWT component. Seam component? To me "swing" is synonymous with Java GUI components. So p:swing, despite not being technically correct, seemed to me to be the only thing captured the idea of a GUI component being inserted. I'm still open to suggestions.

                                  BTW, the problem with the LAF wasn't just that the components were being rendered differently but that they weren't being rendered at all with the default LAF on my machine. That's very troubling because it means none of this is guaranteed to work out of the box.



                                  • 14. Re: A customer JSF tag to display Graphics2D in Seam PDF out

                                     

                                    "norman.richards@jboss.com" wrote:
                                    I couldn't think of a good name. Component is too generic. JSF component. AWT component. Seam component? To me "swing" is synonymous with Java GUI components. So p:swing, despite not being technically correct, seemed to me to be the only thing captured the idea of a GUI component being inserted. I'm still open to suggestions.


                                    Ok, swing is fine. You're right, Component is used in every other sentences when talking about Java anything.

                                    "norman.richards@jboss.com" wrote:
                                    BTW, the problem with the LAF wasn't just that the components were being rendered differently but that they weren't being rendered at all with the default LAF on my machine. That's very troubling because it means none of this is guaranteed to work out of the box.


                                    Hmm. What kind of machine? I only have Linux machines here so that's all I've tested on. As you say, anyone using Swing JComponents is going to want to set the LAF to something that looks more generic or cross-platform. I don't know what's the right way (the "Seam way") of doing that. Could there be a setting for Swing UI LaF in the components.xml file?