Very Informally Maintained by Jeff Harrington
Do a PixelGrab and re-create the image as a MemoryImage source-derived image. Here's some source posted recently to comp.lang.java.programmer:
// // This code is put in the public domain by Ogilvy & Mather Interactive. // O&MI makes no warranty as to its suitability for any application. // In no event shall O&MI be liable for damages arising out of the use of or // inability to use this code. Use at your own risk. // // Written by Andrew Frank, afrank@ogilvy.com // import java.awt.*; import java.awt.image.*; import java.applet.*; import java.net.URL; import java.net.MalformedURLException; public class bApplet extends Applet { // // get a buffered image (without dithering) // public Image getImage(URL url) { Image source = super.getImage(url); if (source == null) return(null); MediaTracker tracker = new MediaTracker(this); tracker.addImage(source, 0); // load the image try { tracker.waitForID(0); } catch (InterruptedException e) {} int width = source.getWidth(this); int height = source.getHeight(this); int pixels[] = new int[width*height]; PixelGrabber grabber = new PixelGrabber( source, 0, 0, width, height, pixels, 0, width ); try { grabber.grabPixels(); } catch (Exception e) {} mem = new MemoryImageSource(width, height, pixels, 0, width); return(createImage(mem)); } public Image getImage(URL url, String name) { try { return getImage(new URL(url, name)); } catch (MalformedURLException e) { return null; } } } ---- snip ---- Instructions: Step 1. Compile this and put the resulting class file somewhere in your CLASSPATH (preferably in the same directory as the applet you're building). Step 2. Modify the applet which you want to stop dithering by adding a line near the top that says "import bApplet;", and changing the declaration which says "public class myApplet extends Applet" to say ..."extends bApplet". Step 3. Recompile your applet. That's it! Why does it work? Not sure yet, but Sun is looking into it. My only request is that you not remove the comments from the top of the source code if you copy or distribute it. Please send feedback to afrank@ogilvy.com or afrank@panix.com. Andrew Frank Director of Technical Design Ogilvy & Mather Interactive 309 W 49 St NY NY USA 1-212-237-5071/1-212-237-4138 (fax) afrank@ogilvy.com http://www.ogilvy.com
Alexandre Rafalovitch (alex@access.com.au) wrote:
1) Broken static communication in the case that should work (falls
under David's rules)
2) Milky-White screen, when applets of size 0*0 or 1*1 are
present.
3) White lines around applets (this might be Win95/VideoCard combo
dependant, because I have problems with reproducing them)
Java Bugs:
Jeff: These are the bugs they claim they fixed in 3.01 - which, incidentally, were never listed in the known bug list of 3.0!
/** clnt.java */ import java.io.*; import java.net.*; public class clnt { public static final int DEFAULT_PORT=4000; public static void usage() { System.out.println ("Usage: java clnt[ ]"); System.exit(0); } public static void main (String [] args) { int port = DEFAULT_PORT; Socket s = null; if ((args.length != 1) && (args.length !=2)) usage(); if (args.length == 1) port = DEFAULT_PORT; else { try {port = Integer.parseInt(args[1]);} catch(NumberFormatException e) {usage();} } try { s = new Socket (args[0], port); DataInputStream in = new DataInputStream (s.getInputStream()); while (true) { String line = in.readLine(); System.out.println (line); } } catch (IOException e) { System.err.println (e); } finally { try { if (s!=null) s.close(); } catch (IOException e2){} } } }
/** @author Yew Kuan Choo Program: clnt.java */ import java.io.*; import java.net.*; public class clnt { public static final int DEFAULT_PORT=4000; public static void usage() { System.out.println ("Usage: java clnt[ ]"); System.exit(0); } public static void main (String [] args) { int port = DEFAULT_PORT; Socket s = null; if ((args.length != 1) && (args.length !=2)) usage(); if (args.length == 1) port = DEFAULT_PORT; else { try {port = Integer.parseInt(args[1]);} catch(NumberFormatException e) {usage();} } try { s = new Socket (args[0], port); DataInputStream in = new DataInputStream (s.getInputStream()); while (true) { String line = in.readLine(); System.out.println (line); } } catch (IOException e) { System.err.println (e); } finally { try { if (s!=null) s.close(); } catch (IOException e2){} } } } /** @author: Yew Kuan Choo Program: svr.java */ import java.io.*; import java.net.*; public class svr extends Thread { public final static int DEFAULT_PORT = 4000; protected int port; protected ServerSocket listen_socket; public static void fail(Exception e, String msg) { System.err.println (msg + ":" + e); System.exit(1); } public svr (int port) { if (port == 0) port = DEFAULT_PORT; this.port = port; try { listen_socket = new ServerSocket (port); } catch (IOException e) {fail (e, "Exception creating svr socket");} System.out.println ("Svr: listening on port " + port); this.start(); } public void run() { try { while (true) { Socket clnt = listen_socket.accept(); Connection c = new Connection (clnt); } } catch (IOException e) { fail (e, "Error While listening");} } public static void main (String [] args) { int port = 0; if (args.length == 1) { try {port = Integer.parseInt(args[0]);} catch (NumberFormatException e) {port = 0;} } new svr (port); } } class Connection extends Thread { protected Socket clnt; protected DataInputStream in; protected DataOutputStream out; public Connection (Socket clnt) { this.clnt = clnt; try { in = new DataInputStream (clnt.getInputStream()); out = new DataOutputStream (new BufferedOutputStream(clnt.getOutputStream())); } catch (IOException e) { try {clnt.close();} catch (IOException e2) { System.err.println ("Connection : " + e2); } return; } this.start(); } public void run() { try { for (int i=1; i <= 10; i++) { out.writeBytes ("Line " + i + "\n"); out.flush(); } } catch (IOException x) { System.err.println ("Error writting"); } try { Thread.sleep (3000);} catch (InterruptedException ie) {} PrintStream prn = new PrintStream (out, true); for (int i=100; i < 120; i++) { prn.println ("Line : " + i); if (prn.checkError()) { System.err.println ("Error writting to socket"); break; } } try { for (int i=200; i <= 210; i++) { out.writeBytes ("Line " + i + "\n"); out.flush(); } } catch (IOException x) { x.printStackTrace(); } catch (IOException t) { t.printStackTrace(); } try { clnt.close(); } catch (IOException e2) {} } }
IndexColorModel doesn't work properly
The colors returned by the IndexColorModel routines in the Mac version of Netscape 3.0 are in the range -127 to 128 instead of 0 to 255. The following applet demonstrates this behavior and shows a work-around. A related bug associated with handling the transparency appears on the Unix version of Netscape 3.0 as well. Although not demonstrated in this applet, this same work-around applies.
/* * This small applet demonstrates a bug in the handling of * IndexColorModel's in Netscape 3.0. Two color bars, varying from * red to blue, with increasing opacity, going left to right. When * the bug is present, the left bar is nearly all black. If not, the two * bars will be identical. * * Author: Daren Stotler, dstotler@pppl.gov */ import java.awt.*; import java.awt.image.*; import java.util.*; import java.applet.Applet; public class TestNSCM extends Applet { private int barHeight, barWidth; private Image imgICM, imgDCM; public void init() { /* * Set up "hotMetal" IndexColorModel with increasing opacity. */ int numColors = 40; byte alpha[] = new byte[256]; byte red[] = new byte[256]; byte green[] = new byte[256]; byte blue[] = new byte[256]; for (int i=0; i < numColors; i++) { alpha[i] = (byte) ((255*i) / (numColors-1)); red[i] = (byte) ((255*i) / (numColors-1)); blue[i] = (byte) ((255*(numColors-1-i)) / (numColors-1)); green[i] = (byte) 0; } IndexColorModel icm = new IndexColorModel(8,numColors,red,green,blue,alpha); /* * Generate the two bar images. */ barHeight = 50; barWidth = 150; int bar_icm[] = new int[barWidth * barHeight]; int bar_dcm[] = new int[barWidth * barHeight]; int index = 0; int value = 0; for (int y=0; y
Daren Stotler, Princeton, New Jersey, USA
The rules for IAC as formulated by David Hopwood a while ago were wrong. The real rules are different when the documents are in different directories and are like this. Thanks to David Hopwood for reformulating the rules to be more correct. Applets A and B use the same ClassLoader if (A and B have the same CODEBASE) && ((A and B have the same ARCHIVE tag) || (neither A nor B have an ARCHIVE tag, and they have the same document base)) && ((neither A nor B have a MAYSCRIPT tag) || (both A and B have a MAYSCRIPT tag, and they are in the same frame).
Image imageOriginal = createImage( width, height ); // DO SOME DRAWING ONTO imageOriginal HERE Image imageCopy = createImage( imageOriginal.getSource() );
I have a tiny 20-line applet which demonstrates this, with source code, at http://www.electrum.co.uk/gary/bugger. Please drop by and take a look if you think this might affect you, or better still if you think you might know of a workaround.
Gary McGill//****************************************************************************** // KeyPress.java: Applet // //****************************************************************************** import java.applet.*; import java.awt.*; import java.util.*; //============================================================================== // Main Class for applet KeyPress // //============================================================================== public class KeyPress extends Applet { String[] text; Hashtable lookup; static final int numTexts = 14; // KeyPress Class Constructor //-------------------------------------------------------------------------- public KeyPress() { // TODO: Add constructor code here int index; text = new String[numTexts]; for (index = 0 ; index < numTexts ; ++index) text[index] = null; lookup = new Hashtable(); lookup.put(new Integer(Event.KEY_ACTION), "KEY_ACTION"); lookup.put(new Integer(Event.KEY_ACTION_RELEASE), "KEY_ACTION_RELEASE"); lookup.put(new Integer(Event.KEY_PRESS), "KEY_PRESS"); lookup.put(new Integer(Event.KEY_RELEASE), "KEY_RELEASE"); lookup.put(new Integer(Event.MOUSE_DOWN), "MOUSE_DOWN"); lookup.put(new Integer(Event.MOUSE_DRAG), "MOUSE_DRAG"); lookup.put(new Integer(Event.MOUSE_ENTER), "MOUSE_ENTER"); lookup.put(new Integer(Event.MOUSE_EXIT), "MOUSE_EXIT"); lookup.put(new Integer(Event.MOUSE_MOVE), "MOUSE_MOVE"); lookup.put(new Integer(Event.MOUSE_UP), "MOUSE_UP"); } // APPLET INFO SUPPORT: // The getAppletInfo() method returns a string describing the applet's // author, copyright date, or miscellaneous information. //-------------------------------------------------------------------------- public String getAppletInfo() { return "Name: KeyPress\r\n" + "Author: Larry Widing\r\n" + "Created with Microsoft Visual J++ Version 1.1"; } // The init() method is called by the AWT when an applet is first loaded or // reloaded. Override this method to perform whatever initialization your // applet needs, such as initializing data structures, loading images or // fonts, creating frame windows, setting the layout manager, or adding UI // components. //-------------------------------------------------------------------------- public void init() { // If you use a ResourceWizard-generated "control creator" class to // arrange controls in your applet, you may want to call its // CreateControls() method from within this method. Remove the following // call to resize() before adding the call to CreateControls(); // CreateControls() does its own resizing. //---------------------------------------------------------------------- resize(320, 240); // TODO: Place additional initialization code here } // Place additional applet clean up code here. destroy() is called when // when you applet is terminating and being unloaded. //------------------------------------------------------------------------- public void destroy() { // TODO: Place applet cleanup code here text = null; } // KeyPress Paint Handler //-------------------------------------------------------------------------- public void paint(Graphics g) { int index; for (index = 0 ; index < numTexts ; ++index) { if (text[index] != null) g.drawString(text[index], 10, 15 + (index * 15)); } } // The start() method is called when the page containing the applet // first appears on the screen. The AppletWizard's initial implementation // of this method starts execution of the applet's thread. //-------------------------------------------------------------------------- public void start() { requestFocus(); } // The stop() method is called when the page containing the applet is // no longer on the screen. The AppletWizard's initial implementation of // this method stops execution of the applet's thread. //-------------------------------------------------------------------------- public void stop() { } public boolean handleEvent(Event evt) { String msg = null; switch (evt.id) { case Event.KEY_ACTION: case Event.KEY_ACTION_RELEASE: case Event.KEY_PRESS: case Event.KEY_RELEASE: msg = "Event: " + evt.id + ", " + evt.modifiers + ", " + evt.key + " (" + (String)lookup.get(new Integer(evt.id)) + ")"; addText(msg); repaint(); System.out.println(text); break; case Event.MOUSE_DOWN: case Event.MOUSE_DRAG: case Event.MOUSE_ENTER: case Event.MOUSE_EXIT: case Event.MOUSE_MOVE: case Event.MOUSE_UP: msg = "Event: " + evt.id + ", " + evt.modifiers + ", " + evt.clickCount + " (" + (String)lookup.get(new Integer(evt.id)) + ")"; addText(msg); repaint(); System.out.println(text); break; } return super.handleEvent(evt); } void addText(String msg) { int index; for (index = 0 ; index < numTexts ; ++index) { if (text[index] == null) { text[index] = msg; return ; } } for (index = 0 ; index < numTexts - 1 ; ++index) { text[index] = text[index+1]; } text[numTexts - 1] = msg; } }
I have problem with loading Images in Netscape 3.0. Gold. A small Images are loaded correctly. Bigger are loaded correctly only in Intranet. Large Images may occurs error while loading also in Intranet(sometimes). In MSIE 3.0. or 4.0. all Images are loaded correctly(in Internet or Intranet). I try to load Image in two ways: ///With help of a class MediaTracker: int pocet=0; boolean abbruch; do { pocet++; abbruch=false; image = getImage (getCodeBase(), string); mt.addImage (image, 0); try { mt.waitForId(0); } catch (InterruptedException e) { abbruch=true; image.flush(); showStatus("Error - interrupted "+String.valueOf(pocet)); } if (mt.isErrorID(0)) // here is detected an error { abbruch=true; image.flush(); showStatus("Chyba - pri loadovani obrazku cislo"+String.valueOf(pocet)); } } while (pocet < 4 && abbruch); ///The error was detected in function mt.isErrorID(0). ///Applet try to load image in 3 loops but without succes. ///The image has 27 kB size. After loading cca 20 - 30 kB during ///my modem this the MadiaTracker stopped loading. ///With help of function prepareImage: boolean kenner=this.getToolkit().prepareImage(image,-1,-1, this); int pocet=0; do { pocet++; test=this.getToolkit().checkImage(image, -1, -1, this); try{Thread.sleep(500);} catch(InterruptedException ie) {;} showStatus("test= "+String.valueOf(test)+" testujem kazdych "+String.valueOf(pocet/2)+" sekund"); if (0!= (test & ERROR) ) break; // here is detected an error } while (0== (test & ALLBITS) && pocet < 2000); ///The situation is the same as in upper example. ///After loading 20- 30 kB checkImage return ImageObserver.ALLBITS ///and thread for loading is stopped.
Recent sightings: WIN95 - Net4/IE4 - (Java 1.1.x) - copyArea method fails to 'copy' in all 4 possible directions. Only 2 are supported. The deltaX and deltaY directions _MUST_ be negative. Positive values will effectively 'tile' the 'copiedArea' along that axis. Using: g.drawImage(TENbyTEN,0,0,null); // draw image in upper left g.copyArea(0,0,200,200,10,0); // tile the image accross the top g.copyArea(0,0,200,200,0,10); // tile the top row of images down It's a >>Great<< way to tile a background screen with the image of your choice. Is it a bug or a feature? User beware! ONLY currently works under Net4/IE4 on WINDOWS95! MAC - (OS?) - Net? - Reports that the following code will produce an error when trying to use the parseInt method to parse a negative valued string. Try this: string test = "-123"; int testnum = Integer.parseInt(test); This appears to be only MAC related at this point in time. PC users are safe for now. *** END Special Report ***sab@cruzio.com, SAB's GAME ARCADE
/** * This applet shows how buggly browsers dies * Just press button one or two times * * @author Vladislav Protasov. mailto:vladp@novavox.ru * @version 1.0, 12 Feb 1999 */ import java.applet.Applet; import java.awt.*; public class NetscapeKiller extends Applet { Button killer=new Button("Kill Netscape!"); public void init() { add(killer); } public boolean action(Event evt, Object what) { postEvent( new Event( killer, Event.ACTION_EVENT, null ) ); return true; } }