

This page in the Java Developer's FAQ covers questions on drawing and using images in the Abstract Window Toolkit (AWT).
What is paint() for, when is it invoked, and by whom?
The paint() method is the fundamental means by which a Component subclass (e.g., a Button, TextField, or Applet) draws itself on the screen. The best use of paint() is for quickly drawing the current state of the Component. Many Component subclasses, such as Button and TextField, know how to draw themselves. You need to define paint() in your own code if you subclass from a Component that does not already know how to draw itself (e.g., subclassing from Canvas, Panel, or Applet).
The paint() method is typically invoked by the update() method. The default implementation of update(), as defined in Component.java, clears the Component's area and then calls paint():
public void update(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
g.setColor(getForeground());
paint(g);
}
The paint() method is sometimes invoked directly, bypassing update(),
such as when a Component is scrolled or part of a window is exposed
after being covered on screen.
Examples: SimpleGraph, PaintExample.html
See also: Java Language Tutorial drawing overview, repaint(), update()
What is repaint() for, when is it invoked, and by whom?
The repaint() method issues a request that a Component be redrawn within a specified time, or as soon as possible if the time is left unspecified. The AWT organizes all drawing requests via a central drawing authority, managed by a single thread, so that various drawing requests don't interrupt each other and leave the screen in an inconsistent state. The central AWT thread translates repaint() requests into update() messages that it sends to the relevant components.
You normally invoke the repaint() method on a component when you know it no longer accurately reflects the internal state of your program. For instance, if you have several components (call them observers) that show information about a given object, a change to that object should typically be followed by repaint() messages to each of the observer components.
In some situations, the following details may be important. First, the repaint() request is asynchronous, which means that a call to repaint() returns immediately rather than waiting for the drawing to actually occur. Second, if a component has two or more unfulfilled repaint() requests waiting in the drawing queue, they can be merged into a single request.
Example:RepaintExample.html
See also: Java Language Tutorial drawing overview, paint()
Why would my repaint() method not have any effect?
A common reason that repaint() would appear not to work is that the CPU is 100% busy in a tight loop making repeated repaint() calls. A Component's repaint() method issues an asynchronous request for an update() message, but the central drawing thread that manages the update() messages only gets chance to run when the system is not busy.
A simple fix is to put some breathing space in your repaint() loop, by means of Thread's sleep() method.
Example: BusyRepaintExample.html
What is update() for, when is it invoked, and by whom?
The update() method works together with Component's paint() and repaint() methods to keep a program's appearance up to date with any changes in its internal state. The AWT sends update() messages to components when it wants them to redraw themselves. The default implementation of update(), as defined in Component.java, clears the Component's area and then calls paint():
public void update(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
g.setColor(getForeground());
paint(g);
}
It is often useful to define your own version of update().
For example, a simple way to reduce flicker in animations is to
replace the default update() with a your own version that simply
paints on top of what's already present rather than clearing the whole
area first. Remember, if you override update(), it's your
responsibility to call paint().
See also: Java Language Tutorial drawing overview, paint(), repaint()
Can I do drawing outside of the paint(), repaint(), and update() methods?
Yes, but we don't recommend it. Drawing in the AWT requires a Graphics object (java.awt.Graphics). In paint() and update(), a Graphics object is provided to you as the method's single argument. as their single parameter. (The repaint() method issues a request for update() to do its drawing.) Outside of these methods, it is possible to call getGraphics() on any Component subclass, and then use the returned Graphics object for drawing.
We recommend, instead, that you stick with paint(), repaint(), and update(). Grabbing a graphics context from a component may interact poorly with other parts of the system, such as scrolling.
Can I implement an invisible or partly transparent component?
The 1.0 Java Developers Kit release does not support transparent Components. All Components cover their space with an opaque background color, on top of which you can draw as much as you like. There is presently no way to have all or part of a component be systematically transparent.
See also: TextOnImageExample.html
Can I clear a clipping rectangle that either I or the system has created?
No. For a given Graphics object, the drawable region represented by clipping rectangles can only get smaller, so that any higher clipping rectangle is always guaranteed to be honored. One important result of this one-way restrictiveness is that applets are prevented from ever drawing outside their bounds.
If you need more freedom in using multiple clipping rectangles within your program, you can create separate "throwaway" graphics objects as children of your main Graphics object. The Graphics.create(x, y, w, h) method will create a new Graphics object with the clipping rectangle (x, y, w, h) based on the old Graphics object. Note that the origin (0, 0) in new Graphics object corresponds to (x, y) in the parent Graphics context. Also, any clipping rectangle in the child will still be constrained to lie completely within the parent's clipping rectangle.
Example:
SubgraphicsExample.html
How do I load an image into my applet?
Loading and displaying an image in an applet can be done with a minimum of two steps: Applet's getImage() method uses URL information to fetch the image, and Graphics's drawImage() method renders the image at a given location (and optionally scaled to fit a given rectangle). For further details and sample code, see Converting Applets that Use Images. See also: TextOnImageExample.html
How can I draw text over an image background?
Text is always transparent. You can simply draw it over the an image and only the letter themselves will be drawn. The example code illustrates the difference between drawing text directly on top of an image and placing a Label
You might be tempted to place a Label component on your image, but that won't work right. Components always have opaque backgrounds, so the Label will give the text but will also cover the image with an opaque background rectangle.
Example: TextOnImageExample.html
How can I create an image from a buffer of raw image data (red, green, and blue values for each pixel)?
The MemoryImageSource class (in java.awt.image) uses an array of int's to produce pixel values for an Image.
Examples: DitherTest, ImageTest
How can I create and draw to an offscreen image?
There are two preparatory steps: create an offscreen Image object and then get its Graphics object:
...
int width = ...;
int height = ...;
Image offscreenImage = createImage(width, height);
Graphics offscreenGraphics = offscreenImage.getGraphics();
...
At this point, you can place images or draw into this new Graphics
object the same as any other Graphics object.
Using offscreen images has the main advantage that a complex image can be created only once and then brought (rendered) on screen as many times as needed. Also, since the initial creation takes place off screen, time-consuming drawing can be done without intermediate stages being visible to the user (as either flicker or unintended "animation").
Example: OffscreenImageExample.html
See also: Converting Applets that Use Images
Can I copy a subarea of one image into another image?
Yes, and the trick is to use the clipping rectangle of the target image to define the subarea.
Like all drawing methods in java.awt.Graphics, drawImage() honors the current clipping rectangle of the Graphics object. The following code excerpt loads one image from a file, creates a second image that is one-half as long on each edge, and then draws a randomly selected portion of the main image into the subArea image.
myImage = getImage(getDocumentBase(), myImageName); subArea = createImage(size/2, size/2); subAreaGraphics = subArea.getGraphics(); ... int x = (int) (Math.random() * (size/2)); int y = (int) (Math.random() * (size/2)); subAreaGraphics.drawImage(myImage, -x, -y, this);Note in the final code line above how the -x, -y arguments shift the portion of main image that gets copied to the subarea. If these were 0, 0 instead, the subarea shown would always be the upper left corner of the main image.
Example: ImageSubareaExample.html
See also: SubgraphicsExample.html
Is there any way to force getImage() not to use the cached version of the image and make a new connection for each image ?
Yes. The 1.0 final release of the JDK contains a flush() method in java.awt.Image for just this purpose. This method was not available in earlier beta releases.
What could cause Graphics.drawImage() to fail or show no output?
In the 1.0 JDK, the drawImage() method will always return immediately even if none of the data is loaded. The final argument to drawImage(), an ImageObserver object, will be notified as the image is loaded. It is common to use the applet itself as the ImageObserver since, by default, it implements the ImageObserver interface and executes repaint() when more data comes in for the image.
If you have set your applet as the to be the ImageObserver yet you still get no output, then the image probably had an error and the imageUpdate() method in your applet was notified. The current default Applet imageUpdate() method does nothing with image errors, however. To check for errors, you need to override imageUpdate() yourself.
See also: Converting Applets that Use Images
Is it possible to "crop" the image (set its demensions) through java, or is that something that I'd have to do through a GIF editing program?
The 1.0 JDK contains a built-in filter to do cropping. The java.awt.image.CropImageFilter class provides an example. Alternately you could just draw the image with a clip rectangle and only those parts that show through the clip rectangle will be rendered. If the image is very large and you only want to show a small part of it, then using a cropping filter will allow us to conserve space internally by only dithering the part that will be shown.
See also: Converting Applets that Use Images
How can I make sure that images are loaded before I check for their data or parameters (e.g., so that .width() and .height() values are guaranteed to work)?
You can use a class which implements the ImageObserver interface to track the state of images as they load. Unfortunately, you have to render the image at least once so that the system knows which images and at what sizes you want the images scaled before they will be downloaded. The MediaTracker object was added to the Java Applet API to help deal with these issues.
See also: Converting Applets that Use Images, MediaTracker information
Why must an image be rendered in order to be fetched? Isn't this an excessive use of resources?
I was a little too brief in my previous explanation. In particular, the image data will load whenever you execute a method that requires some information about the image. If you execute getWidth() and getHeight() these methods will also induce the image to start loading.
One of the problems with the Alpha releases was that we had to have enough memory around to hold an image in memory before you could do anything with it. Also, once we constructed a screen representation of that image, we no longer had the original image data around any more to do things like filter it, scale it, or print it. The new APIs allow us to be much more conservative on memory utilization for loading and rendering images. In the Beta APIs I can do a getImage() on a file that is a 10Megabyte GIF which expands to 24 million pixels. I can then render that image in my applet at 100 x 100 and everything works great. Under Alpha, I had to explicitly run HotJava with a 32 Megabyte address space and then my machine would page incessantly for 5 minutes while it filled that 32 meg with pixel data that it would eventually discard. This is a rather extreme case, but when memory gets tight, smaller images could end up causing the same problems. Witness the fact that the Alpha ImageMap demo will tend to fail if you've been running HotJava for more than a couple of hours since memory fragmentation would prevent allocating a buffer large enough to store all of the pixel data (and that's only a 522x486 image).
There were potentially a number of solutions to these problems, but the basic solution that I came up with that seems to provide a tremendous amount of robustness at the expense of a more asynchronous twist to the APIs is the current architecture in which Image data is delivered asynchronously (with various caching tricks to help out) rather than simply viewing images as big monolithic buckets of pixels.
We also went with delayed realization of images so that we could more quickly format HTML pages and instantiate applets. If every applet that we init() needs to do lengthy download operations then we will end up wasting lots of time in page layout and applet startup that the user might wish to use in reading the surrounding text. In general, we would like to have the goal of throwing as few roadblocks in the way of completely instantiating an HTML page as we can for higher performance web browsing...
One particular fallout of this system is that we don't make any assumptions about what particular size you plan to render the image at. If we made the default assumption and automatically loaded and produced a full-size 1:1 scale version of the image when you first create it then we would end up preventing you from dealing with any images that are bigger than our existing contiguous heap space, or causing some really nasty performance hits when you tried. Instead, we wait for you to indicate what size you want to render the image at before we start downloading it. On the other hand, if you ask for the width or height and you haven't executed a drawImage call yet, we download anyway and hope that our internal caching of the pixels will allow us to produce the desired screen representation when you eventually get to rendering it.
One modification that I've toyed with is automatically starting the download when the applet does the getImage and automatically make an assumption and produce a 1:1 version of the image without waiting for the Applet to tell us what size to produce. Unfortunately, this will have the net effect of starting up a bunch of background threads which will compete with the threads that are trying to complete the instantiation and layout of the HTML page. I think things will be much better overall if we have applets wait until they are "start()"ed before they start their media downloads.
The MediaTracker class gives some explicit control over all of this back to the Applet and we are working on phasing in some new APIs that allow a Component (i.e. an Applet) to explicitly request the construction of a particular size of an image to fix this problem that you can't declare what size you want without rendering it. Until then, the version of the MediaTracker that I posted on my home page will work within the existing APIs (if you look at it, it renders the images to a 1x1 off screen image in order to kick off the construction of the image...)
How does XOR mode work?
XOR mode restores the colors if you do it twice. The Color argument when you enable XOR mode allows the system to calculate the pixel value you want to XOR with in a system-independent manner. In other words, if you know that the color on the screen is (predominantly) white, and you want to XOR with some value that changes that white to green and then back again, you have no way of calculating the appropriate pixel value to use to make those alternations. So, you tell us the two colors that you are interested in alternating when you draw and then we will calculate the appropriate pixel value for you taking into account the Color Model of the screen. Other colors will be changed in a random, but reversible manner as per the boolean XOR operation.
How do you display a gif image file in a standalone java program, rather than in an applet?
Unfortunately the standard Java packages do not contain the helper classes that you need to do this, nor do they contain factory-style APIs to instantiate the sun-specific classes you need. Only the Applet class with its AppletContext and AppletStub contain the necessary environment to get these classes instantiated for you in a portable way.
This is an oversight...
For now, you will have to instantiate one of:
Toolkit.getDefaultToolkit().createImage(ImageProducer ip);Since this requires you to refer to a class in a Sun-specific package directly, this won't be portable.
How do you display a gif image file in a standalone java program, rather than in an applet?
From: Mentor
On Thu, 21 Sep 1995, Karl Asha wrote:
Would anyone care to show some sample code to simply display a gif
in a -standalone- java program. Not an applet.
It's simpler than you'd think: First, you set up a window (there's code in the
archives from rizzoti.sven@ch.swissbank.com which tells how). Then, you haul
in the image with one of the following:
How do you display a gif image file in a standalone java program,
rather than in an applet?
How can I get at the raw data of an image, such as the pixel value
at a given coordinate?
Use the PixelGrabber class. To use it you would write:
What is the basic idea behind ImageFilter objects?
The idea behind the ImageFilter objects was that if you filter an
image, then you should filter it as the data is delivered rather than
to grab a buffer of pixels for the image, modify the pixels, and then
turn around and make a new image from that buffer. This doesn't work
when you need to filter lots of large images. The beta version of the
Sun home page now loads much more frequently in a lot less memory since
the ImageMap applet now uses dynamic filters rather than getDIBitmap
and createImage to make its button highlight areas...
How do I display a GIF file in windows on Windows N%/95?
The URL you use, C:\\hotjava\\..., is incorrect. Try file:c:/hotjava/...
Use forward slashes and use a "file:" at the front of the URL to
indicate that the URL is a file rather than an HTTP or FTP
connection...
How do I load and display a transparent gif over a background image?
Java doesn't paint anything for the transparent pixels of an image.
The background might be getting painted if you don't override update().
What painting occurs if my applet reappears after being covered by
some other window?
If your applet gets damage (i.e. it is behind some other window and
then that other window is moved away), the background of the exposed
or damaged area is filled with the background color and paint(Graphics g)
is called for you to repaint the applet.
How do you know that your picture has been read and it's finished ?
There are a number of ways:
What ImageConsumer objects work behind the scenes?
There are a number of different ImageConsumer objects that will attach
themselves to you for any number of different reasons. An "InfoGrabber"
object will attach itself to you when you first create the image so that
it can catch the width, height and any properties you may report. It
will remove itself at the first imageComplete, whether it is FRAMEDONE
or STATICIMAGEDONE.
The first time you try to draw the image using drawImage, you will get
an "ImageRepresentation" object attached to you which will handle the
conversion of the pixels for the screen...
The following applet when run will display nothing. If I change the drawImage
all to pass in "this" instead of "null" then the applet does the right
thing and displays the image as soon as it is loaded. Seems to me that there
should be away to request an entire image without trying to draw it...
The problem is that we don't know what size image to construct without
the applet telling us. If we automatically construct a full size
version of the image and the applet then draws it at 50% scale we may
have constructed the full size version for nothing. In the case of
your applet, the only call that you guaranteeably execute is getWidth()
so only the basic information (width, height, properties) is generated.
If the width and height were to happen to be known by the time your
paint method is first executed, then you will execute drawImage and
trigger off the generation of a screen image, but that isn't reliable.
How is an image constructed?
There are 3 ways to cause the construction of an image:
See also:
Converting Applets
that Use Images,
MediaTracker information
What is the default ColorModel for AWT Components(e.g. Frames)?
The default ColorModel depends on the characteristics of the
display of the user who is running your Applet. You have to execute
Component.getColorModel() at runtime and adapt to it.
The basic correlations is that if you are running on anything less than
8 bits deep you will probably get an IndexColorModel, but if you are
running on a deeper display you will probably get a DirectColorModel.
But, don't count on that you may get some "FoobarColorModel" if there
is a screen that doesn't match these two common color spaces. Any
subclass of ColorModel can be returned by that method, Index and Direct
are just the two most common mechanisms for specifying color...
In any case, while it may be useful to know the color model of the
underlying screen for optimizations under some circumstances, you can
always invent your own color model, report pixels in that color model,
and the image display code will adapt itself to your color model. If
you recognize the ColorModel you get, you can generate pixels in that
space and the underlying code should work faster, but if you don't
recognize it, then just pick one of your own that you are comfortable
working in. That is why the ImageConsumer.setPixels methods take a
ColorModel argument. Currently the image code doesn't have any
optimizations to take advantage of noticing if you are reporting
pixels in the default ColorModel, but the APIs are in place for adding
that optimization in the future (hopefully by 1.0 Final).
What do x,y in java.awt.Graphics.drawImage() refer to?
The x,y in drawImage refer to the location on the screen (relative to
the origin or translation of the Graphics object) at which to draw
the upper left corner of the image.
The reason this is confusing in the "drawing a subset of an image"
example you have is that if you want pixel i,j of the image to appear
at 0,0 which is also the upper left corner of the clipping rectangle,
then you have to draw the image at screen location -i,-j so that the
screen location 0,0 is i pixels from the left edge of the image and j
pixels from the top edge of the image - thus screen location 0,0 shows
image pixel i,j...
If you want to draw imgX, imgY, imgW, imgH subset of an image at
scrX, scrY, then do the following:
How do I track multiple versions of the same image at different scales?
Constructing one particular scaled size of an image does not
necessarily mean that you can then render the image at other scales
and get immediate results. Each scaled size of an image is
separately constructed and cached. Moreover, unless you construct
them in parallel, if you construct one size, and then try to draw
another size, we may have to refetch the original image since the
raw pixels may have been decached by the garbage collector in the
meantime.
Does Java support progressive jpeg, and interlaced gif formats when
using drawImage(), etc?
The JDK 1.0 supports both interlaced GIF and progressive JPEG.
How can a I drag a selected image?
The "How to Avoid Flashing in an Applet" example illustrates how to
do this in alpha 3 Java. The basic idea is the same in beta Java.
Does Java/HotJava provide support for drag and drop?
We currently provide no API for drag and drop. We hope to add this in
future versions.
I have some images that I want to rotate by 90 degrees.
Can anyone give me some guidence or examples?
There really isn't a way to rotate images using the AWT.
However, I wrote a little applet that uses copyArea recursively
to rotate an image by 90 degrees. (avh)
Example:
rotate
When does a component's background get painted?
Unfortunately we have no support for transparent Components in this
release. All Components will have some background color, and although
you can paint over it as much as you want, you can't prevent it from
opaquely obscuring everything underneath you.
The update method only bypasses the background painting in one particular
case - when you call the "repaint()" method. All other causes for painting,
primarily display damage caused by moving or resizing windows, will cause
the background to be painted. On many platforms the system does this
without any chance for the application to prevent it.
Java does not generally allow drawing on an underlying Component to
show through an overlapping Component. Drawing is generally clipped to
all overlapping Components.
In a future release, we might implement an "input-only" Component which
received input, but which could not be drawn to.
How do I coordinate between paint(), repaint(), and update() to handle
all my drawing?
Several main strategies are common, and they vary considerably in
complexity:
String nice_image = "http://www.io.org/~mentor/images/moose.gif";
// one way:
Object o = (new URL(nice_image)).getContent();
// second way:
GifImage i = new GifImage(nice_image);
// third way (more complex, but more general):
URL url = new URL(nice_image);
InputStream in = url.openStreamInteractively();
Object o = url.getContent(in, null);
From: Anujit Sarkar
int[] pix = new int[w * h];
PixelGrabber pg = new PixelGrabber(img.getSource(),
x, y, w, h,
pix, 0, w);
pg.grabPixels();
When that method returns, the pix array will contain the data for the
specified subrectangle of the image in the default RGB format (see
ColorModel.getRGBdefault()). Note that since the grabPixels method
can take an arbitrarily large amount of time to complete, you should
not call it during any of an applet's methods that may be called by
a system thread (such as init(), paint(), or update()). Instead, call
it from a helper thread you create to do asynchronous setup.
We encourage applet-writers to use the MediaTracker since it will
take care of the details the right way for them.
g.clipRect(scrX, scrY, imgW, imgH);
g.drawImage(img, scrX-imgX, scrY-imgY, this);
Note that this permanently changes the clip rectangle of the g object.
If you want to avoid modifying g that way, then this is equivalent to:
Graphics subg = g.create(scrX, scrY, imgW, imgH);
// Note that subg has been translated by scrX, scrY
// so that (scrX, scrY) in g is at (0, 0) in subg
subg.drawImage(img, -imgX, -imgY, this);
subg.dispose();
except that in the second case, the original g object has its clipRect
left undisturbed.
First, for very simple programs, typically small applets, (... fill
out answer ...)