How to use JFreeChart with SWT (includes sample code)

A free public discussion forum for the JFreeChart class library.

How to use JFreeChart with SWT (includes sample code)

Postby Robert Gash » Wed Jul 09, 2003 7:32 pm

I have seen a number of posts asking how to use JFreeChart within SWT applications. Most solutions appear to rely on converting AWT Image's into SWT Image's. That process works fine, but seems overly tiedious.

Newer SWT implementations are beginning to provide very rough wrappers around a java.awt.Panel that allow older AWT/Swing components to be reused inside of SWT applications. Currently only Win32 platforms are supported, although I imagine that other ports aren't far off.

Here's a quick and dirty example of how to use JFreeChart "natively" (without converting Images, etc.) inside of your Win32 SWT application. This has been tested on the Eclipse 3.0M1 SWT drop (build 3007). This WILL NOT work with older 2.x SWT drops.

0) Take a look at
Code: Select all
org.eclipse.swt.internal.SWT_AWT
, all of the functionality to create a Panel backed by our Composite resides here in the
Code: Select all
new_Panel
method.

1) Create a simple SWT Composite that will contain your AWT/Swing components (in this case a ChartPanel). Align the Composite using your usual SWT layout managers.

2) Create a JFreeChart based on your data using the usual ChartFactory methods.

3) Create a new java.awt.Panel that is backed by your SWT Composite. Optionally you may wish to set the background color to that of the composite and add a layout manager if you want to have several JFreeChart's in the same Composite, or you want the chart to resize itself based on the size of the SWT Composite.

4) Create ChartPanel's and add them to your java.awt.Panel that you obtained from SWT_AWT in step 3.

5) Sit back and enjoy!

Sounds easy, doesn't it? Here's the code (tested using SWT 3.0M1, JFreeChart 0.9.8, JCommon 0.8.3, J2SDK 1.4.2 on Win32 [Win2k]).

Code: Select all
/// STEP 1 ////////////////////////////////////////////////
// create a composite suitable for displaying all of our chart data
Composite chartComposite = new Composite(/* options */);
chartComposite.setLayoutData(/* set the layout options */);

/// STEP 2 ////////////////////////////////////////////////
// create the dataset for the pie chart of the distribution
DefaultPieDataset pieData = new DefaultPieDataset();
/* populate the pieData here */

JFreeChart chart = ChartFactory.createPie3DChart(/* some options */);
// OPTIONAL: tinkering with plot options here

/// STEP 3 ////////////////////////////////////////////////
// Grab the background color from the SWT Composite
// so our AWT panel "matches" the SWT Composite
Color backgroundColor = chartComposite.getBackground();

// create the panel
Panel chartPanel = SWT_AWT.new_Panel(chartComposite);

// set the panel's background (defaults to pure white)
chartPanel.setBackground(new java.awt.Color(backgroundColor.getRed(),
                                                    backgroundColor.getGreen(),
                                                    backgroundColor.getBlue()));
// set the AWT layout manager
chartPanel.setLayout(/* some AWT/Swing layout manager like BoxLayout */);

/// STEP 4 ////////////////////////////////////////////////       
ChartPanel jfreeChartPanel = new ChartPanel(chart);
chartPanel.add(jfreeChartPanel);


-Robert Gash, Software Developer, Enkia Corporation
gashalot <at> enkia.com
Robert Gash
 

Postby david.gilbert » Thu Jul 10, 2003 8:21 am

Hi Robert,

