What is PJA ?
PJA contents
Tested platforms
FAQ
History
What's next ?
Copyright and license
PJA documentation
PJA feedback
PJA (Pure Java AWT) Toolkit is a JavaTM library for drawing graphics developed by eTeks. It is 100% Pure Java and doesn't use any native graphics resource of the system on which the Java Virtual Machine runs.
java.awt.Graphics methods such as drawLine (), fillOval (), drawString (),... are implemented in the default JVM with native graphical functions (except in some cases for Java2D) : That means that drawLine () finally calls a GDI system function on Windows or X11 function on a X11/UNIX machine even if the drawing is done in an off-screen image using the class java.awt.Image. This ensures the best performance for drawing graphics with Java.
But in a few cases, this default behavior can cause problems that PJA library improves :
Finally, PJA library is supplied under GNU General Public License with its Java source files, and is a good exemple for studying :
Sources are supplied to allow developers to improve and optimize the graphic drawing methods.
com.eteks.awt package files are Java 1.0 compliant but needs JDK 1.2 or higher library to compile (for Java < 1.2 compilers, this can be
done using any Java 2 rt.jar library instead of classes.zip in -classpath option at compile time).
PJA library core classes weighs 144 Ko at run-time (can be reduced to 73 Ko if compressed).
PJA library is supplied with :
- pja.jar and pjatools.jar JAR libraries.
- Java source files.
- Javadoc documentation.
- a FAQ list.
- PJANativeToolkitComparison a demo to compare at screen the rendering of the PJA toolkit and the native toolkit of your system. A speed meter allows to see the average duration of drawing with PJA toolkit compared to native toolkit.
- PJAToolkitDemo a demo that creates GIF files using the PJA toolkit.
- NativeToolkitDemo a demo that creates GIF files using the native toolkit of your system.
- PJADemo a demo that creates GIF files using PJA and a restrictive SecurityManager that prevents the use of awt library.
- PJAFontCapture a Font capture utility to generate font files (to avoid copyright problems on fonts, no font is provided). You can use any machine where AWT works to generate these portable files.
- TeksSurveyPie an exemple of a servlet generating a survey pie.
Servlet host providers can use it for their customers, if they provide copyright information and a link to http://www.eteks.com on their web site and other documentation.
eTeks made successful tests of PJA on the following systems :
JDK version Windows MacOS UNIX 1.0 Win 98/SunJDK 1.0.2 1.1 Win 98/SunJDK 1.1.8 MacOS 9/MRJ 2.2 Linux/JDK 1.1.7 (without DISPLAY)
1.2 Win 98/SunJDK 1.2.2 Linux/JDK 1.2.2 (with and without DISPLAY)
1.3 Win 98/SunJDK 1.3.0 Other users reported they succeeded to use PJA on the following systems :
- Linux with JDK 1.3.0
- AIX with JDK 1.3.0
- Sun Solaris
- OS/390
- HP-UX with JDK 1.2.2 and JDK 1.3.1.02
- FreeBSD with JDK 1.3
In which cases should I use PJA ?
Audience Problem Solution User / Developer You wonder if graphics servlets and applications can work on your server. Test com.eteks.servlet.DefaultToolkitTest servlet and/or PJAToolkitDemo application. User You have problems to run graphics servlets on your server. You can't change java command line options.
Test com.eteks.servlet.PJAServletTest.
If it works fine use
com.eteks.awt.servlet.PJARedirectServlet to run graphics servlets.
Otherwise, ask your servlet server administrator to add these options to java command line (at least -Xbootclasspath/a:pja.jar)You can change java command line options. See which options to use. Developer You want to develop graphics servlets that will work everywhere. Extend the class com.eteks.awt.servlet.PJAServlet to minimize support to customer who don't have access to a Display (see com.eteks.servlet.TeksSurveyPie as an actual case)
You may also use only PJA Graphics methods.
What options do I have to add to java command line to use PJA with my servlet server on UNIX platform ?
(JDK version is obtained with the command java -version)
- JDK version <= 1.1 : The demo closest to this situation is PJAToolkitDemo.sh. It requires at least one .pjaf font file to run.
- First, run PJAFontCapture on a platform with a working Display (Windows, MacOS, UNIX with X11 Display) to create at least one .pjaf font file.
- Copy or ftp (in binary mode) .pjaf files to PJA install directory.
- Check classpath in PJAToolkitDemo.sh.
- Run PJAToolkitDemo.sh : It tests most of the Graphics methods and creates 4 GIF files (PJAToolkit*.gif). Check if the images looks like this.
- Finally, add these options to your Java command line :
- -classpath $CLASSPATH:pja.jar (or change CLASSPATH variable).
- -Dawt.toolkit=com.eteks.awt.PJAToolkit : this enables to change AWT Toolkit.
- -Djava.awt.fonts=. or the path where you'll put your .pjaf files.
- JDK version >= 1.2 : The demo closest to this situation is PJAToolkitDemo1.2.sh. It uses Lucida True Type fonts delivered with the JDK.
- First check the parameters in PJAToolkitDemo1.2.sh :
- java.awt.fonts property must be equal to the directory where Lucida*.ttf files can be found. Normaly it looks like /.../jdk.../jre/lib/fonts depending on the directory where the JDK is installed.
- user.home property must be equal to PJA install directory.
- Run PJAToolkitDemo1.2.sh : It tests most of the Graphics methods and creates 4 GIF files (PJAToolkit*.gif). Check if the images looks like this and use some anti-aliasing. If JVM crashes try this addtionnal change.
- Finally, add these options to your Java command line :
- -Xbootclasspath/a:pja.jar (changing classpath is not enough).
- -Dawt.toolkit=com.eteks.awt.PJAToolkit : this enables to change AWT Toolkit.
- -Djava.awt.graphicsenv=com.eteks.java2d.PJAGraphicsEnvironment : this enables to change Graphics environment.
- -Djava2d.font.usePlatformFont=false : this avoids the class sun.java2d.loops.RasterOutputManager to call the native method getPlatformFontVar (), that may cause a JVM crash.
- -Djava.awt.fonts=path with path equal to the directory where Lucida*.ttf files can be found. You can add to path other directories containing True Type Fonts by using : separator.
- Either -Duser.home=dir with dir equal to the directory where a sub directory lib containing PJA font.properties file can be found, or add lib/font.properties to user.home system property directory, or replace Java font.properties file by PJA font.properties file (it can be found in /.../jdk.../jre/lib directory).
Some JDK configuration (depending on your country or the type of your OS) may require you to rename the font.properties file or change the content of this file : have a look at the document Adding Fonts to the Java Runtime for more information. Note that fonts must be coded as required for Win32 platform and only True Type fonts can be used.
As JDK doesn't provide any ZapfDingbats and Symbol fonts, you may need to add yourself these fonts to font.properties.For your information, the JDK version >= 1.4 includes its own headless system (see AWT Enhancements in JDK 1.4 docs) : Just set the system property java.awt.headless to true or add the -Djava.awt.headless=true option to your Java command line to use it.
How can I add pja.jar to bootclasspath in JServ with JDK version >= 1.2 ?
Add the following line in the jserv.properties file with the good path to pja.jar :
wrapper.bin.parameter = -Xbootclasspath/a:/path/pja.jarWhy do I still get the exception java.awt.AWTError : Toolkit not Found in a java.awt.Toolkit.getDefaultToolkit () call, as I can instantiate the class com.eteks.awt.PJAToolkit ?
getDefaultToolkit () tries to instantiate the class described by the system property awt.toolkit. This method uses the system classpath of the default class loader to find this toolkit class. If com.eteks.awt.PJAToolkit is in a user or servlet classpath, your program may be able to instantiate this class but getDefaultToolkit () won't still be able to find it.
That's why pja.jar must be in the options -classpath (JDK <= 1.1) or -Xbootclasspath (JDK >= 1.2) of the java command line. If you don't have access to the command line, see the parts In which cases should I use PJA ? and What methods can be called in a servlet with no problem of Toolkit access for end users ?Why the Java Virtual Machine crashes when I use fonts on UNIX platform ?
With some implementations of JDK >= 1.2 (particulary on Solaris), sun.java2d.SunGraphicsEnvironment class uses the method private static native boolean validPropertiesFile (java.lang.String, java.lang.String). This static method must have a bug which makes the JVM crashes when it's called without a correct Display. The following ugly patch works :
- Extract the latest file sun/java2d/SunGraphicsEnvironment.class from the file rt.jar of the matching JDK (1.2 or 1.3) for Windows distributed by Sun (it doesn't use the validPropertiesFile method), with the command :
jar xvf /.../jdk.../jre/lib/rt.jar sun/java2d/SunGraphicsEnvironment.class- Put the file sun/java2d/SunGraphicsEnvironment.class in a new jar archive named rtgraphics.jar with the command :
jar cvf rtgraphics.jar sun/java2d/SunGraphicsEnvironment.class- Change the option -Xbootclasspath of your Java command line to -Xbootclasspath/p:pja.jar:rtgraphics.jar (rtgraphics.jar must be prepending to default bootclasspath to ensure JVM uses the sun.java2d.SunGraphicsEnvironment class of rtgraphics.jar).
Some users reported that inner classes of sun.java2d.SunGraphicsEnvironment (all the files named SunGraphicsEnvironment$*.class) must be included also in rtgraphics.jar to make this patch work (this depends on the JDK version).
This bug doesn't appear with the latest version of the JDK 1.3.What methods can be called in a servlet with no problem of Toolkit access for end users ?
Problems with graphics servlet may occure because users can't access to AWT default toolkit on UNIX platform where no Display is available. In this case, the classes java.awt.Toolkit and java.awt.Font can't be instantiated and the methods of java.awt.Component requiring a Toolkit instance can't be called.
Providing PJA Toolkit to these users instead of default toolkit may be a good solution, except if they can't modify themselves the options of their Java Virtual Machine because they are not the servlet server administrator :
- System properties can be replaced in the servlet by a call to System.setProperties () or System.setProperty (). For example, System.setProperty ("awt.toolkit", "com.eteks.awt.PJAToolkit") can be called to replace the -Dawt.toolkit=com.eteks.awt.PJAToolkit option.
- -classpath $CLASSPATH:pja.jar (or -Xbootclasspath/a:pja.jar) can't be replaced easily. Some servlet servers (like JServ or JRun) provide the ability for each user to specify a different classpath to which you can add pja.jar. This classpath will be used by the Servlet server class loader to load user servlets and its depending classes.
But AWT toolkit is instantiated by the method getDefaultToolkit () of the class java.awt.Toolkit : this method uses awt.toolkit property to guess which class must be instantiated. Generally, system default class loader will be used to load java.awt.Toolkit and this class. As system class loader will use system classpath to load com.eteks.awt.PJAToolkit class, it won't find it because pja.jar is in servlet classpath and not in system classpath !The class com.eteks.awt.servlet.PJAServlet resolves the problem of the classpath option, but may cause some security problems on java environment running with strong security manager : this class requires the access to classpath and other system properties, the ability to instantiate a class loader,...
PJA provides also a way to perform graphics even if no default toolkit was instantiated. Here's the list of the methods you can call without using an AWT Toolkit instantiated by a java.awt.Toolkit.getDefaultToolkit () call :
Default AWT toolkit PJA toolkit (package com.eteks.awt) Toolkit getImage (URL url) PJAToolkit getImage (URL url) Toolkit getImage (String file) PJAToolkit getImage (String file) Toolkit createImage (ImageProducer producer) PJAToolkit createImage (ImageProducer producer) Toolkit createImage (byte[] imagedata, int imageoffset, int imagelength) PJAToolkit createImage (byte[] imagedata, int imageoffset, int imagelength) Toolkit prepareImage (Image image, int width, int height, ImageObserver observer) PJAToolkit prepareImage (Image image, int width, int height, ImageObserver observer) Toolkit checkImage (Image image, int width, int height, ImageObserver observer) PJAToolkit checkImage (Image image, int width, int height, ImageObserver observer) Toolkit getColorModel () PJAToolkit getColorModel () Component createImage (int width, int height) new PJAImage (int width, int height) Component createImage (ImageProducer producer) PJAToolkit createImage (ImageProducer producer) Graphics getFont ()
PJAGraphicsExtension getFontName ()
getFontStyle ()
getFontSize ()Graphics setFont (Font font)
PJAGraphicsExtension setFont (String fontName, int fontStyle, int fontSize)
PJAToolkit can be instantiated by a new PJAToolkit () call.
PJAGraphicsExtension is implemented by PJAGraphics used to draw in PJAImage instances. This means you can cast the Graphics instance returned by new PJAImage (width, height).getGraphics () to PJAGraphicsExtension.As com.eteks.awt.PJAImage doesn't implement Java2D, this solution implies that your program doesn't use Java2D and Graphics2D capabilities.
.pjaf font files will be used to draw strings.Why the methods show () or setVisible () of the class java.awt.Component throws ClassCastException with JDK >= 1.3 ?
These methods use the class sun.awt.GlobalCursorManager which supposes that the AWT toolkit returned by the method getDefaultToolkit () of the class java.awt.Toolkit inherits from sun.awt.SunToolkit ! As com.eteks.awt.PJAToolkit inherits directly from java.awt.Toolkit, it throws a ClassCastException exception.
Using addNotify () on an instance of java.awt.Frame instead of these methods is enough to enable the creation of off-screen images with the createImage () method of java.awt.Frame class, and avoids to wonder where will appear such a frame once the method show () is executed.What fonts can I use to draw strings with PJA ?
With JDK >= 1.2, True Type fonts are used.
With JDK <= 1.1 or if com.eteks.awt.nojava2d system property is equal to true with JDK >= 1.2, .pjaf font files are used. You can build these files from existing fonts with PJAFontCapture utility.What are these .pjaf files for ?
With the default toolkit of JDK <= 1.1, strings are drawn using native functions and fonts of the platform where the JVM runs (UNIX, Windows,...). To be able to draw strings with only pure Java, PJA toolkit needs some font information. Instead of implementing a decoder for X format or True Type font, it was decided to retrieve fonts drawing information from a new format stored in files with the .pjaf extension. These portable files store the bitmap drawing of each character of a font. PJAFontCapture utility allows to capture native fonts and save them in .pjaf files.
As Java2D includes its own decoder for True Type Font files, .pjaf files are useless with JDK >= 1.2. Use instead existing True Type Font files.Why PJAFontCapture (or java com.eteks.tools.fontcapture.PJAFontCapture) can't work ?
PJAFontCapture captures native fonts using default toolkit of the Java Virtual Machine. You can't run it on a UNIX machine with no Display available.
If you need .pjaf fonts on a UNIX machine with no Display, launch PJAFontCapture on a machine where default toolkit can run (Windows, MacOS, UNIX with X11 Display). Then, ftp (in binary mode) or copy the .pjaf files to the UNIX machine.How can I save my images ?
Off-screen images computed by PJA toolkit and more generally any Java images can be saved with encoders that generate images files or streams at different formats. The encoding operation can be programmed easily in a few lines. Please read the ToolkitDemo.java file for an example using ACME's GIF encoder.
Here are 3 small and free encoders that were successfully tested with PJA toolkit (with little modifications to ToolkitDemo.java) :
Encoder
formatJDK version
supportedLink GIF 1.1 http://www.acme.com/java/
The modified class Acme.JPM.Encoders.GifEncoder provided with PJA distribution supports also the JDK 1.0JPEG 1.1 http://www.obrador.com/essentialjpeg/ PNG 1.1 http://catcode.com/pngencoder/ Sun Microsystems provides also the 2 following libraries that include decoders/encoders :
- JIMI, running under JDK version >= 1.1, supports the following formats : GIF (decoder only), JPEG, TIFF, PNG, PICT, Photoshop, BMP, Targa, ICO, CUR, Sunraster, XBM, XPM and PCX.
- JAI (Java Advanced Imaging), running under JDK version >= 1.2, supports the following format : BMP, GIF (decoder only), FlashPix (decoder only), JPEG, PNG, PNM and TIFF.
For your information, the JDK version >= 1.2 provides the class com.sun.image.codec.jpeg.JPEGImageEncoder to encode images that are instances of the class java.awt.image.BufferedImage, in JPEG format.
Drawing with PJA is too slow. How can I improve performances ?
If you use PJA toolkit with a JDK >= 1.2, most AWT methods are implemented by existing classes of the Java standard library, except the methods that read image files. As a lot of these methods are implemented in C librairies by Sun, it's difficult to expect a speed improvement in the future.
PJA drawing methods are used if JDK <= 1.1, if the com.eteks.awt.nojava2d system property is set to true or if you use directly com.eteks.awt.PJAImage and com.eteks.awt.PJAGraphics classes. In this case, PJA toolkit is slower than default toolkit because com.eteks.awt.PJAGraphics drawing methods were implemented with classical drawing algorithms and could be optimized. That's one of the reasons why PJA is free : if you know any algorithm that could improve PJA performance, let us know so we could implement it and let other PJA users share this improvement.
In all cases, check if your JIT (Just In Time) or HotSpot compiler is on.Is PJA toolkit 100% Pure Java ?
PJA isn't 100% Pure Java according to Sun JavaPureCheck tool test.
It lists the two following errors because PJA uses sun.awt.image.ByteArrayImageSource and sun.java2d.SunGraphicsEnvironment JDK internal classes :
- sun.awt.image.ByteArrayImageSource class is used in the method createImage (byte [] imagedata, int imageoffset, int imagelength) of com.eteks.awt.PJAGraphicsManager class, and is the same implementation as sun.awt.SunToolkit.
- sun.java2d.SunGraphicsEnvironment is the super class of com.eteks.java2d.PJAGraphicsEnvironment. Its use can't be avoided because the class java.awt.Font casts the default graphics environment returned by the method getLocalGraphicsEnvironment () of java.awt.GraphicsEnvironment to sun.java2d.SunGraphicsEnvironment !
This second reason avoids PJA to ever succeed at JavaPureCheck tool test.
Version 2.4 03/14/2002
- getImage () methods of com.eteks.awt.PJAGraphicsManager : InputStream not immediately closed once GIF images were read.
- Added a contructor in com.eteks.awt.image.GIFDecoder to be able to chose the close of the input stream once the image is read.
- createImage (byte[] imagedata, int imageoffset, int imagelength) method of com.eteks.awt.PJAGraphicsManager bug : zero length arrays shouldn't throw exceptions.
- Added methods to com.eteks.awt.PJAComponentPeer, com.eteks.awt.PJAFramePeer and com.eteks.java2d.PJAGraphicsConfiguration to enable PJA to run with JDK 1.4 (some useless methods were commented to be able to compile PJA with 1.2 rt.jar library).
- Added information in the FAQ.
Version 2.3.1 07/05/2001
- copyArea () method of com.eteks.awt.PJAGraphics bug : wrong method call to get the height of the image (thanks to Dean Brettle).
- No use of character encoding in writeString () method of Acme.JPM.Encoders.GifEncoderNoCM, so headers of GIF images are correctly generated under OS/390. Note that users of Acme.JPM.Encoders.GifEncoder may force the correct character encoding with the -Dfile.encoding=ISO8859_1 java option that sets the file.encoding system property.
- Changed -Duser.home=. to -Duser.home=.. in PJAToolkitDemo1.2.sh.
- Added information in the FAQ about rtgraphics.jar patch.
Version 2.3 03/23/2001
- getImage (File filename) method of com.eteks.awt.PJAToolkit and com.eteks.awt.PJAGraphicsManager tries to find the image filename in a path relative to user.dir system property as before, and then if image isn't found with that path it tries to find filename with the path returned by the method getAbsolutePath () of the class java.io.File.
- Java2D is turned off if JVM version returned by the system property java.version returns something that can't be parse in the form x.y.z, where x, y and z are numbers.
- PJA fonts management and drawString () method of com.eteks.awt.PJAGraphics optimized : drawing strings run up to 4 times as fast (thanks to Fernando Echeverria).
- Inlined code com.eteks.awt.PJAGraphics for optimization (thanks again to Fernando Echeverria).
- Added support for 8 bit color images using java.awt.image.IndexColorModel in com.eteks.awt.Image and com.eteks.awt.PJAGraphics classes : All images created with PJA toolkit can use a 8 bit/pixel buffer with an indexed color model if the class name given by the system property com.eteks.awt.colormodel inherits from java.awt.image.IndexColorModel.
The new com.eteks.awt.image.Web216ColorModel class can be used as an indexed color model for that purpose (thanks again to Fernando Echeverria).- Added information in the FAQ.
Version 2.2 11/02/2000
- Changed the condition that detects GIF transparency in the class com.eteks.awt.image.GIFDecoder.
- readCode () method of com.eteks.awt.image.GIFDecoder bug : fixed raster over-run errors (thanks to Alan Dix).
- Better GIF detection from content type in com.eteks.awt.PJAGraphicsManager (thanks to Fernando Echeverria).
- Added minimum support for EventQueue in com.eteks.awt.PJAToolkit.
- getClipBounds () method of com.eteks.awt.PJAGraphics bug : returns a correct Rectangle instance.
- create () method of com.eteks.awt.PJAGraphics bug : changed com.eteks.awt.PJAGraphics constructors.
- translate () method of com.eteks.awt.PJAGraphics bug : changed to enable the cumulative effect of translations after multiple call to translate ().
- Clipping bugs in com.eteks.awt.PJAGraphics.
Version 2.1 07/30/2000
- PJA library is available under GNU General Public License from this version.
- PJA is now supplied with a font.properties file using the Lucida True Type fonts provided with JDK 1.2. The described properties use a font format that works with com.eteks.java2d.PJAGraphicsEnvironment class. It uses the same font format as its super class sun.java2d.SunGraphicsEnvironment and as Windows implementation.
This file is required with JDK version greater or equal to 1.2 when using com.eteks.awt.PJAToolkit and com.eteks.java2d.PJAGraphicsEnvironment classes on a UNIX platform. It must be in a lib sub directory of the directory defined by $HOME or user.home system property.
Check if the path you set in java.awt.fonts system property contains the directory /.../jdk.../jre/lib/fonts where Lucida True Type fonts files are by default.
If you need to change font.properties yourself, have a look at the document Adding Fonts to the Java Runtime.- Created the com.eteks.awt.servlet.PJAServlet class extending javax.servlet.http.HttpServlet.
This class should be used by developers as a super class to ensure their graphics servlets will work with all servlet servers in almost any case.- Created the com.eteks.awt.servlet.PJARedirectServlet class extending com.eteks.awt.servlet.PJAServlet.
This class should be used by users of graphics existing servlets to provide an AWT toolkit to their servlet server if they have some problems using the default JVM one.- Added a FAQ list.
- Organized differently PJA files.
- Splited pja.jar in two files : pja.jar and pjatools.jar.
- pja.jar contains the core PJA classes (packages com.eteks.awt, com.eteks.awt.image, com.eteks.awt.servlet and com.eteks.java2d).
This jar file contains all the classes needed to replace default JVM toolkit.- pjatools.jar contains some utility classes, the classes used for demo and PJAFontCapture utility class.
Version 2.0 06/23/2000
- After a close study of the JDK 1.2.2 sources available at Sun, support of Java2D in Pure Java AWT images was added for JVM version greater or equal to 1.2 (using java.awt.image.BufferedImage class or java.awt.Component class createImage () method). It may interest people who want to generate images with Java2D features even if they don't have access to any X11 Display on UNIX machines.
This study was done respecting this process :
- In the import instructions and in the code of all the classes of java.awt package and sub packages, search the non standard Java classes they need. Most of these classes belongs to sun.dc, sun.awt, sun.java2d and sun.security.action packages and sub packages.
Untill Java 1.1, all java.awt classes imported classes only from standard Java packages (and Sun shouldn't have changed this paradigm !).- In the import instructions of all the classes of the latter packages, search what other packages are needed. A few ones use conversion classes of sun.io package, sun.security.action.GetProperty class, sun.security.action.LoadLibraryAction class and sun.misc classes for weak references (nothing that seems annoying).
- In the classes of java.awt, sun.dc, sun.awt and sun.java2d packages and sub packages, search abstract classes and classes with native methods (event managing classes were a little neglected because they aren't usefull in PJA).
The result of this research told roughly :
- Which abstract classes are extended in platform dependent classes or not (classes of sun.awt.motif and sun.awt.windows packages).
- Which native methods are implemented using common portable C code (sources found in share/native/sun/awt, share/native/sun/dc and share/native/sun/java2d directories) or using platform dependent code (using Windows GDI or an X11 display for example).
All the native classes of java.awt package and sub packages are named initIDs (). The implementation of initIDs () is only used by native objects to initialize their struct data and don't use any X11 Display but requires the awt library to be loaded.
Almost all the methods of the class java.awt.image.BufferedImage used to render Java2D are implemented in common Java classes or C programs, except a few ones that are corrected by the following classes.The following new classes belong to the package com.eteks.java2d. The classes of com.eteks.awt package don't require them if you wish to work with JDK 1.1 or if a DISPLAY is available.
- Created the com.eteks.java2d.PJAGraphicsManager2D class extending com.eteks.awt.PJAGraphicsManager.
- Created the com.eteks.java2d.PJAGraphicsEnvironment class extending sun.java2d.SunGraphicsEnvironment.
- java.awt.graphicsenv system property have to be set to com.eteks.java2d.PJAGraphicsEnvironment to permit the change of java.awt.GraphicsEnvironment implementation.
- java.awt.fonts system property have to be set to the path where True Type fonts files will be loaded from.
This path can be equal to :
WinDir\Font
directory on Windows/usr/openwin/lib/X11/fonts/Type1:/usr/openwin/lib/X11/fonts/TrueType
directories on Solaris($JAVAHOME)/lib/fonts
- Any directory list containing True Type fonts.
When drawing in images of class java.awt.image.BufferedImage, .pjaf font files are not used.
- Created the com.eteks.java2d.PJAGraphicsDevice class extending java.awt.GraphicsDevice.
- Created the com.eteks.java2d.PJAGraphicsConfiguration class extending java.awt.GraphicsConfiguration.
- Created the com.eteks.java2d.PJABufferedImage class extending java.awt.image.BufferedImage. It has the same constructors as BufferedImage and overrides the method public Graphics2D createGraphics (); to return the Graphics instance returned by the method createGraphics () of PJAGraphicsEnvironment.
- Changed the methods createImage (int width, int height) and createImage (ImageProducer producer) of the class com.eteks.awt.PJAGraphicsManager to return a PJABufferedImage instance if JVM version is greater or equal to 1.2.
- For security reasons or for a need of homogeneous image result whatever JDK is used, the boolean system property com.eteks.awt.nojava2d can be set to true to disallow Java2D in PJA.
In that case, PJAImage will be used as images class along with PJAGraphics class and .pjaf fonts.
Version 1.2 06/08/2000
- Added the method public int charWidth (char ch) in the class com.eteks.awt.PJAFontMetrics (it overrides java.awt.FontMetrics to return the width of a character).
- com.eteks.awt.PJAImage bug : drawing images constructed by a prepareImage () call could throw exceptions.
- Changed com.eteks.awt.PJAComponent default background color : new images created by createImage (int width, int height) are now white by default (when setBackground () is not set on the component).
- Created the com.eteks.awt.PJAMenuComponentPeer class for internal needs.
- Created the com.eteks.awt.image.GIFDecoder class : it is now the default GIF files loader (it avoids the exception java.lang.UnsatisfiedLinkError: parseImage with JDK 1.1).
If you need a GIF loader, it can be used alone without com.eteks.awt package (it implements the interface java.awt.image.ImageProducer).Version 1.1 05/30/2000
- Version 1.0 .pjaf font files are not compatible with PJA version 1.1.
Please use font capture utility to produce PJA 1.1 new font files. For security reasons and wider platform compliance, it was impossible to support PJA 1.0 fonts in PJA 1.1.- Version 1.0 targeted the replacement of Java standard AWT Toolkit by PJA Toolkit when standard Toolkit couldn't be instantiated.
Version 1.1 aims at enabling the creation of an image and drawing into it with all the java.awt.Graphics methods, even if no Toolkit can be instantiated by getDefaultToolkit () static method of the class java.awt.Toolkit, for security or other reason (JServ 1.1 refuses to load the class com.eteks.awt.PJAToolkit because it's not in its default classpath).
Version 1.0 allowed to create an instance of com.eteks.awt.PJAImage but using java.awt.Graphics drawString () threw an AWTError exception, when no Toolkit was available. This is because the class java.awt.Font requires the instance of a Toolkit to be instantiated in Java 1.1 and without any Toolkit you can't get any font to draw strings...
com.eteks.awt.PJAGraphics was changed in version 1.1 and now has a default internal font created from a .pjaf font file. This default font is used in drawString () method to draw text.
On the other hand, in Java 1.1, the creation of a java.awt.Font object is still impossible without a Toolkit instance, which prevents from changing the default font to an other one, with Graphics setFont () method. To be able although to modify the font used in drawString (), the non standard setFont (String fontName, int fontStyle, int fontSize) method of the new interface com.eteks.awt.PJAGraphicsExtension was implemented in PJAGraphics class (see also com.eteks.awt.PJAToolkit class).- Following the same idea, version 1.0 was modified to enable the use of PJA even if the awt library can't be loaded for security or other reasons. If awt isn't available, a lot of AWT classes (in particular,
java.awt.Color
,java.awt.Rectangle
,java.awt.Font
,java.awt.FontMetrics
,java.awt.image.ColorModel
) can't be loaded preventing some graphics operations. Changing the current color and querying font metrics is although possible when awt library isn't available thanks to com.eteks.awt.PJAGraphicsExtension new methods implemented in PJAGraphics class (see the new PJADemo.java example to see what it may change in your Java code).
- Changed com.eteks.servlet.TeksSurveyPie to improve error catching and provide a good model for Image creation.
- Changed createImage (int width, int height) method in the class com.eteks.awt.PJAComponent to fill the image with component background color.
- Improved Javadoc documention of all classes.
- Cleaned import instructions in PJA classes to enhance maintenance ; there are no more import ...*; and class prefixed with its package (except when a class name is in a String, and mustn't be loaded) : all the classes of foreign packages used in a class have an import.
- Created the com.eteks.awt.PJAGraphicsManager class into which the font loading methods of the class com.eteks.awt.PJAToolkit were copied.
- Created the com.eteks.awt.PJAFontData class into which all the font data management code of the class com.eteks.awt.PJAFontMetrics was copied.
- com.eteks.awt.PJAGraphics class optimization : this class doesn't use anymore floating point Java type (float or double). Thanks to this change, floating point is useless in the package com.eteks.awt, enabling PJA to be used in a J2ME environment.
- com.eteks.awt.PJAGraphics class change : this class doesn't use anymore the classes java.awt.Color, java.awt.Rectangle, java.awt.FontMetrics or java.awt.Polygon for internal use.
- com.eteks.awt.PJAGraphics bug : Large ellipse weren't drawn correctly, ellipse generator uses long now.
- com.eteks.awt.PJAGraphics drawString (AttributedCharacterIterator iterator, int x, int y) method implemented.
- com.eteks.awt.PJAImage flush () method correctly implemented.
- PJA 1.1 now supports JDK 1.0.2.
- Changed demo programs.
- To reduce the size of the package com.eteks.awt, the two next methods moved :
- The main () method of the class com.eteks.awt.PJAFontPeer moved to the new class com.eteks.tools.fontcapture.PJAFontCapture.
- The main () demo method of the class com.eteks.awt.PJAToolkit moved to the new class PJAToolkitDemo (with no package).
Version 1.0 05/17/2000
First version. JDK 1.1 compliant.
Javadoc documentation should be clearer and more consistent. Meanwhile, if you have problems using PJA library, please read first the FAQ.
Features that may be interesting to implement in PJA :
- Supporting Java2D in PJA for JVM version 1.1 :
It's a great amount of work that could be simplified by using or modifying JDK 1.2 classes sources (if possible), but Sun may not grant the authorization to distribute such modified JDK 1.2 classes for JVM version 1.1 use.
Maybe, supporting anti-aliasing on current PJA would be enough for most people...- PJAToolkit getPrintJob () method could be implemented as sun.awt.motif.MToolkit getPrintJob () method.
- Stuff not implemented in PJAToolkit should throw java.awt.AWTError.
- Keep track of all PJAGraphics calls, to be able to generate vector PNG files.
- The method sync() of the class PJAToolkit should do something.
- PJAFrame should be linked to JInternalFrame to looks like a frame and then allow to capture it.
If you have any suggestion about how PJA should evolve, please send them to info@eteks.com or fill the PJA feedback form.
Copyright © 2000-2001 Emmanuel PUYBARET / eTeks info@eteks.com. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAVisit eTeks web site for up-to-date versions of PJA and other Java tools and tutorials : http://www.eteks.com/
Copyright © 1996,1998 by Jef Poskanzer jef@acme.com. All rights reserved. (for the use of Acme.JPM.Encoders.GifEncoder class)
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Visit the ACME Labs Java page for up-to-date versions of this and other fine Java utilities : http://www.acme.com/java/