-
Bug
-
Resolution: Cannot Reproduce
-
P4
-
None
-
1.2.0
-
x86
-
windows_95
Name: et89391 Date: 07/14/99
A sample program from p.172 in "Graphic Java 1.2: Mastering the JFC, Vol.1" works with JDK1.1.7B but not with JDK1.2, Somehow Dissolver.imageComplete() is called twice with JDK1.2. I attached three source code(Dissolver.java, DissolverFilter.java, Test.java). To test, you need a gif file whose name must be "tiger.gif":
------------ Souce Code from the book (slightly modified) -----
//
// File: Dissolver.java from "Graphic Java 1.2: Mastering the JFC, Vol.1"
//
import java.awt.*;
import java.awt.image.*;
class Dissolver implements ImageConsumer {
Image images[];
Image image;
ColorModel defaultRGB = ColorModel.getRGBdefault();
Component component;
Graphics g;
int intPixels[], x, y, width, height, pauseInterval;
int numImages;
boolean isAlreadyCompleted = false;
public Dissolver(Component c, int x, int y) {
this(c,x,y,10,50);
}
public Dissolver(Component c, int x, int y,
int numImages, int pauseInterval) {
this.component = c;
this.numImages = numImages;
this.pauseInterval = pauseInterval;
this.x = x;
this.y = y;
images = new Image[numImages];
}
public void setColorModel(ColorModel model) {
// don't care - we use our own in imageComplete(),
// and the one passed into setPixels()
}
public void setHints(int hints) {
// don't care
}
public void setProperties(java.util.Hashtable props) {
// don't care
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
intPixels = new int[width * height];
}
public void setPixels(int x, int y, int w, int h,
ColorModel model, int[] pixels,
int offset, int scansize) {
for(int r=0; r < h; ++r) {
for(int c=0; c < w; ++c) {
int index = offset + r*scansize + c;
intPixels[index] =
model.getRGB(pixels[index]);
}
}
}
public void setPixels(int x, int y, int w, int h,
ColorModel model, byte[] pixels,
int offset, int scansize) {
for(int r=0; r < h; ++r) {
for(int c=0; c < w; ++c) {
int index = offset + r*scansize + c;
intPixels[index] =
model.getRGB(pixels[index] & 0xff);
}
}
}
public synchronized void imageComplete(int status) {
if(status == IMAGEERROR || status == IMAGEABORTED) {
return;
}
//
// With JDK 1.2, imageComplete() is called twice: BUG?
// With JDK 1.2, imageComplete() is callced only once.
//
if (isAlreadyCompleted)
System.out.println("imageComplete() is called again.");
else
isAlreadyCompleted = true;
MemoryImageSource mis = new MemoryImageSource(
width, height, defaultRGB,
intPixels, 0, width);
image = component.createImage(mis);
makeDissolvedImages(); // this takes some time, so ...
notifyAll(); // notify all threads waiting on us
}
private void makeDissolvedImages() {
MediaTracker mt = new MediaTracker(component);
DissolveFilter filter;
for(int i=0; i < images.length; ++i) {
filter = new DissolveFilter((255/(numImages-1))*i);
FilteredImageSource fis = new FilteredImageSource(
image.getSource(),
filter);
images[i] = component.createImage(fis);
mt.addImage(images[i], i);
}
mt.addImage(image, numImages);
try { mt.waitForAll(); }
catch(Exception e) { e.printStackTrace(); }
}
public void fadeOut() {
g = component.getGraphics();
if(g != null) {
try {
for(int i=numImages-1; i >= 0; --i) {
g.clearRect(x, y, width, height);
g.drawImage(images[i], x, y, component);
pause();
}
}
finally {
g.dispose();
}
}
}
public void fadeIn() {
g = component.getGraphics();
if(g != null) {
try {
for(int i=0; i < numImages; ++i) {
g.clearRect(x, y, width, height);
g.drawImage(images[i], x, y, component);
pause();
}
g.drawImage(image, x, y, component);
}
finally {
g.dispose();
}
}
}
private void pause() {
try { Thread.currentThread().sleep(pauseInterval); }
catch(InterruptedException e) { }
}
}
//
// File: DissolverFilter.java from "Graphic Java 1.2: Mastering the JFC, Vol.1"
//
import java.awt.image.*;
public class DissolveFilter extends RGBImageFilter {
private int alpha;
public DissolveFilter() {
this(0);
}
public DissolveFilter(int alpha) {
canFilterIndexColorModel = true;
if(alpha < 0 && alpha > 255)
throw new IllegalArgumentException("bad alpha");
this.alpha = alpha;
}
public int filterRGB(int x, int y, int rgb) {
DirectColorModel cm =
(DirectColorModel)ColorModel.getRGBdefault();
int alpha = cm.getAlpha(rgb);
int red = cm.getRed (rgb);
int green = cm.getGreen(rgb);
int blue = cm.getBlue (rgb);
alpha = alpha == 0 ? 0 : this.alpha;
return alpha << 24 | red << 16 | green << 8 | blue;
}
}
//
// File: Test.java from "Graphic Java 1.2: Mastering the JFC, Vol.1"
//
import java.net.URL;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class Test extends Frame implements Runnable {
Image tiger;
boolean showing = false;
Dissolver dissolver = null;
int x,y;
public Test() {
super("Image Dissolver");
MediaTracker mt = new MediaTracker(this);
URL url = getClass().getResource("tiger.gif");
try {
tiger = createImage((ImageProducer)url.getContent());
mt.addImage(tiger, 0);
mt.waitForID(0);
}
catch(Exception e) { e.printStackTrace(); }
}
public void addNotify() {
super.addNotify();
Insets i = getInsets();
dissolver = new Dissolver(this, x=i.left, y=i.top);
synchronized(dissolver) {
ImageProducer ip = tiger.getSource();
ip.startProduction(dissolver);
try {
dissolver.wait(); // wait for dissolved images ...
}
catch(Exception e) { // wait() was interrupted
e.printStackTrace();
}
}
try {
Thread thread = new Thread(this);
thread.start();
}
catch(Exception e) { // thread was interrupted
e.printStackTrace();
}
}
public void run() {
while(true) {
if(isShowing()) {
if(showing) dissolver.fadeOut();
else dissolver.fadeIn();
showing = showing ? false : true;
try {
Thread.currentThread().sleep(1000);
}
catch(Exception e) { e.printStackTrace(); }
}
}
}
public static void main(String args[]) {
final Test f = new Test();
f.setBounds(100,100,375,375);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
f.dispose();
System.exit(0);
}
});
}
}
(Review ID: 52794)
======================================================================
A sample program from p.172 in "Graphic Java 1.2: Mastering the JFC, Vol.1" works with JDK1.1.7B but not with JDK1.2, Somehow Dissolver.imageComplete() is called twice with JDK1.2. I attached three source code(Dissolver.java, DissolverFilter.java, Test.java). To test, you need a gif file whose name must be "tiger.gif":
------------ Souce Code from the book (slightly modified) -----
//
// File: Dissolver.java from "Graphic Java 1.2: Mastering the JFC, Vol.1"
//
import java.awt.*;
import java.awt.image.*;
class Dissolver implements ImageConsumer {
Image images[];
Image image;
ColorModel defaultRGB = ColorModel.getRGBdefault();
Component component;
Graphics g;
int intPixels[], x, y, width, height, pauseInterval;
int numImages;
boolean isAlreadyCompleted = false;
public Dissolver(Component c, int x, int y) {
this(c,x,y,10,50);
}
public Dissolver(Component c, int x, int y,
int numImages, int pauseInterval) {
this.component = c;
this.numImages = numImages;
this.pauseInterval = pauseInterval;
this.x = x;
this.y = y;
images = new Image[numImages];
}
public void setColorModel(ColorModel model) {
// don't care - we use our own in imageComplete(),
// and the one passed into setPixels()
}
public void setHints(int hints) {
// don't care
}
public void setProperties(java.util.Hashtable props) {
// don't care
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
intPixels = new int[width * height];
}
public void setPixels(int x, int y, int w, int h,
ColorModel model, int[] pixels,
int offset, int scansize) {
for(int r=0; r < h; ++r) {
for(int c=0; c < w; ++c) {
int index = offset + r*scansize + c;
intPixels[index] =
model.getRGB(pixels[index]);
}
}
}
public void setPixels(int x, int y, int w, int h,
ColorModel model, byte[] pixels,
int offset, int scansize) {
for(int r=0; r < h; ++r) {
for(int c=0; c < w; ++c) {
int index = offset + r*scansize + c;
intPixels[index] =
model.getRGB(pixels[index] & 0xff);
}
}
}
public synchronized void imageComplete(int status) {
if(status == IMAGEERROR || status == IMAGEABORTED) {
return;
}
//
// With JDK 1.2, imageComplete() is called twice: BUG?
// With JDK 1.2, imageComplete() is callced only once.
//
if (isAlreadyCompleted)
System.out.println("imageComplete() is called again.");
else
isAlreadyCompleted = true;
MemoryImageSource mis = new MemoryImageSource(
width, height, defaultRGB,
intPixels, 0, width);
image = component.createImage(mis);
makeDissolvedImages(); // this takes some time, so ...
notifyAll(); // notify all threads waiting on us
}
private void makeDissolvedImages() {
MediaTracker mt = new MediaTracker(component);
DissolveFilter filter;
for(int i=0; i < images.length; ++i) {
filter = new DissolveFilter((255/(numImages-1))*i);
FilteredImageSource fis = new FilteredImageSource(
image.getSource(),
filter);
images[i] = component.createImage(fis);
mt.addImage(images[i], i);
}
mt.addImage(image, numImages);
try { mt.waitForAll(); }
catch(Exception e) { e.printStackTrace(); }
}
public void fadeOut() {
g = component.getGraphics();
if(g != null) {
try {
for(int i=numImages-1; i >= 0; --i) {
g.clearRect(x, y, width, height);
g.drawImage(images[i], x, y, component);
pause();
}
}
finally {
g.dispose();
}
}
}
public void fadeIn() {
g = component.getGraphics();
if(g != null) {
try {
for(int i=0; i < numImages; ++i) {
g.clearRect(x, y, width, height);
g.drawImage(images[i], x, y, component);
pause();
}
g.drawImage(image, x, y, component);
}
finally {
g.dispose();
}
}
}
private void pause() {
try { Thread.currentThread().sleep(pauseInterval); }
catch(InterruptedException e) { }
}
}
//
// File: DissolverFilter.java from "Graphic Java 1.2: Mastering the JFC, Vol.1"
//
import java.awt.image.*;
public class DissolveFilter extends RGBImageFilter {
private int alpha;
public DissolveFilter() {
this(0);
}
public DissolveFilter(int alpha) {
canFilterIndexColorModel = true;
if(alpha < 0 && alpha > 255)
throw new IllegalArgumentException("bad alpha");
this.alpha = alpha;
}
public int filterRGB(int x, int y, int rgb) {
DirectColorModel cm =
(DirectColorModel)ColorModel.getRGBdefault();
int alpha = cm.getAlpha(rgb);
int red = cm.getRed (rgb);
int green = cm.getGreen(rgb);
int blue = cm.getBlue (rgb);
alpha = alpha == 0 ? 0 : this.alpha;
return alpha << 24 | red << 16 | green << 8 | blue;
}
}
//
// File: Test.java from "Graphic Java 1.2: Mastering the JFC, Vol.1"
//
import java.net.URL;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class Test extends Frame implements Runnable {
Image tiger;
boolean showing = false;
Dissolver dissolver = null;
int x,y;
public Test() {
super("Image Dissolver");
MediaTracker mt = new MediaTracker(this);
URL url = getClass().getResource("tiger.gif");
try {
tiger = createImage((ImageProducer)url.getContent());
mt.addImage(tiger, 0);
mt.waitForID(0);
}
catch(Exception e) { e.printStackTrace(); }
}
public void addNotify() {
super.addNotify();
Insets i = getInsets();
dissolver = new Dissolver(this, x=i.left, y=i.top);
synchronized(dissolver) {
ImageProducer ip = tiger.getSource();
ip.startProduction(dissolver);
try {
dissolver.wait(); // wait for dissolved images ...
}
catch(Exception e) { // wait() was interrupted
e.printStackTrace();
}
}
try {
Thread thread = new Thread(this);
thread.start();
}
catch(Exception e) { // thread was interrupted
e.printStackTrace();
}
}
public void run() {
while(true) {
if(isShowing()) {
if(showing) dissolver.fadeOut();
else dissolver.fadeIn();
showing = showing ? false : true;
try {
Thread.currentThread().sleep(1000);
}
catch(Exception e) { e.printStackTrace(); }
}
}
}
public static void main(String args[]) {
final Test f = new Test();
f.setBounds(100,100,375,375);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
f.dispose();
System.exit(0);
}
});
}
}
(Review ID: 52794)
======================================================================