Thanks for your post. I get the occasional question about using JFreeChart in SWT (I've never tried SWT myself) so this is useful...
Dave Gilbert
JFreeChart Project Leader

:idea: Buy the JFreeChart Developer Guide :idea:
david.gilbert
JFreeChart Project Leader
 
Posts: 10759
Joined: Fri Mar 14, 2003 10:29 am
Location: Europe

Works in Linux!

Postby Murali » Fri Oct 03, 2003 4:13 am

I have attempted the above method in linux under Eclipse 2.1.1. Got the chart, everything working!
Murali
 

Wow Thanx

Postby Shilpa » Fri Oct 17, 2003 8:46 pm

Hi Thanx its v good..
Shilpa
 

Postby Jon » Mon Nov 24, 2003 11:14 am

When I upgraded to ver 3 of eclipse to try and get JFreeChart to work inside swt it no longer recognised

Panel chartPanel = SWT_AWT.new_Panel(chartComposite);

From random reading on web i found:

Panel org.eclipse.swt.internal.awt.win32.SWT_AWT.new_Panel(Composite)

The new_Panel method has one parameter, an SWT Composite object, and
it returns an AWT Panel object. The awt Panel is contained within the
swt Composite, and is constructed using a WEmbeddedFrame from Sun's
internal package sun.awt.windows. Sun has changed this internal code
in jdk 1.4, and so this undocumented Eclipse mechanism does not work
with that version.

Any on e have any suggestions on how I can get graphs to display inside my SWT application?

Cheers

Jon
Jon
 

Postby Robert Gash » Fri Apr 02, 2004 3:47 am

Jon wrote:swt Composite, and is constructed using a WEmbeddedFrame from Sun's
internal package sun.awt.windows. Sun has changed this internal code
in jdk 1.4, and so this undocumented Eclipse mechanism does not work
with that version.

Any on e have any suggestions on how I can get graphs to display inside my SWT application?


Jon,

I actually just tested a new demo using SWT 3.0M8, J2SDK 1.4.2_03, and JFreeChart 0.9.17 on my Windows XP system (SP1). I was able to use JFreeChart without any problems.

The sample code can be found at http://www.gashalot.com/software/JFreeChartSWTDemo.java.

Let me know if you have any questions.

-R
Robert Gash
 

Dynamically dispose a chart in SWT?

Postby Chengdong » Sat May 01, 2004 5:49 pm

Hi, there:

I tried the suggestions here and found it was okay for just showing a chart in SWT application by using SWT_AWT. However there are still some potential problems exist:

SWT and AWT has diffent UI loop, they can not iteroperate seamlessly which is also discouraged by Eclipse developers.

For example, can somebody show me how to solve this problem:
==========================================
Show the pie-chart first, then click pie-chart, this will show a new bar-chart beside the pie-chart; click the bar-chart, then only show the piechart.

I tried to make this run by dynimically disposing the SWT_AWT widget, it gave me some error from SWT AWT interoperation sometime and did not work.

I think only pure SWT implementation of JFreeChart can solve this problem.

Can anybody give me some suggestion?

You can answer me by email: cli4@uky.edu

Thanks in advance.

-Chengdong
Chengdong
 

IllegalArgumentException

Postby ftam_ftp » Fri Jun 04, 2004 3:06 am

I've tried the solution above, and after working out that I should be using SWT_AWT.new_Frame(), I get an IllegalArgumentException. I've tried passing both the Composite, and the Shell as an argument, but it makes no difference. I also tried the JFreeChartSWTDemo with the same results. I'm running Eclipse 2.1.2 Build 200311030802, and using the SWT drop 3.0RC1 build 3054. Any ideas?

Thanks
ftam_ftp
 

Tried and failed

Postby Geoffrey Peart » Mon Sep 20, 2004 5:41 pm

Robert Gash wrote:
Jon wrote:swt Composite, and is constructed using a WEmbeddedFrame from Sun's
internal package sun.awt.windows. Sun has changed this internal code
in jdk 1.4, and so this undocumented Eclipse mechanism does not work
with that version.

Any on e have any suggestions on how I can get graphs to display inside my SWT application?


Jon,

I actually just tested a new demo using SWT 3.0M8, J2SDK 1.4.2_03, and JFreeChart 0.9.17 on my Windows XP system (SP1). I was able to use JFreeChart without any problems.

The sample code can be found at http://www.gashalot.com/software/JFreeChartSWTDemo.java.

Let me know if you have any questions.

-R

Robert, I attempted to run the code at that link, I am running
eclipse 3.0.0 GA with J2SDK 1.4.2_03, and I have tried jFreeChart 0.9.17 and the recent .21 releases. I enccounter two issues. the first is this:
Code: Select all
java.lang.NoClassDefFoundError: org/jfree/util/PublicCloneable
   at java.lang.ClassLoader.defineClass0(Native Method)
   at java.lang.ClassLoader.defineClass(Unknown Source)
   at java.security.SecureClassLoader.defineClass(Unknown Source)
   at java.net.URLClassLoader.defineClass(Unknown Source)
   at java.net.URLClassLoader.access$100(Unknown Source)
   at java.net.URLClassLoader$1.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClassInternal(Unknown Source)
   at com.gashalot.sample.JFreeChartSWTDemo.main(JFreeChartSWTDemo.java:45)
Exception in thread "main"

That is occuring on this line :
Code: Select all
JFreeChart chart = ChartFactory.createPieChart3D("Sample Chart", pieData, true, true, false);


If I comment that, and the ones depend on it, I end up with:
Code: Select all
java.lang.IllegalArgumentException: Argument not valid
   at org.eclipse.swt.SWT.error(SWT.java:2677)
   at org.eclipse.swt.SWT.error(SWT.java:2616)
   at org.eclipse.swt.SWT.error(SWT.java:2587)
   at org.eclipse.swt.awt.SWT_AWT.new_Frame(SWT_AWT.java:118)
   at com.gashalot.sample.JFreeChartSWTDemo.main(JFreeChartSWTDemo.java:48)
Exception in thread "main"

on line
Code: Select all
Frame chartFrame = SWT_AWT.new_Frame(shell);


Is there anything I am missing here?

If you check this, I could use your help, or anyones.

Thanks in advance.
Geoffrey Peart
 

In reply to my own message

Postby Geoffrey Peart » Mon Sep 20, 2004 6:50 pm

Okay first error because I am a fool :) I didn't include the jcommon.jar in my class path. The second one, well here is the javadoc for SWT_AWT class

Code: Select all
Creates a new java.awt.Frame. This frame is the root for the AWT components that will be embedded within the composite. In order for the embedding to succeed, the composite must have been created with the SWT.EMBEDDED style.


so I changed the new shell(display) to this

Code: Select all
Shell shell = new Shell(display,SWT.EMBEDDED);


worked like a charm, not sure if that is a new release of SWT going on there or what, but it works so I'm happy. Thanks Robert for the good sample.

g
Geoffrey Peart
 

Postby Tim99 » Tue Oct 05, 2004 6:34 pm

Unfortunately I can't use this method on Mac OS X because of this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=67384

Mixing up AWT and SWT with Eclipse (Mac OS X) doesn't seem to work. :-(

Any suggestions?
Tim99
 

jfreechar and swt

Postby Giuseppe » Wed Oct 27, 2004 12:34 pm

Hi
I'm an italian designer and I don't speak english very well, sorry.
I have seen your message but I'm not able to put into practice your solution because eclipse tell me that the method SWT_AWT.new_Composite not exists. How can I do?

Thanks in advance,
Giuseppe
Giuseppe
 

SWT Problem

Postby pixeldude » Mon Dec 13, 2004 2:03 pm

1. you have to create a display and a shell

Code: Select all
Display display = new Display();
Shell shell = new Shell(display);


2. Create an SWT composite with the style SWT.EMBEDDED
Code: Select all
Composite chartComposite = new Composite(shell, SWT.EMBEDDED);


3. Create an AWT Frame using SWT_AWT
Code: Select all
Frame chartFrame = SWT_AWT.new_Frame(chartComposite);


4. Go on with JFreeChart

This worked for me with SWT 3.0
pixeldude
 

Postby Guest » Fri Jan 07, 2005 5:38 pm

Tim99 wrote:Unfortunately I can't use this method on Mac OS X because of this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=67384

Mixing up AWT and SWT with Eclipse (Mac OS X) doesn't seem to work. :-(

Any suggestions?


I had the same problem with Linux, too. But there is a way. You can save the image in a local buffer using AWT and load it from that buffer using SWT afterwards.

This is a little bit ugly, but it works...

Here is my code:
Code: Select all
  public static Image createChartImage(Control parent, JFreeChart chart,
    int width, int height)
  {
    // Color adjustment
    Color swtBackground = parent.getBackground();
    java.awt.Color awtBackground = new java.awt.Color(swtBackground.getRed(),
                                                      swtBackground.getGreen(),
                                                      swtBackground.getBlue());
    chart.setBackgroundPaint(awtBackground);
   
    try {
      // Write the image to a buffer in memory using AWT
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      ChartUtilities.writeChartAsPNG(out, chart, width, height);
      out.close();
     
      // Load the image from the same buffer using SWT
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
      Image swtImage = new Image(display, in);
      in.close();
     
      return swtImage;
    }
    catch (Exception exc) {
      exc.printStackTrace();
      return null;
    }
  }
Guest
 

Postby Til » Wed Jan 12, 2005 3:16 pm

I'm the "Guest" who wrote the last post...

I just found a faster way without the indirection over creating PNG data.

Here is the code:

Code: Select all
  public static Image createChartImage(Control parent, JFreeChart chart,
    int width, int height)
  {
    // Color adjustment
    Color swtBackground = parent.getBackground();
    java.awt.Color awtBackground = new java.awt.Color(swtBackground.getRed(),
                                                      swtBackground.getGreen(),
                                                      swtBackground.getBlue());
    chart.setBackgroundPaint(awtBackground);

    // Draw the chart in an AWT buffered image
    BufferedImage bufferedImage
      = chart.createBufferedImage(width, height, null);

    // Get the data buffer of the image
    DataBuffer buffer = bufferedImage.getRaster().getDataBuffer();
    DataBufferInt intBuffer = (DataBufferInt) buffer;
   
    // Copy the data from the AWT buffer to a SWT buffer
    PaletteData paletteData = new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF);
    ImageData imageData = new ImageData(width, height, 32, paletteData);
    for (int bank = 0; bank < intBuffer.getNumBanks(); bank++) {
      int[] bankData = intBuffer.getData(bank);
      imageData.setPixels(0, bank, bankData.length, bankData, 0);     
    }
   
    // Create an SWT image
    return new Image(parent.getDisplay(), imageData);
}
Til
 
Posts: 1
Joined: Wed Jan 12, 2005 2:57 pm

Next

Return to JFreeChart - General

Who is online

Users browsing this forum: Yahoo [Bot] and 0 guests