home *** CD-ROM | disk | FTP | other *** search
- Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.kodak.com!news-nysernet-16.sprintlink.net!news-east1.sprintlink.net!news-peer1.sprintlink.net!news.sprintlink.net!newsfeed.berkeley.edu!news2.best.com!news3.best.com!nntp1.ba.best.com!not-for-mail
- From: pvdl@best.com (Peter van der Linden)
- Newsgroups: comp.lang.java.programmer,comp.lang.java.help,comp.lang.java.gui,comp.answers,news.answers
- Subject: Java Programmers FAQ
- Supersedes: <7ha5k9$3ng$1@shell15.ba.best.com>
- Followup-To: poster
- Date: 21 May 1999 13:50:56 -0700
- Approved: news-answers-request@MIT.EDU
- Message-ID: <7i4gvg$1aq$1@shell15.ba.best.com>
- Summary: This posting answers frequently-asked questions by Java programmers
- Lines: 9607
- NNTP-Posting-Host: shell15.ba.best.com
- X-Trace: nntp1.ba.best.com 927319862 226 pvdl@206.184.139.147
- Xref: senator-bedfellow.mit.edu comp.lang.java.programmer:210403 comp.lang.java.help:54566 comp.lang.java.gui:33281 comp.answers:36236 news.answers:158373
-
- Archive-name: computer-lang/java/programmers/faq
- Posting-Frequency: weekly
- Last-modified: 1999/05/19
- URL: http://www.afu.com/javafaq.html
-
- Frequently Asked Questions (with answers) for Java programmers
-
- _____________________________________________________
- ________| |________
- \ | Java Programmers FAQ http://www.afu.com | /
- \ | Last modified May 19, 1999 Peter van der Linden | /
- / |_____________________________________________________| \
- /___________) (__________\
-
- The Java FAQs here are intended for people who already have some programming
- experience, though maybe not in Java.
-
- Go to the FAQ home page at http://www.afu.com for other Java information and
- downloads, and the most up-to-date copy of the FAQ. Report FAQ updates to
- faqidea at the address afu.com.
-
- ------------------------------------------------------------------------
-
- The sections of the Java FAQ are:
-
- * 1. Java Book Information
- * 2. Getting Started
- * 2.5 Portability
- * 3. General Information
- * 4. Compilers and Tools
- * 5. Compiler Messages
- * 6. Java Language issues
- * 7. I/O
- * 8. Core library issues
- * 9. Computer Dating
- * 10. AWT
- * 11. Swing
- * 12. Browsers
- * 13. Applets
- * 14. Multi-Media
- * 15. Networking
- * 16. Security
- * 17. For C, C++ Afficionados
- * 18. Java Idioms
- * 19. Java Gotcha's
- * 20. Further Resources
- * 21. Acknowledgements
-
- -------------------------------
-
- 1. Java Book Information
-
- 1. (sect. 1) How do I choose a Java book?
-
- [*] There is no one right answer to "which is the right Java book for
- me?"
- A lot depends on what you already know, and how you like to
- learn.
- If you already know how to program in another language, and Just want
- to learn Java, consider Just Java 1.2 from the FAQ author.
-
- Everything in one handy volume (language basics, Swing, networking,
- I/O, database access, etc) and it comes with a CD with tons of Java
- applets, games, applications, compiler tools, complete with source.
- Includes a Java compiler for Windows, the Mac, Linux, and Solaris
- (sparc and x86). look at http://www.amazon.com for details
-
- If you or your manager instead want a briefing on Java
- technology, thin clients, XML, CORBA, TCP/IP, Java beans,
- etc., take a look at Not Just Java from the FAQ author.
- [Image]
- This book doesn't teach you how to program in Java; it tells
- you why you might want to, and what kind of systems are most
- suited to Java. It describes E-Commerce and XML. look at
- http://www.amazon.com for details
-
- Here are the points to check when evaluating a programming book.
- o Above all, make sure that it is a Java book. If it comes with a
- CD, check that it has a Java compiler on it, not a J++ compiler.
- VJ++ does not implement Java 2. VJ++ is also a different language
- in some important ways, and is missing the latest Java libraries
- (Swing, Collections, JFC, RMI). If your interest is Java, leave
- the downrev VJ++ book back on the shelf.
- o Does the book cover the current level of Java, which is Java 1.2
- (aka Java 2)? Look up "JApplet" in the index. If it's not there
- the book doesn't cover JDK 1.2, and you probably need a more
- up-to-date book.
- o Check that the book has a reasonable number of figures, diagrams,
- and illustrations. It is not possible to explain how to program a
- window system without pictures and diagrams. Other topics benefit
- from pictures, too.
- o Check what the book says about itself. Is it a reference work,
- intended for Java-experts to look things up in? This is the role
- of "Java in a Nutshell", and "The Java Almanac". Do you need that,
- or are you looking for a book that teaches by examples and
- explanations?
- o Read Peter Norvig's excellent advice on learning programming
- languages and being a programmer.
- o Appraise your own level of programming knowledge: are you
- proficient in some other language, or are you learning programming
- as well? Does the book cater to your level?
- o Read a section of the book. Does the style keep you interested, as
- it educates you? Will you get bored if you read many pages? Is the
- book too long for your initial purpose? Browse Amazon online and
- see what other readers say about the text.
- o If the book comes with a CD, how much other software is on the CD?
- You want at least a Java compiler plus all the examples from the
- book. Does the Java compiler work on your platform (Mac, Linux,
- etc)? Additional software on the CD is a big plus, as we learn the
- most from reading other people's code.
-
- Most people buy one book to begin with, then four or five more as they
- wish to learn more, and about more specialized topics. The FAQ author
- has purchased and read probably 60 Java books in the last three years.
-
- 2. (sect. 1) Where can I find a some lists of Java books and book reviews?
-
- [*] Here are some good ones:
- http://www.hszk.bme.hu/~werner/Java2BookReviewBETA.html
- and
- http://www.geocities.com/RainForest/Canopy/4774/Java/education.html
- also
- http://www.flathill.com/languages/java/
- also
- http://www.fastgraph.com/books/java.html
- also
- http://teamjava.com/links/tj-srv.cgi?MUF=0,tj-booklist.muf
- also
- http://www.javaworld.com/javaworld/books/jw-books-index.html
- (an exhaustive list -- takes a long time to load).
-
- -------------------------------
-
- 2. Getting Started
-
- 1. (Sect. 2) What is the easiest way to get started with Java?
-
- [*] Follow these steps.
- 1. Look at the books section of the FAQ to see what kind of book will
- suit you. There is no one perfect Java book. The right book
- depends on the style, pace, and detail that you are comfortable
- with. Amazon has good info and reviews on Java books.
-
- 2. Download a free Java compiler from http://java.sun.com Service
- packs for Solaris (if any are needed) can be found at:
- http://www.sun.com/solaris/jdk/download.1.2.1_02/en/sparc/1.2.1_02_sparc_jdk_patches.tar
-
- 3. Read the free Java tutorial, at
- http://java.sun.com/docs/books/tutorial/index.html
- (bookmark it, so you will easily find it again).
-
- 4. Avoid Microsoft's J++ product, which is in the words of
- Microsoft's own employees "polluted Java". It is designed to
- undermine standard Java, and has many deliberate platform-specific
- incompatibilities, including new keywords in the language.
-
- 5. To get some tips on getting started with a programming homework
- assignment, look at http://www.concentric.net/~pats/beginner.html.
-
- 6. Search this FAQ when something in Java confuses you. Many people
- have trodden this path before you, and the FAQ contains the
- accumulated knowledge and pointers to other references.
-
- 2. (Sect. 2) Why doesn't my "Hello World!" program compile?
-
- [*] There are three basic possibilities:
- 1. Are you successfully running the javac compiler?
- Try
-
- javac -garbage
-
- to see if it prints out a message about correct usage. If not,
- invoke javac using the full pathname, or set your PATH variable to
- include the directory that contains javac.
- 2. Is the CLASSPATH environment variable used correctly?
- In JDK 1.0.2, beginners had to set CLASSPATH, and it had to
- include both system libraries and your programs.
- In JDK 1.2, CLASSPATH is no longer needed for system libraries.
- You do want CLASSPATH to point to the directories containing any
- "user classes" you're using.
- Getting started, you will probably want at a minimum "." (the
- current directory) in your CLASSPATH.
- When CLASSPATH is wrong, javac will tell you it can't find
- definitions for classes you reference in the source file. For
- information on setting up the CLASSPATH, see Question 1.3
- 3. Is the source correct?
- Here javac will emit error and warning messages. See the questions
- on compiler messages in the next section.
-
- 3. (Sect. 2) Why doesn't my "Hello World!" program run?
-
- [*] There are five common mistakes that cause your VM (java or browser)
- to be unable to execute your classes
- 1. First, did you write an applet or an application? If an applet,
- you must make sure that you did extend the java.applet.Applet
- class. Your starting code should be in the init routine.
- If you wrote an application, your starting code should be in a
- routine called main(). Don't mix applets with applications until
- you have a bit more experience.
- 2. You must declare your main class as "public". If you don't,
- unfortunately some systems will still run the code, while others
- won't. The main class is either the one with the main() method in,
- or in the case of an Applet, the class that extends Applet.
- 3. Your class name and the file name must match exactly, even letter
- case. If your class is HelloWorld, your source file must be
- HelloWorld.java and your class file will be "HelloWorld.class".
- 4. If an Applet, and you used ftp to transfer the classes to the
- server, you must ftp all the classes, and you must use BINARY
- transfer not ASCII.
- 5. Errors in setting the CLASSPATH (and/or codebase in an applet).
- Even seasoned programmers do this, pointing inside a package or
- mistyping a path delimiter. For information on setting up the
- CLASSPATH and codebase, see Question 1.3
-
- If you are running an applet, you should check the following further
- points:
- 1. If your class isn't loading, recheck the HTML applet tag.
- 2. If you are writing to System.out, the results are displayed in the
- browser's java console. You'll have to create a window if you want
- one.
- 3. Make sure your browser is compatible with the Java language
- features you are using. Internet Explorer and older versions of
- Netscape's browsers have omitted some support for JDK 1.1. Try
- your applet in the JDK's appletviewer first.
-
- 4. How do I set the CLASSPATH?
-
- [*] The CLASSPATH environment variable tells the VM's class loader
- where to find classes that are directly or indirectly invoked,
- including system classes. The CLASSPATH variable should
- o point to the directory containing the class file, for classes not
- in a package.
- o point to the package root, for classes in a package. The root is
- the parent directory of the highest directory of the package name.
- o point directly to the zip or jar file, if the classes are in an
- archive file. You may have to list the contents of the archive to
- get the correct package/path name for the class.
- Separate multiple paths and archives with a platform-specific
- separator, ";" for Windows; ":" for Solaris
- Also remember that
- o Browsers set the CLASSPATH to the directory of the HTML file, plus
- the codebase parameter.
- o in JDK 1.1 and after, java adds the system classes
- (lib/classes.zip), so you don't have to.
- o JDK 1.2 versions of java add "." (current directory), so you don't
- have to. (But jre doesn't - see below.)
- o JDK 1.1 jre tool does not use the CLASSPATH variable or assume the
- current directory. (On Solaris, CLASSPATH does work.)
-
- From JDK 1.1.2 on, it is generally an error if the user sets the
- CLASSPATH to include classes.zip. But CLASSPATH will need to be set to
- o point to the roots of the programmer's own packages, and third
- party packages
- o use rmic
- o use unbundled packages like Swing in JDK 1.1
- o point to native code libraries.
-
- For the sake of consistency, the minimal classpath setting should be: "
- set CLASSPATH=. "
- Below you'll find examples for Windows (basic application class),
- Solaris (package class), javac (multiple packages), and browsers
- (applet codebase).
- -----------------------------
-
- Here's some Windows examples, assuming the application class is
-
- D:\src\tries\HelloWorld.class
-
- ## JDK 1.1, no CLASSPATH set
- > cd D:\src\tries\
- > D:\jdk11\bin\java HelloWorld
- # OK: 1.1 implicitly adds classes.zip and current dir
-
- > D:\jdk11\bin\jre HelloWorld
- # FAILS: jre does not automatically add . to CLASSPATH
-
- > cd D:\
- > D:\jdk11\bin\jre -cp D:\src\tries HelloWorld
- # OK: jre adds classes.zip, -cp adds class directory
-
- ## JDK 1.1, CLASSPATH set
- > set CLASSPATH=D:\src\tries
- > D:\jdk11\bin\java HelloWorld
- # OK: java using CLASSPATH
-
- > D:\jdk11\bin\jre HelloWorld
- # FAILS: jre does not use CLASSPATH (on Windows)
-
- ## JDK 1.0.2, CLASSPATH set
- > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
- > D:\jdk102\bin\java HelloWorld
- # OK:
-
- > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
- > D:\jdk11\bin\java HelloWorld
- # FAILS: exception in thread NULL - wrong system classes
-
-
- -----------------------------
-
- Here's some Solaris examples, assuming the application class is
-
- /usr/src/com/devjoes/killer/App.class
-
- and it is in package com.devjoes.killer:
-
- # JDK 1.1, no CLASSPATH set
- $ /usr/bin/jdk11/bin/jre -cp /usr/src com.devjoes.killer.App
- # OK:
-
- $ cd /usr/src/com/devjoes/killer/
- $ /usr/bin/jdk11/bin/java App
- # fails: class name and path are wrong
-
- $ CLASSPATH=/usr/src/
- $ /usr/bin/jdk11/bin/java App
- # fails: class name is com.devjoes.killer.App
-
- $ /usr/bin/jdk11/bin/java com.devjoes.killer.App
- # OK:
-
-
- -----------------------------
-
- Here's some javac examples, for both Solaris and Windows, based on the
- following:
- Source files package Makes the call
- /usr/src/pack/Minimal.java package pack pack.sub.Try.run()
- /usr/src/pack/sub/Try.java package pack.sub (nothing)
-
- $ CLASSPATH=""
- $ /usr/bin/jdk11/bin/javac /usr/src/pack/sub/Try.java
- # OK: works fine
-
- $ /usr/bin/jdk11/bin/javac /usr/src/pack/Minimal.java
- # FAILS: can't find pack.sub.Try
-
- $ cd /usr/src
- $ /usr/bin/jdk10/bin/javac pack/Minimal.java
- # OK: finds pack.sub.Try based on . as package root
-
- $ cd /usr/src/pack
- $ CLASSPATH=/usr/src
- $ /usr/bin/jdk11/bin/javac Minimal.java
- # OK: finds pack.sub.Try based on CLASSPATH
-
-
- Now assume the killer application class
-
- /usr/src/com/devjoes/killer/FastApp.java
-
- (in package com.devjoes.killer) uses a third-party package in a jar
- file
-
- /usr/jars/JShapes.jar
-
- but makes no other reference to other classes. The following works
- fine:
-
- $ CLASSPATH=/usr/jars/JShapes.jar
- $ cd /usr/src/com/devjoes
- $ /usr/bin/jdk11/bin/javac killer/FastApp.java
-
-
- Finally, some applet examples. Many applets only use one class, in the
- same directory as the html file:
-
- <applet code=ArcTest.class height=400 width=400>
-
-
- To use classes in subdirectory, use the codebase parameter:
-
- <applet codebase="mysubdir/" code=ArcTest.class ..
-
-
- To use classes in an archive, use the archive parameter:
-
- <applet archive="applets.jar" code=ArcTest.class ..
-
-
- See also: JDK 1.1 ReadMe
- Solaris JDK 1.1 tool documentation
- Win32 JDK 1.1 tool documentation
-
- 5. (Sect. 2) How do I do keyboard (interactive) I/O in Java?
-
- [*] Interactive I/O in Java is very poorly supported. Programmers must
- piece together several library classes in non-obvious ways to get the
- required functionality. See the answer to Question 7.1.
-
- 6. (Sect. 2) How do I do file I/O in an applet?
-
- [*] By default, an applet can read files on the server, but not write
- them, and has no access to the client. This is for reasons of security.
- It would be very unsafe to let any old applet that you downloaded from
- an unknown origin on the Internet read/write your files. It would be as
- unwise as allowing this kind of access to an ActiveX control (which is
- one reason ActiveX is dead on the Internet).
-
- There are several different ways to relax the default rules. See the
- answer to Question 7.8.
-
- 7. (Sect. 2) How do I do I/O to the serial port on my computer?
-
- [*] Java 1.0 and 1.1 do not have a serial port API. There are several
- commercially-available libraries that supply the needed functionality.
- JDK 1.2 introduces access to the serial and parallel ports as an
- extension (optional extra) library. See also the answer to Question
- 6.3.
-
- 8. (Sect. 2) How do I do formatted I/O like printf and scanf in C/C++?
-
- [*] The java.text package introduced with Java 1.1 supports formatted
- I/O. See also the answer to questions 7.11, 7.12, and 17.7.
-
- 9. (Sect. 2) I have spent more debugging time finding case (upper vs
- lower) typos than everything else put together and squared!
-
- [*] Do not forget that your remark must be phrased in the form of a
- question to win on FAQ Jeopardy. In any event, it is worth reminding
- those new to Java that letter case really matters in Java, and that the
- names of public classes should exactly match (including case) the names
- of the files they live in. See also the answer to Question 1.1.2
-
- 10. (Sect. 2) Why do I get this compiler error: "Can't make static
- reference to method..."?
-
- [*] Your code probably looks something like this:
-
- class myclass {
- public static void main(String args[]) {
- myMethod();
- }
-
- public void myMethod() {
- //some code
- }
- }
-
-
- The issue is this: a static method means it belongs to the class, not
- each individual object. If you leave the static keyword off (the usual
- case) as is done here with the method "myMethod()", it means that
- method can only be invoked on an object. But your call from main() has
- not told myMethod() which object it is to be invoked on. Inside a
- non-static method, you don't have to provide this information, as it
- assumes you mean the same object on which it was invoked. But when
- calling from a static method, you must provide the information, and you
- haven't - hence the error message.
-
- A common fix is to instantiate a member of the class, on which to
- invoke myMethod(), like this:
-
- public static void main(String args[]) {
- myclass m = new myclass();
- m.myMethod();
- }
-
-
- This problem is especially common when you are writing code that you
- want to run as an applet and as an application. Naturally, you call
- init() and start() from main. What you really need to do is:
-
- public static void main(String[] args) {
- Applet ma = new myApplet();
- ma.init();
- ma.start();
- }
-
-
- 11. (Sect. 2) Why can't I do myArray.length() ? Arrays are just objects,
- right?
-
- [*] Yes, the Java specification says that arrays are object references
- [JLS 10.2] just like classes are. However, arrays cannot contain
- methods. Instead you have to use myArray.length, which is a data item
- (not a method) called "length", belonging to myArray.
-
- 12. (Sect. 2) How do I close a Java window by using the icon in the upper
- right hand corner of a window?
-
- [*] Create an event handler class to extend WindowAdapter. Then
- override WindowAdapter's windowClosing() to do the actions you want
- when a window's "close" action is clicked. Then add that to the
- listeners for that window.
-
- import java.awt.*;
- import java.awt.event.*;
-
- public class MyFrame extends Frame {
- public MyFrame(String s) {super(s);}
-
- public class WL extends WindowAdapter {
- public void windowClosing(WindowEvent e) {System.exit(0);}
- }
-
- // do your other Frame stuff
-
- }
-
-
- Somewhere in your initialization code, put:
-
- f1.addWindowListener( f1. new WL() );
-
-
- This last syntax is not commonly known to many people yet, it's another
- wacky artifact of inner classes.
-
- Alternatively, combining the inner class and setting the handler in one
- go, you could do this:
-
- MyFrame f1 = new f("wave");
-
- f1.addWindowListener( new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- // and/or setVisible(false) and/or dispose()
- System.exit(0); }
- });
-
-
- See also the answer to questions 1.0.19, 1.0.30 and 15.7.
-
- 13. (Sect. 2) Why is b+=100; OK, but b = b+100; fails to compile?
-
- [*] You have code like this
-
- byte b = 0;
- Incompatible type for =. Explicit cast needed to convert int to byte.
- b = b + 100; // compiler error message
- ^
- b += 100; // works OK
-
- The reason is "promotion". Arithmetic expressions are promoted to the
- type of the longest, floatiest operand in them, or at least to int. The
- first statement involves the assignment of an expression. The
- expression is promoted to 32 bits, and must be cast back down to 8
- bits, like this "b = (byte) (b+100);". The second is an operator
- assignment, and the cast back to byte takes place automatically. The
- Java Specification says:
- "A compound assignment expression of the form E1 op= E2 is
- equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is
- the type of E1, except that E1 is evaluated only once" [JLS
- 15.25.2]
-
- The compile-time narrowing of constants means that code such as:
-
- byte theAnswer = 42;
-
- is allowed, with no cast necessary. [JLS 5.2]
-
- 14. (Sect. 2) How do I add two Float objects together?
-
- [*] You want to write code like this
-
- Float One;
- Float Two;
- Float Hard = One + Two;
-
-
- but the compiler does not allow it.
-
- Java has two separate ways of representing a 32 bit floating point
- number, Float and float. Float is a class, that whose sole purpose is
- to "wrap" a floating point number so it can be treated as an object.
- The class does not support floating point arithmetic, because the
- performance would be too slow. float is a primitive type (like int)
- that is used for floating point arithmetic.
-
- You choose one or the other depending on your predominant use. If all
- you need of your floating point numbers is arithmetic, declare them to
- be "float". If you need to use them as objects, for example to place
- them in a Vector, declare them as "Float".
-
- If you need both, tough. You have to declare them one way and convert
- whenever you need the capabilities of the other. Your specific code can
- be written as:
-
- Float One = new Float(1.0);
- Float Two = new Float(2.0);
- Float Hard = new Float(One.floatValue() + Two.floatValue());
-
-
- See also questions 6.n , 5.1, and 10.1.
-
- 15. (Sect. 2) How can I put all my classes and resources into one file and
- have java run it?
-
- [*] Use a JAR file. Put all the files in a JAR, then run the app like
- this:
-
- java -jar [-options] jarfile Mainclass [args...]
-
-
- 16. (Sect. 2) How can I see line numbers in a stack trace using JDK 1.1.6?
-
- [*] From JDK 1.1.5 on (i.e. JDK 1.1.6, JDK 1.2) the stack trace of an
- uncaught exception no longer has source code line numbers. It only says
- "(Compiled Code)".
-
- To see the line numbers where your program throws an exception, use the
- command line argument in JDK 1.2:
-
- java -Djava.compiler=NONE myapp
-
- This info is well-concealed in the release note at:
- http://java.sun.com/products/jdk/1.2/changes.html#aaa24
-
- -----------------------------
-
- Specify standard Java on your new PC!
-
- Your new PC can come with the most up-to-date standard version
- of Java, but only if you ask for it! The JavaLobby is asking PC
- vendors to support Java, and to ship new machines with the Java Plug-In
- pre-installed.
-
- See http://www.javalobby.org/servlet/PetitionServlet/pjpc
- Please help the Java Lobby to promote this initiative.
-
- -----------------------------------------------------------------------
-
- Please support Java Portability.
-
- The biggest value of Java is its portability.
- o Portability makes it easier for companies to change/upgrade
- operating systems and platforms, without losing their investment
- in applications software.
- o Portability makes it easier for Java programmers to transfer their
- skills to new employers.
- o Portability makes a wider variety of software available on all
- computers.
- Software portability is very much in the interest of most software
- developers and customers. Even if you only use Windows 95, portability
- matters to you. If your software was all written in Java, it would all
- just run when you moved from MS-DOS to Windows 3.1 to Windows 95 to
- Windows 98 to Windows NT, and even on Windows CE. Instead, you
- typically need to buy new applications software all over again when
- Windows changes. Portability is not in Microsoft's interest, as it
- removes a revenue stream and makes it easy for users to try other
- operating systems.
-
- The 1998 anti-monopoly case against Microsoft revealed a Microsoft
- internal memo. The memo revealed that Microsoft's "strategic objective"
- was to "kill cross-platform Java." by "grow[ing] the polluted Java
- market." This is Exhibit 101 (MS7 033448) in the case.
-
- In November 1998, a Federal judge ruled that Microsoft was probably
- breaking its written agreement with Sun by distributing incompatible
- Java, and that Microsoft had to stop doing that. If portability matters
- to you or your users, avoid Java products from Microsoft; it is
- deliberately trying to sabotage it. Microsoft's own internal documents
- make this goal unambiguous. See
- http://www.usdoj.gov/atr/cases/f1700/1762.htm.
-
- See also "The Microsoft Java Dilemma" paper at
- http://www.geocities.com/ResearchTriangle/Node/2005/msjava.htm
- -----------------------------
-
- Windows-Specific
-
- 17. Is there a Java implementation for Windows 3.1?
-
- [*] Yes. See Question 1.6 It's not that great though because Windows
- 3.1 has inadequate features to support great software.
-
- 18. (Sect. 2) I'm using Win95, and my DOS window won't accept filenames
- longer than 8.3.
- "This program cannot be run in DOS mode"
-
- [*] Both these problems are resolved by the same process. Assuming
- you're running the Win95/98 command.com, then you've changed the MS-DOS
- Prompt options under the "Properties" menu item. In the Properties
- dialog, Program->Advanced gets you a dialog. Here, make sure the
- "Prevent MS-DOS-based programs from detecting Windows" checkbox is
- UNCHECKED.
-
- If the option is checked you get exactly the kind of behavior you're
- seeing. The option is unchecked by default, so it must have been
- selected at some time in the past. Change it back to unchecked.
-
- 19. (Sect. 2) I'm using Notepad to edit my files, and how can I save them
- with the extension ".java"? Also, in notepad some source files have all
- the characters on one line. Why is that?
-
- [*] First answer: put the entire filename in quotes in the save dialog.
- Once you have created your first Java file, double click on it in
- Explorer, select "Notepad" from the "Open with" box, and Notepad will
- stop adding the spurious ".txt" to your .java files.
-
- Second answer: Notepad expects to see a "carriage return/line feed"
- pair at the end of each line, rather than just the "newline"
- (line-feed) commonly used on Unix. Use this program to expand all
- newlines,
-
- /*
- * Usage: jre crlf file1.java file2.java ... fileN.java
- */
-
- import java.io.*;
- class crlf {
- public static void main(String s[]){
- byte b[]; byte p;
- FileInputStream is;
- BufferedOutputStream os;
- File f;
- for (int i=0; i < s.length;i++){
- try{
- f=new File(s[i]);
- b=new byte[(int)f.length()];
- is = new FileInputStream(f);
- is.read(b); is.close();
- os = new BufferedOutputStream(
- new FileOutputStream(s[i]),b.length);
- p='?';
- for(int j=0; j < b.length; j++){
- if((p!='\r')&&(b[j]=='\n')) os.write('\r');
- p=b[j]; os.write(p);
- }
- os.flush(); os.close();
- }catch(IOException e){
- System.err.println(e.toString());
- }
- }
- }
- }
-
-
- The source code is to show new users a way to make a simple program
- which can read a file and write it out buffered.
-
- Compile with "javac crlf.java" and run with
- java crlf outfile.txt
- or just use Wordpad instead of Notepad. Wordpad is under
- Start->Programs->Accessories->WordPad
-
- 20. (Sect. 2) How do I fix the message about "out of environment space"?
-
- [*] This occurs under Windows when you have long CLASSPATH names. You
- need to increase the environment space. On Windows 95,8 put this in
- your c:\windows\system.ini
-
- [NonWindowsApp]
- CommandEnvSize=4096
-
-
- On NT you can right-click on My Computer, select System Properties then
- go to the Environment tab and then increase COMSPEC to the value you
- want.
-
- The previous suggestion to put this in your config.sys:
-
- shell=command /e:4096
-
-
- apparently causes you to create two copies of command.com which wastes
- memory.
-
- -------------------------------
-
- 3. General Information
-
- 1. (Sect. 3) Is Java "Open" or "Proprietary"?
-
- [*] The Java specification is publicly available, and anyone is free to
- do clean-room implementations of the JVM and core Java API's. Sun
- includes a perpetual, irrevocable, free and royalty-free license in the
- front of the Addison-Wesley books containing the specification.
-
- Sun also provides free access to the Java source. See
- http://java.sun.com/communitysource/
-
- Using the Java trademark does requires licensing from Sun. It is not
- clear if the Embedded or Personal Java specifications are open, as it
- is not clear if a clean-room implementation may be done without
- licensing from Sun.
-
- The relative openness of Java contrasts with systems that are only
- available from one vendor, whose interfaces are developed in secret,
- without an open process for others to participate, whose owners do not
- allow competing implementations of the same API, and whose owners
- change the APIs as a strategic weapon against competitors. Typically,
- such systems also feature "private" APIs that are published late or not
- published at all, to allow the single vendor to gain a competitive
- advantage for their other products. Typically such proprietary systems
- do not make the source code available for inspection by all.
-
- 2. (Sect. 3) What is the best way to refer someone to the FAQ when they
- ask a question I know is answered there?
-
- [*] The Java Programmers FAQ (at http://www.afu.com) answers your
- question in section N.n. ...
-
- This gives them the answer, and shows them where to go for future
- questions. It also demonstrates that the FAQ can answer their
- questions, supplying an incentive to go there next time. It's regarded
- as elementary politeness to look for the FAQ of a newsgroup and read it
- before posting any questions.
-
- In general, FAQs for any newsgroup are available by looking at past
- postings in a group, or by searching Deja News (see Q 1.4), or via
- anonymous FTP at directories under ftp://rtfm.mit.edu. The pathnames
- are called things like
- /pub/usenet-by-group/comp.lang.java.programmer/Java_Programmers_FAQ
- which may help you get to the right one directly, as it takes some time
- to get a directory listing there. Alternatively, you can look for
- newsgroup names on the same ftp site by going to the same site and
- looking under /pub/usenet-by-hierarchy/. That has subdirectories such
- as alt/, ba/, ca/, comp/, and subdirectories under them such as
- /pub/usenet-by-hierarchy/comp/lang/ and so on. This helps you explore
- the world of newsgroups with FAQs.
-
- If you do not have anonymous FTP access, you can access the
- rtfm.mit.edu archives by mail server as well. Send an E-mail message to
- mail-server@rtfm.mit.edu with "help" in the body for more information.
- "RTFM" stands for "Read The effing Manual" - you must expect to put in
- some time and effort to master a new area of study.
-
- If you want to look at the definition of Internet standards like FTP,
- telnet, visit the IETF site at http://www.ietf.org where all the RFC's
- (Request For Comments) can be found.
-
- 3. (Sect. 3) What if my question is not answered in this FAQ?
-
- [*] Go to http://www.dejanews.com/home_ps.shtml
- In May 1999, Dejanews changed their name to Deja.com, and their web
- design to a truly horrible garish interface, covered with ads and
- harder to search. Consider using these search sites instead:
- http://www.exit109.com/~jeremy/news/deja.html
- http://www.dogpile.com
- http://www.google.com
- http://www.hotbot.com
- http://www.mamma.com
- o Under "Newsgroups" enter "comp.lang.java.programmer" (or whatever)
- o Under "Subject" enter "Frotteur" (or other topic you find
- pressing)
- o Click "Create Filter"
- o It will go to a new document, and you should click the link
- labeled
-
- nnn Documents (nnn is some number).
-
- The chances are that you will find several answers to your question.
- Some may not be complete or completely accurate however. That is the
- nature of Usenet, and free information. If you still don't have an
- answer, then post your question on the most appropriate of the
- newsgroups. Don't spam the newsgroups by posting to multiple groups.
- Knowledgeable posters tend to ignore questions like that.
-
- Also look at http://sunsite.unc.edu/java/cgi-bin/query
- and look at http://asknpac.npac.syr.edu/ for a Java newsgroup search.
-
- http://www.javaworld.com/search.html can search the Javaworld
- newspaper.
-
- 4. (Sect. 3) What Java mailing lists are there?
-
- [*] There are quite a few Java mailing lists.
- http://java.miningco.com/msub7.htm has a comprehensive list.
-
- 5. (Sect. 3) Where can I look at the definitive Java Language
- Specification?
-
- [*] This is available online at:
- http://java.sun.com/docs/books/jls/html/index.html (Java 1.0)
-
- and the Java 1.1 inner classes document at:
- http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/
- spec/innerclasses.doc.html
-
- and the other Java 1.1 update at:
- http://java.sun.com/docs/books/jls/html/1.1Update.html
-
- and the Java API is at:
- http://java.sun.com/products/jdk/1.1/docs/api
-
- It is also available as a book in printed form (details at website).
- Also see the "Clarifications and Amendments"
- http://java.sun.com/docs/books/jls/clarify.html.
-
- You can also see the virtual machine (execution environment)
- specification at
- http://docs.sun.com:80/ab2/coll.127.1/@Ab2CollToc?subject=java
-
- 6. (Sect. 3) Where can I find information about future Java APIs?
-
- [*] JavaSoft has followed a policy of creating new APIs in consultation
- with leading industry participants, then posting the draft
- specification for public review and comments. Check the JavaSoft
- roadmap of new APIs and products at
- http://java.sun.com:80/products/api-overview/index.html
- Also, some APIs that are under consideration, possibly for JDK 1.2 are
- at:
- http://java.sun.com/products/jdk/preview/docs/
-
- 7. (Sect. 3) I'm looking for a Java style guide on naming conventions.
-
- [*] Check out the section "Naming Conventions" in the language
- specification
- http://java.sun.com/docs/books/jls/html/6.doc.html#11186
-
- Also take a look at Doug Lea's draft coding standard -
- http://gee.cs.oswego.edu/dl/html/javaCodingStd.html
-
- See also naming conventions for some basic rules of thumb.
-
- 8. (Sect. 3) How do I check on known bugs in the JDK?
-
- [*] Look at the Java Developer Connection at http://java.sun.com/jdc.
-
- All the Java bugs that Sun knows about are listed there, with the
- exception of security-related bugs. The legal department in Sun vetoed
- the open publication of security bugs. After you have checked that the
- bug is not already listed, you can submit a bug report through:
- http://java.sun.com:80/cgi-bin/bugreport.cgi
- You should check that the bug doesn't already exist for two reasons:
- first, you might find the bug with a workaround listed. Second, you
- don't want to waste everyone's time with a duplicate bug report.
-
- You can also send in an RFE (Request For Enhancement) or ease-of-use
- issue there. You can even vote on the priority you would assign to a
- particular bug fix! Join the Java Developer Connection (it's free) by
- going to http://java.sun.com/jdc. Then browse
- http://developer.javasoft.com/developer/bugParade/#votes
-
- 9. (Sect. 3) What computers have Java ports? Is there a port to Win 3.1?
-
- [*] A partial list of JDK ports is available from
- http://java.sun.com/cgi-bin/java-ports.cgi
- An (impressive) list of the systems that the GPL Kaffee JVM runs on is
- at http://www.transvirtual.com/ports.html
-
- A list of the software updates you should install to run Java on
- Solaris is at
- http://java.sun.com/products/jdk/1.2/install-solaris-patches.html#2.6
-
- There are several Java ports to Win 3.1. IBM's ADK1.02 is available at
- the following locations:
- o http://ncc.hursley.ibm.com/javainfo/latest/answers/faq0.html
- o http://www.alphaworks.ibm.com/formula
- IBM offers a port to Linux, as do others. The IBM Jikes port is at
- http://www.alphaworks.ibm.com/ There is a large amount of useful
- software there, including a profiling tool called jinsight.
-
- Netscape Navigator for Win3.1 has Java support. Java will never be
- well-supported under Win3.1 because Win3.1 lacks the basic features
- expected of a modern OS (primarily lengthy filenames and multithreading
- support).
-
- Also take a look at JavaSoft's JavaPC kit that can switch a PC into a
- thin client Java system (and back to Win3.1/DOS when you want). It's
- meant for software OEMs and large corporations running lots of older
- PCs, but you can use it on the latest Pentium II too. Details are at
- http://java.sun.com/products/javapc/index.html. JavaPC is available now
- for $100, runs on 486's with 8Mb or more Unlike the 16-bit versions of
- Netscape Navigator and Microsoft Internet Explorer, which provide a
- Java Virtual Machine that is only compliant with the JDK 1.0.2 API, the
- JavaPC software allows IS managers to deploy JDK 1.1-compatible Java
- applications on PCs running DOS and Windows 3.x.
-
- 10. (Sect. 3) Where can I find information on Java 3D?
-
- [*] The Java 3D FAQ at http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html
- may have the answers you're looking for. It contains general
- information about Java 3D, as well as programming tips.
-
- 11. (Sect. 3) Where can I find information about Java Certification?
-
- [*] Sun is sponsoring an examination which programmers worldwide can
- take. Those passing can use the designation "Sun Certified Java
- Programmer". There is also a second-level test, involving writing a
- program to spec, and taking a further test. That results in the
- qualification "Sun Certified Java Developer". You can find out all
- about the exam at:
- http://www.sun.com/service/suned/
-
- and then search for "sun certified java". It costs $150 to sit the Java
- Programmer exam. It is not trivial to pass the Java certification exam.
- It requires understanding the objectives of the test, and the material
- that is tested for. These are given, along with sample questions, at
- the URL mentioned above.
-
- There is a Java certification FAQ at: http://www.marcusgreen.co.uk
-
- 12. (Sect. 3) How can I find links to recent news about Java?
-
- [*] This site contains links to late-breaking online news stories about
- Java. http://www.intelligence.com/java/
- Another good Java news source is http://www.nikos.com/javatoys.
-
- This site is a fine site for programmers who want to be well-informed
- about computer industry topics. It has a lot of coverage of Linux as
- well as more general news. http://slashdot.org Highly recommended.
-
- This site is a source of independent news and commentary on the
- computer industry, including Java. http://www.pjprimer.com/media.html.
- You have to subscribe ($10/year, 30 day free trial).
-
- 13. (Sect. 3) What are the folks at GNU doing with Java?
-
- [*] First note that the URLs in this section change quickly, and soon
- become outdated. If you have an update, send it in. There is a Gnu Java
- page at http://www.gnu.org/software/java/java.html
- Guava (a GPL'd Java compiler) can be found at
- ftp://ftp.yggdrasil.com/pub/dist/devel/compilers/guavac/
- Alternatively, it may be available at
- http://http.cs.berkeley.edu/~engberg/guavac
- Work is progressing on the Cygnus Java frontend to gcc. See
- http://www.cygnus.com/product/javalang/
-
- Kaffe (a JVM) can be found at
- http://www.transvirtual.com This is Tim Wilkenson's company
- devoted to commercializing the Kaffe JVM for the embedded systems
- market. He also releases a version of it under the GPL. It also
- comes with a the beginnings of a class library and the Pizza
- compiler.
-
- Classpath is a free implementation of Sun's Java libraries (v1.1),
- being developed for the GNU Project ( http://www.gnu.org). Information
- regarding classpath is at http://www.classpath.org They aim to develop
- a 100% free drop in replacement for Sun's class libraries, targeting
- first the Japhar JVM (below). They are always looking for help, so feel
- free to stop by and volunteer.
-
- See also http://www.japhar.org This is the Hungry Programmer's JVM.
- Currently it is development grade only.
-
- 14. (Sect. 3) What is "San Francisco"?
-
- [*] San Francisco is the code name for a very large Java project led by
- IBM, and involving other companies. The project is to provide a Java
- framework for data processing applications. A large number of classes
- are provided for general ledger, sales order, inventory management,
- etc., and these classes can be extended and customized for particular
- industries (vertical markets). It is a large and ambitious software
- project.
-
- IBM's SF project competes with products from companies like SAP and
- Baan. Of course, the SF project is multi-platform and uses Java beans
- and GUI interfaces. More information on SF is available at
- http://www.ibm.com/Java/Sanfrancisco
-
- 15. (Sect. 3) What large Office-style or other applications have been
- written in Java?
-
- [*] Well, the first one to consider is IBM's San Francisco project,
- mentioned above. There is also Lotus's e-suite - a suite of Java
- applets and beans including a spreadsheet and a word processor. See
- http://esuite.lotus.com. These became available in March 1998.
-
- Another office suite in Java is Applix Anyware at
- http://www.applix.com/anyware/index.htm. Applix became available in
- downloadable demo form in April 1998.
-
- Yet another is Star Division's Client/Server Office. It is an office
- suite with the client part written in Java and able to run on
- JavaStations. The server part will run on Solaris, NT, OS/390, and
- AS/400. The older (non-Java) version is bundled with all Sun
- workstations sold in Germany. The Linux version is freely downloadable
- from http://www.stardivision.com.
-
- Another is Digital Harbor's Wav word processor. It supports component
- software, and it runs in 1MB, not the 114Mb of the latest MS Word. A
- free trial is avilable. See: http://www.digitalharbor.com
-
- Another Java application is Formula One for Java, an Excel-compatible
- spreadsheet written in 100% pure Java, and available for all systems
- that support Java. It runs as a Java Bean, so can easily be assembled
- as one component of a larger system. It also runs as an application,
- and as an applet! Formula One is a product of Visual Components, Inc.
- See http://www.f1j.com.
-
- Another one is Ncode Research Inc. who write Java viewers for office
- suites. They are file-format specialists. Their mission is to make all
- popular file formats available for the Java platform. They write 100%
- Pure Java viewers for Word, Excel and PowerPoint (including Office 95
- and 97 formats). See http://www.ncode.com/
- Another company operating in the same space is JSoft, at
- http://www.jsoftinc.com
-
- Intentia, the 8th largest ERP vendor (annual sales of $320 million),
- has moved their entire suite of applications (Movex - covering 8
- markets) from RPG to Java - 20 million lines worth. See their press
- release.
-
- However, the industry is seeing few new office productivity
- applications written in any language. The niche for single-user office
- productivity applications is already dominated by Microsoft products,
- and it is unrealistic to think that Java software will unseat
- shrink-wrapped software simply because it is written in Java. This is
- why Corel replanned its Java rewrite of Corel Office before taking it
- to FCS. When Corel did that, it also increased its investment in Java
- from 33% of R&D budget to 50%, at the expense of Windows.
-
- Most of Java development is taking place for custom applications
- internal to a company. Most programmers of any kind have never worked
- on MS Office, but work on internal applications, and so it is with
- Java. These projects don't have the high profile of major vendors'
- products, but they are the mainstay of the industry. There are many
- companies working on Java Beans, like http://www.quadbase.com who have
- Java graphing software (see also GraphMaker mentioned later in this
- document). EspressChart is a Java Bean that gives you the ability to
- add 2D and 3D graphs in your applications/applets. This bean is easy to
- use, 100% Java, and runs anywhere.
-
- There are some excellent Java games applets at
- http://www.javaarcade.com Check out the pinball -- dig that crazy
- rhythm, man.
- There are more good Java games applets at
- http://www.frontiernet.net/~imaging/java_games.html
- and at http://www.gamesdomain.co.uk/GamesArena
- If you want to use Java to learn math & computer graphics, visit
- http://www.frontiernet.net/~imaging/math_is_a_game.html
-
- ObjectDesign Inc., has an ODBMS written in 100% java. The product is
- named PSE Pro for Java. See http://www.objectdesign.com
- Another database written in Java is available from
- http://www.cloudscape.com.
- Another database written in Java is available from
- http://www.instantdb.co.uk. InstantDB is available free to
- non-commercial organizations, and is very well documented and
- maintained. (Recommended!)
- Finally, note that Sun's Java compiler is written in Java. This is a
- really big application in widespread use on millions of platforms. The
- compile command "javac test.java" is equivalent to
-
- java sun.tools.javac.Main test.java
-
-
- javac has a script wrapper just to set the heap size as a command line
- argument, as you can do in your own programs.
-
- 16. (Sect 3.) What Java User Groups are there?
-
- [*] There are scores of Java User groups around the world, mostly in
- urban areas, and centers of software technology development. A partial
- list with contact information can be found at
- http://sunsite.unc.edu/javafaq/usergroups.html.
- If you can't find a user group in your area/school, it's easy and
- satisfying to start one.
-
- 17. (Sect 3.) What is a Java Bean?
-
- [*] A Java bean is a Java class that follows some simple conventions.
- Because it follows conventions, it can easily be processed by a
- software tool that connects Beans together at runtime. Java beans are
- reusable software components.
-
- Think of Java beans as being the software equivalent of Lego[tm]
- bricks. Instead of plugging together plastic bricks, you can easily
- plug together classes, and have them fit and work with each other. See
- http://www.jc100.org/
- See the Java Bean FAQ at http://java.sun.com/beans/faq/faq.general.html
-
- 18. (Sect 3.) Where can I find examples of the use of the Java class
- libraries?
-
- [*] The two volumes of "Java Class Libraries" by Chan, Lee and Krama
- published by Addison Wesley, have extensive examples of how to use the
- standard libraries. One programmer comments "When I need to use an
- unfamiliar area of the class libraries one of the first things I do is
- read their examples." You can see them online at
- http://java.sun.com/docs/books/chanlee/second_edition/vol1/examples.html
- and http://java.sun.com/docs/books/chanlee/second_edition/examples.html
-
- 19. (Sect 3.) How can I find out exactly what version of Java I have on my
- system?
-
- [*] On a Solaris system, you can use the pkginfo command, like this:
-
- pkginfo -l SUNWjvrt
-
- It will give a reply like this:
-
- PKGINST: SUNWjvrt
- NAME: JavaVM run time environment
- CATEGORY: system
- ARCH: sparc
- VERSION: 1.1.6,REV=1998.07.30.16.21
- BASEDIR: /
- VENDOR: Sun Microsystems, Inc.
- ...etc
-
- You may also try
-
- java -fullversion
-
- Although that's not an officially-supported command option, and has
- gone away in JDK 1.2. Try also
-
- java -version
-
- 20. (Sect 3.) What Java newsgroups are there?
-
- [*]
-
-
- comp.lang.java.beans
- comp.lang.java.corba
- comp.lang.java.databases
- comp.lang.java.gui
- comp.lang.java.help (it renamed comp.lang.java.setup)
- comp.lang.java.machine (it renamed comp.lang.java.tech)
- comp.lang.java.programmer (it renamed c.l.j.api and c.l.j.misc)
- comp.lang.java.advocacy (argue all day with anonymous shills)
- comp.lang.java.softwaretools
- alt.comp.lang.java-games
-
- New Java newsgroups are added every so often. Try not to crosspost.
-
- -------------------------------
-
- 4. Compilers and Tools
-
- 1. (Sect. 4) Is there a lex and yacc or preferably a flex and bison
- equivalent for Java?
-
- [*] There is a lex equivalent called JavaLex and a yacc equivalent
- called CUP.
-
- LALR(1) parser JavaLex and JavaCup:
- http://www.cs.princeton.edu/~appel/modern/java/
-
- LL(k) parser JavaCC: http://www.suntest.com/JavaCC/
- LALR(1) parser SableCC from McGill U.
- http://www.sable.mcgill.ca/sablecc/index.html is generously made
- available under GNU license.
-
- 2. (Sect. 4) Where can I find a byte code obfuscator?
-
- [*] Java Obfuscators replace the original class, field and methods
- names in the bytecode with meaningless strings. Second generation
- obfuscators are now appearing that also obfuscate the control flow and
- encrypt String literals. People use obfuscators on their applets if
- they want to hide their code from others. Generally, you wouldn't do
- this with software that you put on your website for others to enjoy. It
- runs counter to the "open source" philosophy of learning from other's
- code and allowing them to learn from yours.
-
- Zelix KlassMaster is a commercially supported obfuscator. It has a free
- evaluation version at http://www.zelix.com/klassmaster
- Another commercially supported obfuscator, with a downloadable free
- trial is at http://www.4thpass.com/SourceGuard. There are also some
- free works from students and others. http://www.primenet.com/~ej/
- http://www.math.gatech.edu/~mladue/HoseMocha.java
-
- Some people have reported problems using these with JDK 1.1.
-
- This obfuscator has been updated to be fully compatible with JDK 1.1:
- http://www.monmouth.com/~neil/Obfuscate.html
-
- Obfuscators are intended to foil decompilers. Decompilers translate
- byte code back into Java source code. Mocha was the first and most well
- known of the decompilers; it's no longer supported. There is a
- decompiler (written in C++) at
- http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
- Because it is in C++, there are different versions for every
- architecture (hah!) There are also commercial products, such as
- SourceAgain from
- http://www.ahpah.com/
-
- There's a very good Java Code Engineering and Reverse Engineering FAQ
- page at http://www.meurrens.org/ip-Links/Java/codeEngineering/.
-
- 3. (Sect. 4) Which program is used to create .zip files compatible with
- the java* programs?
- (e.g. classes.zip, moz3_0.zip)
-
- [*] Use the jar-tool from JDK1.1(.1):
- jar [ options ] [manifest] destination input-file [input-files]
-
- E.g.:
- jar cvf myJarFile.jar *.class
-
- creates a compressed archive. And watch out -- the order of the options
- ("cvf") determine the order of the arguments!
- jar cvfO myJarFile.zip *.class
-
- creates it fullsize (uncompressed) (note the 'O'-option used for
- JDK1.0.2)
-
- On Unix you can also use:
- zip -rn ".class" my_file.zip *
-
- Info-ZIP home page: http://www.cdrom.com/pub/infozip/
- Latest source code: ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip
-
- Netscape's command line version of its JAR packager and signing tool is
- called "zigbert". They also have a signing tool with GUI written in
- Java. More info
- http://developer.netscape.com/software/signedobj/jarpack.html
-
- If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a Jar):
- 1. zip your files uncompressed (can use WinZip 6.2 up);
- Unix command:
-
- zip -r0 classes.zip <directories>
-
- 2. Make sure the main class has no parent directory inside the
- archive, (in other words, don't build an archive with
- foo/bar/myMain.class, unless your myMain is in a package called
- foo.bar. Instead start it at myMain.class). Your packages must be
- placed in the archive using their corresponding filesystem
- pathnames.
- 3. Put the archive in the same directory as the .html page.
- 4. Put something like the following tag in the .html file:
-
- <APPLET CODEBASE="."
- ARCHIVE=my_zip_file.zip,myOtherZip.zip,thirdfile.zip
- CODE="my_main_class.class"
- WIDTH=600 HEIGHT=250>
- </APPLET>
-
-
- From JDK 1.1 on, an example of the applet tag used with a jar file is
-
- <APPLET ARCHIVE=myfile.jar
- CODE=myapplet.class
- WIDTH=600 HEIGHT=250>
- </APPLET>
-
-
- These lines will use an applet called myapplet that can be found in the
- jarfile myfile.jar. An example applet tag of a jar file used to hold
- classes in packages is
-
- <APPLET ARCHIVE="myclasses.jar"
- CODE="linden.net.MyApplet.class"
- WIDTH=480
- HEIGHT=120>
- </APPLET>
-
-
- You can supply several jar filenames in a comma-separated list. Jar
- files are in compressed PKZIP format.
-
- 4. (Sect. 4) Can I compile a Java program to a binary executable, .exe on
- a PC?
-
- [*] Compiling into native code destroys portability, which is one of
- the main benefits of Java. If you want to create a native executable
- because you wanted to make it easy to distribute and use programs,
- consider a Jar file instead.
- Some companies make products that do this. See the webpages for
- Symantec http://www.symantec.com, Supercede http://www.supercede.com,
- and Tower Technology http://www.twr.com. The first two are targeted to
- Windows. Tower Technology supports several flavors of Unix.
-
- Also, there is a native Java compiler from IBM, known as the HPJ (High
- Performance Java) compiler. One user has reported that it created a 2Mb
- executable from a 12K java file, and did not run any faster. See
- http://www.alphaworks.ibm.com/
-
- See also Instantiations JOVE http://www.instantiations.com/jove.htm,
- the paper about the Toba project
- http://research.microsoft.com/research/lt/toddpro/papers/coots97.pdf,
- Network World, "Vendors Rush To Speed Java Performance", Feb 9 1998, at
- http://www.nwfusion.com/news/0209java.html
-
- Compiling to native code takes away the most significant benefit of
- Java: portability of executables. Further, if you want your Java DLL
- (or .exe) to interact with C++, you'll have to specify which specific
- C++ compiler and/or actually compile some sort of linkage via the
- appropriate C++ compiler. C++ does not have a standard ABI, so there is
- a big problem with interoperability. Every C++ compiler uses a
- different object model, a different way of laying out class members,
- and a different way of "mangling" names for the linker.
-
- C is much simpler. The only question here is how structures are
- "packed" (i.e., are integers aligned on four-byte bounds?). All the C++
- compilers can interact with C code, thanks to 'extern "C"'
- declarations.
-
- Consider carefully why you want to compile to a native executable, and
- whether there is a Java way to accomplish your goal. There may be a
- good reason for compiling to native code, but it needs to be thought
- through.
-
- 5. (Sect. 4) How can I performance profile my Java code?
-
- [*]java -prof MyClass
-
- produces some basic output in a file called java.prof, showing the
- number of times methods were invoked. The output lines are of the form:
- # of calls method called called by time spent
- On a Unix system, you can sort the file with something like
-
- sort -r +82 <java.prof > java.sort
-
- More and better Java tools are a third party opportunity. One Java
- profiler is JProbe Profiler, available from http://www.klg.com/jprobe.
- JProbe is said to be easy to use. Another profiler is OptimizeIt,
- available from http://www.optimizeit.com. Each of these profilers has
- performance tuning, which shows which methods took how much time, and
- also memory tuning, which shows what objects are in memory and how they
- were allocated. Both are important things to know. The latest version
- of the CodeWarrior IDE http://www.metrowerks.com has a time-based
- profiler for Java code. Java Workshop from Sun also has a time-based
- profiler.
-
- JDK 1.2 comes with some limited profiling capability built-in.
- Depending on your needs, it may be all that you need. Execute the
- following to get a short summary of what you can do:
-
- java -Xrunhprof:help
-
- For example, you can see which methods are taking the most time to
- execute, in the context of particular stack traces.
-
- 6. (Sect. 4) When I use javadoc and I click on any java class included in
- the JDK why do I get this message?
-
- Netscape is unable to find the file or directory named:
- /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html
-
-
- [*] References to the JDK classes assume that all generated html files
- are in the same directory and, in fact, that all files for all classes
- referenced are generated at the same time. There is no way to generate
- files incrementally and have them all reference each other, as you
- would like.
-
- As long as you have source for everything involved (including the JDK
- and all third-party classes), you can list all of your packages and all
- of the others on the javadoc command line and generate the whole set at
- once, but it is burdensome. Of course, if you receive any libraries as
- .class files, even this workaround will not suffice.
-
- Also javadoc will not generate the image files - you need to get them
- from the images directory under the JDK API documentation files. You
- can just copy the entire directory into your own doc directory. javadoc
- is a very nice concept, with a few implementation flaws.
-
- 7. (Sect. 4) I'm working on a project with lots of classes and I use the
- JDK. A recompile from scratch takes forever when I do it a class at a
- time. How do I recompile everything?
-
- [*] The first way is
- javac *.java
-
- Another way is
- javac -depend tip.java
-
- where "tip.java" is a class "at the tip of the iceberg", i.e. that
- depends on (uses) all the other classes. Typically, this may be your
- main class. However, "-depend" is known to be buggy and cannot be
- relied upon. It also doesn't issue compile commands in parallel to make
- use of multi-processor systems.
-
- Without the "-depend" option, the standard "javac files" doesn't look
- beyond the immediately adjacent dependencies to find classes lower down
- the hierarchy where the source has changed.
-
- The -depend options searches recursively for depending classes and
- recompiles it. This option doesn't help when you have dynamically
- loaded classes whose names cannot be determined by the compiler from
- the dependency graph. E.g. you use something like
- Class.forName(argv[0]);
-
- The author of the code using those classes should make sure that those
- classes are mentioned in a Makefile.
-
- 8. (Sect. 4) Why do I get the java.lang.UnsatisfiedLinkError when I run my
- Java program containing Native Method invocations?
-
- [*] Your program is not able to find your shared library or DLL.
-
- On Windows 95/NT, make sure that the DLL exists in a path that is
- included within the PATH environment variable. (This need is true for
- both standard (untrusted) applications and trusted applets. At least,
- if you use the Java Plug-in to give yourself standard Java inside a
- browser).
-
- On Solaris, make sure that the environment variable LD_LIBRARY_PATH
- includes the path of your shared library.
-
- Note that jdb looks for libraries with "_g" appended to their names.
- Thus, if you intend to use jdb on a Java application that invokes
- native methods, you must ensure that the appropriately named libraries
- are in jdb's path. The "debug" nm libraries can simply be renamed
- copies of the nondebug libraries.
-
- For example, if your app invokes native methods in a library named
- mynm.dll (on Windows) or mynm.so (on Solaris), make a copy in the same
- directory and name it mynm_g.dll or mynm_g.so.
-
- 9. (Sect. 4) An anonymous class can't seem to access a private outer
- method. Why is that?
-
- [*] It's a known bug in the JDK 1.1.4. The code is:
-
- public class MyDialog {
-
- void Setup() {
- addWindowListener( new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- myCloseWindow(); }
- }
- ); // anon inner class
- }
-
- private void myCloseWindow() { // private outer method
- dispose();
- }
- }
-
- This code sends javac into an infinite loop. The workaround is to make
- the private method non-private, or to make the inner class a named
- class. Sun put a workaround in the compiler to silently set the field
- to package access.
-
- 10. (Sect. 4) What are the major Java releases and their contents?
-
- [*] There have been three Java releases from Sun so far, plus a number
- of bugfix (dot-dot) releases. The releases are:
- o JDK 1.0.2
- This was the release FCS in May 1996. It had some security fixes
- over JDK 1.0.
- o JDK 1.1
- This release (Feb 1997) introduced a new event model in the window
- system. It also made JDBC support and beans support a standard
- feature. It changed and standardized the native code interface to
- JNI. It also introduced inner classes.
- o JDK 1.2
- This release (Dec 1998) made the Swing library a standard feature.
- Swing is a set of rich platform-independent graphical components.
- It also introduced the Collections library, and Java 2D.
-
- 11. (Sect. 4) What is the difference between jre and java?
-
- [*] They are functionally equivalent, with minor differences in the
- handling of default classpath and options supported. To reduce
- confusion, the jre command was removed in JDK 1.2. Instead there is a
- "java" command in both bin and jre/bin.
-
- jre.exe is the java launcher that comes with the Java Runtime
- Environment. It ignores the CLASSPATH environment setting in favor of
- its own internally generated default and whatever is supplied on the
- cmd line using -cp or -classpath. It's intended to be a bit simpler for
- those who are only ever running Java programs, not developing them.
-
- java.exe is the java launcher that comes with the JDK. It uses the
- CLASSPATH environment setting as a starting point and then tacks on its
- own internally generated entries.
-
- They both serve the same purpose and that's to start a Java VM, have it
- run a Java application, then terminate. The source for jre.exe is
- provided in the JDK. The source to java.exe is provided only in the JDK
- Source distribution.
-
- 12. (Sect. 4) What IDEs (Integrated Development Environments) are there?
-
- [*] Some popular IDEs include: (... if you have info on the platforms
- that each of these support, send it in, and I'll add it to the FAQ).
- Apptivity (Progress) http://www.apptivity.com
- Blue J (free) http://www.sd.monash.edu.au/bluej
- Bluette (free) http://www.bluette.com
- Chicory (free) http://www.chicory.com
- CodeWarrior
- Professional http://www.metrowerks.com
- Freebuilder (free) http://www.freebuilder.org
- GRASP (free) http://www.eng.auburn.edu/grasp
- Grinder http://www.tpex.com
- Java WorkShop (Sun) http://www.sun.com/workshop/java
- Javelin, Visual Object
- Development for Java http://www.stepahead.com.au
- JBuilder (Inprise) http://www.inprise.com/jbuilder
- JDE for emacs http://sunsite.auc.dk/jde/
- Jirvana (free) http://www.jirvana.com/Jirvana/Jirvana.html
- JPadPro http://www.modelworks.com
- Kawa (Webcetera) http://www.tek-tools.com/kawa
- Metamata http://www.metamata.com
- NetBeans (Swing-based) http://www.netbeans.com
- PARTS alpha
- (ObjectShare) http://www.objectshare.com
- PowerJ (Sybase) http://www.sybase.com/products/powerj
- SilverStream http://www.silverstream.com
- Simplicity for Java http://www.datarepresentations.com
- Super Mojo (Penumbra) http://www.penumbrasoftware.com
- SuperCede (Asymetrix) http://www.supercede.com
- teikade (PFU Ltd) http://www.pfu.co.jp/teikade
- Together/J (Object Intl
- Inc.) http://www.oi.com
- Visaj (Imperial SW
- Tech) http://www.imperial-software-tech.co.uk
- VisualAge (IBM) http://www.software.ibm.com/ad/vajava
- Visual Cafe (Symantec) http://cafe.symantec.com
-
- Visual J++ (Microsoft) http://msdn.microsoft.com/visualj/default.asp
- (not recommended)
- Xelfi 0.94 http://www.xelfi.com
-
- 13. (Sect. 4) Why is Visual J++ not recommended?
-
- Because Microsoft's strategic objective is "Kill cross-platform Java"
-
- [*] It is not in Microsoft's financial interest to allow users to
- easily move software to different platforms. Microsoft is the only
- company in the computer industry that is actively trying to undermine
- Java. This is not speculation -- the Department of Justice's lawsuit
- quoted a Microsoft memo describing the strategic objective to "kill
- cross-platform Java by grow[ing] the polluted Java market". See
- http://www.usdoj.gov/atr/cases/f1700/1762.htm
- VJ++ can be used in a compatible way, but the tool encourages use of
- Windows lock-ins. The J++ compiler introduced new keywords and other
- deliberate incompatibilities.
-
- Microsoft is being sued because of unauthorized changes it made in
- Java. A federal judge issued a preliminary injunction against Microsoft
- in March 1998, prohibiting them from labelling their incompatible J++
- product as Java. Another injunction was issued against Microsoft in Nov
- 1998, requiring them to remove some deliberate incompatibilities with
- standard Java. (Recall that Microsoft did not create Java, but
- contracted with Sun to distribute it).
-
- Microsoft is in a real jam over Java; it contracted with Sun to
- distribute standard Java, and then made many changes to its product
- to make it deliberately non-portable. Sun sued Microsoft to enforce the
- contract, and the preliminary legal decisions have been in Sun's favor.
- Some analysts speculate that Microsoft will leave its customers in the
- lurch and cancel VJ++. See
- http://cnn.com/TECH/computing/9903/23/javajam.idg/index.html
-
- Speak to your management chain - how comfortable do they feel using a
- Microsoft product that is embroiled in a legal dispute, that introduces
- deliberate incompatibilities, and whose stated goal is to lock you in
- to one platform? It is a safer choice to get standard Java from any
- other source than Microsoft. You can use these facts to move your
- company to standard Java.
-
- As a Java programmer please join the Java Lobby, an independent
- organization dedicated to representing independent non-vendor interests
- in Java. It's free, and you can sign up by visiting
- http://www.javalobby.org for details. Other ways to encourage portable
- java:
- o Use development environments from other vendors, or convert
- Microsoft Visual J++ to use Sun's JDK, following the instructions
- at http://www.orbiter.demon.co.uk/
- o Use Netscape Communicator (not Internet Explorer)
- o If required to use Internet Explorer, use the Java Plug-In to get
- a standard Java system inside it.
- o Use a standard JVM from GNU, Kaffe, any of the IDE vendors, or Sun
- (but not Microsoft's J++ SDK)
-
- o Free standard Java compilers and the Java Plug-In can be
- downloaded from http://java.sun.com.
- o Free standard Java Virtual Machines can be downloaded from
- http://www.kaffe.org, http://www.oryxsoft.com/projects/gvm, and
- http://www.redhat.com/linux-info/jolt
- o Free Java AWT software can be downloaded from
- http://www.biss-net.com/biss-awt.html and the files are all at
- ftp.java-linux.org (the linux site) too.
- o Free Java software can be downloaded from
- http://www.gnu.org/software/java/java.html
-
- Just for the record, the May 1998 federal case against Microsoft has
- nothing to do with innovation or product design, as Microsoft
- frequently insists. Microsoft is actually charged with
- o taking anti-competitive action to exclude competition in browsers,
- in order to protect its monopoly in desktop operating systems.
- o using its monopoly to impose restrictive agreements that require
- PC manufacturers to accept the Microsoft browser with Windows, and
- that hinder the promotion of competing browsers.
- Many people think that contracts between "A" and "B",
- restricting/discouraging "B" from distributing "C's" products are
- sleazy. ["A" is Microsoft, "B" is AOL, many ISPs, computer vendors,
- etc. "C" is Netscape"]. Such contracts are in restraint of competition
- and illegal when used by a monopoly. This is why Microsoft is facing
- mounting legal problems in the United States, Italy, Brazil, and the
- European Union.
-
- 14. (Sect. 4) What language is the Java compiler and JVM written in?
-
- [*] Sun's javac Java compiler is written in Java.
- Sun's java JVM interpreter is written in Java with some C, C++ for
- platform-specific and low level routines.
- Sun's Java Web Server is written in Java.
-
- Other companies have chosen other approaches. IBM's Jikes compiler
- (which is praised for its speed) is written in C++, but of course each
- version only runs on one platform. Jikes versions have been prepared
- for IBM AIX, Linux Intel (glibc), Win95/NT and Solaris Sparc at
- http://www.alphaworks.ibm.com/formula/jikes.
-
- 15. (Sect. 4) How do I turn off the JIT in the JDK?
-
- [*] The command that works in both JDK 1.1.6 on, and JDK 1.2/2 is
-
- java -Djava.compiler=NONE ...
-
-
- One reason for turning off the JIT is to get more
- information about any exception that is thrown in your code.
- But HotSpot is able to produce line numbers in stack traces
- even for JIT'd code. HotSpot rocks.
-
- 16. (Sect. 4)
- How can I store the errors from the javac compiler in a DOS file?
-
- javac foo.java > errorfile doesn't work.
- [*]
- javac writes errors to stderr,
- The problem is that DOS doesn't allow stderr to be redirected
- (as command.com is very poor software). So you
- have to use a special error redirection mechanism in the compiler:
-
-
- javac -J-Djavac.pipe.output=true myfile.java > errors.txt
-
-
- In JDK 1.2, you can use:
- javac -Xstdout
-
- You typically use this when a compilation produces a lot of error messages,
- and they scroll off the DOS window before you can read them.
-
-
- Alternatively,
- you can get a scollbar to appear on a DOS window by changing the properties
- with the "Layout" tab. Change the Screen Buffer Size Height: to some
- multiple > 1 of the Window Size Height. E.g. use a buffer height of 100 and
- screen height of 25 (the default). This will give you three buffers of
- scroll "history."
-
-
- The DOS limitation is improved in NT, where you can write
-
-
- javac myfile.java 2> errors.dat
-
-
- 17. (Sect. 4)
- How can I pretty-print Java source?
- [*]
- For tools that reformat code, try:
-
-
-
-
-
- o
-
- http://www.parallax.co.uk/~rolf/download/jpp.pl
-
- o
-
- http://www.bigfoot.com/~davidsont/jstyle
-
- o
-
- http://www.mmsindia.com/JPretty.html
-
- o
-
- http://www.almide.demon.co.uk/source_code/java/JavaCC/Pretty/Pretty.html
-
- o
-
- http://www.geocities.com/~starkville
-
-
-
-
- For tools that print code neatly, try:
-
-
-
-
-
- o
-
- http://www.eng.auburn.edu/department/cse/research/grasp/
-
-
- Some Unix utilities work adequately:
-
-
-
- o
- cb (very few style choices though)
-
- o
- alias printjava 'vgrind -lC++ -t -w \!* | lp' works pretty well too.
-
-
- Perhaps the best tools are the GNU utilities. Use enscript to
- generate postscript files with Java-specific formatting. Then use
- GhostScript/GhostView to preview and print the files to a
- non-PostScript printer, if necessary. The scripts can be found at:
-
-
-
- o
- GNU Enscript - pretty
- printer and PostScript formatter
-
- o
- Ghostscript, Ghostview, and
- GSView for Unix
-
- o gsv25w32.zip
- - GSView for NT (requires the following Ghostscript files)
-
- o
-
- gs510ini.zip - Ghostscript configuration, initialization, and
- example files
-
- o
-
- gs510w32.zip - Ghostscript core binaries for Windows NT
-
- o
-
- gs510fn1.zip - Ghostscript standard fonts
-
-
- -------------------------------
-
- 5. Compiler Messages
-
-
- Most of the "questions" in this section are diagnostic messages from the
- compiler. Each answer explains what the message means, and how to avoid it.
-
- 1. (Sect. 5)
- Why did I get an OutOfMemory error when porting working code from
- JDK 1.0.2 to 1.1?
- [*]
- The preset memory limit has changed. It went down to 16MB so as not to
- penalize low memory machines. You can adjust it with
-
- java -mx128m Frotz # jdk 1.1
- java -Xmx128m Frotz # jdk 1.2
-
-
- to get a 128MB extent.
-
- Also see the Runtime methods freeMemory() and totalMemory().
-
- 2. (Sect. 5) Why do I get a "Statement not reached" error from javac for
- no apparent reason?
-
- [*] JDK 1.0 has a limit of 63 words of storage for local variables in
- any method. longs and doubles require two words of storage, and all
- other primitive types and all reference types require one word. If you
- assign values to more than 63 words of local variables, you will get a
- "Statement not reached" error on the statement after you assign to the
- variable that contains the 64th word. In JDK 1.1, the low limit was
- removed.
-
- 3. (Sect. 5) class MyOrdinaryClass must be declared abstract.
- It does not define void actionPerformed(java.awt.event.ActionEvent)
-
- [*] This is one of those error messages where the compiler tries to
- guess what you meant, and gives you a message based on a wrong guess!
- So the message is confusing.
-
- Your MyOrdinaryClass class implements ActionListener, which means you
- must include a definition of the methods from the ActionListener
- interface.
-
- But you did not. You either left a method out, or (more likely) you
- misspelled its name. Perhaps you wrote "ActionListener" instead of
- "actionListener".
-
- So the compiler did not find the method to fulfill the interface. Since
- there was a method promised but not supplied, the compiler thinks you
- were aiming at an abstract class, and it prints an error message
- accordingly.
-
- 4. (Sect. 5) Variable may not have been initialized.
-
- URL test;
- try {
- test = new URL("http://osprey.avs.dec.com");
- } catch (MalformedURLException e) {
- System.out.println("bad URL:" + e.getMessage());
- }
- System.out.println("this is url " + test);
-
-
- [*] The compiler will warn you if you use a variable before it is
- certain to have been initialized (not just with the default value)
- since this means you probably forgot to set it.
-
- In the case of exceptions, you have to consider that the flow of
- control may terminate abruptly, with no operations completed. In the
- example above, if an exception is raised in the try clause, variable
- test will not be assigned a value, yet you are using it after the catch
- clause. One solution would be to declare test with an explicit initial
- value of null, but this works only because toString() works on a null
- reference. (toString() is invoked implicitly by operator + with String
- operand.)
-
- Always initialize to a value that will work notwithstanding exceptions
- being thrown.
-
- 5. (Sect. 5) No constructor {superclass}()
- I extended the class called Frotz, and the compiler is giving me an
- error message "No constructor Frotz()" in the child class. Why?
-
- [*] When you define a constructor for a class, the compiler inserts a
- call to the superclass' parameterless constructor unless you explicitly
- call the superclass' constructor at the start of your constructor. If
- the superclass doesn't *have* a parameterless constructor, the compiler
- emits a message to that effect. The solution is usually to call the
- superclass' constructor at the start of your constructor.
-
- 6. (Sect. 5) No constructor matching MyCheckbox(myApplet)
-
- MyApplet.java:11: No constructor matching MyCheckbox(myApplet)
- found in class MyCheckbox.
-
- bp1 = new MyCheckbox(this);
- ^
-
- [*] If a compiler isn't finding a constructor you thought you created,
- check whether you gave a return value to the method (remember,
- constructors have no return value). E.g.,
-
- public void MyCheckbox( Container parent )
-
-
- If you did, the compiler will think it is an ordinary method, not a
- constructor. This is a common mistake and hard to spot.
-
- 7. (Sect. 5) Type expected {public method variable}
-
- public static void main(String[] args) {
- ^
- Statement expected.
- public static final float Conversion_Factor = 39.37;
- ^
- Type expected.
-
- [*] Argument and variable declarations inside methods are never public
- or static because they are local to a method. (Before JDK 1.1 they
- couldn't be final either, but there was no good reason for that
- restriction and it was dropped.) If you have public or static
- variables, move them outside the method. They are usually put at the
- beginning of the class.
-
- 8. (Sect. 5) Can't access protected method clone in class java.lang.Object
-
- T.java:96: Can't access protected method clone in
- class java.lang.Object. OtherT is not a subclass of
- the current class.
-
- [*] Object.clone() is protected because subclasses might want to
- restrict access to cloning, and if Object.clone() were declared public,
- subclasses could never make it more restrictive. The subclass can make
- access to the clone() operation less restrictive.
- This means that a method can clone its own objects, but a method cannot
- clone objects of another class, unless you do something like:
-
- class SomeObject implements Cloneable {
- public Object clone()
- throws CloneNotSupportedException {
- return super.clone();
- }
- }
-
-
- i.e., override clone() to make it public, and call the superclass
- clone().
-
- class Foo {
- Bar bar;
- Foo (Bar b) {
- try {bar = (Bar) b.clone();}
- catch (Exception e) {}
- }
- ...
- class Bar implements Cloneable {
- public Object clone()
- throws java.lang.CloneNotSupportedException {
- return super.clone();
- }
- }
-
-
- Another refinement is to note that Object.clone() only throws a
- CloneNotSupportedException when the object doesn't implement Cloneable.
- Since you control what your classes do and don't implement, you can
- ensure that Cloneable classes implement the interface, and you don't
- need to make the overridden clone() throw the exception.
-
- public class X implements Cloneable {
- public Object clone() { // no throws
- try {
- // in case members need cloning
- X c = (X)super.clone();
- return c;
- } catch (CloneNotSupportedException e) {
- // should not happen, because of Cloneable
- throw new InternalError();
- }
- }
- }
-
-
- 9. (Sect. 5) Deprecated methods
- What does "deprecated" mean? I got this in a compiler error message.
-
- [*] "Deprecated" means you are using an older API, that Sun has
- replaced with a newer one (usually to follow more consistent naming
- conventions). Deprecated methods are not recommended for use. They are
- supported in the short term, but your code should be updated with the
- new. To update your code, compile your old code using javac's
- "-deprecation" option to list deprecated methods, then find the
- replacement methods in the current HTML API documentation for the old
- deprecated methods.
- As an example of a deprecated API, Component.size() was replaced by
- Component.getSize().
-
- See also
- http://java.sun.com/products/jdk/1.1/docs/guide/
- misc/deprecation/index.html, "1.1 Deprecated Methods"
- and
- http://java.sun.com/products/jdk/1.1/docs/guide/
- awt/DeprecatedMethods.html, "Deprecated methods in the 1.1 AWT"
-
- 10. (Sect. 5) double y = sin(90);
- What's wrong? That code provokes compiler messages.
-
- [*] You need to write it this way:
-
- double cvtDegToRad = Math.PI/180;
- double x = 90*cvtDegToRad;
- double y = Math.sin(x);
-
-
- sin is a static method of the Math class that takes radians. You need
- to use the "Math" classname, e.g. Math.sin instead of plain sin,
- because you have to say what class or object these methods belong to.
-
- A very common mistake is to assume that importing a class means that
- you don't have to qualify the names of its members. When you call a
- method you have to state the name of the class or object it belongs to,
- regardless of any imports you have done. (Except inside the class
- itself, obviously).
-
- The trig functions are static methods of the Math class, so you give
- the name of the class in invoking them. Further, the Math class works
- in radians, not degrees. 360 degrees = 2 pi radians, so use a
- conversion factor as shown if you are working with degrees.
-
- 11. (Sect. 5) Can't make static reference to method...
-
- [*] Your code probably looks something like this:
-
- class myclass {
- public static void main(String args[]) {
- myMethod();
- }
- public void myMethod() { //some code
- }
- }
-
-
- Static (class) methods can only call without qualification other static
- methods, so you either have to qualify the call in (static) main() to
- (nonstatic) myMethod() with an object of type myclass, or you have to
- make myMethod() static.
-
- People often forget that even though main is "in" myclass, there is no
- implicit object when you are in main() because it is static. This
- happens especially when writing code to run an applet as an
- application, where you want to call init() and start() from main.
-
- public static void main(String[] args) {
- Applet ma = new myApplet(); // have to create object
- ma.init(); // use to qualify access to non-static methods
- ma.start();
- }
-
-
- 12. (Sect. 5) Incompatible type for =. Explicit cast needed...
-
- byte b = 0;
- Incompatible type for =.
- Explicit cast needed to convert int to byte.
- b = b + 100; // compiler error message
- b += 100; // works OK
-
-
- [*] Arithmetic expressions are promoted to the type of the longest,
- floatiest operand in them, or at least to int. The first statement
- involves the assignment of an expression. The expression is promoted to
- 32 bits, and must be cast back down to 8 bits, like this: b = (byte)
- (b+100); The second is an operator assignment, and the cast back to
- byte takes place automatically. The Java Language Specification says
- that a compound assignment expression of the form E1 op= E2 is
- equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the
- type of E1, except that E1 is evaluated only once. (See JLS 15.25.2
- Compound Assignment Operators) The compile-time narrowing of constants
- means that code such as:
-
- byte theAnswer = 42;
-
-
- is allowed, with no cast necessary. (See JLS 5.2 Assignment Conversion)
-
- Other sites:
- JLS 5.2 Assignment Conversion
- JLS 15.25.2 Compound Assignment Operators
-
- 13. (Sect. 5) Class {package}.{class} not found in type declaration.
- I am trying to compile file "{class2}.java" in a package, and I get
- this compiler error. {class2}.java refers to {package}.{class}, but the
- file {class}.java and {class2}.java are in the same {package}
- directory, which is the current directory and which is in the CLASSPATH
- variable. Both files have "package {package};" at the top of the file.
- What's the problem?
-
- [*] When the source refers to classes in packages, the CLASSPATH has to
- point to the root of the package/directory hierarchy for a reference to
- resolve correctly. This is true even for source files in the same
- package (and directory). I.e., assuming {class} and {class2} are both
- in {package}, {class} can't make a reference to {class2} unless the
- CLASSPATH is set so javac can find {package}/{class2}.java. It should
- make no difference what directory you are in when you invoke javac,
- unless you are relying on "." in the CLASSPATH to point to the package
- root or are specifying the source file with a relative path (e.g.,
- {package}/{class}.java).
-
- Some examples, assuming
- o - Foo.java and Bar.java are in /java/source/pack/
- o - Both have "package pack;" as the first statement
- o - Foo.java includes "Bar b = new Bar();"
-
- # solaris ksh
- $ alias jc=/java/jdk11/bin/javac
- $ CLASSPATH=/java/source/
- $ jc /java/source/pack/*.java # works fine
- $ cd /java/source/pack
- $ CLASSPATH=.
- $ jc *.java # fails - Foo.java can't find class Bar
- $ cd .. # now . is package root, /java/source/
- $ jc pack/*.java # works
-
-
- 14. (Sect. 5) public class "Foo" must be defined in "Foo.java"
- I get this message even though it is in Foo.java. What gives?
-
- [*] Javac verifies that a public class is defined in a file of the same
- name (e.g., that public class Foo is defined in Foo.java). Two things
- you can check:
-
- First, make sure the case matches exactly. public class Foo cannot be
- in foo.java; it has to be in Foo.java.
-
- Second, are you using MKS on win32? Javac on win32 assumes you are
- using the DOS path separator (\) even though MKS accepts the Unix path
- separator (/). When javac tries to parse a your Unix-style path, it
- won't produce the correct filename, the match will fail, and it will
- emit an error. You have to use the DOS path separator (\), which must
- be escaped in MKS - e.g., "javac H:\\source\\package\\Foo.java".
- Alternatively, you can traverse to each source directory and avoid
- pathnames altogether.
-
- -------------------------------
-
- 6. Java Language Issues
-
- How-to
-
- 1. (Sect 6.) How do I compare two Strings?
-
- if (s1 == s2)
-
- is giving me funny results.
-
- [*] The comparison using "==" on objects, such as Strings, is asking,
- "Do these two objects have the same reference?" Do they have the same
- address, and hence are the same object? What you really want to do is
- ask, "Do these two Strings have the same *contents*?"
- Compare String contents with any of the following:
-
- if (s1.equals(s2) )
- if (s1.equalsIgnoreCase(s2) )
- if (s1.startsWith(s2) )
- if (s1.endsWith(s2) )
- if (s1.regionMatches(s1_offset, s2, s2_offset, length) )
- if (s1.compareTo(s2) < 0)
-
-
- (There are other ways, too.)
- Note that you can do this with literals:
-
- if ("apple".equals(s2) ) ...
-
-
- If you compare these the other way round, like this:
-
- if ( s2.equals("apple") ) ...
-
-
- and s2 is null, you will get a null pointer exception.
-
- 2. (Sect. 6) How do you get the code value of a char?
- I would like to transform a char into the corresponding int value, that
- represents the code value of the char. How?
-
- [*] Like this.
-
- char c = 'A';
- int i = c;
-
-
- Going the other way is just
-
- c = (char) i;
-
-
- This question crops up so frequently because the BASIC language uses
- functions to map characters into ints, ASC( 'A' ) => 65 causing BASIC
- programmers to seek the corresponding Java functions. The same is true
- for Pascal, Ada, and other languages.
-
- 3. (Sect. 6) Why does b >>>= 1 give me the same result as b >>= 1?
-
- [*] ">>" is a "signed" or "arithmetic" shift, namely, it replicates the
- sign bit on the left as it shifts.
- The ">>>" operator is an "unsigned" or "logical" shift; it does a shift
- right and zero fill. However, ">>>" looks like it does a signed shift
- with negative bytes and shorts, where int promotion alters the sign.
-
- This occurs when you have a non-canonical type, byte, or short, with a
- negative value, e.g.
-
- byte b = -15; // 0xf1
- b = (byte) b >>> 4; // why isn't b 0x0f ?
-
-
- The initial expectation is that an unsigned shift right of 0xf1 would
- successively be (in binary)
-
- 0111_1000 then
- 0011_1100 then
- 0001_1110 then
- 0000_1111
-
-
- But that doesn't happen. The rules of arithmetic in Java say that all
- operands are converted at least to int before the operation (and
- possibly to a more capacious type). That means our byte is promoted to
- an int, so instead of shifting 0xf1, we are shifting 0xfffffff1. If you
- shift right unsigned 4 places, you get 0x0fffffff. When you cast that
- to a byte it becomes 0xff, or -1.
-
- The bottom line is that the final result is the same as if you had
- performed the signed shift because the unsigned shift applied to the
- intermediate int, not to the original byte. This anomaly means that
- ">>>" is useless for negative bytes and shorts. It is probably safer
- and clearer not to use it at all, but to mask and shift instead:
-
- // not recommended
- byte b = -15;
- b = (byte) (b>>>4);
- System.out.println("b= "+Integer.toHexString(b) );
- // recommended
- b = -15;
- b = (byte) ( (b & 0xFF) >> 4 );
- System.out.println("b= "+Integer.toHexString(b) );
-
-
- 4. (Sect. 6) Why does the <unexpected> happen in floating point?
-
- [*] There are several unexpected things that seem to bite programmers
- with floating point. This is almost always a result of the programmer
- not being fully conversant with floating point arithmetic in general,
- rather than a problem relating to Java.
-
- The question of floating point accuracy comes up with Java more than
- with C++ (for example) because of Java's decision in the println()
- method to print enough digits to distinguish the number from the
- next-closest number, rather than rounding it to 6 significant digits by
- default as the C/C++ libraries do. [ISO C, Sect 7.9.6.1, line 21 of
- "the double argument"]
-
- If you seem to be having problems with floating point, the problem
- probably stems from the fact that floating-point arithmetic is
- inherently imprecise. You can expect up to 7 digits of precision with
- floats and 16 digits with doubles. However, that does not mean that a
- number that can be exactly represented in 7 digits decimal or can be
- exactly represented as a binary floating point number. On the contrary,
- that is usually not the case.
-
- Additionally, when Java converts floating point numbers to a String, as
- is done when they are output, enough digits are printed so the number
- can be read back in with no loss of precision. For this reason, you may
- see more "inaccuracies" in floating point output than you are used to.
- You are actually getting more accuracy than on systems (like C,C++)
- that suppress the less significant digits.
-
- For more information and detailed specifications on how Java deals with
- floating point, see the URLs listed below.
-
- Other sites:
- What Every Computer Scientist Should Know About Floating Point.
- http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities
-
- JLS 4.2.3 Floating-Point Types and Values
- JLS 4.2.4 Floating-Point Operations
- JLS 3.10.2 Floating-Point Literals
- JLS 5.2.3 Narrowing Primitive Conversions
- http://gams.nist.gov/javanumerics/jgfnwg-01.html
- See also "the guff from Hough" at http://www.validgh.com/java
-
- If you want the rounded floating point output that most languages have,
- use the new java.text package of Java 1.1 to limit the number of digits
- that are output. If you need more precision than about 16 digits, use
- the BigInteger and BigDecimal classes of Java 1.1.
-
- Understanding the Java Language
-
- 5. (Sect. 6) How can I program linked lists if Java doesn't have pointers?
-
- [*] Of all the misconceptions about Java, this is the most egregious.
- Far from not having pointers, in Java, object-oriented programming is
- conducted exclusively with pointers. In other words, objects are only
- ever accessed through pointers, never directly. The pointers are termed
- "references" and they are automatically dereferenced for you.
-
- Java does not have pointer arithmetic or untyped casting. By removing
- the ability for programmers to create and modify pointers in arbitrary
- ways, Java makes memory management more reliable, while still allowing
- dynamic data structures. Also note that Java has NullPointerException,
- not NullReferenceException.
-
- A linked list class in Java might start like this:
-
- public class LinkedList {
- public LinkedList head;
- public LinkedList next;
- public Object data;
- public LinkedList advanceToNext(LinkedList current) { ...
- }
-
-
- Another choice for a linked list structure is to use the built-in class
- java.util.Vector which accepts and stores arbitrary amounts of Object
- data (as a linked list does), and retrieves it by index number on
- demand (as an array does). It grows automatically as needed to
- accommodate more elements. Insertion at the front of a Vector is a slow
- operation compared with insertion in a linked list, but retrieval is
- fast. Which is more important in the application you have?
-
- 6. (Sect. 6) Are parameters in Java passed by value or by reference?
-
- [*] All parameters (values of primitive types and values that are
- references to objects) are passed by value. However this does not tell
- the whole story, since objects are always manipulated through reference
- variables in Java. Thus one can equally say that objects are passed by
- reference (and the reference variable is passed by value). This is a
- consequence of the fact that variables do not take on the values of
- "objects" but values of "references to objects" as described in the
- previous question on linked lists.
-
- Bottom line: The caller's copy of primitive type arguments (int, char,
- etc.) _do not_ change when the corresponding parameter is changed.
- However, the fields of the caller's object _do_ change when the called
- method changes the corresponding fields of the object (reference)
- passed as a parameter.
-
- Also in this FAQ:
- How can I program linked lists if Java doesn't have pointers?
- Other sites:
- JLS 8.4.1 Formal Parameters
-
- 7. (Sect. 6) What are "class literals"?
-
- [*] A feature introduced in JDK 1.1. They are literals of type "Class"
- that hold a value representing any class. There are even values to
- represent "void" and an array, like this:
-
- Class myCl1 = Character.class;
- Class myCl2 = Void.class;
- Class myCl3 = Object.class;
- Class myCl4 = String[].class;
- Class myCl5 = int[][].class;
-
-
- You might use it like this:
-
- Class cl = thing.getClass();
- if (cl.equals(myCl1))
- System.out.println("It's a Character class");
-
-
- Note that a class literal
-
- Component.class
-
-
- is the equivalent of
-
- Class.forName("java.awt.Component")
-
-
- The second can throw an exception, but the first cannot. If you don't
- know the name of the class when you write the code, you cannot use the
- first form.
-
- 8. (Sect. 6) What are the naming conventions in Java?
-
- [*] The naming conventions are straightforward:
- 1. Package names are guaranteed uniqueness by using the Internet
- domain name in reverse order: com.javasoft.jag - the "com" or
- "edu" (etc.) part used to be in upper case, but now lower case is
- the recommendation.
- 2. Class and interface names are descriptive nouns, with the first
- letter of each word capitalized: PolarCoords. Interfaces are often
- (not always) called "something-able", e.g. "Runnable", "Sortable".
- Caution: java.util.Observable is not an interface, though
- java.util.Observer is. These two are poorly designed.
- 3. Object and data (field) names are nouns/noun phrases, with the
- first letter lowercase, and the first letter of subsequent words
- capitalized: currentLimit
- 4. Method names are verbs/verb phrases, with the first letter
- lowercase, and the first letter of subsequent words capitalized:
- calculateCurrentLimit
- 5. Constant (final) names are in caps: UPPER_LIMIT
- 6. Also in the FAQ:
- Where can I find a Java style guide on naming conventions?
- Other sites:
- JLS 6.8 Naming Conventions
-
- 9. (Sect. 6) Should I prefer importing {package}.{class} over {package}.*?
-
- Does it make a difference to the class file in any way, if I import a
- package versus use the full name, i.e.
-
- import java.rmi.server.*;
- ...
- RemoteObject ro;
-
- versus:
-
- java.rmi.server.RemoteObject ro;
-
- [*] No, it makes no difference to the class files or runtime speed.
- Import is just a shorthand for quoting the full name package and class
- name (as in the examples in the question). Importing a class does not
- cause the class to be loaded at run time. There is no runtime penalty
- for using the * form of import. The class file will contain the name of
- the packages it uses, and the loader will look for those classes as
- needed at runtime.
-
- At compile time, the different forms of import may or may not make a
- difference to compile time. Such a difference is likely to be
- negligible, and should not be a factor in which form of import you use.
-
- However, there are style advantages. Some say that stating which
- classes you are importing can help program readability. In a program
- with many * import statements, it may take a programmer time to find
- which package an obscure class is imported from. If you explicitly list
- each class you import at the top of the program, you document which
- package each class you use comes from. These people suggest that you
- use
-
- import java.rmi.server.RemoteObject;
-
-
- in preference to:
-
- import java.rmi.server.*;
-
-
- Other people say that it is clearer still to use the full package and
- class name, at the point where you use classes in other packages.
- These people suggest that you use:
-
- java.rmi.server.RemoteObject ro;
-
-
- But that gets a little lengthy when you instantiate:
-
- java.rmi.server.RemoteObject ro
- = new java.rmi.server.RemoteObject();
-
-
- You always have the option of stating the full package and class name,
- whether you use import or not.
-
- Another good reason not to use the * form is when you are importing two
- packages that have classes of the same name and you want to use only
- one of those classes. E.g.
-
- import com.sun.*;
- import com.ms.*;
-
-
- where there is a class called Modem in both those packages. If you use
- the * form of import, you import both of the Modem classes and then
- must fully qualify the class each time you use it, to say which of the
- two you mean. In Java 1.2, the class java.util.List was introduced.
- That had the same unqualified name as java.awt.List. If your code had
- "import java.awt.*; import java.util.*;" it would no longer compile.
- You'd get a message about ambiguous classname. If you import all of a
- package indiscriminately you might get bitten when the package API
- changes.
-
- In Java 1.0, if you import a class that has the same name as a class
- defined in that source file, you will get an error that the class names
- clash. In Java 1.1, the local class will be used when the package name
- is not given; to use the imported class, you have to use the full
- package name.
-
- The best advice is to write the program so that it is as readable as
- possible. Where you have a group of well-known classes, as in java.awt,
- there is no reason not to use "import java.awt.*;"
-
- 10. (Sect. 6) How can I use Math.cos() etc. without the prefix "Math."?
- Is there some declaration that I can use to make "acos", "cos", "sin",
- etc. (from java.lang.Math) recognizable in my own class, so I don't
- have to prefix "Math." to them?
-
- [*] No. There is no good alternative. There are several bad
- alternatives:
- 1. Using "import" doesn't work.
- The import stament only imports packages, subpackages, and
- classes, not class members. This doesn't work:
-
- import java.lang.Math.*;
-
-
- 2. Minimizing class name usage is unclear and bad style.
- - You could wrap the functions in your own class.
-
- double sin(double x) {
- return Math.sin(x);
- } // etc. for each function
-
-
- But you'd have to use your class name everywhere but inside your
- class, so it doesn't help.
- - You can make a null reference to the Math class and use it to
- refer to the static methods. Declare
-
- java.lang.Math M = null;
- angle = M.cos(i);
-
-
- Besides not being clear, this invites abuse and errors.
-
- - You could inherit the names
- If java.lang.Math were not final and your class did not extend
- another class, you could have your class extend Math, to bring the
- namespace in. However, it is poor OOP style to use inheritance to
- obtain a name abbreviation rather than to express a type
- hierarchy.
-
- 11. (Sect. 6) Why is there a standard JNI?
-
- [*] JNI is the Java Native Interface. It defines the way that a Java
- program can call C programs. The industry has agreed on, and Sun has
- codified, JNI as the standard. Microsoft shuns the standard and uses a
- protocol of its own called Raw Native Interface, RNI.
-
- You might think that once a Java program uses JNI, portability is lost,
- and hence it doesn't matter if vendors diverge from the JNI standard.
- Not so. Code that accesses a native library using JNI can run on any VM
- that supports JNI, so it's portable across VMs on the same platform.
- Further, you can port a native library to all platforms Java supports
- (indeed, this is how Sun implements the Java Platform), so JNI
- _enables_ cross-platform development where it's necessary to use
- platform-specific idioms for certain functionality.
-
- Conversely, code that uses RNI can only run on Microsoft's VMs on the
- win32 platform. Microsoft's RNI has the effect of limiting RNI programs
- to the Microsoft VM. Further, Microsoft's failure to support JNI locks
- out JNI-based functionality on Windows. Microsoft's non-standard RNI is
- the reason that programs using the Microsoft JVM cannot use the
- standard Java jdbc-odbc library. That library has a piece written in C.
- It works for all JVMs except Microsoft's.
-
- The standard JNI thus has two purposes:
- 1. Source code compatibility between different platforms.
- 2. Binary code compatibility between different JVMs on the same
- platform.
- Microsoft's use of RNI locks in programmers who use it, and Microsoft's
- failure to support JNI locks out programmers who don't use RNI. Users
- can't run standard JNI applications on Microsoft VMs, or RNI
- applications on non-Microsoft VM's. As a result, since most users will
- support only one VM, they'll be locked in to complementary software -
- in the case of Microsoft, a proprietary standard. A standard JNI means
- that you can use any standard JVM to run your code on this platform.
-
- 12. (Sect. 6) How do I find out more about JNI? How do I find out more
- about Java Anything?
-
- [*] Taking the questions one at a time. Use of JNI detracts from
- program portability. So you would only do it when you need some
- critical single-platform effect. The documentation on JNI is at:
- http://java.sun.com/docs/books/tutorial/native1.1/index.html
-
- If your interest extends to reading a book on JNI, a good one is
- "Essential JNI Java Native Interface" by Rob Gordon; ISBN
- 0-13-679895-0. See
- http://www.amazon.com/exec/obidos/ASIN/0136798950/afuinc
-
- In general, if you want to find out about topic "X" in Java, your first
- stop should be to search the http://java.sun.com website for "X". For
- example if you want to know about Internationalization in Java, a
- search at the site quickly takes you to
- http://java.sun.com/products/jdk/1.1/docs/guide/intl/intlTOC.doc.html.
-
- 13. (Sect. 6) How do I get unsigned ints in Java?
-
- [*] Java doesn't have unsigned ints. The reason is that this is a
- poorly designed area of C. The rules for what type you end up with when
- you mix signed and unsigned in expressions are complicated, and they
- changed between K&R and ANSI C (you might have heard this under the
- name "unsigned preserving vs. value preserving"). Worse, they depended
- on the underlying hardware, so they varied from platform to platform,
- causing bugs in all kinds of unexpected places. The book "Expert C
- Programming" goes into this in more depth (page 25). So, to avoid
- bringing over the hidden complexities, Java does not bring over
- unsigned types from C.
-
- Use type char if you are OK with 16-bit unsigned quantities. Otherwise,
- go to the next larger type and use masking. If you don't have to worry
- about division by numbers with the high bit set, then when you use >>>
- for right shift and remember to AND each byte with 0xFF where they are
- being expanded into a larger type, then there is no difference in the
- bit patterns generated.
-
- Specifically, to convert an int to its unsigned representation, use:
-
- ((long)i) & 0x00000000FFFFFFFFL
-
-
- This promotes the signed (and possibly negative) int to long (with sign
- extension) then chops off the sign-extension, leaving it as the same
- 32-bit quantity held in a 64-bit type.
- Also worth noting is that if you're going to work with unsigned bytes,
- int is a more efficient larger type to use than short or char, since
- smaller values have to be promoted to int to do any arithmetic or
- testing on them.
-
- 14. (Sect. 6) What happened to "private protected"?
-
- [*] It first appeared in JDK 1.0 FCS (it had not been in the betas).
- Then it was removed in JDK 1.0.1. It was an ugly hack syntax-wise, and
- it didn't fit consistently with the other access modifiers. It never
- worked properly: in the versions of the JDK before it was removed,
- calls to private protected methods were not dynamically bound, as they
- should have been. It added very little capability to the language. It's
- always a bad idea to reuse existing keywords with a different meaning.
- Using two of them together only compounds the sin.
-
- The official story is that it was a bug. That's not the full story.
- Private protected was put in because it was championed by a strong
- advocate. It was pulled out when he was overruled by popular
- acclamation.
-
- Inheritance
-
- 15. What are the differences between an interface and an abstract class?
-
- [*] Some use a semantic distinction: an abstract superclass models the
- "is" relationship, while an interface models the "has" relationship.
- The rule would be, if it's a subtype, inherit; otherwise, implement.
-
- But, in the absence of real-world characteristics to distinguish the
- objects from their properties and parents, that becomes a circular
- argument. In this case, you have to look at the practical differences
- in Java (compared with C++).
-
- Most differences between interfaces and abstract classes stem from
- three characteristics:
- 1. Both define method signatures that a derived class will have.
- 2. An abstract class can also define a partial implementation.
- 3. A class can implement many interfaces, but inherit from only one
- class.
-
- In greater detail, these topics are:
- 1. Method signatures Both interfaces and abstract classes permit one
- to treat the derived-type class as the derived-from-type class.
- Both define a set of available methods in a way that can be
- enforced by the type-checking mechanism. This is typically used to
- permit different (derived) types to behave in the same way (as
- what they are derived from - i.e., they all support particular
- methods). For example, all java.* types can be printed as Strings
- because Object, the superclass of all java.* types, has a
- toString() method. Similarly, all types that implement the
- Observable interface can be passed an Observer to signal when an
- event has occurred. This permits an algorithm or service to
- operate on different (derived) types as if they were the same
- (derived-from) type.
- This mechanism supports not only polymorphism (one object treated
- as another), but differentiation. In either case, the (derived)
- types can implement the method in the way appropriate to that
- type. However, you're not likely to override inherited
- functionality, but you must implement interface methods, so if you
- expect significant differentiation, then an interface might be
- warranted.
- Finally, this mechanism supports a weak variant of access control.
- Only inherited methods are available to callers who only have a
- reference to the superclass or interface type. It's weak because
- they can attempt a narrowing cast if they know their target type.
- Nonetheless, it reduces some complexity.
- 2. Inheriting implementation Inheriting an implementation is useful
- where the code should be shared. This happens where derived types
- vary the functionality only a little bit, or where a complex set
- of method interfaces can through mutual reference be implemented
- with relatively few methods that can be implemented by derived
- types. You can also reuse code by having your class use or keep an
- object of another type that implements that code, but that doesn't
- permit your callers to treat you in a particular way. To both
- "get" functionality and to be treated "as" the superclass are the
- essentials of the type/subtype relationship.
- 3. Java's rule of single inheritance Java differs from C++ in
- permitting only single inheritance. This makes for some difficult
- choices, if you would like to share combinations of inherited
- functionality and polymorphism from more than one source. However,
- it does reinforce the notion of inheritance as a subtyping (is)
- relationship, and implicitly that type relationships form a tree
- rather than a network.
-
- Other differences to consider:
- 1. Abstract class implementations may include fields
- 2. Interfaces may include final data members
- 3. It is slightly slower to call an implemented method via an
- interface reference. There is an even smaller penalty for calling
- a superclass method via a subclass reference (i.e., where the
- subclass does not override the method). There is almost no penalty
- for calling a subclass method via a superclass reference. (All are
- compared to a direct method call, i.e., calling the derived class
- method via a derived class reference).
-
- 16. (Sect. 6) How do static methods interact with inheritance?
-
- [*] Static (per-class, rather than per-object) methods do not
- participate in overriding (choosing the right method at runtime based
- on the class of the object). Probably the best and simplest way to
- think about this (and to write your code) is to write every invocation
- of a static method using the fully qualified class name:
-
- class A {
- public static method1() {
- A.method2();
- }
- public static method2() {
- }
- }
-
- class B extends A {
- public static method3() {
- A.method1();
- }
- public static method2() {
- }
- }
-
-
- Now it is perfectly clear that the static method2() that is called is
- A.method2(), not B.method2(). A.method2() will be called regardless of
- whether you use the fully-qualified class name or not, but using "A."
- makes it obvious to all.
-
- 17. (Sect. 6) Why is the String class final? I often want to override it.
-
- [*] Being final guarantees that instances of String are read-only. (The
- String class implements read-only objects, but if it were not final it
- would be possible to write a subclass of String which permitted
- instances to be changed.) Strings need to be read-only for security and
- efficiency.
-
- As for efficiency, Strings are very commonly used, even behind the
- scenes by the Java compiler. Efficiency gains in the String class yield
- big dividends. If no one can change a String, then you never have to
- worry about who else has a reference to your String. It's easier to
- optimize accesses to an object that is known to be unchanging.
-
- Security is a more compelling reason. Before String was changed to be
- final (while Java 1.0 was still in beta) there was a race condition
- which could be used to subvert security restrictions. It had to do with
- one thread changing a pathname to a file after another thread had
- checked that the access was permitted and was about to open it.
-
- There are other ways to solve these problems, but the designers
- preferred making String final, particularly since the StringBuffer
- class is available as an alternative.
-
- 18. (Sect. 6) If I extend/subclass a class, are the constructors inherited?
-
- [*] "Constructor declarations are not members. They are never inherited
- and therefore are not subject to hiding or overriding." The default
- constructor is not inherited, but provided. (See JLS 8.6.7 Default
- Constructors)
-
- If you don't give your child class any constructors, a default no-arg
- constructor that invokes the superclass' constructor is provided for
- you. If the superclass doesn't have a no-arg constructor, you should
- create a constructor and call the appropriate superclass constructor.
-
- Also in the FAQ:
- Compiler message No constructor {superclass}()
-
- Other sites:
- JLS 8.6.7 Default Constructors
-
- 19. (Sect. 6) How can I safely store particular types in general
- containers?
- I often want to store particular types of objects but don't want to
- subclass my basic storage classes to enforce the particular type; that
- would make for too many subclasses (e.g., IntegerLinkedList,
- StringLinkedList, etc.).
-
- [*] Generic programming in java (the rough equivalent of C++'s
- templates) works reasonably well since all java classes are subclasses
- of Object. There is, however one potential problem - there is always a
- possibility that a generic container may contain different classes of
- objects.
-
- This naturally leads to the question of how to do this in a type-safe
- way. If you've created a generic LinkedList class, how can you be type
- safe without having to create a multitude of subclasses
- (IntegerLinkedList, StringLinkedList, etc.)?
-
- One way to handle this would be to offer up an additional constructor
- in your generic class that takes a parameter of type "Class" and uses
- that parameter along with Class's "isInstance" method to guarantee that
- Objects added to the container are the expected type.
-
- public class LinkedList {
- Protected Class type = Object.class;
-
- public LinkedList(Class type) { this.type = type; }
-
- public void addElement(Object element) throws Exception
- {
- if(!type.isInstance( element ))
- throw new Exception(
- "Expected element of type (" + type + ")" +
- " got element of type (" + element + ")" );
- ...
- }
- }
-
-
- Note that the comments in the source for isInstance() refer to a
- "specified Class parameter", suggesting that you are supposed to write
- something like:
-
- public void addElement(Object element) throws Exception
- {
- Class c = element.getClass();
- if(!type.isInstance(c))
-
-
- This works, but the documentation for isInstance is clear that the
- parameter should be an Object rather than a Class. Also, note that
- "Collections" are coming in JDK 1.2, and they provide a much safer and
- more extensible mechanism. More information about this is available at
- the Java Developer Connection at the Java website: http://java.sun.com/
-
- Method interfaces
-
- 20. How do I send a variable number of arguments to a method?
-
- [*]
- 1. (Easy) Use method overloading to support different parameters.
- This makes things easy on the caller but can get out of hand if
- you want to support a wide number and variety of parameter types.
- You should ask yourself if your code design is well-organized if
- you need to do this.
- 2. (More complicated) Use arrays. It's even possible to declare
- arrays inline as shown below:
-
- foo("A param",
- new Object[] {"param3", "param4", new Integer(5)} );
- // ...
-
- void foo(String param1, Object param2[]) {
- System.out.println(param1);
- for (int i = 0; i < param2.length; i++) {
- System.out.println(param2[i].toString());
- }
- }
-
-
- You can even pass arrays of arrays using this method. Of course,
- inside the method you need to be able to decode what the arguments
- are and how you use them.
- 3. Alternatively you can invent a class that just contains all the
- possible fields you might want to pass into a method (plus
- booleans to say if each field is set or not), and make an object
- of that class be a parameter to the method. You can return
- multiple values from a method the same ways; either have the
- method return an array or a wrapper object.
-
- However, remember the wise words of Professor Alan Perlis, "if your
- procedure has more than about half a dozen parameters, you probably
- forgot a few." Passing large numbers of arguments into a function
- suggests your function is badly organized.
-
- 21. (Sect. 6) How can I return a different object in a method parameter?
- How can I pass an object to a method, and have the method change the
- reference so it points to a different object back in the calling code?
-
- indirection". Wrap the object in another class, whose purpose is simply
- to be passed as a parameter, allowing the nested object reference to be
- modified.
- The second alternative is a clearer variant of this. Pass in a single
- element array. Since arrays are objects, this works.
-
- void jfoo(Object ref[]){
- ref[0] = new Object();
- }
- ...
- Object kludge[] = new Object[1];
- kludge[0]= myObj;
- jfoo(kludge);
- if (kludge[0] == myObj) ...
- else ...
-
-
- Note that changing a global variable/object inside a method is an
- egregious programming practice; it usually violates basic OOP
- constructs.
-
- 22. (Sect. 6) How do I get multiple return values back from a method?
-
- [*] You can just have the function return a Vector. This is
- particularly convenient when you're not sure how much you are going to
- be returning, based on what occurs in the method. A Vector is
- essentially a dynamically-growable array. Regular arrays can't grow
- after you declare them - you have to declare a bigger array and move
- the old stuff into it.
-
- Arrays
-
- 23. (Sect. 6) How do I allocate a multidimensional array?
-
- [*] There are several ways. If you want a rectangular array, you can
- allocate the space for the array all at once. The following creates a
- 4x5 array:
-
- int arr[][] = new int[4][5];
-
-
- If you want each row to have a different number of columns, you can use
- the fact that a two-dimensional array is actually an array of arrays.
- The following code allocates a triangular array:
-
- int arr[][] = new int[4][]; // allocate the four row arrays
- for (int i = 0; i < 4; i++) // initialize each of the four rows
- arr[i] = new int[i + 1]; // row i has i + 1 columns
-
-
- Note that if you allocate an array of any kind of object (as opposed to
- primitive type), all the references will be null by default. These null
- references can result in NullPointerExceptions if you try to
- dereference them.
- In other words, after doing:
-
- int arr[] = new int[4];
-
-
- you can say
-
- if (arr[2] == 0)
-
-
- But after doing
-
- Integer Iarr[] = new Integer[4];
-
-
- you must fill in the object reference before using it. E.g.,
-
- Iarr[2] = myInt;
-
-
- or
-
- arr[2] = new Int(27);
-
-
- before you can say
-
- if (Iarr[2].equals(myInt))
-
-
- 24. (Sect. 6) How do I copy an array?
-
- [*] If the array only contains primitive types or if you want to copy
- only the object references, not duplicate the objects, then use the
- method
-
- java.lang.System.arraycopy(Object src, int src_position,
- Object dst, int dst_position, int length);
-
-
- Otherwise, if you want to duplicate the objects, you have to initialize
- your new array and write a loop that duplicates each object in the old
- array into the new.
-
- Note that the documentation for arraycopy() says that if src and dst
- refer to the same object, then arraycopy behaves as if the source array
- elements are copied into a temporary array (i.e., they are preserved).
- Some interpret this as meaning a temporary array will be so allocated,
- but that's not Sun's implementation.
-
- Other sites:
- JLS 20.18.16 {java.lang.System.arraycopy()}
-
- 25. (Sect. 6) How do I clear an array?
-
- [*] There is no method to clear an array to 0.0, 0, null, false,
- '\u0000' etc. When you allocate an array, the elements are set to their
- default values, but that doesn't help when you want to reuse an array.
-
- If you want to set the same array to the same set of values many times,
- create a template array. Fill it with the reset value, then use
- System.arraycopy() to copy it into the work array each time you need to
- set the work array.
-
- 26. (Sect. 6) What is a fast way to set all elements of an array?
- I don't want to use a template array. I would like to set all array
- elements to a given value without duplicating the (possibly large)
- array.
-
- [*] Using a loop that does it one by one is probably 20 to 40 times
- slower than good old memset() in C.
-
- A fast way on many VM's is to set the first byte of the array, then use
- System.arraycopy() repeatedly to fill the next byte, the next two
- bytes, the next four bytes, the next eight bytes, etc., and when you
- get past halfway, fill in the rest.
-
- public static void bytefill(byte[] array, byte value) {
- int len = array.length;
- if (len > 0)
- array[0] = value;
- for (int i = 1; i < len; i += i)
- System.arraycopy( array, 0, array, i,
- ((len - i) < i) ? (len - i) : i);
- }
-
-
- This is faster on Sun's VM than a simple loop, and probably even faster
- under JITs because it only performs at most log2(array.length) bounds
- checks. This is a clever code idiom applying the binary chop algorithm
- to arrays even when their size is not a power of 2.
-
- -------------------------------
-
- 7. I/O
-
- 1. (Sect. 7) How do I read a file containing ASCII numbers?
-
- [*] There are several ways to do this. Here is one way. Let's assume
- your file is called "C:\work\mydata.txt" and it contains lines like:
-
- 135 7512 3659814 328 1 54829
- 68522 19982810 38
-
- i.e. lines contain several ASCII strings that are numbers separated by
- spaces.
- The code fragment is as follows:
-
- // Open the file with
- RandomAccessFile f = new RandomAccessFile("c:\\work\\datafile.txt", "r");
-
- // read an entire line from it
- String s= f.readLine();
-
- // get some methods to break up a line into tokens
- StringTokenizer st = new StringTokenizer(s);
-
- // extract the next int from the line
- i = Integer.parseInt(st.nextToken());
-
- We use a RandomAccessFile because that supports the readLine() method
- directly. An alternative would be to instantiate a FileReader, and wrap
- a BufferedReader around it. Putting it all together, including the
- exception handling in the event the file is missing, the code looks
- like:
-
- import java.io.*;
- import java.util.*;
- public class c {
- public static void main(String args[]) {
- try {
- RandomAccessFile f = new RandomAccessFile
- ("datafile.txt", "r");
- String s;
- while ( (s=f.readLine()) != null ) {
- System.out.println("read: "+s);
-
- StringTokenizer st = new StringTokenizer(s);
- int i=0;
- while (st.hasMoreTokens()) {
- i = Integer.parseInt(st.nextToken());
- // i now holds the next int on the line
- // could also use Double.parseDouble(), etc.
-
- System.out.print(" "+ i);
- }
- System.out.println();
- }
-
- } catch (Exception e) {System.out.println("Excpn: "+e); }
- // file I/O, from book "Just Java" by Peter van der Linden
- }
- }
-
- See also the next question on how to read data interactively.
-
- 2. (Sect. 7) How do I read a String/int/boolean/etc from the keyboard?
-
- [*] The easiest way is to pick up the source for the 100% pure Java
- class EasyIn from http://www.afu.com/ (same place as this FAQ). Compile
- it with your code and use it like this:
-
- EasyIn easy = new EasyIn();
-
- int i = easy.readInt(); // gets an int from System.in
- boolean b = easy.readBoolean(); // gets a boolean from System.in
- double d = easy.readDouble(); // gets a double from System.in
-
-
- ... etc.
-
- EasyIn is free, comes with source, and you can do what you like with
- it, including improve it, and send me back the results.
-
- If, instead, you want to "roll your own" code (why?!), in JDK 1.0.2
-
- java.io.DataInputStream in = new java.io.DataInputStream(System.in);
- String s = in.readLine();
-
-
- One way in JDK 1.1:
-
- java.io.BufferedReader in =
- new java.io.BufferedReader( new InputStreamReader(System.in));
-
- String s = in.readLine();
-
-
- Once you have the token in a String, it is easy to parse it into one of
- the other types, as shown earlier in the FAQ. Yes, it is bone-headed,
- as it makes the simplest case of keyboard I/O unnecessarily
- complicated. A bug was filed with Javasoft to record this problem, but
- don't count on this being fixed any time soon.
-
- 3. (Sect. 7) Why do I have trouble with System.out.println()?
-
- [*] Check the spelling. The last two characters are the letters "ell
- enn" not "one enn".
-
- The name of the method stands for "print line", since it prints a
- String and goes to the next line, rather than staying on the same line
- as System.out.print() does. Yes, the name is yet another Java naming
- inconsistency, since the input equivalent is readLine(), not readln().
-
- 4. (Sect. 7) How do I write to the serial port on my PC using Java?
-
- [*] There is a platform-independent serial port API introduced in JDK
- 1.2. You can download the documentation by registering with the Java
- Developer Connection (it's free, http://java.sun.com) and browsing
- http://java.sun.com/jdc/earlyAccess/communications.html.
-
- For systems prior to JDK 1.2, read on. At least two companies have
- written a library to drive the port. See
- o http://www.sc-systems.com has a library for Windows 95, WindowsNT,
- OS/2, Macintosh PPC, Solaris Sparc, Linux x86, FreeBSD x86, HP/UX
- PA-RISC, and possibly others too.
- o http://www.cd.com/portio
- o In addition, there is a Unix serial port utility available with
- source at http://jarvi.ezlink.com/rxtx/ It's free under the GPL,
- and works on Linux, Irix, Solaris, Windows 95, and NT.
-
- While not helpful to typical home users, there is an alternative
- portable COM port solution for Java 1.1 and even 1.0. Buy your COM
- ports in the form of "terminal servers". Using a COM port is now as
- easy as connecting to it with a Socket. Port parameters can be changed
- programatically using SNMP for most terminal servers (but this is never
- necessary when a modern modem or other fixed-rate equipment is
- attached). Any networked box can serve as a terminal server - even
- Win95 - with a simple native server application for that box, but
- buying an actual firmware based hardware box is much easier.
-
- Furthermore, your Win95 native applications can now share the COM ports
- (and any attached modems) via a Win95 product called "Dial-out IP" at
- http://www.tactical-sw.com/.
-
- If the port exists as a pathname in the filesystem, you can open it as
- a file and read/write. You can also print text this way by writing to
- "prn" or "lpt1" on a pc, and "/dev/something" on Unix. Writing a
- formfeed at the end of the file is essential on Windows 95. Here is
- some sample code:
-
- // class that opens the printer as a file
- // and writes "Hello World" to it
-
- import java.io.*;
- public class lpt {
- public static void main (String[] argv) {
- try {
- FileOutputStream os = new FileOutputStream("LPT1");
- //wrap stream in "friendly" PrintStream
- PrintStream ps = new PrintStream(os);
-
- //print text here
- ps.println("Hello world!");
-
- //form feed -- this is important
- //Without the form feed, the text will simply sit
- // in print buffer until something else gets printed.
- ps.print("\f");
- //flush buffer and close
- ps.close();
- } catch (Exception e) {
- System.out.println("Exception occurred: " + e);
- }
- }
- }
-
-
- If you wish to change the characteristics of the port (e.g. baud rate,
- parity, etc.), not just read/write data, Java currently offers no
- portable way to do this. You will need to use one of the packages
- mentioned above or some native code or a system command.
-
- 5. (Sect. 7) How do I append to a file?
-
- [*] There are two ways. JDK 1.1 introduced new constructors for two of
- the output classes that allowed you to set a boolean flag:
-
- public FileWriter(String fileName, boolean append) throws IOException
- public FileOutputStream(String name, boolean append) throws IOException
-
-
- Another way is to do this:
-
- RandomAccessFile fd = new RandomAccessFile(file,"rw");
- fd.seek(fd.length());
-
-
- Then write using fd. Note that the latter method does not take
- advantage of the "append" mode present in many operating systems (such
- as all Unixes). Such a difference may make a difference with multiple
- processes or threads appending to the same output file. This can happen
- frequently, even if not intended by the programmer, e.g. with logfiles
- in multitasking environments.
-
- 6. (Sect. 7) Is it possible to lock a file using Java ?
-
- [*] JDK 1.2 introduces the ability to lock a file (indirectly) using
- the File class. Use createTempFile() with delete on exit. Prior
- releases of Java do not feature an API to lock a file or regions within
- a file. Code that needs to do this must take one of four approaches:
- 1. Implement an advisory locking scheme using features that Java does
- have (synchronized methods). This allows you to lock files against
- use by other Java code running in the same JVM.
-
- 2. Use the atomic operation File.createNewFile(), and mark it as
- deleteOnExit(). Have all processes (Java and non-Java) follow the
- same protocol: if the create operation succeeded, you have the
- lock. To give up the lock, you either delete the file or exit the
- JVM.
-
- Note that this may fail if the file is remotely mounted using NFS
- version 2. (There's a window of opportunity bewteen the LOOKUP to
- see if it's already there, and the CREATE if it's not). However,
- NFS version 3 does guarantee exclusive create of remotely mounted
- files, and is not subject to this race condition failure.
-
- 3. Make calls to native code to issue the locking ioctls. This
- approach is not portable, but gives you a shot at having your
- locks respected by legacy code in non-Java programs using standard
- locking ioctls.
-
- 4. Push the work to a central server. Since socket connection
- requests arrive in a single queue on the server, this can be used
- to serialize lock requests. There might be some merit in copying
- the NFS lockd protocol for a general approach. Rolling your own
- simple version for a specific application is pretty easy. A
- database would be better off locking records or fields, not byte
- offsets. In theory, the server socket approach would make it
- easier to perform automatic cleanup of a lock on abrupt VM process
- failure, e.g. by asking "are you still alive?" to the lock holder
- occasionally.
-
- 7. (Sect. 7) How do I make the keyboard beep in Java?
-
- [*] In JDK 1.1, java.awt.Toolkit has the method beep(). The pre-1.1
- alternative of
-
- System.out.print("\07");
- System.out.flush();
-
- (the ASCII BEL character) doesn't work on Macs, but does on some other
- platforms. Java doesn't support the C abstraction of '\a' for an alert
- character.
-
- 8. (Sect. 7) How do you do file I/O from an applet?
-
- [*] For security reasons, untrusted applets accessed across the network
- are restricted from doing certain operations, including I/O. This
- prevents rogue applets from sending out your private data, or deleting
- it. A trusted (signed) applet can perform these operations (JDK 1.1
- on).
-
- The simplest approach for server-side I/O is to use the Linlyn class
- available from http://www.afu.com. This is free software under the GNU
- license, and uses FTP to move files between an applet and the server.
- It is suitable for low-volume non-critical use like keeping a
- high-score file. The Linlyn class has a very simple application
- programmer interface.
-
- o The following suggestion is for server-side input.
-
- You can read a file on the server if you can create a URL
- referencing the file. Then open a stream, then use any of the
- stream-based methods to read.
-
- This allows reading but not writing. It requires an http daemon
- running on the server, which will usually be the case.
-
- try{
- URL url = new URL("http://somewhere.com/test.txt");
- // or URL url = new URL( getDocumentBase(), filename);
- BufferedReader in = new BufferedReader(
- new InputStreamReader(
- url.openStream() ) );
- String s = in.readLine(); //read till you get a null line.
- } catch(MalformedURLException e){
- System.out.println("URLException:"+e);
- } catch(IOException e){
- System.out.println("IOException:"+e);
- }
- }
-
-
- You cannot write a file on the server this way.
- o The following suggestions are for server-side output.
-
- It absolutely requires the cooperation of the server to allow an
- applet to write a file to the server. This cooperation may take
- any of several forms:
- + FTP server
- + File server (webnfs or custom written)
- + Listening on a socket for data from applets
- + CGI script
- + Java RMI (remote method invocation)
- + JDBC process
-
- In particular:
- + FTP code. Use the Linlyn class mentioned above.
- + WebNFS. This is an evolution of the NFS (Network File System)
- to make file resources visible in browsers. More information
- at http://www.sun.com/webnfs
- + Open a socket back to the server and read/write the data.
- Have a process on the server that listens for socket
- connections from applets and does the requisite I/O. This
- does I/O on the server.
- + Or use a CGI script or servlet on the server to write when
- browsed.
-
- o The following suggestions are for client-side I/O. Use a trusted
- applet (see section on security). This will permit local I/O
- without any of the restraints mentioned above. In this regard, the
- appletviewer and many other browsers regard applets loaded from a
- local filesystem (rather than across the net) as being more
- trustworthy, and perhaps even allowed to do I/O.
- o The simplest form of output is probably for the applet to connect
- to the mailserver port on the server, and prompt the user to enter
- his email address. Then email him the data to save locally if he
- wishes. If a small amount of data he can later enter it by
- cut-and-paste into the applet when he next invokes it.
- o Or use a browser that has a security policy that is configured to
- allow file I/O (such as Sun's appletviewer).
- o Read this article
- http://www.javareport.com/html/features/archive/9802/somers.shtml
- for an introduction to the basics.
-
- 9. (Sect. 7) What are Resources files and how do they work?
-
- [*] In Java 1.1 and above, a resource file is a file that your code
- should be able to access no matter where it was loaded from: the local
- file system, via http, or some other means. This is a different concept
- than system resources. See question (TBD) for more information about
- system resources. (Volunteer sought to write answer on system resource
- files).
-
- There are two ways to specify resources.
- o using an absolute path name, such as
- "/myPackage/resourcedir/myResource.txt"
- With an absolute path name, the resource file is actually relative
- to the classpath.
- o using a relative path such as "dir/myResource.txt".
- If you specify a relative path, then the file is found relative to
- where the class loader found the package of the Class that is
- loading the resource. The consequence of this is that relative
- resource files can only be in the same directory as your class
- file or in a directory below.
- If you want to access resources from an unsigned applet, use relative
- resources.
-
- There are a couple of methods to get at resources, including methods in
- the java.lang.Class and java.lang.Classloader. It uses the class loader
- because that code knew where to find the class on the filesystem. If
- the resource file is nearby, it can be found the same way. One simple
- method to get a stream for a resource for a particular class, say
- Mypackage.MyClass, is as follows:
-
- String relativePath = "resourceDir/somefile.txt";
- String absolutePath = "/somePackage/somefile.txt";
- InputStream in=Mypackage.MyClass.class.getResourceAsStream(relativePath);
-
- If the class cannot be loaded, "in" would be assigned a null value.
- Otherwise, you can use the inputStream just as any other.
-
- A brief note about the syntax used above. In java 1.1 and above, a
- java.lang.Class object for a particular class can be acquired by
- appending .class to the class's name. Though it looks like every object
- has a static member variable, this is not actually the case.
-
- When using resources with Netscape, be aware of the Netscape
- restrictions that:
- o Netscape does not implement the getResource() methods in
- java.lang.Class and java.lang.ClassLoader, but only
- getResourceAsStream() methods.
- o All resources must be in a Jar/archive file
- o Resource files must have a Netscape-approved extension, or you
- must call certain functions before hand. See the following for
- details:
- http://developer.netscape.com/docs/technote/java/getresource/getresource.html
- Internet Explorer does not seem to have these restrictions.
-
- One final "gotcha" is that jpgStream.available() (wrongly) returns 1
- when .gif files in the .jar file are compressed! Some people now create
- a .jar file in two steps, essentially:
-
- jar cvf x.jar *.class
- jar uf0 x.jar *.gif
-
- This ensures .gifs are not compressed, and hence that available()
- doesn't lie to you. David Alex Lamb stumbled onto this after wondering
- why his .gif files looked bad, then realized that compression of a .gif
- might throw away detail. The conjecture is that available() returns 1
- because it has to block to do uncompression.
-
- 10. (Sect. 7) How do I execute a command from Java? How do I do I/O
- redirection in Java using exec()?
-
- [*] See the answer to Question 18.7.
-
- 11. (Sect. 7) I used a C program to write a binary file. When I instantiate
- a DataInputStream on the file in Java, and try to readInt, I do not get
- the correct numbers. Why is this?
-
- [*] Java does everything in network byte order (big-endian order), as
- do many computers including Motorola, and SPARC. The Intel x86 uses
- little-endian order in which the 4 bytes of an int are stored least
- significant first. Rearranging the bytes on the way in will get you the
- results you need. This is only necessary when the file was written by a
- non-Java program on a little-endian machine such as a PC.
-
- The following code will byte-swap little-endian integers into network
- standard order:
-
- public int swap(int i) {
- int byte0 = i & 0xff;
- int byte1 = (i>>8) & 0xff;
- int byte2 = (i>>16) & 0xff;
- int byte3 = (i>>24) & 0xff;
- // swap the byte order
- return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
- }
-
-
- Alternatively, the following code assembles bytes from a byte array
- that is in big-endian order (as used by Java) into an int:
-
- byte[] bytes = ... // whatever
- int start_index = ... // wherever
-
- int value = 0;
- for ( int i = start_index; i < start_index+4; ++i ) {
- value = ( value << 8 ) | ( bytes[i] & 0xFF );
- }
-
-
- If the bytes are in little-endian order, just change the "for"
-
- for ( int i = start_index+3; i >= start_index; --i )
-
-
- And this code will assemble a double that has been written in reverse
- byte order:
-
- byte[] gnol = new byte[8];
- stream.read(gnol);
-
- long l = (
- ( (gnol[7] & 0xff) << 56) |
- ( (gnol[6] & 0xff) << 48) |
- ( (gnol[5] & 0xff) << 40) |
- ( (gnol[4] & 0xff) << 32) |
- ( (gnol[3] & 0xff) << 24) |
- ( (gnol[2] & 0xff) << 16) |
- ( (gnol[1] & 0xff) << 8) |
- (gnol[0] & 0xff)
- );
-
- double d = Double.longBitsToDouble(l);
-
-
- 12. (Sect. 7) How do I make I/O faster? My file copy program is slow.
-
- [*] This is the purpose of BufferedInputStream. It is a flaw in Java
- that buffered I/O is not the default, with a flag or different
- constructor to turn it off. I/O is the second worst designed package in
- Java, after the Date class. ,
-
- 13. (Sect. 7) How do I do formatted I/O of floating point numbers?
-
- [*] Use the class java.text.NumberFormat.
-
- Or use http://www.newbie.net/sharky/lava/. Or use Cay Horstmann's
- http://www.horstmann.com/corejava/Format.java
- Although many utilities claim to handle all varieties of C's printf, as
- far as has been found, this is the only one to correctly handle the
- equivalent of %e in printf.
-
- See also the standard packages java.text.DecimalFormat and
- java.text.NumberFormat
-
- 14. (Sect. 7) How do I read numbers in exponential format in Java?
-
- [*] The program below (written by Steve Chapel) uses StreamTokenizer to
- read data from the standard input and recognizes doubles in exponential
- format (e.g. -1.23e-45).
-
- import java.io.*;
-
- public class ReadExponential {
- public static void main(String argv[]) {
- DataInputStream in = new DataInputStream(System.in);
- StreamTokenizer st = new StreamTokenizer(in);
- try {
- while (st.nextToken() != StreamTokenizer.TT_EOF) {
- switch (st.ttype) {
-
- case StreamTokenizer.TT_NUMBER:
- double num = st.nval;
- int exp = 0;
- st.ordinaryChars('\0', ' ');
- st.nextToken();
- st.whitespaceChars('\0', ' ');
- if (st.ttype == StreamTokenizer.TT_WORD &&
- Character.toUpperCase(st.sval.charAt(0)) == 'E') {
- try {
- exp = Integer.parseInt(st.sval.substring(1));
- } catch (NumberFormatException e) {
- st.pushBack();
- }
- } else if (st.ttype < 0 || st.ttype > ' ')
- st.pushBack();
- System.out.println("Num " + num * Math.pow(10, exp));
- break;
- case StreamTokenizer.TT_WORD:
- System.out.println("Word " + st.sval);
- break;
- default:
- System.out.println("Char '" + (char) st.ttype + "'");
- break;
- } // end switch
- } // end while
- } catch (IOException e) {
- System.out.println("IOException: " + e);
- }
- } // end main
- }
-
-
- 15. (Sect. 7) I'm trying to read in a character from a text file using the
- DataInputStream's readChar() method. However, when I print it out, I
- get ?'s.
-
- [*] Remember that Java characters are 16-bit Unicode characters, while
- many hosts systems store characters as 8-bit ASCII characters.
- Therefore, to read individual chacters from a text file, you need to
- ensure the proper conversion. The proper way to do this is to use an
- InputStreamReader, which converts from 8 to 16 bit streams:
-
- FileInputStream fis = new FileInputStream("myfile.txt");
- InputStreamReader isr = new InputStreamReader(fis);
- char c3 = (char) isr.read();
-
- The less-favored way (because it is not so portable, as the encodings
- translation is not done) is just to read a byte and cast it into a
- character:
-
- FileInputStream fis = new FileInputStream("myfile.txt");
- DataInputStream dis = new DataInputStream(fis);
- char c1 = (char) dis.readByte();
-
-
- 16. (Sect. 7) How do I delete a directory in Java?
-
- [*] JDK 1.0 did not support directory removal. JDK 1.1 supports
- directory removal with the method:
- public boolean delete() in class java.io.File
-
- Make sure you don't have any open streams in the directory you're
- trying to remove. Do a close() on all streams, even if the underlying
- file is gone.
-
- 17. (Sect. 7) How do I tell how much disk space is free in Java?
-
- [*] There currently aren't any good Java APIs for system introspection.
- There is no Java way to control processes, or look at system resources.
- You can use Runtime.getRuntime().exec() to do "df" on unix or "dir" on
- Windows right now.
-
- Alternatively, check out JConfig:
- http://www.tolstoy.com/samizdat/jconfig.html
- JConfig is a cross-platform library that fills in many of the gaps in
- the core Java API, and makes it possible to work with files, processes,
- file types, video monitors, etc. in a much more Windows- and
- Mac-friendly manner.
-
- 18. (Sect. 7) How do I get a directory listing of the root directory C:\ on
- a PC?
-
- [*] The obvious approach of calling File.list("C:\"); does not work.
- There are two reasons why this fails. First, slash is an escape
- character in Java, so if you want a literal slash, you have to repeat
- it. Second, you need to give the name of the directory, i.e. dot.
- Putting this together, either of the following calls will work
-
- File.list("C:\\.");
-
-
- or
-
- File.list("C:/.");
-
-
- Note: a file separator of "/" works just as well as "\" in most Windows
- programs and library calls. It is an artifact of DOS's origin's as a
- ripped-off port of CP/M. When Microsoft bought the rights to DOS from
- Seattle Computer Products (what, you didn't know Microsoft didn't
- develop DOS? They didn't even own the rights to DOS at the time the
- contracted with IBM to supply DOS for the PC) they were buying software
- which was an unauthorized port of the CP/M operating system.
-
- CP/M didn't have directories, so it didn't use pathname separators. The
- forward slash "/" was already used for giving options to CP/M commands,
- so "\" was pressed into service as the DOS pathname separator, but the
- DOS shell was taught to understood "/" for compatibility with other
- OS's. See also JConfig in Q6.15.
-
- 19. (Sect. 7) What is the difference between the various ZIP formats: ZIP,
- GZIP, and PKZIP?
-
- [*] Zip is an archive file format, popularized on PCs, that contains
- multiple compressed files.
- GZIP comes from Gnu. It is essentially a one file subset of the Zip
- format. You can't put a whole directory into a GZIP archive, just a
- single file. It's intended for compressing a tarball of many files.
- PKZIP is a set of commercially available programs that create Zip
- files. All three use the deflate compression format, which is based on
- the LZ77 algorithm. This compression is also used by the ZLIB library
- and hence the PNG graphics file format (which uses ZLIB). PNG -
- Portable Network Graphics - provides a patent-free replacement for GIF
- and TIFF.
-
- An alternative compression technology, LZW compression, is encumbered
- by Unisys's patent. LZW is used in GIF files and by the Unix compress
- command. Luckily, as well as being free from patent restrictions, LZ77
- also gives better compression than LZW. LZW is the initial letters of
- the last names of the three computer scientists who developed the
- algorithm (Lempel, Ziv, Welch).
-
- The basic classes (all in java.util.zip) that read LZ77 Zip format are
- Deflater and Inflater. These are used by the stream classes
- DeflaterOutputStream and InflaterInputStream. The java.util.zip classes
- GZIPInputStream and ZipInputStream inherit from InflaterInputStream.
-
- PKZIP is a commercial program for DOS, Windows, and OS/2, sold by
- PKWARE Their FAQ, at http://www.pkware.com/zipgfaq.html, specifically
- says
- "Because PKWARE has dedicated the .ZIP file format to the public
- domain, it is possible for other people to write programs which
- can read .ZIP files. NOTE THAT THE PKZIP, PKUNZIP, PKSFX PROGRAMS
- AND THEIR ASSOCIATED SOURCE CODE AND SUPPORT PROGRAMS ARE THE
- EXCLUSIVE PROPERTY OF PKWARE INC. AND ARE NOT PUBLIC DOMAIN
- SOFTWARE PROGRAMS.
-
- The "other people" PKZIP's FAQ refers to is the InfoZIP project, a
- group of public-minded programmers spread over the world producing free
- software that works on most ANSI C compilers and platforms. See
- http://www.cdrom.com/pub/infozip/.
-
- Jar files are in ZIP format, but are not as complete as a full
- filesystem archive format since file permissions are not saved. Some
- versions of WinZip are known to be inadequate for processing the full
- PKZIP format. Use InfoZIP instead.
-
- 20. (Sect. 7) How can I use characters other than ASCII in Java?
-
- [*] Search for the article titled "Adding Fonts to the Java Runtime" or
- visit:
- http://java.sun.com/products/jdk/1.2/docs/guide/internat/fontprop.html
-
- The article explains how to add fonts to Sun's JDK 1.2 using the
- font.properties file. [If anyone has summarised the information, please
- send it in].
-
- 21. (Sect. 7) I did a read from a Buffered stream, and I got fewer bytes
- than I specified.
-
- [*] This is the way that BufferedInputStream works up to and including
- the current release. The behavior is so unintuitive that it really
- represents a bug. Javasoft has "resolved" the bug by writing comments
- in the program so that the broken behavior is in the range of legal
- outcomes. Ugh.
-
- When you instantiate a buffered input stream, you can specify the size
- of buffer it should use. Let's call this the internal buffer. When you
- call read() you can say how many bytes to read. Let's call this the
- request. If the request is smaller than the internal buffer and not a
- multiple of the internal buffer, then the last read returns only the
- odd bytes left in the internal buffer! The more reasonable and
- intuitive behavior would be for the internal buffer to be refilled, so
- that the whole request can be granted.
-
- For example, if you create a BufferedInputStream with an internal
- buffer of 1000 bytes, and try to read 512 byte chunks, your first read
- will return 512 bytes, but your second read will only return
- (1000-512), or 488, bytes. (Assuming that the file has at least that
- many bytes in it). The following code illustrates the problem.
-
- // troubleshooting by Tov Are Jacobsen
- import java.io.*;
- class filebug {
- public static void main(String args[])
- throws FileNotFoundException, IOException {
- BufferedInputStream bis =
- new BufferedInputStream(
- new FileInputStream("test.txt"), 1000 );
- byte[] buf = new byte[2000];
- int numread;
- System.out.println( "Available: "+bis.available() );
- while (true) {
- numread = bis.read(buf,0,512);
- if (numread<0) break;
- System.out.println( "got "+numread
- +", avail:"+ bis.available());
- }
- }
- }
-
-
- Of course, a valid reason for getting less than you asked for is that
- you asked for more data than is actually available in the Stream, e.g.
- you requested 512 bytes from a file that only contains 40 bytes. In
- general, there are no guarantees about how much data is returned for a
- given buffered input stream read request. To avoid this problem, push a
- DataInputStream on top of your buffered stream. Then you can call
- readFully(), which will do what you want.
-
- A similar "got less than I asked for" occurs when reading a socket.
- Network protocols frequently packetize data and send it across in
- bursts. Nothing is lost of course, and you are always told how many
- bytes you actually got. You will get the remaining bytes on a
- subsequent read. This happens regardless of the language used. Be sure
- to check the "amount of data returned" when using the read(byte[], int,
- int) method of BufferedInputStream, or when reading from a socket.
-
- Another problem with java.io.InputStream.read(byte[], int, int) is that
- it catches and ignores IOExceptions. Instead, these exceptions should
- be passed on to the caller. Ace programmer Jef Poskanzer, jef@acme.com,
- has a version to do this at
- http://www.acme.com/java/software/Acme.Utils.html. See Jef's read() and
- readFully() routines.
-
- 22. (Sect. 7) How do I redirect the System.err stream to a file?
-
- [*] You cannot assign a new FileOutputStream to System.err, as it is
- final. Instead use the System.setErr() library call, like this:
-
- FileOutputStream err = new FileOutputStream("stderr.log");
- PrintStream errPrintStream = new PrintStream(err);
- System.setErr(errPrintStream);
-
-
- This was introduced with JDK 1.1. There is also a corresponding setIn()
- for redirecting standard in, and a setOut() for standard out.
-
- Note that you will get a compiler warning about a deprecated construct
- when you do this. PrintStreams are deprecated in favor of PrintWriters,
- which handle Unicode properly. The PrintStream is marked as deprecated
- by marking all its constructors as deprecated. There is no way to
- create the PrintStream needed to redirect System.err or System.out
- without triggering the deprecated warning.
-
- 23. (Sect. 7) What are the values for the Unicode encoding schemes?
-
- [*] If you review the String constructor with this signature
-
- String(byte[] bytes, String encoding)
-
- you can see that one argument is a value for the encoding scheme that
- the conversion of 8-bit bytes to 16-bit Unicode chars is to use.
-
- There are three: "Unicode", "UnicodeBig" and "UnicodeLittle". The first
- one expects the first two bytes of your data to be a Byte Order Mark,
- FEFF or FFFE, which specifies whether the data is in little-endian or
- big-endian order. If there isn't a BOM but you already know the
- endianness, you can use "UnicodeBig" or "UnicodeLittle" directly.
-
- There is also a Sun document at
- http://java.sun.com/products/jdk/1.1/docs/guide/intl/encoding.doc.html
- with some related information (not much).
-
- There is another Sun document at
- http://java.sun.com/products/jdk/1.1/intl/html/intlspec.doc7.html which
- shows the table of encodings. There is a new system property called
- "file.encoding" which translates between codes known to Java like
- "Cp1252", and locale encoding names like "Windows Western Europe /
- Latin-1"
-
- 24. (Sect. 7) Is there a way to read a char from the keyboard without
- having to type carriage-return?
-
- [*] You can do this in a GUI (e.g. in a text component). There is no
- pure Java way to do character-by-character I/O without using a GUI.
-
- -------------------------------
-
- 8. Core Libraries
-
- 1. (Sect. 8) I can't seem to change the value of an Integer object once
- created.
-
- [*] Correct. Integer (Float, Double, etc) are intended as an object
- wrapper for a specific value of a number, not as a general-purpose way
- of shipping a primitive variable around as an Object. If you need that
- it's easy enough to create: class General { public int i; }
-
- 2. (Sect. 8) How do I print from a Java program?
-
- [*] Use the Toolkit.getPrintJob() method
-
- Component c = this.getParent();
- while (c!=null && !(c instanceof Frame))
- c=c.getParent();
- // With a JComponent use c=getTopLevelAncestor();
-
- PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null);
- Graphics pg = pj.getGraphics();
- printAll(pg);
- pg.dispose();
- pj.end();
-
-
- This feature was introduced with JDK 1.1. A common place to put this is
- in the code that handles a button press. Printing from an untrusted
- applet is subject to a check from the SecurityManager.
-
- The JDK 1.1 printing API is more a screen hardcopy facility than a full
- blown publishing and illustration hardcopy API. JDK 1.2 offers a more
- full-featured printing API.
-
- If you simply want to print text, then write it to a file and print the
- file. Or open a filename that corresponds to the printer. On Windows,
- that is "LPT1" and the code looks like:
-
- try {
- FileOutputStream fos = new FileOutputStream("LPT1");
- PrintStream ps = new PrintStream(fos);
- ps.print("Your string goes here");
- ps.print("\f");
- ps.close();
- } catch (Exception e) {
- System.out.println("Exception occurred: " + e);
- }
-
-
- The final formfeed is needed by windows to start the printjob.
-
- 3. (Sect. 8) What are the properties that can be used in a PrintJob?
-
- [*] The properties are
- o awt.print.destination - can be "printer" or "file"
- o awt.print.printer - printer name
- o awt.print.fileName - name of the file to print
- o awt.print.numCopies - obvious
- o awt.print.options - options to pass to the print command
- o awt.print.orientation - can be "portrait" or "landscape"
- o awt.print.paperSize - can be "letter","legal","executive" or "a4"
- paperSize=letter, and numCopies=1.
-
- You can search for info like this by joining the Java Developer
- Connection (it's free) at http://java.sun.com/jdc.
-
- and doing a search for "PrintJob".
-
- 4. (Sect. 8) Is there any package in Java to handle HTML?
-
- [*] See the answer to Question 13.14.
-
- 5. (Sect. 8) Why don't Dialogs work the way I want them to?
-
- [*] Modal dialogs (dialog windows that stay up until you click on them)
- are buggy in many browsers and in the 1.0.2 JDK. One bug is that the
- dialog is not necessarily put on top when it is displayed. Most of the
- modal dialog bugs are fixed in JDK 1.1.
-
- 6. (Sect. 8) Where can I find information about the sun.* classes in the
- JDK?
-
- [*] You're not supposed to. Those classes are only to support functions
- in the java.* hierarchy. They are not part of the API, and won't be
- present in Java systems from non-Sun vendors. Some people have
- reverse-engineered the code and published an API for these classes but
- you use it at your own risk, and it may change without warning.
-
- Worst of all, those programs will not have the portability of true Java
- but will only run on Sun JDKs. For the same reason you shouldn't use
- classes outside the java.* packages when using JDKs from other vendors.
-
- If you still insist on going ahead, check these URLs:
- http://java.sun.com/products/api-overview/index.html
- http://www.parmly.luc.edu/javaudio/
- http://www.users.interport.net/~mash/javamidi.html
-
- 7. (Sect. 8) How do you read environment variables from with a Java
- program?
-
- [*] Environment variables are not used in Java, as they are not
- platform-portable. The Mac doesn't have environment variables, for
- example. A Windows 95 application not started from a DOS window does
- not have environment variables. Use properties instead. It was a design
- error in JDK 1.0 that programmers had to set the CLASSPATH environment
- variable. This should have been set in a property file
-
- Create your own properties file (see java.util.Properties) or specify
- them with the -D option when you invoke the interpreter or JRE.
- Additionally, on some systems you can set a property from the command
- invocation line like this:
-
- java -Dfoo=$foo MyClass (Unix)
-
- or
-
- java -Dfoo=%foo% MyClass (Win95/NT)
-
- This sets the "foo" property to the value of the environment variable
- foo, and makes it available in the System properties. Make sure you do
- not leave any spaces after the -D or around the = sign. Inside the
- program you get the value with:
-
- String env = System.getProperty("foo");
-
- More simply, just put the environment variable on the command line and
- read it as arg[0].
-
- java MyClass %FOO% ; Win32
- java MyClass $FOO ; Unix
-
-
- Finally, you could execute a Runtime process to get the environment
- variables if you are on a platform that has them.
-
- import java.io.*;
- import java.util.Properties;
-
- public class Main {
- public static void main(String[] argv) {
- Properties envVars = new Properties();
-
- try {
- envVars.load( // use "set" on Windows
- Runtime.getRuntime().exec("/bin/env").getInputStream());
- } catch (Throwable t) {t.printStackTrace();}
-
- System.out.println("\n\n" + argv[0]
- + " = <" + envVars.get(argv[0]) + ">");
- }
- }
-
- This is not a Pure Java approach as it builds platform-specific
- knowledge into the program. See Question 10.6 for more details. On
- Unix, the command that prints environment variables is "/usr/bin/env".
- On Windows95, it is "set"
-
- 8. (Sect. 8) How do I get Java talking to a Microsoft Access database?
-
- [*] Use the JDBC-ODBC bridge. It is not especially challenging to set
- up, but it does require painstaking attention to detail. There is a
- step-by-step example in the van der Linden text "Just Java" mentioned
- in the sponsorship section of this document.
-
- Note that the Microsoft version of the Java kit does not support
- JDBC-ODBC access because it uses a non-standard native code interface.
- The JDBC FAQ can be found at
- http://java.sun.com/products/jdbc/jdbc-frequent.html
-
- 9. (Sect. 8) I can't seem to change the current working directory.
-
- [*] Correct. This missing functionality is an oversight that we hope
- will be corrected in the future. The bug id is 4156278, please feel
- free to join the JDC, and vote to have this (or any other) fixed.
- Changing the user.dir property merely changes the text property, not
- the underlying reality that it is supposed to reflect.
-
- There are several workarounds.
- o Run your java app from a .bat or .sh file and do the "cd" in that
- (before you run your java app), assuming that all the external
- processes you need to exec can be run from the same directory.
- o Do: exec("cd /home/wherever; externalApp.exe") on unix, (there
- doesn't seem to be an equivalent on NT).
- o Instead of running the .exe directly, run (or write on the fly) a
- .bat or .sh file that does the cd and then runs the .exe for you
- (this could well create trouble with getting back the correct
- return status)
-
- 10. (Sect. 8) How do I create a Vector of ints?
-
- [*] ints are primitive types and hence can't be stored by the Vector
- class, which stores objects. You'll need to wrap the ints. Try this:
-
- int i =7;
- Vector holdsInts = new Vector(5,1);
-
- holdsInts.addElement(new Integer(i));
- int j = ((Integer)holdsInts.elementAt(0)).intValue();
-
-
- 11. (Sect. 8) I have several worker threads. I want my main thread to wait
- for any of them to complete, and take action as soon as any of them
- completes. I don't know which will complete soonest, so I can't just
- call Thread.join on that one. How do I do it?
-
- [*] You need to use the wait/notify mechanism to allow any of the
- worker threads to wake up your main thread when the worker has
- completed.
-
- 12. (Sect. 8) How do I get random numbers?
-
- [*] If you just need a quick random double between 0.0 and just less
- than 1.0
-
- double myrandom = Math.random(); // [0,1)
-
-
- The notation "[0,1)" is common math notation for "zero to .9999999 etc"
- The Sun documents say this returns 0.0 to 1.0, but inspection of the
- source shows they are wrong. However, due to the inherent inaccuracies
- of floating point arithmetic, multiplying N by 0.999999 etc can result
- in an answer of N, not N * .999999. So watch out when N is big.
-
- JDK 1.2 adds another version of nextInt that accepts a parameter for
- returning ranged random numbers.
-
- Where things get trickier is when you use JDK 1.1 and want an int in a
- certain range, say 1 to 6 to simulate the throw of a die or 1 to 52 to
- represent a playing card. Class Random has a nextInt method that will
- return any integer:
-
- import java.util.Random;
- Random r = new Random();
- int i = r.nextInt();
-
-
- However, that has an (almost) 50% chance of being negative, and it
- doesn't come from the right range. So you just take the abs() value and
- then mod it into the right range:
-
- int dice_throw = 1 + Math.abs(i) % 6;
-
-
- Except, the abs() method fails gracelessly in the presence of the
- Integer.MIN_VALUE (it returns the same, negative, result!). So it is
- better to AND to get the non-negative value: In general, to get a
- random int between high and low limits (inclusive):
-
- java.util.Random r = new java.util.Random();
- int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low;
-
-
- The sentence above states "(almost) 50% chance" because there is one
- more value in the negative integers than in the positive integers in
- two's complement arithmetic as used by Java. For most purposes, the
- bias introduced will be insignificant, but we "and" the nextInt() to
- convert it to zero. Sure, it's unlikely to occur, but you don't want
- the reactor going critical just because you missed this case while
- testing.
-
- A worse problem is that with the algorithm used, the low order bits are
- significantly less random than the higher order bits. And the low order
- bits are precisely the ones you get when you do a (mod 2^n) operation.
- You may consider using java.security.SecureRandom which provides much
- better randomness by using a Cryptographic hash, although it is much
- more expensive to compute.
-
- 13. (Sect. 8) What does "deprecated" mean? I got this in a compiler error
- message.
-
- [*] The compiler will flag a now-obsolete API as "deprecated". The word
- means "officially disapproved of". Compile again with the
- "-deprecation" option to see what is deprecated. In almost all cases,
- the old API has been replaced by a new one. Update your code to use the
- new one.
-
- An example of using a deprecated API is calling component.size(). That
- has been replaced by component.getSize().
-
- 14. (Sect. 8) Where/why should I use the Enumeration interface?
-
- [*] It's a very convenient way to step through some of the library data
- structures, such as HashTable, Vector, and ZipFile. It is thread safe.
- If you're looking at an element in one thread while another thread is
- trying to delete it, it won't half vanish.
-
- Here's how you might look at every file in a ZIP file:
-
- ZipFile z = new ZipFile("foo.zip");
- Enumeration e = null;
- for (e=z.entries(); e.hasMoreElements(); ) {
- ZipEntry ze = (ZipEntry)e.nextElement();
- System.out.println("got " + ze.getName() );
- }
-
-
- And here's how you might look at all the tokens in a String:
-
- StringTokenizer tokens =
- new StringTokenizer (SomeArbitraryString, "\n", false);
-
- Enumeration enum = tokens.elements();
- while enum.hasMoreElements()
- System.out.println(enum.nextElement());
-
- You should look for opportunities in your own data structures to
- implement Enumeration anywhere where the structure has repeated
- elements.
-
- 15. (Sect. 8) Which version of WinZip is compatible with java.util.zip?
-
- [*] You need WinZip version 6.2 or later. Version 6.1 or earlier is not
- good enough. WinZip can be downloaded from
- http://www.winzip.com/download.cgi. The pkzip software works fine.
- Infozip is better than WinZip because it lacks the winzip "feature" of
- failing to recreate directories unless given a special option. Use
- Infozip.
-
- 16. (Sect. 8) How can Java access other fonts on my system?
-
- [*] You do it by editing the fontnames in the font.properties file in
- the lib directory of your JDK release. Watch out for program
- portability when you do this.
-
- For more details, check the website
- http://www.alumni.caltech.edu/~dank/javafont.htm and the JavaSoft site
- at http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
- They have lots of information on this.
-
- 17. (Sect. 8) How can I trap Control-C in Java?
-
- [*] Control-C is used on some OS's to break into a running program
- interactively and terminate it. On Unix Control-C is sent to the
- process as a signal. If a C program declares a handler for that signal,
- the program will be able to continue even if Control-C is sent to it.
-
- Control-C is not a Java concept, and there is no way to do this
- portably.
- On Unix you can write the signal handler in C, and impose the handler
- by calling the C routine through the Java Native Interface.
- On Win32 in a GUI a KeyPressedListener will see a control-C as
- java.awt.event.KeyEvent[KEY_PRESSED,keyCode=67,modifiers=Ctrl]
- On Win32 in a command line app you can't read a control-C in Java
- because it is sent to the process as a signal (as with Unix).
- Instead of interposing a signal handler thru JNI, you could launch java
- from perl or a shell script which is capable of doing this.
- Alternatively, use javaw to launch the JVM so that it has no keyboard
- which can ctrl-C it.
-
- 18. (Sect. 8) How do you parse commandline arguments to a Java program?
-
- [*] Perhaps surprisingly, commandline arguments are not encouraged, as
- they make a program not 100% pure Java. The reason is that some systems
- like MacOS don't normally have a command line or command-line
- arguments. Consider using properties instead so that your programs fit
- more naturally into the environment.
-
- If you must use command-line arguments, have them comply with the POSIX
- conventions, i.e. they should
- o use a "-" instead of a "/"
- o be case sensitive, and
- o be concatenatable (-pst == -p-s-t).
- See
- http://java.sun.com/docs/books/tutorial/essential/attributes/_posix.html
-
- If such arguments are used, it should NOT be up to the invocating
- application (ie java.exe) to propperly parse them. According to the
- getopts routine from gnu, getopts is required to know exactly what the
- usable parameters are before it can properly parse them and create
- argc/argv.
-
- Because of that, it becomes unduly hard for calling programs such as
- java.exe to properly parse class arguments by themselves. Instead, they
- should create an argc/argv pair (actually a java specific array
- dependant on the way in which the method is called) where the number of
- elements equals the number of text words in the options. Text word
- means a group of ascii characters outside of quotation marks, not
- separated by white space. Once these text words are passed to the
- class, it is up to the class to actually parse them correctly.
-
- The text words passed to the class can be parsed however the class
- author wishes. It is up to the author to correctly parse the options.
- There are several implementations of getopts which perform such
- parsing, in C, Perl, and Java. You will find one at
- http://www.urbanophile.com/arenn/hacking/download.html#getopt
-
- 19. (Sect. 8) How many threads can I create?
-
- [*] By default, on a Win32 machine, each ("native") thread gets one MB
- (1024*1024 bytes) of stack space reserved for it. The memory is not
- actually allocated. If it were, you'd run out of memory with dozens of
- threads instead of hundreds. The space needs to be reserved as a
- contiguous block of memory so the stack can grow as needed.
-
- Under Win32, the max amount of memory is 2GB, which corresponds to
- 2,000 threads each reserving 1MB of memory. That's an upper bound; in
- practice you'd run out of other OS resources before running out of
- memory. Each thread has some system resources that will be used to
- manage the thread -- register storage area, thread-local storage, state
- information, exception condition info, etc.
-
- You should design your programs so that you use threads only where
- necessary. It's almost always a mistake to have one thread per object.
- Successful programs are much more likely to have 5 threads (or fewer)
- than 500.
-
- -------------------------------
-
- 9. Dates and Times
-
- Credit to Paul Hill who completely rewrote this section, and to
- the programmers at IBM who implemented much of the Java Date code,
- and reviewed this section of the FAQ for accuracy.
-
- java.util.Date
-
- 1. (Sect. 9) Is Java "Year 2000"-compliant?
-
- [*] Java is Y2K compliant in release JDK 1.1.6 and later. See
- http://www.sun.com/y2000/cpl.html. Prior to this release there were
- certain corner case bugs that had to be fixed.
-
- The Date class, as you can see from the discussion, contains more than
- enough resolution to represent dates in this century and the next and
- the last. The SimpleDateFormat when parsing a 2 digit year could cause
- problems; see discussion below.
-
- 2. (Sect. 9) What happen to java.util.Date between JDK 1.0 and JDK 1.1?
-
- [*] In JDK 1.1 the java.util.Date class was split to provide better
- support for timezones, and internationalization.
-
- The classes specifially related to dates are summarized below:
-
- 1. The class Date represents a specific instant in time,
- with millisecond precision.
- 2. The class TimeZone is an abstract class that represents
- a time zone offset, and also figures out daylight
- savings time adjustment.
- 3. The class SimpleTimeZone is the only concrete subclass
- of TimeZone in the JDK. It is what defines an ordinary
- timezone with a simple daylight savings and daylight
- savings time period.
- 4. The class Calendar is an abstract class for converting
- between a Date object and a set of integer fields such
- as year, month, day, and hour.
- 5. The class GregorianCalendar is the only concrete
- subclass of Calendar in the JDK. It does the
- Date-to-fields conversions for the calendar system in
- common use.
- 6. The class DateFormat is an abstract class that lets you
- convert a Date to a printable string with fields in the
- way you want (e.g. dd/mm/yy or dd.MMM.yyyy).
- 7. The class SimpleDateFormat is the only concrete subclass
- of DateFormat in the JDK. It takes a format string and
- either parses a string to produce a date or takes a
- date and produces a string.
-
- At least one critic has used the term "baroque" when describing the
- complexities of the Java date related classes, but other critics would
- spell that "broke". The good news is that as of JDK 1.2 all of the
- common problems have been corrected and many of the bugs were corrected
- in 1.1.4 and 1.1.6. Even in 1.1.1, you can avoid most of the most
- annoying bugs by always keeping in mind which timezone each class is
- using.
-
- 3. (Sect. 9) Exactly what is a java.util.Date?
-
- [*] A java.util.Date stores a moment in time as a long integer
- representing the number of milliseconds since 00:00:00 Jan 1, 1970 UTC
- (Coordinated Universal Time). This zero moment is known as the "Epoch".
- This is the same Epoch as is used on Unix systems. Dates earlier than
- the Epoch are represented as negative numbers, counting away from
- 1/1/1970.
-
- The scheme is sufficient to represent dates from 292,269,053 B.C. to
- 292,272,993 A.D. (64 bits covers -9,223,372,036,854,775,808 to
- +9,223,372,036,854,775,807 milliseconds. But note that prior to JDK
- 1.2, a GregorianCalendar will not accept values earlier than 4713 B.C.
-
- A java.util.Date is the light-weight object intended to just hold a
- millisecond value. It is used to hold, communicate and store a moment
- in time. Other tasks like creating a formated string, or calculating
- dates are best done using other classes.
-
- 4. (Sect. 9) Does a java.util.Date really represent the true UTC?
-
- [*] No, but it is close enough for most human time-keeping purposes. On
- most computers, it only represents the time since the epoch as
- converted from the value on the underlying hardware. If you have
- hardware that is synchronized with an atomic clock your time is UTC;
- most hardware assumes a day is 24 hours long, but there have been more
- than 20 leap seconds added to UTC, since the first one was added in
- 1972.
-
- 5. (Sect. 9) How do I create a Date object that represents the current
- time?
-
- [*] The default value of a date object is the current time, so the
- following code creates a date object that contains the current time.
-
- Date now = new Date();
-
- 6. (Sect. 9) I want to create a string that represents a date in a format
- other than what is returned by java.util.Date.toString() do I have to
- use a Calendar?
-
- [*] No. Instead of creating a Calendar and pulling out all of the
- appropriate fields and making a string, you could use
- SimpleDateFormat.format() to create a string.
-
- 7. (Sect. 9) Why are all the methods in java.util.Date deprecated?
-
- [*] Mostly because the original java.util.Date was not completely aware
- of the timezone and "not amenable to internationalization". To make it
- timezone aware and internationalizable would have required adding some
- of the functionality which can now be seen in java.util.Calendar and
- some of the functionality in java.util.DateFormat. If you find the
- combination all of the date related classes complex, just be glad they
- were separated into different classes.
-
- 8. (Sect. 9) I really don't need a internationalizable, timezone aware,
- extra flexible formating set of date classes. Is there anything else I
- can use that stores only a date, and allows me to do some date
- calculations?
-
- [*]You could consider using the BigDate class written by Roedy Green,
- and available in his very informative glossary (search for BigDate). If
- you want to store the result in a database as a Date or TimeStamp, you
- should read the section below on java.sql.Date.
-
- 9. (Sect. 9) Since the Date( String ) constructor is deprecated what do I
- use instead?
-
- [*] The best choice is to use SimpleDateFormat.parse() to create a
- java.util.Date object.
-
- The Date constructor that accepts a string calls Date.parse( String ).
- The Date.parse() function had its own rules for converting 2 digit
- years (it used a 1980 pivot date) and other limitiations which makes it
- of limited value. Other "features" of Date.parse() that are not
- supported in SimpleDate have not been missed by many developers.
-
- 10. (Sect. 9) Since Date(int year, int month, int date) and related
- constructors are deprecated what do I use instead?
-
- [*] The constructor GregorianCalendar(int year, int month, int date) is
- the newer replacement. Other choices are the Calendar.set( year, month,
- day ) method. Note that the year in the GregorianCalendar starts at 1
- A.D., not at 1901 like the old Date constructor.
-
-
- java.util.TimeZone
-
- 11. (Sect. 9) How can I see if my JVM is using the right timezone?
-
- [*] The following codes displays the ID of the current default
- timezone.
-
- System.out.println( TimeZone.getDefault().getID() );
-
- 12. (Sect. 9) The value of TimeZone.getDefault is not what I expected. What
- is the problem?
-
- [*] The value of the default timezone is based on the value of the
- system property "user.timezone". The JVM is supposed to set this
- value. In releases such as JDK 1.1 the value of user.timezone was often
- not set to anything, so TimeZone.getDefault() used its own built in
- "fallback" value (the default when there is no default value). In later
- JDK 1.1 releases and in JDK 1.2 the setting of the value of
- user.timezone is much better and the "fallback" value is now GMT
- (Greenwich Mean Time). Up until JDK 1.1.3, the fallback value was "PST"
- (North American Pacific Timezone).
-
- 13. (Sect. 9) Do all the standard objects use the same default timezone?
-
- [*] Not until JDK 1.2. In JDK 1.1, Date.toString() and Calendar used
- the value of TimeZone.getDefault() which could often be undefined (see
- the previous question). In JDK 1.1, The Calendar in a SimpleDateFormat
- was set to the 1st timezone resource for the locale (for the US this is
- PST).
-
- System.out.println( "Date format TZ = " + TimeZone.getDefault().getID() );
- sdf = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );
- System.out.println( "Date format TZ = " + sdf.getTimeZone().getID() );
- Calendar cal = Calendar.getInstance();
- System.out.println( "Calendar TZ = " + cal.getTimeZone().getID() );
-
- When run on a system running JDK 1.1.6, NOT in the North American
- Pacific Time nor in the GMT timezone results in:
-
- Timezone default = GMT
- Date format TZ = PST
- Calendar TZ = GMT
-
- This example shows two bugs, the value of user.timezone is undefined,
- so its defaulting to GMT (see discussion of TimeZone.getDefault()) and
- it shows that the DateFormat depends on the 1st locale entry which in
- this case is PST.
-
- If you don't want the DateFormat to use the Locale timezone, see the
- code provided below.
-
- 14. (Sect. 9) If I explicitly set the default timezone, don't I need code
- to choose between (a) the daylight savings version or (b) the standard
- version of a timezone?
-
- [*] No. The ID that you use to select a timezone with
- TimeZone.getTimeZone refers to a predefined timezone that contains
- daylight savings information (when applicable). For example, the
- following code selects the timezone used in New York, USA.
-
- // Get the North American Eastern Time definition.
- TimeZone theTz = TimeZone.getTimeZone( "EST" );
- // get a really detailed date format and set it to the right timezone
- DateFormat df = DateFormat.getDateTimeInstance( DateFormat.LONG,
- DateFormat.LONG );
- df.setTimeZone( theTz );
- // create a date in the locale's calendar, set its timezone and hour.
- Calendar day = Calendar.getInstance();
- day.setTimeZone( theTz );
- day.set( 1998, Calendar.FEBRUARY, 1 );
- day.set( Calendar.HOUR, 12 );
-
- // print that date/time and
- // that date/time 150 full days of milliseconds later.
- System.out.println( df.format( day.getTime() ) );
- System.out.println( df.format(
- new Date( day.getTime().getTime() + // get the millis
- 150L*24*60*60*1000L ) ) ); // add exactly 150 days of millis
-
- Results in:
-
- February 1, 1998 12:00:00 PM EST
- July 1, 1998 1:00:00 PM EDT
-
- Notice that this example selected something refered to as "EST", but
- that this TimeZone was aware of the daylight savings time change and
- either printed as "EST" or "EDT".
-
- The confusion is reduced in JDK 1.2, you can use longer TimeZone IDs
- each maps to its own set of text resources. For example the following
- IDs are 5 hour West of GMT and have various DST rules:
- "America/Nassau", "America/Montreal", "America/Havana",
- "America/Port-au-Prince", "America/Grand_Turk", "America/New_York" and
- "EST".
-
- You can look at a list of other timezone names and offsets in the file
- $JAVAHOME/src/java/util/TimeZone.java
-
- 15. (Sect. 9) How do I create my own Time Zone to apply to dates?
-
- [*] You can create a TimeZone object with the GMT offset of your
- choice. The following code creates British Time, a timezone that was
- not defined in 1.1.
-
- britTime = new SimpleTimeZone(0*ONE_HOUR, "Europe/London" /*GMT/BST*/,
- Calendar.MARCH, -1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
- Calendar.OCTOBER,-1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
- 1*ONE_HOUR),
-
- TimeZone.setDefault( britTime );
-
- Or you can then apply that TimeZone to a particular Calendar object
- like so:
-
- Calendar myCal = Calendar.getInstance();
- myCal.setTimeZone( britTime );
-
- If you are running 1.2, You can choose this existing timezone as the
- default with the code:
-
- TimeZone.setDefault( TimeZone.getTimeZone( "Europe/London" ) );
-
- Note that BST is defined from JDK 1.1 and later, but it is Bangladesh
- Standard Time. For a longer example of creating and testing the British
- timezone, Tony Dahlman provides a nice example in his BSumTime.java
- code.
-
- 16. (Sect. 9) How do I create the BST timezone specifically?
-
- [*] You can create an arbitrary TimeZone object with the code below. In
- most or all other timezones, daylight savings time is handled
- automatically and internally. But GMT is the reference for all other
- timezones, and so does not have the summertime update applied
- automatically. The rules for BST can be found at
- http://www.rog.nmm.ac.uk/leaflets/summer/summer.html
-
- Here is the code to create a British Summer Time timezone that is
- offset one hour from GMT between two dates:
-
- import java.util.*;
- import java.text.*;
- // create a BST timezone (code courtesy of Tony Dahlman).
-
- public static GregorianCalendar setBritSummTime(String zoneName){
- // Set up the default GMT0BST time zone
- SimpleTimeZone bst_tz =
- new SimpleTimeZone( 0, // no offset from GMT
- zoneName, // individualized tz id
- // last Sun Mar 1AM
- Calendar.MARCH,-1,Calendar.SUNDAY,1*60*60*1000,
- // last Sun Oct 2AM
- Calendar.OCTOBER,-1,Calendar.SUNDAY,2*60*60*1000
- );
- SimpleTimeZone.setDefault(bst_tz);
-
- // Apply TimeZone to create a Calendar object for UK locale
- return (new GregorianCalendar(bst_tz,Locale.UK) );
- }
-
-
- and here is how you would print out values using BST:
-
- // create a template for printing the date
- DateFormat df = DateFormat.getTimeInstance(
- DateFormat.LONG,Locale.UK);
-
- // tell the template to use BST tz.
- df.setTimeZone(TimeZone.getDefault());
- System.out.println("Using British Summer Time "
- +"the time is: "
- + df.format( BritishSummerTime.getTime() ) );
-
- // Now get and compare with current time in GMT
- df.setTimeZone(TimeZone.getTimeZone("GMT") );
- System.out.println("\nCurrent time in GMT is: "
- + df.format(BritishSummerTime.getTime() ) );
-
-
- In the winter, this BST zone is aligned with GMT; in the summer it is
- one hour later (4 a.m. GMT is 5 a.m. BST).
-
- You can look at a list of timezone names and offsets in the file
- $JAVAHOME/src/java/util/TimeZone.java
-
- java.util.Calendar and java.util.GregorianCalendar
-
- 17. (Sect. 9)How do I a create a specific date in the Gregorian Calendar?
-
- [*]If you have a Date use:
-
- myCal.setTime( myDate );
-
- If you have a set of integers representing the year, month and day of
- month use:
-
- Calendar myCal = Calendar.getInstance();
- myCal.set( 1998, Calendar.MARCH, 15 );
-
- Note: Months start with January = 0!
-
- 18. (Sect. 9) How do I use a GregorianCalendar to extract a few fields from
- a Date?
-
- [*]The following code shows how to get some fields from a Date.
-
- Calendar g = Calendar.getInstance();
- g.setTime( aDate );
- int year = g.get( Calendar.YEAR );
- int mon = g.get( Calendar.MONTH );
- int date = g.get( Calendar.DATE );
- mon++; // in class Calendar & GregCal, months run 0-11 ;-(
- System.out.println( mon + "/" + date + "/" + year);
-
- If you want to build a string that has a formated date consider using
- SimpleDateFormat.format().
-
- 19. (Sect. 9) Some people use Calendar.getInstance() while others use new
- GregorianCalendar(). Which one is the correct way to get a Calendar?
-
- [*] Either way is correct, it depends on what you want to be able to
- do. You should use Calendar.getInstance(), if you want your code to be
- ready when the loading of other Calendars are added to the JDK and some
- other calendar is the default for the locale. A particular locale might
- have configured a Hebrew or Islamic Calendar as the default calendar
- and you might want a user to enter a date in his own Calendar, i.e.
- 1-Jan-2000 (Gregorian) = 23-Tevet-576 (Hebrew) = 24-Ramadan-1420
- (Islamic). If you really are trying to place a particular Gregorian
- date, i.e. 4-July-1776, into a Date object, you might as well create a
- GregorianCalendar directly.
-
- 20. (Sect. 9) I changed a field using Calendar.set() and then I checked
- another field. Its value is inconsistent with the value I just set.
- What is going on?
-
- [*]In JDK 1.1.0 the Calendar class did not update all of its fields
- until you called getTime to retrieve the Date that corresponds to the
- fields in the Calendar. To get the earlier version of the Calendar to
- "turn the crank" and calculate all fields you can use the trick:
-
- myCal.setTime( myCal.getTime() ) // pull the date out and put it back
- in.
-
- 21. (Sect. 9) When I create the date July 4th, 1776 using new
- GregorianCalendar( 1776, 7, 4 ) the month is off by one. What is the
- problem?
-
- [*]You need to be be aware that months start with January equal to 0. A
- better way to create that date would be:
-
- independanceDayUSA = new GregorianCalendar( 1776, Calendar.JULY, 4 );
-
- 22. (Sect. 9)Why aren't there constants for milliseconds per day, week or
- year?
-
- [*]The short answer is: these values are not constants. While some date
- calculations would find these useful, it is important to remember that
- in areas with daylight savings time rules, there are two days per year
- that are not 24 hours long, therefore not all weeks are the same length
- (2 out of 52). Also, because of leap years, not all years are the same
- length.
-
- If you adding values to a calendar consider using either add or roll;
- for example:
-
- myCal.add(Calendar.YEAR, 1 ); // get a value 1 year later.
-
- 23. (Sect. 9) By my count the week of the Year is off by one. What is the
- problem?
-
- [*]The GregorianCalendar class uses the value set by
- setMinimalDaysInFirstWeek() to determine if the fractional week at the
- beginning of the year should be week 1 or week 0. If you don't change
- it, any fractional week could be week 1, depending on the value defined
- for the locale.
- 24. (Sect. 9) What timezone does a calendar use when I don't explicitly set
- one?
-
- [*]The Calendar uses the TimeZone.getDefault() (see discussion under
- TimeZone).
-
- 25. (Sect. 9) Should I stop using Date all together and just use Calendar?
-
- [*] Probably not. The Calendar class is a much larger than a Date
- object. Many other interfaces in standard APIs are defined using a Date
- object. Use Date objects to hold, store or communicate a date-time
- value. Use a Calendar object to manipulate a date-time value.
-
- 26. (Sect. 9) The GregorianCalendar will not accept a date prior to 4713
- B.C. Why?
-
- [*]January 1, 4713 B.C. is the "epoch" date for the Julian Day calendar
- which was invented in the 16th century by the Joseph Justus Scaliger.
- "[T]he Julian day calendar, ... does not use individual years at all,
- but a cycle of 7980 astronomical years that counts a day at a time,
- with no fractional days, no mean year, and no leap years. He came up
- with his number by mulitplying three chronological cycles: an 18-year
- solar cycle, a 19-year lunar cycle, and the 15-year indication period
- used by Romans. All three cycles began together at the same moment at
- the start of the "Julian cycle. ... [This] Calendar lives on among
- astronomers."
- -- David Ewing Duncan, "Calendar", Avon Books, 1998; p 207
-
- Note that the Julian Day calendar is not the same as the Julian
- calendar. The Julian Calendar is named for Julius Caesar. The Julian
- Calendar was used in the Europe from what we now call January 1, 45
- B.C. until at least October 4, 1582 and is still used today by the
- Eastern Orthodox Church to date holidays.
-
- The limitation on dates prior to 4713 BC has been dropped in JDK 1.2.
-
- 27. (Sect. 9) The Calendar class is said not to handle certain historical
- changes. Can you explain some of the limitations?
-
- [*]The date of change from the Julian to the Gregorian calendar depends
- on where you lived at the time. The date can vary from 1582 (most
- Catholic countries, which of course followed the Papal edict) to 1949
- (China). The date of the cutover from using the Julian Calendar (leap
- years ever 4 years) to using the Gregorian Calendar (every 4 years,
- except every 100 unless divisable by 400) is controlled by the method
- GregorianCalendar.setGregorianChange(Date).
-
- It is also the case that January 1 was not always the beginning of the
- year. January 1 was standardized by Julius Caesar in 45 B.C. and Pope
- Gregory XIII in 1582, but others who used the Julian Calendar between
- those dates used other dates for New Years Day. (Anyone who has ever
- been involved in a standardization effort may find it interesting that
- neither an emperor nor a pope could actually complete the
- standardization effort).
-
- The Calendar class uses a TimeZone which does not handle historical
- changes, i.e. the SimpleTimeZone contains only two dates the "spring
- forward" and "fall back" dates and a date that the DST starts (see
- SimpleTimeZone.setStartYear() ). If the local definitions have changed
- then a date/time may not accurately reflect the historical local time.
-
- As noted above, the Date object does not usually include leap seconds,
- unless your hardware includes leap seconds.
-
- While the Calendar class is more than useful for international
- business, it may not be what you want for doing UTC timebased
- calculations or historical dates and times without a more careful
- analysis of its design limits.
-
- java.text.DateFormat and java.text.SimpleDateFormat
-
- 28. (Sect. 9) How do I convert a date in one format to another?
-
- [*] The following code illustrates the technique:
-
- import java.text.*;
- public class DateTest {
- public static void main( String[] args ) {
- SimpleDateFormat df1 =
- new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
- SimpleDateFormat df2 =
- new SimpleDateFormat("dd-MMM-yy");
- String startdatetime = "1998-09-09 06:51:27.0";
-
- try {
- System.out.println("Date is " +
- df2.format( df1.parse(startdatetime) ));
- } catch (ParseException pe) {
- System.out.println("ParseException " + pe );
- }
- }
- }
-
- When run, the program outputs "Date is 09-Sep-98"
- 29. (Sect. 9) How do I use DateFormat to parse a string containing a date?
-
- [*] The easiest way to parse a date that is in a known format is to use
- SimpleDateFormat.parse().
-
- DateFormat df = new SimpleDateFormat( "HH:mm" );
- df.setTimeZone( TimeZone.getDefault() ); // if using JDK 1.1 libraries.
- df.setLenient( false ); // to not allow 26:65 etc.
- Date lateLunchOnDayZero = df.parse( "12:30" );
- System.out.println( lateLunchOnDayZero );
-
- The above code would result in (when in the MST timezone).
-
- Thu Jan 01 12:30:00 MST 1970
-
- To parse other date and time fields, refer to the SimpleDateFormat
- documentation.
-
- 30. (Sect. 9) How do I use a DateFormat to create a text string from a
- Date?
-
- [*] The easiest way to create a string from a date is to use a
- SimpleDateFormat.format(). The following code illustrates how this can
- be done.
-
- DateFormat df = new SimpleDateFormat( "yyyy.MMM.dd HH:mm:ss.SSS z" );
- df.setTimeZone( TimeZone.getDefault() ); // JDK 1.1
- System.out.println( df.format( d ) ); // where d is a Date
-
- For other possible fields from the calendar, see the document for
- SimpleDateFormat.
-
- 31. (Sect. 9) What timezone does a SimpleDateFormat use when I don't
- specify one?
-
- [*]In JDK 1.1, the SimpleDateFormat uses the first timezone defined for
- the locale. In JDK 1.2, it uses the default timezone. See the
- discussion above on how this differs from the Calendar class).
-
- 32. (Sect. 9) I'm not yet using JDK 1.2 and I don't want the DateFormat to
- use the 1st timezone for the locale. How do I change the timezone in a
- SimpleDateFormat to use a different timezone?
-
- [*] The following code sets the timezone of a DateFormat to the current
- default.
-
- DateFormat df = DateFormat.getDateInstance();
- df.setTimeZone(TimeZone.getDefault());
-
- or to set it to a timezone of your chioce.
-
- df.setTimeZone(TimeZone.getTimeZone( "MST" ) ) // Mtn Time, Denver USA
-
- 33. (Sect. 9) What century is assumed when I use a two digit year in a
- SimpleDateFormat string?
-
- [*]In JDK 1.1, the default start for the century used by
- SimpleDateFormat for 2 digit years is 80 years before the current date.
-
- This means that in 1998: 1 = 2001, 2 = 2002, ... 17 = 2017, 18 = 2018,
- 19 = 1919, 20 = 1920, ... 98 = 1998, 99 = 1999,
-
- In JDK 1.2 you can change this "default century start date" with the
- method set2DigitYearStart( Date) and get its current value
- with the method get2DigitYearStart(). One thing to note is that since
- set2DigitYearStart takes a date not a year, you can have your default
- century begin at any day or hour.
-
- When running under JDK 1.1, it is probably best to avoid two-digit year
- fields, when the dates entered could possibly fall outside of the range
- -- now less 80 years and now plus 20 years. If you want to allow
- two-digit year fields in JDK 1.2 and beyond, consider setting the
- 2DigitYearStart property to something appropriate, For example, set it
- to today, when all dates to be entered are in the future (i.e. an
- expiration date), or set it to today less 100 years, when the value is
- always in the past (i.e. birthdate, death date).
-
- 34. (Sect. 9) Does the above mentioned limitation of 2 digit years in JDK
- 1.1 mean that java.text.SimpleDateFormat is not Y2K compliant?
-
- [*] No. It means that any code you write that (1) allows the entry of 2
- digit years and (2) does not make sure they are in an appropriate
- century, would not pass a careful Y2K analysis. This code was put here
- so you could sensibly read old files with non-Y2K compliant dates, not
- so you could create new ones. Once you are using JDK 1.2 it is better
- to set the 2DigitYearStart property to something appropriate for any
- two-digit year field which you are parsing.
-
- java.sql.Date and java.sql.TimeStamp
-
- 35. (Sect. 9) What timezone does a java.sql.date use when converting to an
- SQL DATE?
-
- [*]This is another hidden use of the default java.util.TimeZone. If you
- have carefully set every timezone in every Calendar and DateFormat you
- are using, but you don't set the default in java.util.TimeZone when a
- java.util.Date is converted to a java.sql.Date you may not end up with
- the value you expected in your database.
-
- 36. (Sect. 9) When I print a jave.sql.Timestamp it doesn't include any
- milliseconds. What is the problem?
-
- [*] If you print the java.sql.Timestamp directly you will see this
- problem. The following code demonstrates this surprising behavior.
-
- // incorrect use of java.sql.Timestamp
- DateFormat df = new SimpleDateFormat( "MM/dd/yy hh:mm:ss.SSS a" );
- df.setTimeZone( TimeZone.getDefault() ); // needed in JDK 1.1
-
- java.sql.Timestamp t = new java.sql.Timestamp( 94, Calendar.JANUARY, 1,
- 13, 45, 59, 987654321 );
- System.out.println( df.format( t ) ) ; // Wrong! no fractions of a second.
-
- The results of the above code are:
-
- 01/01/94 01:45:59.000 PM
-
- The above code is using whatever is in the super class (java.util.Date)
- and assumes all of those parts are filled in. java.sql.Timestamp could
- have stored the whole milliseconds in the millisecond part of a
- java.util.Date, and stored the nanoseconds that are not whole
- milliseconds in an additional field. They chose to ignore the fractions
- of a second in the java.util.Date and put all fractional parts in an
- additional nanosecond field.
-
- The following code shows how to convert a java.sql.timestamp to a
- java.util.Date.
-
- Date d = new Date(t.getTime() + (t.getNanos() / 1000000 ));
- // 1 Milli = 1x10^6 Nanos
- System.out.println( df.format( d ) ) ; // Right! At least we have the millis
-
- The result of the above code is a better approximation of the timestamp
- value:
-
- 01/01/94 01:45:59.987 PM
-
- 37. (Sect. 9) How do I calculate the number of days between two dates?
-
- [*] There is no API for this (there should be), but you can calculate
-
- static final long ONE_HOUR = 60 * 60 * 1000L;
-
- Calendar earlierDate = new GregorianCalendar();
- Calendar laterDate = new GregorianCalendar();
-
- earlierDate.set(1997, 1, 5, 0, 0, 0); // FEB!! 05, 1997
- laterDate.set(1998, 1, 5, 0, 0, 0); // Feb 05, 1998
-
- // the first getTime() returns a Date, the second takes
- // that Date object and returns millisecs since 1/1/70.
- // The API has misleading and horrible naming here, sorry.
- long duration = laterDate.getTime().getTime() -
- earlierDate.getTime().getTime();
-
- // Add one hour in case the duration includes a
- // 23 hour Daylight Savings spring forward day.
- long nDays = ( duration + ONE_HOUR ) / (24 * ONE_HOUR);
- System.out.println("difference in days: " + nDays);
-
-
- Note: this method works only if the two times are both created to be
- exactly midnight. Otherwise you might end up finding that for example,
- 11 PM tonight is 0 days away from 6 AM tomorrow, instead of 1 day as
- many applications expect. This is because 24 hours haven't elapsed
- between 11pm on one day and 6am on the next.
-
- Or, use int julian = myCalendar.get(Calendar.DAY_OF_YEAR); and
- subtract, making sure to subtract the years too. Alternatively, use
- BigDate at http://mindprod.com.
-
- For the ultimate in generality, you could get ACM's Collected Algorithm
- 199, recode it in Java (takes about 30 minutes), compute the Julian
- date for each end point, and subtract the two numbers. Here is the code
- in Java to get the GMT Julian day number and a "local Julian Day" that
- leverages the existing algorithms in the GregorianCalendar.
-
- import java.util.*;
- import java.text.*;
-
- /**
- * This Calendar provides Julian Day and "Calendar Day" methods,
- * The Calendar Day starts at _local_ midnight.
- *
- * @author Paul A. Hill
- * @version 1.1
- * @since JDK 1.1.7 3/99
- * @see java.util.Calendar
- */
- public class FAQCalendar extends GregorianCalendar implements Cloneable {
- /**
- ** this constant and the ones that follow are actually private
- ** in the GregorianCalendar, so we'll redefine them here.
- **/
- public static final long
- ONE_SECOND = 1000,
- ONE_MINUTE = ONE_SECOND * 60,
- ONE_HOUR = ONE_MINUTE * 60;
- /**
- * this next constant and the others with it have their uses,
- * but watch out for DST days and the weeks that contain them.
- * Note also that 1/1/1970 doesn't start on the first day of the week.
- */
- protected static final long
- ONE_DAY = ONE_HOUR * 24,
- ONE_WEEK = ONE_DAY * 7;
-
- /** The number of days from Jan 1, 4713 BC (Proleptic Julian)
- ** to 1/1/1970 AD (Gregorian). 1/1/1970 is time 0 for a java.util.Date.
- **/
- public static final long JULIAN_DAY_OFFSET = 2440588L;
-
- /**
- * Same as GregorianCalendar(). Creates a calendar with the time set to
- * the moment it was created.
- *
- Note: for Brevety I have not provided all of the other
- * constructors that you can find in GregorianCalendar.
- *
- * @see java.util.GregorianCalendar#GregorianCalendar
- */
- public FAQCalendar() {
- super();
- }
-
- /**
- * A calendar day as defined here, is like the Julian Day but it starts
- * and ends at _local_ 12 midnight, as defined by the timezone which is
- * attached to this calendar. This value is useful for comparing
- * any date in the calendar to any other date to determine how many days
- * between them, i.e. tomorrow - today = 1
- *
- * @return the calendar day (see above).
- * @see #getCalendarDay
- */
- public long getCalendarDay() {
- TimeZone tz = getTimeZone();
- // Figure the exact offset for the exact time of day.
- int offset = tz.getOffset( get( ERA ), get( YEAR ),
- get( MONTH ), get( DAY_OF_MONTH ), get( DAY_OF_WEEK ),
- (int)((long)get( HOUR_OF_DAY ) * ONE_HOUR +
- get( MINUTE ) * ONE_MINUTE +
- get( SECOND ) * ONE_SECOND ) );
- return round( ONE_DAY, getTime().getTime() + offset ) + JULIAN_DAY_OFFSET;
- }
-
- /**
- * Sets the date in the calendar to 00:00 (midnight) on the local calendar day.
- * See getCalendarDay for the definition of calendar day as used in this class.
- *
- * @param calendarDay the day to set the calendar to.
- * @see #setCalendarDay
- * @see java.util.TimeZone#getRawOffset
- */
- public void setCalendarDay( long calendarDay ) {
- // Set to the beginning of the Julian day.
- // Then add in the difference to make it 00:00 local time.
- setJulianDay( calendarDay );
- setTimeInMillis( getTime().getTime() - getTimeZone().getRawOffset() );
- // we may have gone slightly too far, because we used the
- // raw offset (diff between Standard time to GMT/UT, instead of the
- // actual value for this day, so during DLS we may be at 1 AM or whatever
- // the local DLS offset is), so we'll just drop back to midnight.
- set( HOUR_OF_DAY, 0 );
- }
-
- /**
- * Finds the number of days after 12/31/4312 BC 24:00 GMT on a proleptic
- * Julian Calendar (i.e. extending the Julian Calendar into pre-history)
- * to the current time.
- *
- The Astronomers Julian Day begins at noon. The Julian Day used here
- * sometimes called the Chronologists or Historians Julian Day
- * starts at midnight. For more information see
- * http://www.magnet.ch/serendipity/hermetic/cal_stud/jdn.htm#astronomical
- *
- Note: This routine does NOT take into consideration
- * leap seconds.
- *
- * @return the day number of the current time from 1/
- * @see #getCalendarDay
- */
- public long getJulianDay() {
- return round( ONE_DAY, getTime().getTime() ) + JULIAN_DAY_OFFSET;
- }
-
- /**
- * Sets the current date contained in this calendar to exactly
- * 00:00 GMT on the date defined by the Julian Day provided.
- *
- * @param julianDay the Julian Day to set the calendar to
- * @see #setCalendarDay
- */
-
- public void setJulianDay( long julianDay ) {
- setTimeInMillis( ( julianDay - JULIAN_DAY_OFFSET ) * ONE_DAY );
- }
-
- /**
- * This is a utility routine for rounding (toward negative) to the nearest
- * multiple of the conversion factor.
- *
- BUG? Why is this different than the formula given in
- * java.util.GregorianCalendar private millisToJulianDay?
- *
- * @param conversion typically one of the constants defined
- * above ONE_MINUTE, ONE_DAY etc.
- * @param fractions the value to convert expressed in the same units
- * as the conversion factor (i.e milliseconds).
- *
- * @return the value divided by the conversion factor, rounded to the negative.
- * @see java.util.Calendar
- */
- protected static final long round( long conversion, long fractions ) {
- long wholeUnits;
-
- // round toward negative:
- // For secs rounded to minutes -61/60=-1, -60/60=-1, -59/60=0,
- // but we want -2, -1, -1 not -1,-1,0
- // or month 0..11 => year 1; -12..-1 => 0; -24..-13 => -1
-
- if ( fractions >= 0 ) {
- wholeUnits = fractions / conversion;
- }
- else {
- wholeUnits = ( fractions + 1 )/ conversion - 1;
- }
- return wholeUnits;
- }
- } // FAQCalendar
-
-
- -------------------------------
-
- 10. AWT
-
- Text, Textfield, and TextArea
-
- 1. (Sect. 10) How can I write text at an angle?
-
- [*] Check out http://www.nyx.net/~jbuzbee/font.html. Jim has some code
- to do exactly this. A good way to do it is to draw the text to an
- offscreen image and write an ImageFilter to rotate the image.
-
- Also, from JDK 1.2 on, the Java 2D API handles arbitrary shapes, text,
- and images and allows all of these to be rotated, scaled, skewed, and
- otherwise transformed in a uniform manner. A code example would be:
-
- import java.awt.*;
- import java.awt.geom.*;
- public class r extends Frame {
-
- public static void main(String args[]) { new r(); }
-
- r() { setSize(200,200); setVisible(true); }
-
- public void paint(Graphics g) {
- Graphics2D g2D = (Graphics2D) g;
- AffineTransform aft = new AffineTransform();
- aft.setToTranslation(100.0, 100.0);
- g2D.transform(aft);
- aft.setToRotation(Math.PI / 8.0);
- String s = "Rotated Hello World";
-
- for (int i = 0; i < 16; i++) {
- g2D.drawString(s, 0.0f, 0.0f);
- g2D.transform(aft);
- }
- }
- }
-
- There is more info about the 2D API at
- http://java.sun.com/products/java-media/2D/index.html and
- http://developer.javasoft.com/developer/technicalArticles/
-
- 2. (Sect. 10) How do you change the font type and size of text in a
- TextArea?
-
- [*] Like this.
-
- myTextArea.setFont(new Font("NAME", <STYLE>, <SIZE>));
-
- where:
- o NAMEis the name of the font (e.g. Dialog or TimesRoman).
- o <STYLE> is Font.PLAIN, Font.ITALIC, Font.BOLD or any additive
- combination (e.g. Font.ITALIC+Font.BOLD).
- o <SIZE> is the size of the font, e.g. 12.
-
- Example: new Font("TimesRoman", Font.PLAIN, 18);
-
- 3. (Sect. 10) Can you have different fonts for individual words in a
- TextArea?
-
- [*] No. If you're trying to write a word processor, use the Canvas
- class to render on. Note that this can be done using the Swing JText
- classes.
-
- 4. (Sect. 10) How much text can be put in a TextArea?
-
- [*] TextArea just uses the corresponding widget of the underlying
- window system. It will be bounded by the limit imposed in the native
- window system. In Windows 95 TextAreas can hold about 28Kb. The native
- widget allows 32Kb, but there is some overhead which reduces the amount
- available to the programmer. The limit is removed in JTextComponent in
- Swing (JDK 1.2) which dispenses with peer controls.
-
- 5. (Sect. 10) How do I clear the contents of a TextArea?
-
- [*] Set it to an empty String with this:
-
- area.setText("");
-
- 6. How do I get back to a normal echo after I have used
- TextField.setEchoChar('*')?
-
- [*] TextField.setEchoChar('\0') works on most Windows-based
- browsers...but for most other platforms (i.e. Netscape under UNIX), it
- just locks up the textfield.
-
- There is only one good solution, and that is to make two TextFields on
- top of each other, one normal, and one with .setEchoChar('*'), and
- switch between them.
-
- 7. (Sect. 10) How do I get word wrap in a TextArea?
-
- [*] It's a little obscure. Creating a TextArea with no horizontal
- scrollbar causes wrapping to occur automatically. The idea is that if
- you ask for a scroll to scroll viewing over to the right, there is no
- reason for the widget to do word wrap. So take away the scrollbar, and
- word wrap will be done instead.
-
- Supply TextArea.SCROLLBARS_NONE or TextArea.SCROLLBARS_VERTICAL_ONLY to
- the TextArea constructor to get word wrap. By default, a TextArea is
- created with both horizontal and vertical scrollbars.
-
- 8. (Sect. 10) How can I limit a TextField to no more than N characters, or
- to only allow numeric input?
-
- [*] The approach is to look at keystrokes as they happen, and disallow
- input that does not meet your criteria.
-
- A neat variation is to extend the basic AWT component, and in your
- subclass also include the handler that will look at the keystrokes.
- This bundles everything neatly in one place. The code may look like:
-
- import java.awt.*;
- import java.awt.event.*;
-
- public class XCTextField extends java.awt.TextField implements
- java.awt.event.TextListener {
-
- public XCTextField(int columns) {
- super(columns);
- enableEvents(AWTEvent.FOCUS_EVENT_MASK);
- addTextListener(this);
- }
-
- // other constructors may be useful, too
-
- public void textValueChanged(java.awt.event.TextEvent event) {
- int col = this.getColumns();
- int len = getText().length();
- // int caret = getCaretPosition();
-
- if (col > 0 && len > col) {
- // or if the char just entered is not numeric etc.
- String s = this.getText();
- Toolkit.getDefaultToolkit().beep();
- this.setText(s.substring(0,col));
- this.setCaretPosition(col-1); // caret at end
- }
-
- }
-
- public void processFocusEvent(java.awt.event.FocusEvent e) {
- // this routine highlights according to focus gain/loss.
- super.processFocusEvent(e);
- int id = e.getID();
- if (id==java.awt.event.FocusEvent.FOCUS_GAINED)
- this.selectAll();
- else if (id==java.awt.event.FocusEvent.FOCUS_LOST)
- this.select(0,0);
- }
- }
-
- Here is a much briefer example, which very cleverly does the work in
- the Listener. Oracle really dislikes the "apostrophe" character in a
- data text fields, as it is interpreted as part of an SQL statement.
- Here is the code that James Cloughley wrote to suppress apostrophes
- ("ticks") in a TextField.
-
- import java.awt.*;
- import java.awt.event.*;
- public class NoTick extends KeyAdapter {
- final char tick = '\'';
-
- public void keyPressed( KeyEvent event ) {
- TextComponent tc = ( TextComponent )event.getSource();
- char c = event.getKeyChar();
- if ( c == tick ) { event.consume(); }
- }
- }
-
- Use it like this:
-
- TextField sometextfield = new TextField();
- sometextfield.addKeyListener( new NoTick() );
-
-
- Brief and clever - make the event handler consume unwanted characters.
- However, it doesn't filter out text that arrives in the component via
- cut & paste! If you use ctrl-v to paste, you get key events for the
- ctrl and v, but not for the characters that are pasted.
-
- Finally, check out iDate, iTime, and iNumeric from IBM's alphaworks
- javabeans, available free at http://www.alphaworks.ibm.com/alphaBeans.
- These beans do the kind of validation you want.
-
- Size and Position
-
- 9. (Sect. 10) I use add(Component) to add Components to the Container. Is
- there any way to explicitly set the z-order of these Components?
-
- [*] JDK 1.0 has no way to explicitly set the z-order of components. You
- can try it heuristically, based on the browser you're using, or you can
- use CardLayoutManager to ensure the panel you want is at the front.
-
- In JDK 1.1, the z-order of components ("z-order" means "front-to-back"
- order, i.e. which window is in front of which) can be controlled by
- using the the method add(Component comp, int index). By default,
- components are added 0 to N. The method paint of class Container paints
- its visible components from N to 0.
-
- 10. (Sect. 10) How can I get the dimensions and resolution of the screen?
-
- [*] Use
-
- java.awt.Toolkit.getDefaultToolkit().getScreenSize()
-
- or
-
- java.awt.Toolkit.getDefaultToolkit().getScreenResolution()
-
- Screen resolution is in dots-per-inch.
-
- Take a look in the Toolkit class for other useful methods.
-
- Toolkit.getDefaultToolkit().getColorModel().getPixelSize()
-
- gets you the color model in terms of bits per pixel.
-
- Math.pow(2, Toolkit.getDefaultToolkit().
- getColorModel().getPixelSize())
-
- gets you the color model in terms of number of colors. Or use this:
-
- 1 << Toolkit.getDefaultToolkit().
- getColorModel().getPixelSize()
-
- That does a shift left to calculate the power of two.
-
- 11. (Sect. 10) How do I allow for the size of the title bar and border when
- I draw a Frame?
-
- [*] Use MyFrame.getInsets(). This returns a java.awt.Insets object
- which has four ints: top, left, bottom, right, giving the number of
- pixels each of those margins are inset from the top. You can use these
- value to adjust the Dimension object returned by component.getSize().
-
- If you are doing this in the constructor you need to ensure that the
- Frame's peer object is created first. Otherwise the Insets object
- returned by getInsets() will have all zero values. Make a call to
- Frame.addNotify() to have the peer created.
-
- 12. (Sect. 10) How do I resize a List? I had a List defined as
-
- List tlist = new List(10);
-
- but the Strings in the list were 80 characters long and only the first
- 15 were being shown. I was not able to resize the List to display the
- contents without using the scroll bar.
-
- [*] A List cannot be resized in a constructor, so add the following to
- the Applet (or wherever):
-
- public void paint (Graphics g) {
- tlist.setSize(200,200);
- }
-
- Then before showing panel/frame with the List:
-
- tlist.resize(400,400);
-
- 13. (Sect. 10) How can my program tell when a window is resized?
-
- [*] Override the setBounds(int,int,int,int) method of Component to do
- what you want. Of course, have it call super.setBounds() as well. Note
- that setBounds() replaces reshape() which is deprecated.
-
- Note the new APIs call the deprecated APIs instead of the other way
- round. For example, Component.setBounds calls Component.reshape,
- instead of reshape calling setBounds. This is because the AWT sometimes
- needs to call these for its own purposes. If it called the old one
- which then called the new one, and you overrode the new one, the AWT
- would (wrongly) not call your routine. By having the AWT call the new
- one (and then the new one call the old one), any overrides of the new
- one will correctly be called by the AWT as needed. If that didn't make
- sense, forget I mentioned it.
-
- 14. (Sect. 10) How do I center a dialog box?
-
- [*] You cannot currently get the applet's absolute screen coordinates.
- Its location (0,0) is relative to the browser, not the screen itself.
- But you can center something that it pops up or displays centered on
- the screen with code like this:
-
- Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- my_window.move(
- ( screen.width - my_window.size().width ) / 2,
- ( screen.height - my_window.size().height ) / 2 );
-
- my_window.show().
-
- In a related fashion, you can center something on its parent like this.
- Note the intelligent use of APIs like translate() to do the work for
- you.
-
- void center(Component parent) {
- pack();
-
- Point p = parent.getLocation();
- Dimension d = parent.getSize();
- Dimension s = getSize();
-
- p.translate((d.width - s.width) / 2,
- (d.height - s.height) / 2);
- setLocation(p);
- }
-
- 15. (Sect. 10) How can I get the absolute mouse coordinates?
-
- [*] You mean, if the browser is about 640x480, you want a y-coord
- between 0 and 480. If the browser window is about 800x600 you want a
- y-coord between 0 and 600. This might be needed for a pop-up menu,
- where you want to pop up at the absolute mouse position.
-
- The approach is to sum up the event's (x,y) and the locations of the
- target and its parents until there is no parent. Though on some
- browsers, it seems this is not reliable. [Better suggestions are
- solicited.]
-
- 16. (Sect. 10) How do I detect a resize of a Frame or other Component?
-
- [*] If you are using JDK 1.0.2, you can override the reshape(int, int,
- int, int) method of Component to do what you want; of course, have it
- call super.reshape() as well.
- In JDK 1.1.x, setBounds() replaces reshape(), which is deprecated -
- however, there is a better way of detecting the resize using the new
- event model, than overriding setBounds(). Note the new APIs call the
- depecated one.
-
- The proper way to detect the resize in 1.1.x is to register a
- ComponentListener on the Frame, like this:
-
- import java.awt.*;
- import java.awt.event.*;
-
- class MyFrame extends Frame {
- public MyFrame() {
- addComponentListener(new CmpAdapter());
- }
-
- class CmpAdapter extends ComponentAdapter {
- public void componentResized(ComponentEvent evt) {
- //doSomething();
- }
- }
- }
-
- Alternatively, the same effect can be achieved like this:
-
- class MyFrame extends Frame implements ComponentListener {
- public MyFrame() {
- addComponentListener(this);
- }
-
- public componentHidden(ComponentEvent evt) { }
- public componentMoved(ComponentEvent evt) { }
- public componentShown(ComponentEvent evt) { }
- public componentResized(ComponentEvent evt) {
- //doSomething
- }
- }
-
- Or even with an anonymous inner class
-
- public MyFrame() {
- addComponentListener(new ComponentAdapter() {
- public void componentResized(ComponentEvent evt) {
- // doSomething;
- }
- } );
- }
-
- 17. (Sect. 10) What are those preferredSize() and minimumSize() methods in
- Component?
-
- [*] Those methods allow a LayoutManager to calculate the preferred and
- minimum sizes of the Components it is arranging. You can control the
- values that the LayoutManager gets by creating subclasses of the
- Components you are using and overriding these methods. You don't call
- them; you override them and they are called on your behalf.
-
- 18. (Sect. 10) Why isn't my component showing up at all? Or in some cases
- not until I resize the main window?
-
- [*] The initial sizes of components are not always exactly what the
- programmer would expect. When a component doesn't show up, often it is
- getting added to its parent, but with a size of 0x0. Even when
- getPreferredSize gives a non-zero value. If this seems to be what's
- happening, try calling setSize(getPreferredSize()). If that doesn't
- seem to be the problem, look into your layout manager.
-
- Drawing and Pixels
-
- 19. (Sect. 10) How do I plot a single pixel to the screen?
-
- [*] Use g.drawLine(x1,y1,x1,y1) to draw a line one pixel in length. If
- you are drawing a very large number of individual pixels, consider
- using a java.awt.MemoryImageSource object and measure whether this
- offers better performance.
-
- 20. (Sect. 10) Is it possible to draw a polygon or a line more than 1 pixel
- wide?
-
- [*] JDK 1.1 doesn't have support for this. The standard workaround for
- drawing a thick line is to draw a filled polygon. The standard
- workaround for drawing a thick polygon is to draw several polygons.
-
- There is a useful class at
- http://www.apl.jhu.edu/~hall/java/GraphicsUtil.html which extends the
- drawxxx and fillxxx methods of java.awt.Graphics. It adds a Line Width
- argument to most of the drawxxx methods, a Color argument to most of
- the drawxxx and fillxxx methods, and a Font argument to drawString and
- drawChars.
-
- JDK 1.2 introduces the java.awt.BasicStroke class. You set the stroke
- on a Graphics object, and line rendering is done using that info.
-
- BasicStroke bs = new BasicStroke(width, BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_MITER, 1.0f, null, 0.0f);
- g.setStroke(bs);
- g.drawLine( ... );
-
- 21. (Sect. 10) How can I make an offscreen image with transparent pixels?
- How can I grab the pixel values from an offscreen image?
- How can I use AWT drawing primitives (e.g. drawString() or drawOval())
- on an image I created from an ImageProducer?
-
- [*] None of these things can be done.
-
- Despite the fact that there is only one class called Image in the AWT
- libraries, it suffers from a (currently undocumented) severe case of
- schizophrenia: The code behaves as though there are two unrelated types
- of Image. The first type are those created by the
- Component.createImage(int, int) call, known as "offscreen" images, and
- the second are those created by the
- Component.createImage(ImageProducer) call, or by the
- Toolkit/Applet.getImage() calls, which I will call "produced" images.
-
- The only common ground between these kinds of Image is the following:
- o You may find their width and height by the methods of the Image
- class.
- o You may use them as the argument to the various
- Graphics.drawImage() calls.
- The differences between these objects are the following:
- o You may not put transparent pixels into an offscreen - note that
- all Java primitives accept Color objects, which all represent
- completely opaque colours as if Produced from an int with the
- upper 8 bits equal to 0xff. (See also Question 8.3.)
- o You may not call Image.getGraphics() on a produced image, and
- hence may not use any AWT primitives.
- o You may not grab pixels from an offscreen image using
- PixelGrabber.
- o Anyone know of any other limitations?
- In these cases, "you may not" generally means "you may not
- successfully". Symptoms on attempting these range from Exceptions to
- garblings of the Image. Any or all of these restrictions may be removed
- in Java 1.2, which features a new 2D API. Wait and see.
- Workaround: cause a peer to be created for the Image, and then do the
- operation. It will work. You can add it to a Frame, for example. You do
- not have to show() the Frame. Causing the peer to be created is enough.
-
- There are some relevant bugs shown in the Java Developer Connection:
- Bug ID 4098505. Apparently, from the report from the Sun engineer,
- PixelGrabber is specified to work with offscreen images, just it is
- currently buggy, and invariably gets the wrong color model. No fix has
- been scheduled yet.
-
- Bug ID 4077718 reports that setting transparent Colors in offscreen
- images has been available since Java 1.2b1. I am personally unable to
- verify this.
-
- There is an incorrect answer from Sun to the third matter, of
- getGraphics() on produced images, in article 1501 in Questions&Answers.
-
- 22. (Sect. 10) How can I grab a pixel from an Image object?
-
- [*] This is the purpose of the java.awt.image.PixelGrabber class. A
- fragment of code showing its use is:
-
- import java.awt.image.PixelGrabber;
- import java.awt.Image;
- ...
- public static int pixelValue(Image image, int x, int y) {
- // precondition: buffer must not be created from ImageProducer!
- // x,y should be inside the image,
- // Returns an integer representing color value of the x,y pixel.
- int[] pixel=new int[1];
- pixel[0]=0;
-
- // pixel grabber fills the array with zeros if image you are
- // trying to grab from is non existent (or throws an exception)
- PixelGrabber grabber = new PixelGrabber(image,
- x, y, 1, 1, pixel, 0, 0);
- try {
- grabber.grabPixels();
- } catch (Exception e) {System.err.println(e.getMessage());}
- return pixel[0];
- }
-
- By the way, one issue on working with images is that the Java VM will
- consume virtual memory pretty fast if you are loading lots of images
- without calling the Image.flush() method when done. The getImage()
- method probably caches old images so they aren't garbage collected.
-
- Other AWT FAQs
-
- 23. (Sect. 10) How do I change the icon on my Frame or JFrame from the Java
- coffee cup to my own icon?
-
- [*] Just use
-
- f.setIconImage( Toolkit.getDefaultToolkit().getImage(iconfilename) );
-
- On Windows, the icon must be 16-by-16 pixels.
-
- 24. (Sect. 10) What's all this about subclassing Canvas and overriding
- paint() ? Can't I just do a getGraphics() for a component, and draw
- directly on that?
-
- [*] You can do that, and it might work up to a point (or it might not).
- A problem arises when the window system wants to refresh that component
- e.g. because it has been partially obscured and is now revealed. It
- calls paint(), and paint() has no knowledge of the other g.drawing()
- you have just done.
-
- 25. (Sect. 10) But couldn't the AWT just remember what has been drawn to a
- Graphics context, and replicate that instead of calling paint()?
-
- [*] Possibly it could, but how do you unremember something that has
- been drawn? How do you start drawing over again with different
- contents? You could solve these by creating extra methods, but that is
- not how it works. In practice it is a lot simpler to be able to look at
- the paint method, and see explicitly all the things that will be done
- to draw that component. Bottom line: Use paint(), not g=getGraphics();
- g.drawString( ...
-
- 26. (Sect. 10) When I call repaint() repeatedly, half my requests get lost
- and don't appear on the screen. Why is this?
-
- [*] repaint() just tells the AWT that you'd like a paint to happen. AWT
- will fold several adjacent repaint requests into one, so that only the
- most current paint is done. One possible workaround might be to use a
- clip rectangle and only paint the different areas that have changed.
-
- 27. (Sect. 10) Why do I get this when using JDK 1.1 under X Windows?
-
- java.lang.NullPointerException
- at sun.awt.motif.MFramePeer.<init>(MFramePeer.java:59)
- at sun.awt.motif.MToolkit.createFrame(MToolkit.java:153)
- at java.awt.Frame.addNotify(Frame.java)
- at java.awt.Window.pack(Window.java)
-
- [*] There's a missing font on your system. Move font.properties from
- the "lib" subdirectory aside to font.properties.bak. Then it won't look
- for the font and fail to find it.
-
- The problem occurs because the Motif AWT libraries use the Font "plain
- Dialog 12 point" as a fall-back default font. Unfortunately, when using
- a remote X server sometimes this font isn't available.
-
- On an X terminal, the diagnostic may be slightly different, a segv
-
- % appletviewer HelloWorldApplet.html
- SIGSEGV 11* segmentation violation
- si_signo [11]: SIGSEGV 11* segmentation violation
- si_errno [0]: Error 0
- si_code [1]: SEGV_ACCERR [addr: 0x14]
-
- To determine which fonts you have, issue a command such as
-
- xlsfonts > ~/fonts.txt
-
- Then pick through the long list of fonts to determine which ones you
- want to use. The xfd program will let you look at a font:
-
- xfd -fn "your font name here" &
-
- 28. (Sect. 10) Why is GridBagLayout so hard to use?
-
- [*] There are two reasons. First, while simple layouts are easy.
- detailed GUI layout is difficult. Second, GridBagLayout wasn't designed
- with human factors and ease of use in mind. If that bothers you (it
- bothers me) then don't use it. Create your GUI on several panels and
- use the other layout managers as appropriate to get the exact effect
- you want. The official story from the project leader of the AWT
- project, as explained to the Mountain View Java Users Group on December
- 4 1996, is:
- "The case has been made and is now accepted that GridBagLayout is
- too hard to use for what it offers. GBL will continue to be
- supported, and something better and simpler will eventually be
- provided as well. This 'better GBL' can be used instead of GBL."
- Bottom line: nobody has to spend any effort on GBL, there are simpler
- alternatives available now. In addition GBL is the source of a memory
- leak. GBL puts "added" components into a hashtable, but
- removeLayoutComponent() never removes them. See bug 4195295.
-
- GBL documentation is hard to come by. Based on the obvious similarity,
- it could have been derived from the Tk (of Tcl/Tk) grid layout manager.
- If you're not a fan of nesting panels, and none of the other layout
- managers do what you want (or you're working with legacy code that
- already uses it), you might find some Tk documentation worth a look.
-
- 29. (Sect. 10) MyClass works fine except when I try to set a particular
- font. I just can't seem to get it to work in Win95, but I can get it to
- work on a MacOS and Unix.
-
- [*] You probably specified a font name that isn't available under your
- Win95 installation; this is one of those cross-platform differences
- that can bite you if you over-specify for one platform, like specifying
- "Arial" as a font and expecting it to work on something other than
- Windows.
-
- On both Windows 95 and Solaris 2.6, these fonts
- o Dialog
- o SansSerif
- o Serif
- o Monospaced
- o Helvetica
- o TimesRoman
- o Courier
- o DialogInput
- o ZapfDingbats
- are revealed by this code:
-
- import java.awt.*;
-
- class foonly {
- static public void main(String s[])
- {
- String n[]= new Frame().getToolkit().getFontList();
- for (int i=0;i<n.length; i++)
- System.out.println(n[i]);
-
- System.exit(0);
- }
- }
-
- In other words, You can get a String array of the names of the fonts by
-
- String[] fonts = Toolkit.getDefaultToolkit().getFontList()
-
- The names of actual fonts like Helvetica, TimesRoman, and Courier are
- deprecated in JDK 1.1 in favor of font styles like SansSerif, Serif,
- and Monospaced (respectively). The font style will be mapped into the
- nearest actual font on a platform.
-
- The font styles are now mapped into a system font name using the
- entries in one of the font.properties files in $JAVAHOME/lib. There are
- multiple font.properties files corresponding to different locales. If
- you wanted a quick hack for testing, you could modify the file or add
- to it so a different mapping is done to a new font you want to try.
-
- 30. (Sect. 10) I've made a Lightweight Component (a Component directly
- extending Component), and it keeps flickering/doesn't repaint itself
- properly. Why is this?
-
- [*] Lightweight Components, since they are notionally meant to be
- "transparent", aren't painted directly in response to repaint(), but in
- fact, Component.repaint() goes up the stack of Components until it
- finds an "Opaque" Heavyweight Component (necessarily a Container), and
- then calls repaint() on *that*.
-
- At this point, a call is eventually scheduled to Container.update().
- His first action is to call super.update, plunging us into
- Component.update(), which clears the component to the background color,
- since it has been called on a heavyweight, and returns. Then
- Container.update() proceeds merrily to call update on all contained
- Lightweight Components, recursively.
-
- The bottom line: "transparency" of lightweight components will only
- work correctly (without flickering) if the first upwardly accessible
- heavyweight component in the containment hierarchy is
- o a double-buffered heavyweight Component (necessarily a Container),
- or
- o a heavyweight that never updates, but always paints (i.e. one that
- has overriden the default update() mechanism to not clear the
- background).
- If this is not done, the default Component update() will always clear
- the background before any repainting is done, leading to annoying
- flickering.
-
- Another important point is that if your Container has its own paint()
- method, that paint method of the container must call
- super.update/paint(), otherwise the contained lightweight components
- will never be painted. Putting this all together, the minimal
- alteration to code to cause it to work in this case is to place the
- method
-
- public void update(Graphics g) {
- super.paint(g);
- }
-
- in the most closely containing heavyweight Container, in a Component
- hierarchy where you want to smoothly render lightweights that do not
- paint areas extending past that painted by their parents, i.e. ones
- that are not "transparent". This is dirty, but quick.
-
- If you want smooth transparency, the call above should read
-
-
- public void update(Graphics g) {
- // standard offscreen generation here.
- offg.fillRect(required background colour, full size);
- super.paint(offg);
- g.drawImage(myimage, 0, 0, null);
- }
-
- public void paint(Graphics g) {
- // can generally expect resizes will hit update() first.
- super.paint(offg);
- g.drawImage(myimage, 0, 0, null);
- }
-
- It's possible to intertwine these, by having this.update() calling
- this.paint(), with various replacings of the argument, but it is
- clearest to override them separately, as in the example.
-
- 31. (Sect. 10) What is the difference between Component's
- setForeground(Color c) and Graphics's setColor(Color c) ?
-
- [*] First of all, these methods do the same thing: Set the foreground
- color to the value of the parameter. The difference lies in where you
- use them. There is also a Component.setBackground that will set the
- background color.
-
- If you are in a constructor or an event handler (e.g. "click here to
- turn the canvas blue") you have a Component and should use the
- setForeground() method. If you are in a paint() method, that takes a
- Graphics context as its argument so you will typically use
- g.setColor(c).
-
- Unlike a Component, a Graphics object doesn't have a background color
- and a foreground color that you can change independently. A Graphics
- object arrives in the color(s) inherited from the drawing surface. From
- then on, any rendering (drawLine(), drawRect(), fillOval(), etc.) will
- be done in the setColor() color. Because they do different things, the
- Component and Graphics methods have different names.
-
- 32. (Sect. 10) When I start a mouse drag inside a Component, and go outside
- the Component, still dragging, the mouse events still get sent to the
- Component, even though I am outside it. Is this a bug?
-
- [*] No, it is the specified behavior. The Java API documentation says:
- "... Mouse drag events continue to get sent to this component even
- when the mouse has left the bounds of the component. The drag
- events continue until a mouse up event occurs...."
- It is done for the convenience and ease of the application programmer.
- It allows you to handle all drags from the place of origin. If you
- don't want this, simply look at the coordinates of the mouseDrag Event,
- and if they are outside the Component, ignore them.
-
- 33. (Sect. 10) Why doesn't my window close when I click on the X in the
- title bar?
-
- [*] Here's how to make your program do that.
- o JDK 1.0.2: Handle Event.WINDOW_DESTROY to do a hide() and
- dispose() on the Frame.
- o JDK 1.1:
- + Listen for WindowEvent and do hide(); dispose(); in
- windowClosing() - this really ought to be the "default"
- behaviour, so was made so for a Swing JFrame.
- + Enable AWTEvent.WINDOW_CLOSING and do the hide() and
- dispose() in processWindowEvent().
- o JDK 1.2: The Component JFrame does a close by default (see section
- 10).
-
- 34. (Sect. 10) How can I force a synchronization of the graphics state,
- e.g. of a cursor change, or an animation frame to be rendered?
-
- [*] This is done by the sync() method in Toolkit. So just use:
-
- AnyComponent.getToolkit().sync();
-
- 35. (Sect. 10) How can I tab between components?
-
- [*] In JDK 1.0, you have to read the key press, and program it
- explicitly. JDK 1.1 supports tab and shift-tab (previous field)
- automatically. The tab order is the order that the components were
- added to the container.
-
- 36. (Sect. 10) What is the difference between "low level" and "semantic"
- events?
-
- [*] Low-level events are tied to a specific component (resizing a
- window, dragging the mouse, striking a key, adding a Component to a
- Container, etc.). Semantic events are those generated when you frob a
- control (move a scrollbar, click on a button, select from a menu,
- etc.), and the same kind of event can be generated by several different
- components. A Button and a List both fire an Action event when they are
- clicked on.
-
- To the programmer, the important difference is that you can change a
- low-level event such as the key value in a keypress, and it will
- display the new value. You can also consume low level events so that
- they do not appear in the widget. You can't do these things with
- semantic events - they have already "occurred" to the widget.
-
- Semantic events: Use the method addXListener() to add a listener object
- which implements the XListener interface to get XEvent objects
- delivered (usually via the AWTEventMulticaster). Low level events: Use
- the method enableEvents() and override performX() to grab those events
- in the object itself.
-
- 37. (Sect. 10) Is it possible to have a Java window float above all other
- windows. For example, a tool palette floats in a super-layer always
- above all the regular document windows on which you use the palette's
- tools?
- [*] On MS Windows, a Window object floats above all other windows,
- unlike a Frame, which is layered in with ordinary windows. This
- behavior yields a "floating" effect. Whether a Window object is really
- supposed to float is another question entirely.
-
- On Mac, a Window object is either layered in with other windows, just
- like a Frame is, or else it is entirely modal - depending on which VM
- you use. In Java - there appears to be no easy way to get floating
- behavior. If anyone knows otherwise, please send in your comments.
-
- 38. (Sect. 10) How can iconify/deiconify a window in Java?
-
- [*] JDK 1.1 had no way to write code to force a window to iconify or
- deiconify. Support was added in JDK 1.2.
-
- MyFrame.setState( Frame.ICONIFIED );
- MyFrame.setState( Frame.NORMAL );
-
- will do the trick. There is a corresponding getState();
-
- 39. (Sect. 10) How do I know which mouse button was pressed, and how often?
-
- [*] To handle mouse events you have to implement the MouseListener
- interface, or derive from the MouseAdapter class in order to use one of
- the mouse-handling methods. The MouseEvent argument passed to the
- handling methods contains fields that say which button was pressed, and
- the click count. Use code like this.
-
- public void mouseClicked(MouseEvent m) {
- boolean leftButtonPush =
- (m.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK) != 0;
- boolean centerButtonPush =
- (m.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0;
- boolean rightButtonPush =
- (m.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0;
-
- int click = m.getClickCount(); // might be 1,2,3 clicks or more
-
- You can also call at m.isPopupTrigger(). If it returns a true value,
- the user has asked for a pop-up menu. On a lot of window systems, the
- right mouse button is the trigger for pop-up menus.
-
- You can overload processMouseEvent for your component.
-
- public void processMouseEvent(MouseEvent e) {
- if (e.isPopupTrigger()) {
- // do what you want
- }
- else
- super.processMouseEvent(e);
- }
-
- The code above applies to JDK 1.1. You can also call
- java.awt.swing.SwingUtilities.isRightMouseButton(MouseEvent me).
-
- See also question 15.10.
-
- -------------------------------
-
- 11. Swing
-
- 1. (Sect. 11) What is Swing?
-
- [*] Swing is a new GUI toolkit bundled with JDK 1.2, and available as
- an add-on extension library for JDK 1.1. Swing is part of the Java
- Foundation Classes and supports a GUI toolkit that lets developers
- create components that have a pluggable look-and-feel. From an
- architectural standpoint, the Swing component set extends - but does
- not completely replace - the Abstract Windowing Toolkit (AWT).
-
- Swing has many components that can be used in place of components in
- the AWT (e.g. JFrame instead of Frame, JButton instead of Button,
- JApplet instead of Applet, JPanel instead of Panel). It also has many
- components that don't exist in the AWT (e.g. tool tips, toolbars, and
- progress bars). However Swing relies on the underlying AWT being there.
-
- The Swing toolkit allows the creation of GUI's that are every bit as
- sophisticated as native code toolkits like MFC -- with the Java
- advantage that they run on every platform. The pluggable look and feel
- means that they can have the same appearance on every platform, or you
- can choose to have it look like Windows on a PC, like Motif on a Unix
- box, etc, just as the user chooses.
-
- Swing also supports the Accessiblity API. That API allows the adaptive
- software used by disabled computer users to directly query the Java VM
- and extract information about the running program, the usual purpose
- for this being to determine the UI components. Then the existing
- adaptive software can interpret it to the user (e.g. read the contents
- of a window, etc). Swing doesn't use native components, and the
- adaptive software taps into native components, so without the
- accessibility API has a real role in bringing the two together. The
- beauty of the Accessibility API is that developers need to do little
- work to support it, but they do need to be made aware of it if they add
- new components.
-
- With Swing, native window behavior is confined to external window
- frames (and their borders) and a few other things such as fonts and the
- buffers used to hold window contents. The composition, layout, and
- drawing of controls is now all handled by Java code. So identical code
- is executed to create and manage your user interface on every platform.
- Swing provides a much greater consistency of behavior across different
- platforms.
-
- Swing works with JDK 1.1 if you download the swing.jar file and add it
- to your path. Swing is built in to JDK 1.2, and Javasoft has just
- changed its 1.2 Swing package-naming strategy. It is now called
- javax.swing.
-
- 2. (Sect. 11) Should I use Swing or AWT to build my GUIs?
-
- [*] Use Swing to build your apps now instead of AWT components,
- wherever you have a choice. Swing is a GUI toolkit that is at least as
- good as other commercial GUI toolkits, and better in several respects.
-
- With Swing, it is easier to build an application that is portable
- between Mac, Solaris, Windows 95 and NT, than it is to use Win32 and
- build an application that just runs on Windows 95 and NT.
-
- 3. (Sect. 11) Where can I find a Swing tutorial?
-
- [*] There is a Swing tutorial at
- http://java.sun.com/docs/books/tutorial/ui/swing/index.html which is
- part of this tutorial:
- http://java.sun.com/docs/books/tutorial/ui/TOC.html
- There is also a Swing FAQ at http://www.drye.com/java/faq.html
- See also http://www.codeguru.com/java/Swing/index.shtml
- There is a Swing Developer Connection website with white papers and
- examples at http://www.theswingconnection.com/.
- Please let this FAQ maintainer know about other good Swing tutorials
- and online resources.
-
- 4. (Sect. 11) What is the Model/View/Controller paradigm?
-
- [*] Model/View/Controller is a design pattern or framework originally
- developed by Prof. Trygve Reenskaug at Xerox PARC in 1978/9. MVC was
- developed to allow Smalltalk to conveniently support GUIs.
-
- Model/View/Controller is a design pattern used extensively in Swing.
- Basically, the "model" contains your data, the "view" is the graphical
- representation, and the "controller" is responsible for the interaction
- between the other two. As an example, think of visually editing the
- Tree widget that represents a directory. The display is the view.
- Selecting a file, and dragging it to the trash can will delete the
- file. In order for the delete to happen, the controller must tell the
- model what just happened in the view.
-
- In practice, inter-communication between the view and the controller is
- complex, so the two are bundled together in one category in Swing. The
- model (data) is separate though.
-
- There's a reasonable white paper on MVC in Swing at
- http://java.sun.com:81/products/jfc/swingdoc-static/swing_arch.html .
- There is information on other OO design patterns at
- http://www.parallax.co.uk/cetus/oo_patterns.html.
-
- 5. (Sect. 11) When I run the Swing demo on Windows 95 I get an error "Out
- of environment space."
-
- [*] That's because you don't have enough space for your DOS
- environment. You can fix this with:
- o Right click your MS-DOS Prompt icon or window and choose
- Properties.
- o Choose "Memory" and on "Initial Environment", choose 4096 instead
- of "auto".
- o Run Swing again, you'll be OK.
-
- 6. (Sect. 11) How can I run Swing code in a browser?
-
- [*] Most current browsers have to be specifically set up to run Swing
- applets. Read the article at
- http://www.javasoft.com/products/jfc/swingdoc-current/applets.html for
- information about this. The article also contains a simple Swing
- example applet, so you can confirm that that's your problem.
- Another approach is to use the Java plug-in, which automatically gives
- a Swing-compatible Java in the browser. See
- http://java.sun.com/products/jfc/tsc/swingdoc-current/java_plug_in.html
-
- 7. (Sect. 11) Why is my menu showing up behind other components when I use
- Swing?
-
- [*] The answer relates to lightweight and heavyweight (peer-based)
- components. There is a good article about it at
- http://www.javasoft.com/products/jfc/swingdoc-current/mixing.html
-
- For those who want the quick fix, and will read the article later,
- adding the line:
-
- javax.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);
-
- before you create any menus will probably fix it (even if you're using
- menus other than JPopupMenu).
-
- The summary answer is that a Lightweight component will not appear over
- a heavyweight component by default.
-
- 8. (Sect. 11) Why is there no JCanvas? How do I get a lightweight Canvas?
-
- [*] Use a JPanel as a Swing replacement for Canvas. All Swing
- components have a paint(Graphics) routine that you can override, just
- as you would have with Canvas, (but you probably want to override
- paintComponent(Graphics) instead, see next question).
-
- 9. (Sect. 11) Why don't the borders of my Swing components look right when
- I override paint(Graphics)?
-
- [*] Swing splits painting into several different routines:
- o paintComponent(Graphics),
- o paintBorder(Graphics),
- o paintChildren(Graphics)
- all of which are called from paint(Graphics). If you override paint(),
- unless you remember to do it, the paintBorder() and paintChildren()
- won't get done.
-
- In most cases, what you really want to do is override paintComponent()
- instead of paint().
-
- 10. (Sect. 11) Why does my JFrame go away after I choose system close on
- the window?
-
- [*] Assume that you have a Swing JFrame component, and you handle the
- windowClosing event, but do nothing in the handler. You will see that
- the JFrame disappears anyway.
- The reason is that JFrame's have default handling of the system close
- operation, separate from the windowClosing event. You have to override
- that by calling:
-
- setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
-
- on your JFrame.
-
- 11. (Sect. 11) Why can I run the Mac Look and Feel only on Mac OS?
-
- [*] (This answer comes from the Swing Connection, see
- http://java.sun.com/products/jfc/tsc/swingdoc-current/911.html).
- Sun has not determined that it has the right to deliver the Mac look
- and feel on platforms other than MacOS. If Apple were to confirm Sun's
- right to deliver this look and feel on other operating systems, Sun
- would be delighted to remove the lock. To date, Apple has declined to
- do this.
-
- Although you cannot use the new Mac L&F on non-Macintosh platforms,
- there is a way to examine the source code so developers can use it as
- an example of how to create a custom L&F. The Mac L&F is distributed in
- "stuffed-binhexed" format, which is standard for the Macintosh. If you
- develop on a MS-Windows platform and would like to examine the source
- code for the Mac L&F then you can do that by downloading and using a
- program called Aladdin Expander for Windows. You can download Aladdin
- Expander from this URL: http://www.aladdinsys.com/expander/index.html
- When you have downloaded Aladdin Expander, you can use it to decode the
- Mac L&F file posted on the JDC.
-
- A recent posting on comp.lang.java.gui suggested the following user
- workaround:
-
- import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
- class MyOwnWindowsLookAndFeel extends WindowsLookAndFeel {
- public isSupportedLookAndFeel() { return true; }
- }
-
- The desire on Sun's part to avoid infringing the Windows Look and Feel
- is also the reason why the JTree uses colored circles (and soon, little
- circles with a short line coming out of them) for the nodes to indicate
- whether they are open or not. The Swing team could have used the '+'
- and '-' as Windows does, or even the triangles that MacOS uses, but
- decided against it.
-
- 12. (Sect. 11) When I set the cursor to WAIT_CURSOR why does it only change
- when my cursor is over specific components?
- or
- How can I change the cursor to a WAIT_CURSOR over my entire window and
- all of its components, preventing any user action, while some other
- process is happening. (i.e. database access, opening another window,
- downloading an image, sorting some data, etc.)
-
- [*] In JDK 1.0.2 only the awt Frame could change its Cursor. With the
- advent of JDK 1.1 the Cursor manipulation has been move to the
- Component clss. Now all Components have access to the Cursor class.
-
- You could change your Cursor to a WAIT_CURSOR for each Component. This
- could be time-consuming. You could have a potentially large number of
- Components. With the advent of the JFC Swing, there is a mechanism to
- change the Cursor over the entire Window regardless of the number of
- components. The Swing component JFrame has a method:
-
- public void setGlassPane(Component glassPane)
-
- which sets an awt Component as the 'glassPane' for the JFrame.
-
- This Component will cover the entire JFrame's visible user accessible
- (when visible), area excluding the border set by the underlying
- windowing system. With the 'glassPane' Component you can set the
- 'WAIT_CURSOR' over an entire JFrame, prohibiting user input (the
- 'glassPane' Component gets all user input) and blocking the user until
- your 'other' processing is complete.
-
- NOTE: You must spawn a Thread to accomplish your 'other' work if you
- want to see the WAIT_CURSOR while the 'other' processing is happening.
- When the 'other' work is being accomplished, the 'glassPane' is visible
- with a WAIT_CURSOR and gobbling up all user input. When the 'other'
- work is finished, the Thread uses your waitCursor() method to hide your
- 'glassPane' until its needed again.
-
- 13. (Sect. 11) Why does the compiler complain that the
- javax.swing.ProgressMonitor method "isCancelled()" isn't found?
-
- [*] In American English there are two acceptable spellings: "canceled"
- and "cancelled". Note that the first one has one "el" and the second
- two "el's". Sun spells this "canceled" for ProgressMonitors but many of
- the secondary sources of documentation spell it "cancelled". To make
- matters worse, Sun spells it "cancelled" at other times, such as the
- method "isCancelled()" for PrinterJob.
-
- 14. (Sect. 11) Why doesn't pressing the Enter key activate the default
- button on a Swing dialog?
-
- [*] The default keymap for Swing text components (derived from
- JTextComponent) binds the Enter key (VK_ENTER) to the ActionEvent for
- text fields. This was done to be compatible with the behavior of
- java.awt.Textfield. To enable use of the Enter key to activate the
- default button, remove the Enter key binding from the default text
- component keymap as follows:
-
- static {
- KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
- Keymap map =
- JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
- map.removeKeyStrokeBinding(enter);
- }
-
- 15. (Sect. 11) How do I create non-rectangular Components?
-
- [*] Take a look at the following example that comes with the JDK:
- $JAVAHOME\demo\awt-1.1\lightweight\RoundButtons\example.html
-
- -------------------------------
-
- 12. Browsers
-
- 1. (Sect. 12) When will my favorite browser support Java 1.1?
-
- [*] All popular browsers now have JDK 1.1 support. Netscape
- Communicator 4.04 plus patch "J" fully supports the features of Java
- 1.1. It was released in December 1997, and is only missing the JavaSoft
- support for applet signing (Netscape has gone its own way on this). See
- http://developer.netscape.com/support/faqs/champions/java.html#21
- If you have Netscape 4.05, and the console says anything other than
- Java 1.1.5 then you do not have a fully 1.1 compliant Netscape. There
- is a special preview version available here:
- http://developer.netscape.com/software/jdk/download.html
-
- Netscape badly fumbled its Java support in 1997 as its market was
- seized by Microsoft. Microsoft is using IE as a strategic tool to
- deploy what Microsoft employees call "polluted Java". For both of these
- browsers, the Java Plug-in is currently a good approach.
-
- Sun's HotJava browser fully supports the JDK 1.1 features. People who
- are obliged to use a browser without standard Java support should use
- the Java Plug-In. The Java Plug-In substitutes a standard Java virtual
- machine for the one that shipped with the browser. It allows you to use
- RMI, JavaBeans components, and Java Foundation Classes in Internet
- Explorer 3.02, 4.0, and 4.01. The Java Plug-In also works flawlessly
- with Netscape browsers. You can download the Java Plug-In from
- http://java.sun.com/products/.
- Note that you need to change the HTML a little, to ensure that the
- plug-in JVM is invoked, not the browser JVM. A tool is included to do
- the changes automatically.
-
- 2. (Sect. 12) What applet routines get called in various browsers and the
- plug-in on different browsing actions (back, forward, load, etc)?
-
- [*] Java supporter Dave Postill did the work to get this answer.
- The life cycle of an applet is illustrated by logging calls to init(),
- start(), stop() and destroy(). Use caution when your applets have
- threads since in most sample applet code, the stop() method calls stop
- on any separate threads within the applet, and then sets them to null.
-
- This reckless threadicide is because most people think of the stop()
- method as something called only when the user leaves the page and wants
- to forget about it. But since Netscape calls stop() when you resize the
- window, your users would lose the applet's state when they thought they
- were only making a minor adjustment.
-
- See "Java Tip 8: Threads, Netscape, and the resize problem - How to
- deal with applet resizing in Netscape Navigator", JavaWorld
- http://www.javaworld.com/javatips/jw-javatip8.html. Sadly the JavaWorld
- workaround does not completely fix the problem, since it relies on
- start() being called soon after stop() to identify a resize. However if
- you minimise the browser it may send a stop() to the Applet and then
- may not send a start() until the Browser is either restored or
- maximised. In this case, using the workaround results in the Applet
- being destroyed following minimising of the Browser - unless the
- Browser gets un-minimised within the killThreads timeout.
-
- Netscape Netscape Applet- Internet Internet
- [4.04/JDK with Viewer Explorer 4 Explorer
- 1.1.4] Plug-In [JDK SP1 with Plug-In
- [4.05/JDK [4.05/ JDK 1.1.5] 4.72.3110.8 [5.00.0518.10
- 1.1.5] 1.1.5/ [JDK on NT 4.0 / Plugin 1.1]
- Plugin 1.1] 1.1.6] SP3 on NT 4.0 SP3
- 1. Clear
- browser nothing nothing nothing nothing nothing
- cache
- init(),
- 2. start() or
- Initial init(), init(), init(), init(), init(),
- load of start(), start() start() start() start()
- .html stop(),
- start() [1]
-
- 3. Back stop() stop(), [4] stop(), stop(),
- destroy() destroy() destroy()
- 4. init(), init(), init(),
- Forward start() start() [4] start() start()
- stop(), stop(), stop(), stop(),
- 5. Reloaddestroy(), destroy(), [4] destroy(), destroy(),
- init(), init(), init(), init(),
- start() start() start() start()
- 6.
- <shift>
- reload stop(), stop(), stop(), stop(),
- [NS], destroy(), destroy(), [4] destroy(), destroy(),
- <ctrl> init(), init(), init(), init(),
- reload start() start() start() start()
- [IE]
-
- 7. Resizestop(), [3] [3] [3] [3]
- start()
- 8.
- Minimize [2] [3] stop() [2] [3]
- 9.
- Restore [2] [3] start() [2] [3]
-
- 10. Exit stop(), stop(), stop(), stop(), stop(),
- destroy() destroy() destroy() destroy() destroy()
-
- Notes:
- [1] Results not repeatable.
- [2] Not tested.
- [3] Tested, and found that no logged methods are called.
- [4] Test not applicable.
-
- 3. (Sect. 12) Is it possible to set and retrieve cookies from Java, in a
- manner that is compatible with all browsers supporting cookies?
-
- [*] Short answer: no.
- Longer answer: probably no.
- Ultimate answer:
- A cookie is a morsel of tasty data that a server sends back to the
- client, and can retrieve on demand. It allows the server to retain some
- state information for each of its clients. The information is typically
- something like "what pages has the user seen?" or "is this a privileged
- user?".
- The DevEdge site on Netscape's home page has a Javascript-Java example
- on getting cookies. Also
- http://www.geocities.com/SiliconValley/Vista/1337 has info on
- connecting an applet with JavaScript functions. It's quite involved.
- Stick to just Java if you can.
-
- 4. (Sect. 12) I am developing an applet and testing it in Netscape
- Navigator. I find that after I recompile, I press reload, clear the
- caches, retype the URL of the HTML wrapper, and I still have the old
- version. Why is this?
-
- [*] Note: a reader reports that as of Netscape Communicator 4.05 it is
- possible to force the browser to reload the applet by holding down
- "control"+"shift" while clicking "Reload"
- In the past Netscape has completely failed to improve the defective
- code that does this monstrously wrong thing. It has been like this for
- many successive releases.
- Flushing the network cache will make no difference; that isn't where
- the caching is taking place. Although applets are sometimes "pruned"
- and their ClassLoaders garbage-collected, this doesn't happen
- predictably, so restarting Netscape is the only reliable work-around at
- the moment.
- A related question is "how do I make the browser reload from a
- URLConnection instead of just getting the content from the local
- cache?" The answer is to use
-
- java.net.URLConnection.setUseCaches(false)
-
- Browsers seem to vary in their conformance to this programmatic
- request. Netscape caching varies depending on whether a proxy server is
- in use, and which thread in the applet made the get request.
-
- Another approach is adding "?" to the URL, e.g.
-
-
- http://www.somesite.com/webcam/image.jpg?100
-
- and increasing this number each time the Applet fetches the image.
-
- 5. (Sect. 12) Why didn't Netscape reload the applet when you pressed the
- Reload button?
-
- [*] For the applet to be reloaded, the new version would have to be
- loaded in a different ClassLoader. Navigator/Communicator's policy for
- assigning ClassLoaders to applets doesn't take into account whether a
- reload has been done (although there is no technical reason why it
- couldn't).
- Some versions of Netscape reload the Applet if you use
- Edit/Preferences/Advanced/Cache to Clear Memory Cache and Clear Disk
- Cache, then <Shift> while you click on reload.
- In Explorer, use View/Options/General/Delete Files, then <Control>
- 'Reload' button to reload the page containing the applet.
-
- Until they fix it, use the appletviewer to test applets. And send them
- mail - developers can only fix the bugs they know about.
-
- 6. (Sect. 12) Should I use Microsoft CAB files or Java JAR files?
-
- [*] The question contains its own answer.
- CAB format is a Microsoft-only format. So do not use it as it destroys
- software portability.
- JAR format is the Java standard format, based on PKZIP format including
- data compression. JARs were introduced with JDK 1.1.
- See http://www.ibm.com/java/community/viewarchive4.html for more
- information.
- You should use the Java standard format JAR (Java Archive) files, not a
- vendor-specific format. JAR files are not just a Java standard, they
- are in industry-standard PKZIP format. One reader comments that both
- formats can be used with this tag:
- <APPLET NAME=myapplet
- ARCHIVE="myzip.zip"
- CODE="com/nnnnn/nnnn/cccccccc.class"
- WIDTH=n
- HEIGHT=n>
- <PARAM NAME="cabbase" VALUE="mycab.cab">
- </APPLET>
- IE3 does not support JAR
- IE4 supports compressed and uncompressed JAR, but not signed JAR
-
- 7. (Sect. 12) How can I tell the version of Java that my browser supports?
-
- [*] See http://java.rrzn.uni-hannover.de/insel/beispiele/vertest.html.
- This page tells you whether your browser supports JDK 1.1.
-
- See http://www.uni-kassel.de/~pfuetz/Properties.html This page tells
- you which classes you may expect to be present in the browser's
- runtime.
-
- 8. (Sect. 12) How can I tell the options/commands that Netscape's JVM
- takes?
-
- [*] You can open the Java Console and type a "?" to get a list of all
- the commands/options available to you in Netscape's built-in JVM.
-
- -------------------------------
-
- 13. Applets
-
- 1. (Sect. 13) What is the difference between an application, an applet,
- and a servlet?
-
- [*] An applicationis a standalone program.
- An applet is a downloadable program that runs in a web browser.
- Typically an applet has restricted access to the client system for
- reasons of security. Other than that it is virtually no different from
- a regular Java program.
- A servlet is a Java program whose input comes from a server and whose
- output goes to a server. Other than that it is virtually no different
- from a regular Java program. Think of a servlet as an application, but
- one that (like an applet) requires a context in which to run, namely
- web server software. Servlets are used like CGI scripts, but take much
- less processor resources, and they allow the server end to be written
- in Java as well as the client. There is a page with much servlet
- information at: http://www.frontiernet.net/~imaging/servlets_intro.html
-
- There is a servlet tutorial at
- http://java.sun.com/docs/books/tutorial/servlets/index.html
- and another servlet tutorial at
- http://www.novocode.com/doc/servlet-essentials/
- There is a servlet FAQ at http://www.saint-elie.com
-
- The web server starts up a servlet when the URL is referenced, and now
- your applets have something that they can talk to (via sockets) on the
- server that can write files, open connections to other servers, or
- whatever.
- There is also a software technology from IBM called an "Aglet".
- An aglet is a mobile agent that can go from machine to machine,
- performing tasks, serializing data collected, and "shipping itself"
- (code and data) to the next machine. It's too early to say if aglets
- are a flash in the pan or a dawning technology. Read about aglets at
- http://www.trl.ibm.co.jp/aglets/
- Finally, there is the ticklet (Tcl/Tk) plugin for your browser
- (Netscape or Explorer) available at http://sunscript.sun.com/plugin/
- Don't confuse Sun's JWS "Java Web Server" with JWS "Java Workshop".
- Java Web Server supports servlets, as does the lightweight and free
- server at Acme.com:
- http://www.acme.com/java/software/Acme.Serve.Serve.html
-
- 2. (Sect. 13) My applet works on my machine, but fails when I put it on
- our web server. Why?
-
- [*] It could be one of several reasons, and unfortunately the messages
- that you get in this situation aren't much help. In general, you can
- assume that either your applet's class files are corrupted somehow, or
- the web server can't find one or more of them when the browser needs
- them.
- Be careful of the following things:
- o Make sure you transfer the class files in binary mode, rather than
- text or ASCII mode. An error from the browser saying "cannot start
- applet ... bad magic number" usually means that one of the class
- files on the server is corrupted. Replace your class binary files
- on the web server, clean up the cache of your browser, and reload
- your applet.
- o Make sure you transfer all of the class files that are a part of
- your applet. Sometimes people are surprised by how many there are.
- There will be a class file for every class and interface you
- define, even if you define more than one in a single source file.
- If you use the Java 1.1 "inner classes" feature, there will be
- class files for each inner class as well.
- o Make sure you maintain the appropriate case distinctions in your
- filenames. If a class is called StUdLy, it must be found in a file
- called StUdLy.class.
- o Make sure you maintain the directory structure that matches your
- package structure. If you declare a class in package com.foo.util,
- the class either needs to be in a Jar file, or the class file
- needs to be in directory com/foo/util under the applet's codebase
- directory. Again, case distinctions are important for
- package/directory names, just as they are for class/file names.
- o Make sure that the web server process will have read access to the
- class files, and search access to the directories that the files
- are in. For example, if the web server runs on a Unix machine, use
- the command "chmod o+r filename" for the files, and "chmod o+x
- dirname" for the directories.
-
- 3. (Sect. 13) How do I load a webpage using an applet?
-
- [*] Use code like this,
-
- getAppletContext().showDocument(
- new URL("http://www.here.com") );
-
- Or, to show the page in another window or frame,
-
- getAppletContext().showDocument(
- new URL("http://www.here.com"), "windowname" );
-
- 4. (Sect. 13) How do I use an image as the background to my applet? How do
- I set the background color of my applet the same as the browser?
-
- [*] You can simply do a g.drawImage(yourImage, x, y, this) in the
- paint() routine of your applet. If the image isn't big enough to fill
- the entire background, tile it or scale it. Here is some code to tile
- it
-
- // The background image is named "bg".
- int w = 0, h = 0;
- while (w < size().width) {
- g.drawImage(bg, w, h, this);
- while ((h + bg.getHeight(this)) < size().height) {
- h += bg.getHeight(this);
- g.drawImage(bg, w, h, this);
- }
- h = 0;
- w += bg.getWidth(this);
- }
-
- Alternatively, the AWT can scale your background image to the size of
- the applet. The result quality will depend on the kind of image. Inside
- an applet class, you can use:
-
- drawImage(img, 0, 0, size().width, size().height, this);
-
- You can set the background color to match the background color of the
- browser by passing the value in as a parameter, like this:
- In the HTML applet tag:
- <param name=BrowserColor value=F1F1F1>
- (value should be the same hex as the HTML COLOR value).
- In the Applet init() method:
-
- String colparam = getParameter("BrowserColor");
- int col = Integer.valueOf(colparam,16).intValue();
- setBackground( new Color(col) );
-
- An applet cannot override the size imposed by the HTML. If you make the
- applet larger, the browser will still clip to the original size. If you
- need more room, open up a new Frame, Window or Dialog to show your
- output.
-
- 5. (Sect. 13) How do you make the applet's background transparent?
-
- [*] There is no way to give an applet a transparent background that
- lets the web browser background show through. You can simulate it by
- giving the applet a background that matches the underlying browser
- background. (For a straight color, it will be the value of <BODY
- BGCOLOR=nnnnnn> in the HTML file). It doesn't produce satisfactory
- results with a patterned background because of problems aligning the
- edges.
- Lightweight components (new in JDK 1.1) have a transparent background,
- but that merely allows other components to show through. A lightweight
- component is always ultimately positioned in a heavyweight component.
-
- 6. (Sect. 13) How do you do file I/O from an applet?
-
- [*] Unsigned applets are simply not allowed to read or write files on
- the local file system (see answer to question 7.8).
-
- Unsigned applets can, however, read (but not write) non-class files
- bundled with your applet on the server, called resource files.
-
- See answer to question 7.8 and question 7.9.
-
- 7. (Sect. 13) How do I pull a non-class file, such as a .gif, out of a jar
- file?
-
- [*] [Question has been retired, in favor of question Q7.9]
-
- 8. (Sect. 13) How do I read a text file stored in a Jar?
-
- [*] [Question has been retired in favor of Q7.9]
-
- 9. (Sect. 13) How do you get a Menubar/Menu in an applet?
-
- [*] In your applet's init() method, create a Frame instance and then
- attach the Menus, Menubar etc to that frame. You cannot attach the Menu
- or a Menubar to an applet directly.
- Or get the parent Frame like this (doesn't work in all execution
- environments):
-
- Container parent = getParent();
- while (! (parent instanceof Frame) )
- parent = parent.getParent();
- Frame theFrame = (Frame) parent;
-
- This second suggestion definitely doesn't work in the appletviewer, and
- probably won't work on Macs (where would the Menubar go?) or in some
- browsers. In JDK 1.1, just use a popup menu, which isn't attached to a
- Frame.
-
- 10. (Sect. 13) Can I get rid of the message "Warning:Applet Window" along
- the bottom of my popup windows in my Applet?
-
- [*] This is a security feature that prevents the applet programmer from
- popping up a window that looks like it came from the native OS and
- asking for passwords or credit card info (etc.). Users must always be
- aware of when they are talking to an unsigned applet. You can get rid
- of it by signing the applet, if the user accepts signed applets from
- you. In Netscape (only), using the Capabilities API to make the call
-
- PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");
-
- before creating the Frame eliminates the message, if the security
- manager passes it.
-
- 11. (Sect. 13) When I subclass Applet, why should I put setup code in the
- init() method? Why not just a constructor for my class?
-
- [*] The browser invokes your constructor, then setStub, then init().
- Hence when your constructor is invoked, the AppletStub (and through it
- the AppletContext) is not yet available. Although in principle you can
- do things in the constructor that don't rely (even indirectly) on the
- AppletStub or AppletContext, it is less error-prone to simply defer all
- setup to the init() method. That way you know that anything that needs
- the stub/context will have it available.
-
- 12. (Sect. 13) I want to know about {applets,applications} but the lousy
- book I got just talks about {applications,applets}. What can I do?
-
- [*] The truth is that 95% of the material is the same, whichever your
- book chooses to focus on. Some people write their apps to work
- completely in a Panel, then depending on whether they're running
- stand-alone or in a browser the Panel is either added to a Frame or an
- Applet. The trick is that you need to add a listener to the
- application's Frame to handle the WINDOW_CLOSING (previously
- WINDOW_DESTROY) event yourself.
- If you fail to do this, when running as an application, the window
- won't close. See Question 15.7 for a sample of the right handler.
- In this scenario the following code will tell you which environment
- you're running in:
-
- public boolean isRunningInBrowser() {
- Component p = getParent();
- while(p != null && !(p instanceof Frame)) {
- p = p.getParent();
- }
- return (p == null);
- }
-
- 13. (Sect. 13) How do I print a page with an applet?
-
- [*] Browsers are starting to introduce support for this. Until they all
- have it, your best bet is to print a screendump. Using the browser to
- print the page may leave a blank where the applet is. Putting print
- support in the applet will print the applet only, not the rest of the
- browser page.
- Also in the FAQ: Q5.2.
-
- 14. (Sect. 13) How can I position my dialogs centered (not top left)?
-
- [*] Use some code like this:
-
- void center(Component parent) {
- pack();
- Point p = parent.getLocation();
- Dimension d = parent.getSize();
- Dimension s = getSize();
- p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
- setLocation(p);
- }
-
- 15. (Sect. 13) How can I get two applets on the same page to communicate
- with each other?
-
- [*] This is the purpose of the InfoBus protocol. See
- http://java.sun.com/beans/infobus/index.html
-
- The older way to do it was as follows. In your HTML page, give a NAME
- in the APPLET tag for the applet receiving the message, say <APPLET ...
- NAME=someName ...>. In the Java code of the other applet do
-
- Applet anotherApplet = getAppletContext.getApplet("someName");
-
- Cast anotherApplet to the correct applet subclass, and you can call any
- methods in the applet subclass. Don't forget to use appropriate
- synchronization when two threads tweak variables. This only works when
- the applets are truly on the same page. If they are in different
- frames, it doesn't work.
- You can walk through all the applets on an HTML page using code like
- that below. However this appears to be broken in Communicator 4.04 on
- Win95.
-
- Applet otherApplet;
- AppletContext ac =getAppletContext;
- Enumeration applets = null;
- for (applets=ac.getApplets(); applets.hasMoreElements(); ) {
- otherApplet=(Applet)applets.nextElement();
- if (otherApplet!=this) break;
- // do something with otherApplet, e.g.
- // if (otherApplet instanceof FooApplet) ...
- }
-
- Some people suggest using the static members of a common class to
- communicate information between the applets. This is not recommended as
- it relies on class-loading behavior that may change in future. Netscape
- changed it in one Beta so it didn't work, then changed it back again so
- it did. It doesn't work if you use the "mayscript" tag though.
- Inter-applet communication sometimes arises when you have a
- multi-screen type program and you don't want to force the user into
- downloading everything at once. One alternative is to make them into
- one applet with two GUIs. Try to avoid the need for applets to talk to
- each other. Also check the URL
- http://java.sun.com:81/products/hotjava/1.1/applet_environment.html
- which explains how it can be done in HotJava 1.1. Recommendation: avoid
- code which is browser-specific.
-
- 16. (Sect. 13) How can I resize an applet?
-
- [*] If you want resizing behavior from an applet, you should launch an
- external Frame that can be resized independently.
- One programmer suggests using percentages for the height/width
- parameters in an applet tag, like this:
-
- <APPLET CODE="lewinsky.class" WIDTH="100%" HEIGHT="100%">
-
-
- You can't resize the applet directly, but it does get resized when you
- resize the browser window (tested with Netscape 3.04 and 4.04, but does
- not work with appletviewer). If you have nothing else on your HTML page
- and use 100% for your width and height, the browser window looks almost
- like a real application.
- For the extremely tricky: have the browser reload the page with the
- applet when the browser resizes using new values for width and height
- (probably not what you want most of the time). You would need
- Javascript to generate a page dynamically using document.write("...")
- when the browser resizes. Not recommended. Another possibility is to
- use the new SplitPane class in JFC.
-
- 17. (Sect. 13) How do I sign an applet?
-
- [*] The browser vendors have produced independent and different
- solutions for applet signature (alas). Here are some URLs on this
- topic.
-
- See the Java Signing FAQ at
- http://www.fastlane.net/~tlandry/javafaq.txt
-
- Read the basics of signing at:
- http://www.javareport.com/html/features/archive/9802/somers.shtml
- Be aware that the mechanism of signing and administering signed code
- changed significantly between Java 1.1 and Java 2.
-
- Netscape signing:
- http://developer.netscape.com/docs/manuals/signedobj/javadoc/netscape_security_Target.html
-
- https://certs.netscape.com/client.html
- http://developer.netscape.com/docs/manuals/signedobj/capabilities/contents.htm
-
- http://developer.netscape.com/docs/manuals/signedobj/targets/contents.htm
-
- Microsoft signing:
- http://www.microsoft.com/java/security/secfaq.htm
- http://www.microsoft.com/java/sdk/20/tools/signcode.htm
-
- -------------------------------
-
- 14. Multi-Media
-
- 1. (Sect. 14) Are there any good Java Image libraries?
-
- [*] Yes. Try the Java Image Management Interface (JIMI), which offers a
- free trial period. JIMI is a toolkit that lets your Java programs read
- and write many graphics file formats (PNG, JPG, BMP, GIF etc). JIMI is
- written in 100% Java, and best of all, it's a breeze to get started
- with. See http://www.activated.com/jimi.html
-
- 2. (Sect. 14) Why won't my audio file play?
-
- [*] Java 1.1 and earlier releases use one audio format exclusively. The
- audio file must be in .au format, recorded at 8 KHz, mono, in mu-law
- encoding. If your audio clip is in a different format (e.g., .wav) or a
- different frequency it must be converted to the exact specifications
- above before Java can play it. Support for .wav and other formats is
- part of the Java Media Framework coming in JDK 1.2.
- Search at http://www.yahoo.com for GoldWave for Win 95, sox for Unix
- and similar conversion utilities for other systems.
- Other sites:
- o One conversion utility in Java is at
- http://saturn.math.uaa.alaska.edu/~hursha
- o The source of a Java class to play linear PCM .WAV files is at:
- http://www.shef.ac.uk/~cs1mjp/Java/WhiteBoard/WavePlayer.html. It
- can be used in any Java application or applet.
-
- 3. (Sect. 14) How can I do video streaming using Java?
-
- [*] That is the purpose of StreamBean. See
- http://www.streambean.com/streambean/
-
- 4. (Sect. 14) Does Java support animated GIFs?
-
- [*] Java 1.0.2 and earlier releases use GIF and JPEG formats, and do
- not use the GIF89 animated GIF format. (An animated GIF is one that
- contains successive frames of an image, so when they are displayed in
- quick sequence the image appears to contain movement). When you display
- an animated GIF in Java 1.0.2, you will just get the first frame. There
- doesn't appear to be any easy way to get other frames from the image.
- The advantage of an animated GIF file is that there is only one file to
- download, and it is simple to do simple animations. The advantage of
- programmatic control over individual frames is that you control the
- rate and order of displaying them.
- Here's a surprise: JDK 1.1 supports the animated display of animated
- GIFs. For simple animations animated GIFs are a lot easier and
- lighter-weight than coding an animation explicitly.
-
- 5. (Sect. 14) How do I create animated GIFs?
-
- [*] Use GIFanimator from ULead (said to be the best)
- http://www.ulead.com, or GIF Construction Set from Alchemy Mindworks
-
- 6. (Sect. 14) How do I prevent animated GIFs from flashing while
- displaying?
-
- [*] The problem is most likely that in your paint method you have
-
- g.drawImage(img, ix, iy, this);
-
-
- You should change this to
-
- g.drawImage(img, ix, iy, getBackground(), this);
-
-
- This will change all the transparent regions of the image to the
- background color before painting to the screen. If you paint
- transparent images directly to the screen they flicker.
- If that does not solve it then check that imageUpdate is
-
- public boolean imageUpdate(Image img, int flags, int x, int y,
- int width, int height) {
- if ((flags & (FRAMEBITS|ALLBITS))!= 0) repaint();
- return (flags & (ALLBITS|ABORT)) == 0;
- }
-
-
- update is
-
- public void update(Graphics g) { paint(g); }
-
-
- If you have a background Image behind the partly transparent animated
- GIF you will have to double buffer. You can crop the backgound image so
- you won't have to double buffer the full app and waste too much memory.
-
- 7. (Sect. 14) Does Java support transparent GIFs?
-
- GIF89a images with a transparent background show up as transparent
- without further filtering. This has been supported from 1.0 on. Java
- correctly displays both animated GIFs and transparent GIFs.
- Even better, you can fill the transparent pixels with a color (so they
- appear non-transparent in Java). Just pass the fill color explicitly:
-
- drawImage(img, x, y, w, h, fillcolor, this);
-
-
- Further, you can filter the pixels of an Image to turn any bits you
- wish transparent. However, the most you can do is reveal what is
- underneath the image. You cannot reveal what is underneath the applet
- (i.e. on the browser itself). By default applets have a plain grey
- background.
- 8. (Sect. 14) How do I play video in Java?
-
- [*] Use the Java Media Framework Player API.
- Other sites:
- o The Java Media Framework Player API spec can be found at
- http://java.sun.com/products/java-media/jmf/
- o Intel has released a SDK for the Java Media Framework Player API.
- The SDK is for Windows 95 and Windows NT. For more information,
- see http://developer.intel.com/ial/jmedia
- o SGI has released an implementation of JMF for IRIX: See
- http://www.sgi.com/Products/motion/
-
- 9. (Sect. 14) How can I play *.au files from an application?
-
- [*] A new static method was introduced in JDK1.2 in the class Applet:
-
- public final static AudioClip newAudioClip(URL url) {
-
-
- The method turns a URL (pointing to an audio file) into an AudioClip.
- Since the method is static it can be used without any objects of class
- Applet needing to exist, e.g. in an application. Once you have an
- AudioClip, you can play it with:
-
- MyAudioClip.play();
-
-
- The Java Media Framework provides a richer API for playing sounds in an
- application.
- For code prior to JDK 1.2, you can use the AudioClip or AudioPlayer
- class in sun.audio
- http://www.javaworld.com/javaworld/javatips/jw-javatip24.html. If you
- do this your code is no longer 100% pure Java, as it relies on a vendor
- library.
-
- import sun.audio.*;
-
-
- URL url; ...
- AudioStream audiostream = new AudioStream(url.openStream());
- AudioPlayer.player.start(audiostream);
- ...
- AudioPlayer.player.stop(audiostream);
-
-
- Also in the FAQ:
- Use the new Java Media Framework API, allowing a wide range of video
- and audio formats to be played back. See previous question.
-
- 10. (Sect. 14) How do I read in an image file, in an application?
-
- Use
-
- Image img = Toolkit.getDefaultToolkit().getImage(fname);
-
-
- 11. (Sect. 14) When I initialize a component,I call MyComponent.getImage()
- to get its image. createImage() returns null! I know the image works
- elsewhere. What's wrong?
-
- [*] A peer component needs to exist for your component before you can
- get its image. This is done by the method addNotify() (surely one of
- the most poorly named methods in all Java -- it doesn't mean "add a
- Notify". It means "Notify that the Component has been added to a
- Container". It tells the system, "you need to create the peer for this
- Component now"). addNotify will be called for you when you add your
- component to a container.
- Javasoft notes that most applications do not call addNotify() directly.
- It is called for you when you add the component to a container. If you
- have any code that requires peer resources, you can move it into a
- thread that is started from a conditional branch of the paint() or
- update() method. That way the peer will definitely exist when the code
- is executed.
- A common reason for seeming to require peer resources in a constructor,
- or alternatively in the getPreferredSize() method, (which is also
- usually before the peer is created) is to measure the area required for
- your window, in terms of font and image sizes. Font sizes may be
- obtained by calling
- Toolkit.getDefaultToolkit().getFontMetrics(somefont). This does not
- require a peer. Image sizes may be obtained by waiting for the relevant
- Image to load from the ImageProducer by using an ImageObserver, or a
- MediaTracker (see 8.15), also without requiring a peer. See 15.4 for
- more discussion of this problem.
- If you override addNotify(), don't forget to call super.addNotify() in
- your overriding version.
-
- 12. (Sect. 14) How can I force a reload a fresh version of an image into my
- applet? My image file is changed periodically, and I want the applet to
- go and retrieve it, not cache it.
-
- [*] You need to turn off caching for the URL.
-
- URL url = null;
- URLConnection con;
- try {
- url = new URL(getDocumentBase(),"image.jpg");
- con = url.openConnection();
- con.setUseCaches(false);
- } catch (MalformedURLException e1) {
- System.err.println(e1.getMessage());}
- catch (IOException e2) {
- System.err.println(e2.getMessage());}
-
- Note: Some programmers have reported that it caches anyway, even if
- they do this. That is a browser bug.
- One programmer reported that even after turning off caching and calling
- image.flush() before getImage(..), he was still seeing the same picture
- even though it had been changed on the server.
- He worked out a solution: access the image via a cgi script that
- returned a URL. This redirects the browser, and he put in an Expires:
- header as well to force the reload. Painful and laborious, but it got
- the result.
-
- 13. (Sect. 14) How can I save an Image file to disk in JPG or GIF format?
-
- [*]
- o If you have an Image and you want a JPG in a file, download James
- Weeks's code from http://www.obrador.com/essentialjpeg/
- o Sean Breslin also wrote a program that compresses a Java Image
- into a JPEG file. http://www.afu.com/jpeg.txt
- o If you just want to convert some file, a non-Java solution is to
- use the standard IJG 'cjpeg' utility. It supports GIF, PPM, BMP,
- PNG and Targa input files.
- o If you have an Image and you want a GIF or PPM in a file, download
- Jef Poskanzer's abstract ImageEncoder class at
- http://www.acme.com/java/software/
- Also try the Java Image Management Interface (JIMI), which is free for
- non-commercial use. JIMI is a toolkit that lets your Java programs read
- and write many graphics file formats (PNG, JPG, BMP, GIF etc). JIMI is
- written in 100% Java, and best of all, it's a breeze to get started
- with. See http://www.activated.com/jimi.html
-
- 14. (Sect. 14) What causes this problem:
-
- $ appletviewer m.html
- Premature end of JPEG file
- sun.awt.image.Im...Exception: JPEG datastream contains no image
- at sun.awt.image. ... .produceImage(JPEGImageDecoder.java:133)
- at sun.awt.image.Inpu...mageSource.doFetch(
- InputStreamImageSource.java:215)
- at sun.awt.image.ImageFetcher.run(ImageFetcher.java:98)
-
- [*] There's a known bug in early releases of the JDK which can cause
- the above failure when reading a JPEG across a slow connection. The
- failure only occurs if the JPEG contains a large application data block
- (APPn marker) - the problem is that the JPEG decoder is trying to skip
- over the APPn and failing if not all of the APPn has been received yet.
- The quoted error message is only one of several possible complaints,
- but they all stem from the same root.
- Photoshop is the most common source of JPEGs containing oversize APPn
- blocks. In particular, if you allow Photoshop 4 to save a thumbnail
- (preview) in a JPEG, the thumbnail plumps up Photoshop's private APPn
- marker to several K, which is usually enough to cause this problem.
- There are several possible workarounds:
- o Get a newer JDK - this problem is said to be fixed in 1.1. (If you
- are putting images up on the Web, this isn't much of a solution,
- because you can't assume visitors to your site have an up-to-date
- Java installation.)
- o When making JPEGs for Web use from Photoshop, make sure you have
- turned off the "save thumbnails" preference. (This is a good idea
- quite aside from bug workarounds, because the thumbnail is just a
- waste of download time as far as a Web browser is concerned.) You
- might still have a problem if you've got verbose comments or lots
- of paths being saved into the file, but 99% of the time, getting
- rid of the thumbnail will make Photoshop's APPn small enough to
- not trigger the Java bug.
- o Use a tool such as 'jpegtran' (from the Independent JPEG Group) to
- strip out the Photoshop APPn entirely without any loss of image
- quality. Recommended answer for the compulsive byte-trimmer.
- o (Last resort) Load and resave the image in a different image
- editor that won't insert any APPn or other overhead data. This
- implies a JPEG generational loss, so I don't recommend it if you
- are picky about image quality.
- Any large overhead marker will cause the same problem; 4K of comment
- text, say, in a COM marker. So Photoshop is not the only source of
- tickling this bug.
-
- 15. (Sect. 14) How can I convert between GIF and JPEG formats?
-
- [*] In a word: don't.
- There's hardly any overlap between the set of images that JPEG works
- well on and the set that GIF works well on. Sometimes, with enough
- care, you can get an acceptable conversion...but most of the time
- GIF<->JPEG conversion will just turn your image to mush. It's better to
- pick the right format in the first place.
- Other sites:
- o If you're determined to convert formats anyway, try the GBM
- (Generalized Bitmap Module). The package is GNU licensed, in C and
- is very good. Find it at
- http://www.interalpha.net/customer/nyangau/
- GBM does a good job converting to JPEG, and 'lossiness' is
- adjustable to 0%. It also converts to/from about 20 other formats,
- does cropping, sizing, color mapping, gamma correction,
- halftoning, everything you could want. GBM source doesn't support
- JPEG directly, but utilizes JPEG source from IJG called jpeg-6a
- and found at
- ftp://sun2.urz.uni-heidelberg.de/pub/simtel/graphics/jpegsr6a.zip
- o For more info see the JPEG FAQ at
- http://www.faqs.org/faqs/jpeg-faq/
-
- 16. (Sect. 14) If you have an InputStream (rather than a file) that
- contains an Image, how can you display it?
-
- [*] Use this method, and some adroit shuffling.
-
-
- Toolkit.getImage(URL url)
-
-
- Create a thread that pretends to be an http server. Make it listen to
- some port (8765 for example) for incoming requests. When the thread
- gets a request, it should simply whisk up the appropriate http headers
- and follow it by the InputStream. Thus the component that has the input
- stream and wants to do the getImage(url) can now invoke:
-
- Toolkit.getImage("localhost:8765/")
-
-
- The thread will act as a stream-to-url adapter, and send back the data
- It saves you from having to read 200K of JPEG data before you can begin
- drawing anything.
-
- 17. (Sect. 14) How can I record sounds in Java?
-
- [*] The Java Media Framework will eventually support this, but it does
- not yet. JMF 1.0.1 only supports playback.
- JMF 1.0.1 is bundled with JDK 1.2, and available as a separate download
- for JDK 1.1 and Netscape Communicator 4 with Java 1.1.
- Other sites:
- In the meantime, there is a package for Win95/NT available at
- http://www.scrawl.com/store/. It supports 8, 16-bit, stereo, mono,
- 11025, 22050, 44100 Hz record/play, load/save .WAV files. You
- could also interface to native code for your platform.
-
- 18. (Sect. 14) Does Java have any built-in support for displaying HTML?
-
- [*] JDK 1.1 supports rendering HTML using the unbundled JFC 1.1 package
- known as Swing. The Swing package is bundled in JDK 1.2. It has an
- elementary (graphics, tables, text) HTML bean that is good enough for
- simple rendering (help files, email, etc).
- Other sites:
- o JavaBrowser http://www.ii.uib.no/~alexey/jb/index.html Free
- source, free for use under GNU LGPL licence, HTML 2.0 (sort of).
- o ICE Browser - Java Bean Component
- http://www.icesoft.no/ICEBrowser/ Free binaries for use in free
- applications. Commercial licensing available including source -
- flat fee licence. Thin HTML client! Lightweight! HTML 3.2
- o HotJava HTML Component - Java Bean Component
- http://www.javasoft.com/products/hotjava/bean/index.html $195 for
- private use binary licence. HTML 3.2
- o HTML browser (free source)
- http://barium.tn.tudelft.nl/people/gool/java/html/Html.html
- o Web Window Browser http://www.opencube.com/example_wwb.htm $139 -
- no sources.
- o jHelp ($20-650) http://w3.nai.net/~rvdi/jhelp/jhelp2/jhelp.html
- jHelp is a HTML browser component written in Java, HTML 2.0
-
- 19. (Sect. 14) I loaded an Image file from a JPEG/GIF file using the
- Toolkit/Applet.createImage(URL/String) method, and (the height and
- width are -1 / it will not draw to the screen). What is wrong?
-
- [*] The behaviour of the AWT on creating images in this way is to do
- nothing at all.
- When the image is first drawn using Component.drawImage(), or its size
- is requested, the image begins to load in a different Thread.
- As the image loads, the ImageObserver specified in the
- drawImage()/getHeight() call is periodically notified of the loading
- status of the image, by calls to its imageUpdate() method.
- In the case of Component.drawImage() call, the default behavior of
- Component.imageUpdate() is to schedule *another* repaint() call when
- the image has fully loaded. This means that, in particular the
- following code will not work:
-
- class MyComponent extends Component {
- ...
- public void paint(Graphics g) {
- ImageFilter cropper=new CropImageFilter(0,0,16,16);
- Image cropped_image=createImage(new
- FilteredImageSource(image.getSource(),cropper));
- g.drawImage(image,10,400,this); // this line works
- // this line doesn't -
- g.drawImage(cropped_image,400,15,this);
- }
- }
-
-
- The cropped_image will not be created in time to be painted, and when
- it is finally created, another call will be scheduled to paint, which
- will try to draw another one, etc.
- (Note also that creating objects like this in paint() methods is
- generally a very poor idea in Java, since they are called very
- frequently, and you will strongly offend the garbage collector.
- In order to get round this problem, you may i) add all such Images to a
- MediaTracker, and call the waitForAll() method. ii) implement your own
- ImageObserver interface, and wait for the imageUpdate() method to be
- called with the ALLBITS/FRAMEBITS value. i) is easier, but ii) is
- recommended, since there are reports of MediaTracker not working in
- some environments.
- Also in the FAQ:
- o See also Q13.12
- o See Q6.4 for examples of how to reuse objects.
-
- 20. (Sect. 14) How can I record sound in an applet?
-
- [*] If you are using win95/nt, you could use SoundBite - Audio
- Recording in Applets. See http://www.scrawl.com/store/
- It provides easy access to audio data in arrays:
- short[] left, right;
-
- 21. (Sect. 14) Does Java support PNG? Yes. PNG - Portable Network Graphics
- - provides a patent-free replacement for GIF and TIFF. If you save a
- GIF, don't forget to pay the royalty to Unisys - see Unisys's web page
- at http://www.unisys.com/LeadStory/lzwfaq.html. That patent is why GIFs
- are a poor choice for internet images.
-
- The PNG format is specified in RFCs 1950, 1951, and 2083, and is
- unencumbered by licenses or patents. See also the PNG-1.1 specification
- at ftp://swrinde.nde.swri.edu/pub/png/documents.
-
- The PNG format is supported by the Java Advanced Imaging API which is
- part of the 1.2 media APIs.
-
- -------------------------------
-
- 15. Networking and Distributed Objects
-
- RMI Issues
-
- Note that there is an RMI FAQ at
- http://java.sun.com/products/jdk/rmi/faq.html
-
- 1. (Sect. 15) Should I use CORBA in preference to RMI? Or DCOM? Or what?
-
- [*] If your distributed programs are all in Java, then RMI provides a
- simpler mechanism that allows the transfer of code, pass-by-value of
- real Java objects, and automatic garbage collection of remote objects.
- If you need to connect to C++ (or other language) systems or you need
- CORBA-specific services, then CORBA is your choice.
- In July 1997, Sun announced that it was aligning RMI to work more
- closely with CORBA. Sun is simply adding an IIOP transport layer to RMI
- to support interoperability with CORBA. Java programs can then use RMI
- to access CORBA-based objects through IIOP, the OMG's CORBA-based
- protocol. This is very good news for those building heterogenous
- Enterprise systems, although it will take some additions to IIOP to
- support the pieces that RMI uses.
- In 1998 Microsoft spokespeople tried to promote DCOM by spreading
- misinformation that RMI is changing or being dropped. That is totally
- wrong. The RMI API continues unchanged in its current form. Using DCOM
- restricts your code to only ever run on Microsoft platforms using Intel
- hardware, and negates the "write once, run anywhere" Java philosophy.
- You would have to recompile your DCOM code to run it on other Microsoft
- platforms like Compaq's (formerly DEC's) alpha computer. Non-portable,
- single vendor code should be avoided. DCOM/DNA has limitations for use
- in the enterprise.
- Other sites:
- http://www.javaworld.com/javaworld/jw-10-1997/jw-10-corbajava.html
- has a good intro to CORBA in the Java world.
- http://www.objenv.com/cetus has a CORBA/RMI comparison.
-
- 2. (Sect. 15) How do I do RMI into a different domain?"
-
- [*] Similar to the proxy answer in a section below; you must tell the
- program where to find the server. In this case start up the client with
- this commandline option: -Djava.rmi.server.hostname=hostname.domainname
-
- 3. (Sect. 15) RMI seems to have stopped working for me in JDK 1.1. Why is
- this?
-
- [*] The rules for where the client looks for a stub class seem to have
- changed making it necessary to reset your class path on the client
- after starting the RMI registry. In particular, it looks like rmic was
- not updated to the new "don't need $CLASSPATH for current dir"
- convention as the compiler was. You are best off setting classpath
- explicitly.
- Other sites:
- There are several very good sources available from Sun which cover many
- simple and advanced RMI problems.
- o The documentation, of course:
- http://java.sun.com/products/jdk/1.1/docs/guide/rmi/index.html
- o Dedicated FAQs on RMI and Object Serialization
- http://java.sun.com/products/jdk/rmi/faq.html
- o Mailing list RMI-USERS@JAVASOFT.COM with archive at
- http://chatsubo.javasoft.com/email/rmi-users/ Visit the archive!
-
- 4. (Sect. 15) After a number of RMI client to server connections (55 on my
- system), subsequent RMI clients trying to connect fail. Why?
-
- [*] You are hitting the default limit of 64 open file descriptors. Try
- increasing the limit in your OS.
- In addition there is currently a practical RMI connection limit imposed
- by the scalability of the VM and the performance of object
- serialization. This is addressed in JDK 1.2. The actual number of
- active clients you will be able to support will depend on the workload
- mix you have (i.e. the number of clients, how often they talk to the
- server, and how much work must be done per call).
-
- 5. (Sect. 15) I'm using RMI on Win95, and the Naming.lookup() call is
- taking a long time, even for localhost. How do I fix it?
-
- [*] (See also the first answer in next section below, and note that
- this Windows workaround has never worked for some people). Try adding a
- definition for the machine in your "hosts" file. Typically, this file
- will be named c:\windows\hosts (if it doesn't exist, there should be a
- file called c:\windows\hosts.sam). The hosts file is searched by your
- TCP/IP stack before it resorts to DNS, so adding an entry in this file
- can speed up your lookups considerably. The hosts file is used to map
- IP addresses to symbolic addresses. To enter the name "localhost" with
- address 127.0.0.1 (the IP loopback address), enter the following line
- in your hosts file. 127.0.0.1 localhost
-
- Windows Networking
-
- 6. (Sect. 15) Why does < Windows RMI/my java debugger/IDE/other> hang for
- a couple of minutes if my Windows PC is not dialed up to the Internet?
-
- [*] Java has networking support built in. When the Java program starts
- the Winsock DLL automatically gets loaded. The first thing this does is
- to try to resolve the fully qualified domain name for your machine
- under the name "localhost". If your system doesn't have this name
- mapped, it will try to query a nameserver on the internet, which is
- typically (on a PC) your dialup ISP. So it either prompts you to
- connect to the ISP, or waits till the attempt times out.
-
- Some people say you can avoid the Win95 problem by giving your system
- another way to resolve DNS names. This tip has never worked for me.
- Edit the hosts file for your system so that localhost and the full
- domain name are both mentioned. On Windows 95 systems the hosts file
- is: %windir%\HOSTS (for example, C:\WINDOWS\HOSTS). On Windows NT
- systems the hosts file is: %windir%\System32\DRIVERS\ETC\HOSTS (for
- example, C:\WINNT\System32\DRIVERS\ETC\HOSTS).
- One gotcha under Win95 is that if the last entry in the hosts file is
- not concluded with a carriage-return/line-feed then the hosts file will
- not be read at all. So if my system is called goober.best.com change
- the hosts file from
-
-
- 127.0.0.1 localhost
-
-
- to
-
-
- 127.0.0.1 goober.best.com localhost
-
-
- Showing more of the file:
-
- # Hosts file
- 127.0.0.1 localhost
- 129.146.77.177 goober
-
-
- Another alternative is to dial up with a PPP connection to your ISP
- whenever you want to run networking programs.
-
- Fundamentally the experience of some people has been that networking is
- not completely satisfactory on Windows95 using Winsock 1.1, and is
- subject to sporadic unexplained failures. You could try downloading
- Winsock 2.0. To get Winsock 2.0, you need to drag in all the other junk
- from Microsoft Windows Sockets 2.0 Software Development Kit. This free
- software can be downloaded from the following addresses:
- http://www.microsoft.com/win32dev/netwrk/winsock2/ws295sdk.html or
- ftp://ftp.microsoft.com/bussys/WinSock/winsock2/
-
- The patches needed to improve Win95 networking are already in Win98.
-
- Other Networking Issues
-
- 7. (Sect. 15) If I call the InetAddress.getByName() method with an
- IP-address-string argument, like "192.168.0.1", get an
- UnknownHostException on some platforms, but not others. Code like
-
- Socket sock = new Socket("155.152.5.1", 23);
-
- triggers the exception. Why?
-
- [*] This is a platform difference that arises out of different
- semantics in the underlying network libraries, and is [said to be, but
- subject to confirmation] fixed in JDK 1.1. On Solaris and Windows NT,
- the IP address string only works for IP addresses that have an
- associated hostname. On Linux and Windows 95, the IP address string
- works in all cases.
- When InetAddress is instantiated with an IP address, a reverse DNS
- lookup is done. If the IP address is not associated with a valid
- hostname, the instantiation will fail. This is part of anti
- DNS-spoofing, and in JDK 1.1 works because the reverse lookup will not
- occur until the hostname is asked for. So in JDK 1.1,
-
- InetAddress in = InetAddress.getByName("155.152.5.1");
-
-
- [Note: this info is still to be confirmed. Net gurus?]
- Other sites:
- Microsoft has several network-related patches at its site
- http://www.microsoft.com/
-
- 8. (Sect. 15) I want to pass a class file to willing recipients who are
- using my applet. Any ideas how?
-
- [*] You could use a trick: put your .class file(s) in a .zip archive
- and use showDocument() on the URL. A person accessing this will get a
- dialog box put up asking them about saving the file to their local hard
- disk.
- Other sites:
- You can see this in action and try it out yourself at:
- http://www.best.com/~rmlynch/saveit.html
-
- 9. (Sect. 15) How do I get a URLConnection to work through proxy
- firewalls? I.e. How do you get your Java application to do its web
- accesses through a proxy?
-
- [*] This is typically needed for any net access to another domain. Tell
- the run time system what you are trying to do, by using these
- commandline arguments when you start the program.
-
- java -DproxySet=true -DproxyHost=SOMEHOST -DproxyPort=SOMENUM code.java
-
- Note proxyPort is optional and it defaults to 80. Without this, you
- will see an exception like java.net.UnknownHostException or
- java.net.NoRouteToHostException
-
- The proxy settings work for both java.net.URLConnection, and for
- java.net.Sockets.
-
- Netscape's and IE's JVMs (at least in versions 4.x+) take the proxy
- settings for applets from the browser's proxy configuration. You can
- also do URL proxies in applications (not applets) with the following
- code
-
-
- // set up to use proxy
- System.getProperties().put("proxySet", "true");
- System.getProperties().put("proxyHost", "myproxy.server.name");
- System.getProperties().put("proxyPort", "80");
-
-
- But how do I know the name of the proxy server?
- This code just tells you how you can get a URL connection to the
- outside. Since it is your proxy server, you are expected to know the
- name of it. There isn't any code that you can write that will allow
- arbitrary URL connections to be initiated from outside the firewall.
- Think about it! If there were, the firewall would not be doing its job.
-
- Also note there are corresponding socksProxyPort and socksProxyHost for
- when socks is used instead of proxy. The default socks port is 1080.
-
- 10. (Sect. 15) What is "swizzle", as in "Swizzle this object?"
-
- [*] It means serialize. To swizzle an object is to recursively
- serialize or flatten composed objects.
-
- 11. (Sect. 15) I have been using the Serializing capabilities in 1.1 to
- save some objects to disk. I added a new field to one of my objects
- that get serialized and now deserializing my old data no longer works.
- I get this exception:
-
-
- java.io.InvalidClassException: MacroData; Local class not compatible
-
-
- [*] You need to add a declaration such as
-
-
- static final long serialVersionUID = 4021215565287364875L;
-
-
- in the modified class. The actual value of this long is supplied by the
- "serialver" utilitity suppied with the JDK. Any versions of a class
- other than the first version require this static to be defined in the
- class. This is how versioning is achieved.
-
- 12. (Sect. 15) My socket code looks good, but is broken!
-
- [*] When using sockets you typically open both inward and outward
- streams. A TCP connection is full duplex, but either the send or
- receive side may be closed independently. By default, the remote end
- will take the close as indicating that the connection has simply been
- closed, and will close its end as well. Check whether this is happening
- for you, by adding the matched pair. Use tcpdump to check this.
-
- 13. (Sect. 15) How do I map between IP address and hostname?
-
- [*] In Java 1.1 (earlier releases were buggy) use:
-
-
- String host = InetAddress.getByName("211.10.2.119").getHostName();
-
-
- 14. (Sect. 15) How do I embed an anchor in a URL? Just putting it as part
- of the string in the constructor doesn't work.
-
- [*] Like this:
-
-
- URL url = new URL("http://www.my_domain.com/my_page.html");
- URL anchor = new URL(url, "#section2");
- this.getAppletContext().showDocument(anchor);
-
-
- 15. (Sect. 15) How do I POST to a CGI script from an applet?
-
- [*] Let's start by noting that this is more troublesome than it might
- seem at first, and that GET is preferred. For an untrusted applet, the
- CGI script can only be on the server that served the applet. POSTing to
- the server involves sending key/value pairs, not just a message. Also
- values must be encoded. To send "words to the server" you might try:
-
-
- StringBuffer sb = new StringBuffer();
- String str="words to the server";
-
- sb.append("message=");
- sb.append(java.net.URLEncoder.encode(str));
- URLConnection cn = url.openConnection();
-
- // set properties
- cn.setDoOutput(true);
- cn.setUseCaches(false);
- cn.setAllowUserInteraction(false);
- cn.setRequestProperty("content-type","application/x-www-form-urlencoded");
-
- // send parameters
- PrintWriter out = new PrintWriter(cn.getOutputStream());
- out.print(sb.toString());
- out.close();
-
- // read stuff
-
- BufferedReader in = new BufferedReader(
- new InputStreamReader(
- cn.getInputStream()));
-
- sb = new StringBuffer();
- String inputLine;
-
- while ((inputLine = in.readLine()) != null){
- sb.append(inputLine);
- sb.append("\n");
-
- }
- in.close();
-
-
- uresp = new URL(getDocumentBase(),"respond.html");
- getAppletContext().showDocument(uresp); }
-
-
- The CGI has to write its output to respond.html so that it can be
- displayed by the browser. But it may still fail, because respond.html
- could be overwritten by a subsequent request to the same CGI before the
- results of the first POST are read back.
- To get an acceptable solution takes quite a lot of effort. In general
- you should prefer GET to POST for CGI access from Java. As it says on
- the Javaworld page, the answers to the question are really: you can't,
- don't POST (use GET), use a bean, or cheat.
-
- Note, if you request a URL via the URLConnection/HttpURLConnection, the
- server sets the content type, and your applet can use
- URLConnection.getContentType() to get the type. Alternatively, use
- setRequestProperty to set it, like this:
-
-
- url = new URL(cgiUrl);
- urlc = url.openConnection();
- urlc.setRequestProperty(
- "Content-type",
- "application/x-www-form-urlencoded");
-
-
- Other sites:
- There's a pretty good explanation at
- http://www.javaworld.com/javaworld/javatips/jw-javatip41.html
-
- See also the Marty Hall book Core Web Programming (Prentice Hall ISBN:
- 0-13-625666-X). It has comprehensive coverage of writing Java programs
- that interface to CGI scripts. Better still, use servlets, write
- everything in Java, and discard your CGI code.
-
- 16. (Sect. 15) How can I write CGI programs in Java?
-
- [*] CGI (the Common Gateway Interface for web servers) is an API for
- writing programs that use the web as its user interface. By far, the
- most popular language for this task is Perl, because of its powerful
- text handling capabilities, and excellent resources available for
- making the jobs of CGI programmers easier. CGI programs can be written
- in any language, including Java.
- Unfortunately, the interface between the web server and the CGI program
- uses environment variables extensively. Use of environment variables
- has always been deprecated in Java, because of portability issues (not
- all systems have environment variables). The way to get around this is
- to write a "wrapper" for the Java program in a language that supports
- environment variables, and can then invoke the Java program with the
- appropriate environment data passed in as Java properties.
- Because the Java runtime environment is not a lightweight process, it
- might take a moment for the CGI program to get started before anything
- happens. This is particularly true on operating systems, like NT, that
- have a large overhead to spawning new processes.
- In preference to using Java for CGI on the server, you might consider
- using the Java servlet API in Netscape's Enterprise Server. This allows
- you to develop server-side programs in Java without suffering the same
- performance restrictions and other limitations of the CGI API.
- Other sites:
- See http://search.netscape.com/comprod/server_central/
- query/eval_guide/enterprise/advantage.html for more details.
-
- 17. (Sect. 15) How can I write the "ping" program in Java?
-
- [*] You can't do it directly. Quoting from the Java Networking FAQ,
-
- Ping requires ICMP packets. These packets can only be created
- via a socket of the SOCK_RAW type. Currently, Java only
- allows SOCK_STREAM (TCP) and SOCK_DGRAM (UDP) sockets. It
- seems unlikely that this will be added very soon, since many
- Unix versions only allow SOCK_RAW sockets to be created by
- root, and winsock does not address ICMP packets (win32
- includes an unsupported and undocumented ICMP.DLL).
-
- You could write a program that handshakes with a remote system, to
- simulate ping, or you could use native code for the raw socket. Other
- sites:
- You can find the Java Networking FAQ at
- http://www.io.com/~maus/JavaNetworkingFAQ.html
-
- There is an additional Java Networking FAQ (which is being
- modified and reposted regularly) at
- http://www.davidreilly.com/java/java_network_programming/
-
- 18. (Sect. 15) Why, when I make a call to DatagramPacket.getlength() does
- it returns the wrong size?
-
- [*] You are probably reusing a Datagram packet, and it has no way to
- grow its buffer if a longer packet comes in. Take care of it by calling
- setLength(max) before reuse.
-
- Failing to do this is a very common mistake.
-
- 19. (Sect. 15) Why do my networking programs freeze on the Mac?
-
- [*] You shouldn't println to a socket. This is the subject of Apple
- Technical Note 1157 at
- http://developer.apple.com/technotes/tn/tn1157.html
- The problem is that many socket protocols expect CR+LF to terminate a
- string, but println delivers a platform-specific EOL mark. On the Mac,
- it is just CR. Therefore the server hangs waiting for the Mac to send a
- LF. It never does. But the program works fine on platforms that send
- CR+LF.
-
- 20. (Sect. 15) How do I "timeout" a socket read, as the "select" function
- in Unix does?
-
- [*] There are two timeouts at issue here.
- Use the ServerSocket.setSoTimeout(int millis) for timing out your
- 'accept()' calls.
-
- For a select() like mechanism, you can poll InputStreams of your
- connections for available() > 0
-
- URLConnection doesn't have a method for this, but you can do it by
- using multiple threads. Create a timer thread that would just track
- time and close the connection after your specified timeout period.
- Check the URLConnection to see if it's got any data flowing through it
- (calling URLConnection.connected() is probably a sufficient test). The
- URLConnection should be in a separate thread.
-
- -------------------------------
-
- 16. Security
-
- 1. (Sect. 16) What is a "trusted applet"?
-
- [*] JDK 1.1 introduced the notion of a "trusted applet" which is one
- that has been cryptographically signed to guarantee its origin and make
- it tamper-resistant. Trusted applets can be granted more system access
- privileges than untrusted applets.
- You preconfigure your browser with a list of whose X.509 certificate
- you trust, and then applets arrive with X.509's attesting to their
- keys. It's easier than it sounds.
-
- 2. (Sect. 16) What is the story with Java and viruses? What is the
- blackwidow virus?
-
- [*] Java was designed with security in mind. The security features make
- it very difficult, probably impossible, to attach a virus (self-copying
- code) to a Java applet. There has never been a Java virus carried from
- system to system by applets.
- There has been mention of a "Java virus" called "BlackWidow" in the
- media (it was mentioned in Unigram in late 1996, and obliquely on the
- RISKS newsletter in February 1997). A request to the editor of Unigram
- for more information brought the answer that there was no more
- information, it was just a report of a rumor. As far as is known, this
- story exists only as rumors reported on by the press. There is no
- actual Java virus or blackwidow virus (there was a legitimate
- commercial product of that name, since renamed).
- In spring 1998 there were press reports of a "Java applet" called White
- Ghost. It turns out that it relies on security flaws in ActiveX, and
- the only susceptible systems are Microsoft's Active Desktop. If anyone
- has a URL for a copy of this code, and an analysis of it, please
- contact the FAQ author.
-
- In August 1998, Symantec had some information about a Java program
- (application) that could append itself to some other Java program. They
- termed it "Strange Brew". That is just normal file processing, no
- different to a program written in C, C++, Fortran, COBOL, etc. What
- makes PC viruses dangerous is when they have a hidden means of
- travelling between places, such as being attached to code that is
- automatically executed, like boot sector code, or Word macro
- initialization files. No one has yet produced a virus that does this in
- Java.
-
- In March 1999, reports surfaced of a virus called BeanHive. Again this
- was not Java-related, but relied on the browser user explicitly
- accepting an unknown certificate as trusted when prompted. If the user
- allowed that, then any code from that source will be uploaded and run
- without further input from the user. Don't remove security for
- untrusted code simply because it asks for it, is the lesson here.
- If anyone has more concrete information about a virus that can attack a
- Java applet (again, this is thought to be impossible), please contact
- the FAQ author.
-
- 3. (Sect. 16) Why do I get the warning string "Unsigned Java Applet
- Window" at the bottom of popup windows in my applets?
-
- [*] This is a security feature, to make certain that users can always
- tell that a window asking for their password and credit card details
- (or whatever) is from an applet. There should be no way for an
- untrusted applet to work around this message.
- Also in the FAQ:
- See also the answer to Q12.7.
-
- 4. (Sect. 16) Where can I find information on signing applets?
-
- [*] Please take a look at the "Code Signing for Java Applets" page at
- http://www.suitable.com/Doc_CodeSigning.shtml. The page explains how to
- sign your Java applet so that it can be used in both
- Navigator/Communicator and Internet Explorer.
-
- 5. (Sect. 16) Where can I find crypto libraries for Java?
-
- [*] Cryptographic libraries are not part of the Java release because US
- Government policy classifies strong cryptography under the same rules
- as munitions. Its export is regulated under the International Traffic
- in Arms Regulations. Many people regard this as a Kafka-esque (and
- futile) attempt to stem the use of cryptography inside the US.
- Other sites:
- o The comprehensive and free "Cryptix" crypto library written in
- Java is at:
- http://www.cryptix.org
- See also http://www.hi.is/~logir/logi.crypto/
- o Another free crypto library for Java is at:
- http://www.acme.com/java/software/Package-Acme.Crypto.html
- It includes Blowfish, CRC16, CRC32, DES, DES3, IDEA, RC4, ROT13
- (can they really call that "crypto"?), and more.
- o Another pure Java Cryptography toolkit is at
- http://www.freestylesoft.com/products/crypto/avalanche.html (free
- for personal use).
- o One commercial Java encryption source (from Ireland) is:
- http://www.baltimore.ie/jcrypto.htm
- o A complete crypto API for Java (with HTML documentation) at:
- http://www.geocities.com/SiliconValley/Heights/8298
- The library provides comprehensive and complete range of crypto
- library and functions covering DES, 3DES, IDEA, Blowfish ...and
- RSA, DH, DSA and PGP access to Java programmers. The crypto
- functions are based on the C cryptlib, by Peter Gutmann. It would
- be illegal to export this under current US government rules, but
- the author of the code is outside the US, and not subject to US
- export regulations. Download it today before it becomes illegal.
- o Some Java crypto available with source under GPL is at
- http://www.aba.net.au/solutions/crypto/jce.html
- http://www.geocities.com/SiliconValley/1394/
- o Also, data about Sun's Java Cryptography Extension (JCE) is
- available at:
- http://developer.java.sun.com/developer/earlyAccess/jdk12/jce.html
-
- (This may not be exported outside the USA and Canada).
- o An actual port of PGP v2.6.3i to Java is at:
- http://tassun.math.nsc.ru
- o A list of free crypto libraries, not necessarily in Java, and of
- course the FBI will be all over you like hair on an ape if you try
- to export any of these, is at:
- http://www.homeport.org/~adam/crypto/
-
- 6. (Sect. 16) How do I find out what these terms mean?
-
- [*] Read Bruce Schneier's excellent book "Applied Cryptography 2nd Ed."
- for more info on what these terms mean. Read David Kahn's excellent
- (and exhaustive) book "The Codebreakers" for more info on the history
- and background of encryption.
-
- 7. (Sect. 16) Where is Javasoft's Security FAQ?
-
- [*] Javasoft's security FAQ can be found at:
- http://java.sun.com/sfaq/index.html
- Other sites:
- http://java.sun.com/products/jdk/1.1/docs/guide/security/
-
- 8. (Sect. 16) Where is that online book on Java Security?
-
- [*] Gary McGraw and Ed Felten's book Securing Java can be found on the
- web at
- http://www.securingjava.com/
-
- -------------------------------
-
- 17. For C and C++ Afficionados
-
- 1. (Sect. 17) How do I translate C/C++ into Java or vice-versa?
-
- [*] In general it is not simple to translate C/C++ into Java, as Java
- lacks the arbitrary pointer arithmetic of those languages. If your C
- code does not use pointer arithmetic, automatic translation gets a lot
- simpler. Try these URLs:
- http://www.ist.co.uk (search for X-Designer 4.6: Java edition).
- http://members.aol.com/laffra/c2j.html
- http://www.ilog.com/
-
- Going the other way there are currently three freely-available tools to
- translate Java into C. It seems that these have been done for hacking
- value, rather than practical purposes.
- o j2c from Japan,
- http://www.webcity.co.jp/info/andoh/java/j2c.html
- o Toba from the Sumatra research project, translates 1.0.2 .class
- files into .c source code
- http://www.cs.arizona.edu/sumatra/toba
- o JCC from Nik Shaylor.
- http://www.geocities.com/CapeCanaveral/Hangar/4040/
-
- None of them support the AWT yet, and both j2c and JCC have additional
- restrictions.
-
- There's a product to convert Visual Basic to Java. Details at
- http://www.blackdirt.com and
- http://www.javadelphi.com (also a Delphi-to-Java source converter)
- and
- http://www.tvobjects.com
- There's a product to translate COBOL source to Java source, see
- http://www.Synkronix.com/
-
- This program dumps info about the class file:
- http://www.professionals.com/~cmcmanis/java/dump/index.html
-
- Chuck McManis was one of Sun's original Java implementors.
-
- 2. (Sect. 17) How are finalizers different from C++ destructors?
-
- [*] Java objects are not explicitly deleted and do not have
- destructors. Instead they are implicitly garbage collected when the JVM
- realizes your program can no longer access them. Typically this
- technology is _not_ based on reference counting and _will_ cope with
- circular references.
-
- Every object has a routine called finalize() which will be called
- before the object is collected. This is Java's nearest equivalent to
- C++'s destructor. However, it is not a good idea to rely on
- finalization for the timely freeing of resources.
-
- This is because garbage collection and hence finalization may be
- arbitrarily delayed, and may never happen at all if the program
- terminates before it runs out of memory. You should instead provide
- your objects with methods similar to Graphics.dispose() to free
- resources, and call the dispose() method explicitly when you have
- finished using them - typically within the "finally" clause of a
- "try/catch" block. You may then call your dispose() method from within
- your finalize() method as a last-ditch attempt to free the resource if
- someone forgets.
-
- Alas, all this means the C++ idiom of "object construction is resource
- aquisition" does not translate well to Java. However, note that 90% of
- destructors in C++ are there to free memory, and the GC means you don't
- need to do that in Java. As well as fixing an important source of bugs,
- the GC is essential to Java's security model; without it you could
- forge object references by preserving the reference after the object
- has been deleted.
-
- If your program appears to be crashing due to running out of some
- system resource (like File, Window or Graphics handles), it probably
- because the system is running out of handles before it has run out of
- memory. Check that you have called the dispose() method (or equivalent)
- on every object that uses system resources. You can help the GC a
- little bit more by explicitly NULLing out references that you've
- finished with.
-
- 3. (Sect. 17) What's the Java equivalent of sizeof()?
-
- [*] There isn't one. sizeof() in C and C++ is used in three main
- places:
- 1. To check on the size of a primitive type. In Java, the sizes of
- primitive types are fixed in the language specification (a short
- is _always_ 16 bits; an int is _always_ 32 bits, etc), so this is
- no longer necessary.
- 2. In memory allocation (i.e. malloc (32 * (sizeof(int));) In Java
- you always allocate a specific type of object, rather than a block
- of raw memory that you will fill as you like. The system always
- knows the size of the kind of objects you are allocating. So
- sizeof is not needed.
- 3. In pointer arithmetic (i.e. p += sizeof (int)) Pointer arithmetic
- of this type is not allowed in Java, so this isn't necessary,
- either.
-
- For all these reasons, there is no need for a Java sizeof() operator.
- by having the object serialize itself to a ByteArrayOutputStream, and
- looking at the bytearray.length.
-
- That won't work because a lot of additional data is written when an
- object is serialized. The additional data includes a description of the
- class, any objects referenced by the serialized object, null references
- (written as a single byte), etc. If you write another instance of the
- same class, the amount of data written can differ dramatically. And if
- you serialize the same object again, it isn't written at all -- even if
- its data fields have changed! Instead, a one byte token and a four byte
- "sequence number" that refer to the first writing are output. Using
- Object Serialization to determine the size of an object does not
- (except by coincidence) give the right answer.
-
- 4. (Sect. 17) Does Java have the equivalent of "const" arguments in C and
- C++?
-
- [*] Java 1.1 adds the ability to use the "final" keyword to make
- arguments constant. When used to qualify a reference type, however,
- this keyword indicates that the reference is constant, not that the
- object or array referred to is constant. For example, the following
- Java code:
-
- void foo(final MyClass c, final int a[]) {
- c.field = 7; // allowed
- a[0] = 7; // allowed
- c = new MyClass(); // final means this is NOT allowed
- a = new int[13]; // final means this is NOT allowed
- }
-
- is roughly equivalent to the following C/C++ code:
-
- void foo(MyClass * const c, int * const a) {
- c->field = 7; // allowed
- a[0] = 7; // allowed
- c = new MyClass(); // const means this is NOT allowed
- a = new int[13]; // const means this is NOT allowed
- }
-
- Java does not have any equivalent to the following C/C++ function
- declarations:
-
- void foo(const MyClass *c); // a pointer to a const class
- void foo(const int *a); // a pointer to a const int
- void foo(const int a[]); // a pointer to an array of const ints
-
- 5. (Sect. 17) Are there any hacks around this?
-
- [*] Certainly! There are always hacks around stuff. One way of
- enforcing constant values is to have two interfaces, a constant one and
- a non-constant one, e.g.
-
- public interface ConstFoo {
- int getValue();
- }
-
- public interface Foo extends ConstFoo {
- int getValue();
- void setValue(int i);
- }
-
- Then when you want to receive a parameter that cannot be modified you
- have:
-
- void noChange(ConstFoo foo);
-
-
- For a parameter that can be modified
-
- void change(Foo foo);
-
-
- 6. (Sect. 17) How can I write C/C++ style assertions in Java?
-
- [*] The two classes shown below provide an assertion facility in Java.
- Set Assert.enabled to true to enable the assertions, and to false to
- disable assertions in production code. The AssertionException is not
- meant to be caught--instead, let it print a trace. Since the exception
- is not meant to be caught, we just extend Error instead of
- RuntimeException. As with RuntimeException, a method does not need to
- declare that it throws Error. In addition programmers are less likely
- to write "catch(Error) ..." than "catch(RuntimeException)".
-
- With a good optimizing compiler there will be no run time overhead for
- many uses of these assertions when Assert.enabled is set to false.
- However, if the condition in the assertion may have side effects, the
- condition code cannot be optimized away. For example, in the assertion
-
- Assert.assert(size() <= maxSize, "Maximum size exceeded");
-
- the call to size() cannot be optimized away unless the compiler can see
- that the call has no side effects. C and C++ use the preprocessor to
- guarantee that assertions will never cause overhead in production code.
- Without a preprocessor, it seems the best we can do in Java is to write
-
- Assert.assert(Assert.enabled && size() <= maxSize, "Too big");
-
- Alternatively, use
-
- if (Assert.enabled)
- Assert.assert( size() <= maxSize, "Too big" );
-
- In this case, when Assert.enabled is false, the method call can always
- be optimized away totally, even if it has side effects. The relevant
- sections of the JLS are Section 13.4.8, final Fields and Constants and
- Section 14.19, Unreachable Statements. 13.4.8 requires that primitive
- constants ("a field that is static, final, and initialized with a
- compile-time constant expression") be inlined. So everywhere
- Assert.enabled is refered it is replaced at compile time with its
- value. Writing:
-
- if (Assert.enabled) Assert.assert(size() <= maxSize, "Too big");
-
- is exactly the same as writing:
-
- if (false) Assert.assert(size() <= maxSize, "Too big");
-
- ... assuming Assert.enabled is false at compile time. Section 14.19
- discusses compiling away such dead code. To sum up: the inlining of the
- primitive constant is required by the spec. The subsequent optimization
- of not generating code masked by (what turns into) an "if (false) ..."
- is not required but is implemented by many existing Java compilers.
-
- public class AssertionException extends Error {
- public AssertionException(String s) {
- super(s);
- }
- }
-
- public final class Assert {
- public static final boolean enabled = true;
- public static final void assert(boolean b, String s) {
- if (enabled && !b)
- throw new AssertionException(s);
- }
- }
-
- 7. (Sect. 17) How do I do stuff like scanf and sscanf in C/C++? And how do
- I do stuff like sprintf, e.g.
-
- float x = 12345.6789;
- printf("%6.3f/n", x);
-
- [*] You can break a string like "5 loaves 2 fishes" into its parts by
- using java.util.StringTokenizer. This is the Java equivalent of
- sscanf().
-
- StreamTokenizer does a similar thing on a file or any stream (i.e, what
- scanf() and fscanf() do in C).
-
- To do formatted character output, create a format string, and then use
- that to format your binary value, e.g.
-
- import java.text.*;
-
- float fi = 1234.56789F;
- DecimalFormat mydf = new DecimalFormat( "###0.000" );
- mydf.setMinimumIntegerDigits(3); // for example
- System.out.println( mydf.format(fi) );
-
- gives:
- 1234.567
-
- If you want to see a float print out as "0.0000001" instead of "1E-7",
- use:
-
- java.text.DecimalFormat myFmt = new
- java.text.DecimalFormat("#,###,###,###.############");
- System.out.println(myFmt.format(myFloat));
-
- There are lots of different characters you can feed to the
- DecimalFormat constructor, not just "0" and "#". See
- $JAVAHOME/src/java/text/DecimalFormat.java source for details.
-
- The always excellent Acme site has an sprintf() package written in Java
- See http://www.acme.com.
-
- 8. (Sect. 17) What is the Java equivalent of C++'s "friend"?
-
- [*] The keyword "friend" in C++ is a hack to allow a piece of code to
- access the private member declarations of another class. In Java, you
- would do this by labelling, not the friend, but the private members.
- Instead of making them private, make them either protected or package
- (no keyword) or public.
-
- The four different Java protection levels are: private, package,
- protected, and public.
- o private members can only be accessed by the containing class and
- internal classes.
- o package (specified by omitting other keywords) is the default
- level of protection; members are accessible from any class within
- the package of the containing class.
- o protected is package-level-access plus access to sub-classes of
- the containing class. So "protected" is less protected than the
- default.
- o public fields in public classes are accessible from all classes.
-
- 9. (Sect. 17) Does anything like the C++ Standard Template Library exist
- for Java?
-
- [*] Yes, only it's better and simpler to use in Java. It's called the
- Java Generic Library. This library (JGL) is freely downloadable from
- http://www.objectspace.com/
-
- It includes about a dozen nice data structures (including sets and
- bags) and algorithms like unions, searching, and sorting.
-
- It has over 100,000 users and 11 OEM distributors. [Some Java vendors
- are bundling it with their next release]
-
- 10. (Sect. 17) What happens to post-increment when an exception is thrown?
-
- [*] If you have the code:
-
- array[i++] = foo();
-
- and foo() throws an exception, i will be incremented anyway. This can
- cause problems if sometimes foo() throws an exception and you don't
- want i incremented in cases when it does.
-
- This is a consequence of JLS 15.25.1 and 15.6.1 "the left-hand operand
- of a binary operator appears to be fully evaluated before any part of
- the right-hand operand is evaluated." (assignment is taken as a binary
- operator). Note that this is not how C++ behaves.
-
- -------------------------------
-
- 18. Java Idioms
-
- See also the list of Java Design Patterns at
- http://c2.com/cgi/wiki?JavaIdioms
-
- 1. (Sect. 18) What are the naming conventions in Java?
-
- [*] The naming conventions are straightforward:
- o Package names are guaranteed uniqueness by using the Internet
- domain name in reverse order: com.javasoft.jag - the "com" or
- "edu" (etc.) part used to be in upper case, but now lower case is
- the recommendation.
- o Class and interface names are descriptive nouns, with the first
- letter of each word capitalized: PolarCoords. Interfaces are often
- called "something-able", e.g. "Observable", "Runnable",
- "Sortable".
- o Object and data (field) names are nouns/noun phrases, with the
- first letter lowercase, and the first letter of subsequent words
- capitalized: currentLimit.
- o Method names are verbs/verb phrases, with the first letter
- lowercase, and the first letter of subsequent words capitalized:
- calculateCurrentLimit.
- o Constant (final) names are in caps: UPPER_LIMIT.
- Other sites:
- o Check out the section "Naming Conventions" in the language
- specification:
- http://java.sun.com/docs/books/jls/html/6.doc.html#11186
- o Also take a look at Doug Lea's draft coding standard:
- http://gee.cs.oswego.edu/dl/html/javaCodingStd.html
-
- 2. (Sect. 18) How do I convert a String to an int?
-
- [*] There are several ways. The most straightforward is:
-
- String mystring = numString.trim();
- int i = Integer.parseInt(myString);
- long l = Long.parseLong(myString)
-
-
- or
-
- String mystring = numString.trim();
- i = Integer.parseInt(myString,myIntRadix);
-
-
- Note 1: There is a gotcha with parseInt - it will throw a
- NumberFormatException for String values in the range "80000000" to
- "ffffffff". You might expect it to interpret them as negative, but it
- does not. The values have to be "-80000000" .. "-ffffffff" to be
- properly recognized as negative values. This is true for all radixes.
- According to Bug Parade bug report 4068580, the proper way to generate
- negative-valued hex Strings for eventual use by parseInt() is with
- Integer.toString(i, 16). Once that high "sign bit" is on, without the
- accompanying character, parseInt() says "too big".
- Note 2: There are similar methods for Byte, Short, and Long. Use
- myString.trim() to get rid of unwanted spaces before the conversion.
- Some of the parse methods can cope with spaces, others can't. They were
- written by two different people.
-
- int i = Integer.valueOf(my_str).intValue();
-
-
- also works but involves the creation of an extra object. Note: the
- pre-FCS JDK 1.2 documentation at one point said that parseDouble and
- parseFloat methods were to be introduced, but this does not seem to be
- the case (see bug 4160672). JDK 1.2.
-
- float f = Float.valueOf(my_str).floatValue();
- double d = Double.valueOf(my_str).doubleValue();
-
-
- 3. (Sect. 18) How do I convert an int to a string?
-
- [*] Try any of these:
-
- String s = String.valueOf(i);
-
-
- or
-
- String s = Integer.toString(i);
-
-
- or
-
- String s = Integer.toString(i, radix);
-
-
- or
-
- // briefer but may result in extra object allocation.
- String s = "" + i;
-
-
- Note: There are similar classes for Double, Float, Long, etc.
-
- 4. (Sect. 18) How do I print the hex value of an int?
-
- [*] You can print the hex equivalent of an int with:
-
- int i = 0xf1;
- System.out.println("i is hex " + Integer.toHexString(i) );
-
-
- OK, how do I read a hex string into an int?
-
- int i = Integer.valueOf(myHexString, 16).intValue();
-
-
- 5. (Sect. 18) How can you send a function pointer as an argument?
-
- [*] Simple answer: use a "callback". Make the parameter an interface
- and pass an argument instance that implements that interface.
-
- public interface CallShow { public void Show( ); }
-
- public class ShowOff implements CallShow {
- public void Show( ) { .... }
-
- public class ShowOff2 implements CallShow {
- public void Show( ) { .... }
-
- public class UseShow {
- CallShow savecallthis;
-
- UseShow( CallShow withthis ) {
- savecallthis = withthis;
- }
-
- void ReadyToShow( ) { savecallthis.Show( ); }
- }
-
- // in some other class that uses all this stuff:
- UseShow use_1 = new UseShow( new ShowOff() );
- UseShow use_2 = new UseShow( new Showoff2() );
-
-
- and then the ReadyToShow() method on use_1 or use_2 will call the
- appropriate method, as if you had stored a pointer to the method.
-
- 6. (Sect. 18) How do I execute a command from Java?
-
- [*] Use
-
- Runtime.getRuntime().exec( myCommandString )
-
-
- where myCommandString is something like "/full/pathname/command". An
- applet will need to be signed in order to allow this.
-
- Note, there is a gotcha associated with reading output from commands.
- When the runtime exec's the process, it passes to it 3 streams, for
- stdin, stdout, and stderr; the out and err are buffered but the buffer
- size isn't very big. When your process runs, it reads (if needed) from
- in, and writes to out and err. If it doesn't write more than the
- buffer-size, it can run to completion.
-
- But if it tries to write more data to one or the other stream than the
- buffer can hold, the write blocks, and your process hangs, waiting for
- you to empty the buffer so it can write some more.
-
- So after the exec call, get the streams, and read from them in a loop
- until they both hit end-of-stream (don't block on either one, just read
- whatever is available from each, each loop iteration). Then when the
- streams have ended, call the process.waitFor() method to let it finish
- dying.
-
- 7. (Sect. 18) How do I do I/O redirection in Java using exec()?
-
- [*] This solution works on Unix platforms using either JDK 1.0.2, or
- JDK 1.1. The trick is to use an array of Strings for the command line:
-
- String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
-
-
- If you don't do this, and simply use a single string, the shell will
- see the -c and /bin/ls and ignore everything else after that. It only
- expects a single argument after the -c.
-
- import java.io.*;
- import java.util.*;
-
- class IoRedirect {
- public static void main(String Argv[]) {
- try {
- String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
- Process p = Runtime.getRuntime().exec(command);
- p.waitFor();
- System.out.println("return code: "+ p.exitValue());
- } catch (IOException e) {
- System.err.println("IO error: " + e);
- } catch (InterruptedException e1) {
- System.err.println("Exception: " + e1.getMessage());
- }
- }
- }
-
-
- 8. (Sect. 18) So why can't I exec common DOS commands this way (as in
- 18.7)?
-
- [*] The reason is that many of the DOS commands are not individual
- programs, but merely "functions" of command.com. There is no DIR.EXE or
- COPY.EXE for example. Instead, one executes the command processor
- (shell) explicitly with a request to perform the built-in command, like
- so:
- Runtime.getRuntime().exec("command.com /c dir") for example. On NT, the
- command interpreter is "cmd.exe", so the statement would be
- Runtime.getRuntime().exec("cmd /c dir") And you could bring the command
- output into the program with code like:
-
- Process p = runtime.exec ("cmd /c dir");
- DataInputStream procIn = new DataInputStream(p.getInputStream());
- while ( true ) {
- String line = procIn.readLine();
- if ( line == null ) break;
- // do something with lin
- }
-
- This situation occurs on any OS where some commands are actually
- interpreted directly by the shell.
-
- 9. (Sect. 18) OK, how do I read the output of a command?
-
- [*] As above (18.6, 18.7), adjusted like this:
-
- BufferedReader pOut= new BufferedReader(
- new InputStreamReader(p.getInputStream()));
- try {
- String s = pOut.readLine();
- while (s != null) {
- System.out.println(s);
- s = pOut.readLine();
- }
- } catch (IOException e) { }
-
-
- Another possibility is to read chunks of whatever length as they come
- in:
-
- ...
-
- p = r.exec(cmd);
- InputStream is = p.getInputStream();
- int len;
- byte buf[] = new byte[1000];
- try {
- while( (len = is.read(buf)) != -1 ) {
- String str = new String(buf,0,0,len);
- System.out.println( "Process out: " + str );
- }
- } catch( java.io.EOFException eof ) { ...
- } catch( java.io.IOException ioe ) { ... }
-
-
- However, you cannot read output from some DOS commands on Windows
- 95/98. This is bug 4211683 at Sun, but it is actually a Microsoft
- bug/poor design. Windows programs that explicitly use a handle to the
- console ("CON" or "CON:") instead of stdin and stdout cannot be used as
- subprocesses to Java. The Win95 FTP program is an example of such a
- program. Windows provides no convenient way for Java to redirect the
- input and output of such processes from the console to input and output
- pipes. The only workaround is to use a different implementation of the
- program that does not use the console directly.
-
- Microsoft documents a difference in DOS Console stream handling between
- 95 and NT: see
- http://support.microsoft.com/support/kb/articles/q150/9/56.asp
-
- So capturing output from GNU ls on Win95 works, but the output from
- "command.com /c dir" is not captured.
-
- 10. (Sect. 18) How do I compile code which has a cyclic dependency, i.e
- class pkg1.X contains a reference to class pkg2.Y ?
-
- [*] You throw both classes at the compiler at the same time.
- javac pkg1/X.java pkg2/Y.java
-
- 11. (Sect. 18) What is the point of creating the temporary reference to
- this.layoutMgr?
-
- [*] This code is from the 1.0 AWT, and the programmer was probably
- pretty skilled.
-
- public synchronized void layout() {
- LayoutManager layoutMgr = this.layoutMgr;
- if (layoutMgr != null) {
- layoutMgr.layoutContainer(this);
- }
- }
-
-
- The code makes a local copy of a global variable for one or both of two
- reasons.
- The first reason is that accessing local variables can be faster than
- accessing (non final) member variables. It's good for loops or where
- there are many references in the source.
- The second reason is so that even if other threads update the global,
-
- this.layoutMgr = someOtherLayoutMgr;
-
-
- This method will still have a pointer to the original layoutMgr.
- If the local variable were omitted, and another thread used the
- setLayout() method to change layoutMgr to null between when the layout
- method checked for null and when it invoked layoutMgr's layoutContainer
- method, a NullPointerException would result.
- Note that the synchronized keyword on the layout method doesn't help
- any, since setLayout (which could make such a dire change) isn't
- synchronized. Synchronized methods only lock out other synchronized
- methods on this object. (The unhelpful synchronized keyword on the
- layout method is gone in JDK 1.1.)
- There are two alternative solutions. One would be to make setLayout
- synchronized and make layoutMgr private, so that it can't be set other
- ways. This provides a stronger form of thread serialization, in that
- you would never be able to see an old layout manager being used after
- it had been replaced. However, it is slower. Another option that
- provides no increase in thread serialization over the original would be
- to catch the NullPointerException.
- Threaded programming is hard! This idiom was probably put in place by
- someone who got really bitten by this in the past.
-
- 12. (Sect. 18) What is the difference between "a & b" and "a && b" ?
-
- [*] "a & b" takes two boolean operands, or two integer operands. It
- always evaluates both operands. For booleans, it ANDs both operands
- together producing a boolean result. For integer types, it bitwise ANDs
- both operands together, producing a result that is the promoted type of
- the operands (i.e. long, or int). "|" is the corresponding bitwise OR
- operation. "^" is the corresponding bitwise XOR operation.
-
- "a && b" is a "conditional AND" which only takes boolean operands. It
- always avoids evaluating its second operand if possible. If a is
- evaluated to false, the AND result must be "false" and the b operand is
- not evaluated. This is sometimes called "short-circuited" evaluation.
- "||" is the corresponding short-circuited OR operation.
-
- Possible mnemonic: The longer operators "&&" or "||" try to shorten
- themselves by not evaluating the second operator if they can.
-
- 13. (Sect. 18) If I create a thread, and then null out the reference to it,
- what happens to the thread? Does it get interrupted or what?
-
- [*] The code looks like this:
-
- Thread t = new Thread( my_runnable_obj );
- t.start();
- ...
- t = null; // what happens to the thread?
-
-
- The answer is that you may no longer have a reference to the thread,
- but the JVM still does. Once a thread is started, and as long as it
- keeps running, it is a root object. Root objects are the starting
- points for "things in use" that the garbage collector uses.
-
- 14. (Sect. 18) How can a Java program determine the level of JDK support
- given by the underlying VM? I.e. is it running in a JDK 1.0.2 or 1.1
- VM?
-
- [*] Look at the java.version system property with:
-
- String ver = System.getProperty("java.version");
-
-
- There isn't a lot of standardization on the string contents however.
- Another possibility is to try { ... } to load a class that is unique to
- one release, like this:
-
- boolean isJDK1_1 = true;
- try {
- // java.awt.Cursor is available only in the 1.1.x JDK
- Class cls = Class.forName("java.awt.Cursor");
- } catch (Exception e) {
- // we should have written 'ClassNotFoundException e',
- // but Communicator generates security exception instead.
- isJDK1_1 = false;
- }
-
- This approach has the advantage that it can be compiled by any version
- compiler.
-
- 15. (Sect. 18) How can I set a system property?
-
- [*] JDK 1.2 has
-
- System.setProperty( "property", "new value" );
-
-
- Until then, you can get all the properties, and set just the one you
- want with code like this:
-
- System.getProperties().put("property", "new value" );
-
-
- 16. (Sect. 18) How can I clone using serialization?
-
- [*] Look at the code below, submitted by expert programmer John Dumas.
- It uses serialization to write an object into a byte array, and reads
- it back to reconstitute a fresh copy. This is a clever hack!
-
- import java.io.ByteArrayOutputStream;
- import java.io.ByteArrayInputStream;
- import java.io.ObjectOutputStream;
- import java.io.ObjectInputStream;
-
- public class Cloner {
- private Cloner() {}
-
- public static Object cloneObject(Object o) throws Exception {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ObjectOutputStream out = new ObjectOutputStream(bOut);
-
- out.writeObject(o);
-
- ByteArrayInputStream bIn =
- new ByteArrayInputStream(bOut.toByteArray());
- ObjectInputStream in = new ObjectInputStream(bIn);
-
- return(in.readObject());
- }
-
- public static void main(String args[]) throws Exception {
- java.util.Vector v = new java.util.Vector();
- v.addElement(new StringBuffer("Hello"));
-
- java.util.Vector vClone =
- (java.util.Vector)Cloner.cloneObject(v);
-
- // Changing the StringBuffer int the cloned vector has no
- // effect on the original StringBuffer object --
- // demonstrating that we have indeed done a deep copy
-
- ((StringBuffer)vClone.elementAt(0)).append(" world");
-
- StringBuffer sb = (StringBuffer)v.elementAt(0);
- System.out.println(sb.toString());
-
- sb = (StringBuffer)vClone.elementAt(0);
- System.out.println(sb.toString());
-
- int array[] = { 1, 2, 3, 4, 5 };
-
- int arrayClone[] = (int [])Cloner.cloneObject(array);
-
- // Again, changes to an element in the cloned array do not
- // have any effect on the original
-
- arrayClone[0]++;
-
- System.out.println(array[0]);
- System.out.println(arrayClone[0]);
- }
- }
-
- The main() routine is just a driver. All the cleverness is in the very
- brief cloneObject(). It does a "deep" clone, which is what you usually
- want (though Java gives you a "shallow" clone by default).
-
- -------------------------------
-
- 19. Java GOTCHA'S
-
- 1. (Sect. 19) What is a "GOTCHA" (for non-English native speakers)?
-
- [*] It is an abbreviation of "Got you!" It is the triumphant
- exclamation that a bug or programming idiom makes as it traps the
- unwary programmer. This section details some of the popular "gotcha's"
- of Java.
-
- See also the list of Java Gotcha's at
- http://mindprod.com/gloss.html
-
- 2. (Sect. 19) Why can't I filter filenames with the accept() method?
-
- [*] It's a known bug. FileDialog doesn't call FilenameFilter.accept().
- The bug id is 4031440, and it can be seen at the Java Developer
- Connection.
-
- There is no way to implement FilenameFilter support with the current
- reliance on the Win32 common file dialog. To support FilenameFilter,
- the FileDialog needs to issue a callback for each file it wants to
- display, which the FilenameFilter can veto. But the Win32 common
- FileDialog doesn't have any way to issue callbacks. Instead it accepts
- simple wildcard patterns for choosing files which match a certain
- pattern. That's a reasonable alternative to FilenameFilters, but that
- model isn't supported by the current Java API.
-
- JFC has a JFileChooser class that is a better bet for you to use for
- file dialogs. It works fine.
-
- 3. (Sect. 19) I changed a final value, and recompiled just the file that
- it was in, and the entire rest of the program used the old value!
-
- [*] This is the "expected" behavior. If you have this in one file
-
- class Flags { final static boolean debug = true; }
-
- and you change it to, and recompile just this file:
-
- class Flags { final static boolean debug = false; }
-
- Then the rest of your Java .class files will still see it as "true".
-
- When you declare a "static final int" (or any other primitive), the
- compiler turns that into a compile time constant whose value can be
- substituted wherever it is used in your program. If you update the
- value in the source file, you'll need to recompile every class that
- uses it.
-
- See Java Language Specification, section 13.4.8 "final Fields and
- Constants": "We call a field that is static, final, and initialized
- with a compile-time constant expression a primitive constant. If a
- field is a primitive constant, then deleting the keyword final or
- changing its value will not break compatibility with pre-existing
- binaries by causing them not to run, but they will not see any new
- value for the constant unless they are recompiled."
-
- 4. (Sect. 19) What is the "substring trap"?
-
- [*] The "substring trap" is the name for a mistake that is all too easy
- to make when using the substring() method of class String. The method
- signature is:
-
- public String substring(int beginIndex, int endIndex)
-
- The name "endIndex" suggests that is the index where the Substring
- ends.
-
- But in fact, the substring extends only to the character at position
- (endIndex-1)! It seems to be done this way so that
- s.substring(0,s.length()) is equal to s. If so, the name of the second
- parameter should be something like endInxLessOne or Length. But not the
- confusing and misleading endIndex. Beware the substring trap.
-
- 5. (Sect. 19) Why does getGraphics() return null on my offscreen image?
-
- [*] The following code
-
- class MyFrame extends Frame {
- MyFrame() {
- Image offscreen = createImage(100,100);
- Graphics offg = offscreen.getGraphics();
- }
- ...
- }
-
- will usually not work, since the peer will not exist at this time.
- Without the peer for the Frame, you cannot succeed in creating
- offscreen Images. (There's no problem creating Produced Images without
- a peer. Trying to draw them, of course, is another matter).
-
- One "standard" form of offscreen code looks like this: (note the reuse
- of the Graphics and Image objects for as long as possible)
-
- class Gumble extends java.awt.Something {
- private Image offi;
- private Graphics offg;
-
- public void update(Graphics g) {
- if (g == null) return; // Paranoia
- Dimension size = size();
- if ( offi == null
- || offi.getWidth()!=size.width
- || offi.getHeight()!=size.height ) {
- if (offg!=null) offg.dispose();
- offi = createImage(size.width, size.height);
- offg = offi.getGraphics();
- // Regenerate offi here...
- }
- // If you use getClipBounds() here,
- // check that for being null, too!
- // several implementations have been known to pass them....
- g.drawImage(offi);
- }
-
- public void paint(Graphics g) {
- update(g);
- }
- }
-
- See also Question 8.7
-
- 6. (Sect. 19) The dynamic type of a method argument doesn't seem to be
- used to choose an overridden method at runtime.
-
- [*] Correct. Generally, if you invoke a method on an object, the
- object's actual runtime type, not the type of the reference that you
- used to reference it, determines which method is invoked. This is
- regular polymorphism.
-
- It's not the same for object parameters: the compiler decides at
- compile time, depending on the types of the parameter expressions,
- which method signature to use, and this is "hardwired" into the
- bytecode. The compiler does not look at the object argument at runtime
- and say "ah, this is a derived type, so I will choose the method that
- takes the derived type as an argument."
-
- This is best seen in a code example:
-
- class Base { }
- class Derived extends Base { }
-
- public class foo {
-
- public static void method(Base b) {
- System.out.println("In the base method...");
- }
-
- public static void method(Derived d) {
- System.out.println("In the derived method...");
- }
-
- public static void test(Base b) {
- if (b instanceof Derived)
- System.out.print("Derived: ");
- else
- System.out.print("Base: ");
-
- method(b); // which method? method(base) or method(derived)?
- }
-
- public static void main(String args[]) {
- Base b = new Base();
- Derived d = new Derived();
-
- System.out.println("test calls.");
- test(b);
- test(d);
- }
- }
-
- Running the program gives an output of
-
- test calls.
- Base: In the base method...
- Derived: In the base method...
-
- See JLS section 15.11.4.4 and 15.11.3:
- "If class S contains a declaration for a method named m with the same
- descriptor (same number of parameters, the same parameter types, and
- the same return type) required by the method invocation as determined
- at compile time then this is the method to be invoked."
-
- 7. (Sect. 19) Why did I lose my updates when I changed data fields in a
- graph that I was serializing?
-
- [*] Quoting from the object serialization specification at:
- http://www.javasoft.com/products/jdk/1.1/docs/
- guide/serialization/spec/serial-arch.doc.html#4176
- The writeObject method serializes the specified object and
- traverses its references to other objects in the object graph
- recursively to create a complete serialized representation of the
- graph.
-
- Within a stream, the first reference to any object results in the
- object being serialized or externalized and the assignment of a
- handle for that object. Subsequent references to that object are
- encoded as the handle.
-
- In other words, changing an object and then writing it again does not
- really write it twice. Instead it just writes a reference back to the
- first occurrence, losing any fields that have changed in the meantime.
-
- There are three ways around this: (1) (inefficient) Reset (or close and
- reopen) the stream, and start again by writing the new value of the
- object. This is drastic -- you are throwing away all the serialization
- that you have already done.
- (2) (kludgey) Create a new object and write that.
- (3) (could be a lot of work) Write your own protocol for object
- serialization. Have something like a data stream where the contents of
- an object are marked by special identifiers. Each "end" of the stream
- can decide whether it will use a new object each time or reuse an
- existing object.
-
- 8. (Sect. 19) When I click on a Java window frame, it doesn't close!
-
- [*] You need to add the code to listen for a window closing event, and
- take the appropriate action (hide the window, exit the program if the
- top level frame, etc).
-
- The window closing event handler is simple:
-
- Frame mf = new Frame("binky");
- mf.addWindowListener( new WindowAdapter() {
- public void windowClosing(WindowEvent we) {
- System.exit(0); // or setVisible(false); etc.
- } });
-
- This really should be the default behavior of an AWT Frame. So you'll
- be delighted to hear that JavaSoft has "made it so" for the JFrame
- Swing component. That leads to a slightly different problem. See
- Question 4.3.3. See also Question 13.9.
-
- 9. (Sect. 19) What's the deal with "super"? How far back into parent
- classes can I go?
-
- [*] The most common use of super is the call "super()" to invoke a
- constructor in the superclass. The keyword "super" is also used to
- access fields of any superclass (not just the immediate superclass)
- that are hidden by an identically named feature in the current class.
-
- However there is no way to "chain" several super's together, and reach
- back higher into the parent class hierarchy. E.g. do not think that
- "super.x" means the "x of parent" and "super.super.x" means the "x of
- grandparent". This is a very common mistake. There is no
- "super.super.x". Looking at the generated byte code, if you have
-
- class Parent { }
-
- class Child extends Parent { }
-
- then, in Child "super.someParentMethod();" means "invokespecial
- X.someParentMethod()" in the JVM, not "invokevirtual".
- Invokespecial means "call the exact method I am telling you."
- Invokevirtual means "call the right method for whatever object this
- is".
-
- 10. (Sect. 19) When I change some component (e.g. a new label on a button)
- I don't see the change on the screen immediately even if I repaint().
-
- [*] You need to add a call to the paintImmediately(x,y,w,h) method of
- JComponent. That repaints the component completely before continuing
- execution. On pre-JDK 1.2 systems, use:
-
- invalidate();
- validate();
-
- They cause the component hierarchy to be marked as needing to be laid
- out again, and the validate causes that to be done. It may be
- expensive, but is a way of getting the peers to recalculate size and to
- do what is needed to bring the display up to date. It has limitations:
- it doesn't cause an immediate screen update when invoked from an event
- handler, where paintImmediately() does.
-
- 11. (Sect. 19) Why aren't popup menus working cross-platform for me?
-
- [*] On Windows, the pop-up trigger is a mouse release (except in
- certain programs like Netscape Communicator). On Unix, the pop-up
- trigger is a mouse press.
-
- Therefore you need to ask the question isPopupTrigger() in both the
- mousePressed() and mouseReleased() methods when implementing the
- MouseListener interface. Alternatively override Component's
- processMouseEvent as a central place for handling mouse input.
-
- 12. (Sect. 19) Why aren't newlines working cross-platform for me?
-
- [*] Code like this:
-
- if (c == '\n')
- fin = true;
-
- is not cross-platform. On Unix the line terminator is "\n", on Windows,
- it is frequently "\r\n", on the Mac it is "\r".
-
- The call System.getProperty("line.separator") will return a string
- containing the platform-specific line separator character(s), and you
- then need to compare it according to how your data is formatted (e.g.
- compare 2 characters or one). There is also a property for the
- separator character in file pathnames, and other values too.
-
- This can screw-up your networking programs too. Most ASCII based
- protocols like HTTP expect \r\n to terminate a request. They will hang
- on a request from a Mac that only sends \r.
-
- 13. (Sect. 19) Why didn't my text display in my GUI? Is the Inset wrong?
-
- [*] The most common Inset problem is not an Inset problem at all, but
- rather that people just assume the x,y location of a
- Graphics.drawString() actually refers to the top left part of the
- string image. In fact it refers to the baseline. So you'll need to take
-
- g.drawString("Hello World",0,getFontMetrics(getFont()).getAscent());
-
- 14. (Sect. 19) Why did my polygon come out the wrong shape?
-
- [*] This question and answer comes directly off
- comp.lang.java.programmer, and deserves to be immortalized for
- posterity.
- When I use fillPolygon with the following points I get two inverted
- triangles instead of a rectangle. Why?
-
- int xPoints[] = {71, 78, 71, 78};
- int yPoints[] = {147, 147, 130, 130};
- g.fillPolygon(xPoints, ypoints, xPoints.length);
-
- Developer Felix Pahl supplied the answer in limerick form:
- o A developer (for details bored her)
- didn't follow the polygon's border
- so instead of right angles
- she got two triangles
- 'cause the endpoints were in the wrong order!
-
- You must put the points in the order you would encounter them in if you
- went round the polygon's border. The filling algorithm is doing the
- right thing! Try drawing the points on paper to see:
-
- 71,130 78,130
- O--------O
- | |
- | |
- | |
- o--------o
- 71,147 78,147
-
- Under JDK1.1, the two endpoints are connected automatically and you
- would order the array elements as:
-
- int xPoints[] = { 71, 78, 78, 71};
- int yPoints[] = {130, 130, 147, 147};
-
- Under JDK1.0.2, you have to explicitly connect the two endpoints, and
- you would write the array elements as:
-
- int xPoints[] = { 71, 78, 78, 71, 71};
- int yPoints[] = {130, 130, 147, 147, 130};
-
- 15. (Sect. 19) Why can't I see all the components I added to a Frame?
-
- [*] If you have code like:
-
- Frame myframe = new Frame("Child Frame");
- myframe.resize(512,384);
- myframe.add(new Label("Child"));
- myframe.show();
-
- The default layout manager for Frame is BorderLayout. Components
- positioned with a BorderLayout should include a positioning constant to
- be correct. If you don't include one, "-1" is assumed, which causes the
- component to go to the end of the list, and possibly be buried (in
- terms of z-order) under any other components you add. So, change the
- add to
-
- myframe.add("Center", new Label("Child"));
-
- and all will be well.
-
- 16. (Sect. 19) Why do I get the wrong results when I compare two Strings
- together?
-
- if (s1 == s2)
-
- is giving me funny results.
-
- [*] The comparison using "==" on objects, like Strings, is asking the
- question "do these two objects have the same reference?". That is, do
- they have the same address, and hence are not two object but one? What
- you most probably meant is "do these two Strings have the same
- contents?" which you can express this way:
-
- if ( s1.equals(s2) )
-
- This is a very, very easy mistake to make and impossible to spot until
- you have had it explained to you.
-
- People talk about "interning" a String. That means calling the intern()
- method on a String. This places the String in the runtime constant pool
- if it was not already there. The compiler is required to intern() all
- literal Strings. If you intern() all your Strings as well then all
- duplicates are shared and comparisons can be done by the (much faster)
- address comparison rather than content comparison. It's a performance
- optimization. See also Q3.22.
-
- Note that this comparison error also occurs with other objects, not
- just Strings. The code:
-
- if (getBackground() == Color.black)
-
-
- is a test for object identity, rather than content identity. It will
- work if you originally setBackground(Color.black). To avoid difficult
- debugging in the future, you almost certainly want to say
-
- if (getBackground().equals( Color.black ) )
-
-
- or even (in this visual case) compare the darkness of the RGB values of
- the pixels.
-
- 17. (Sect. 19) Why doesn't final prevent my object from changing?
-
- [*] You have code like this
-
- final StringBuffer s = new StringBuffer("don't change me");
- // ...
- s.append(", but I did");
- System.out.println(s);
-
- And the new value of s is "don't change me, but I did". The reason is
- that the "final" modifier makes the reference variable (here, s) final,
- not the object that s points to. It means that the reference variable
- cannot be changed to point to some other StringBuffer. The state of the
- StringBuffer can still be modified by calling methods on it or directly
- assigning to its public fields.
-
- The right way to think about final is that it prevents you assigning to
- that particular variable. The only way to make the fields of an object
- constant (unchanging) is to make all its data fields private, and not
- provide any set methods for them, only get methods. Even that won't
- stop other objects of the same class adjusting it.
-
- 18. (Sect. 19) Why can't the compiler find my package?
-
- [*] When trying to compile a file in a package you get a compiler error
- like:
-
- DBTest.java:10: Class database.Table not found in type declaration.
-
- The file Table.java and DBTest.java are in the same directory. They
- both have "package database;" at the top of the file. The current
- directory is included in the classpath.
-
- The reason is that when compiling packages, you have to be at the 'top'
- of the directory/package hierarchy. So to compile both Table.java and
- DBTest.java, you have to be in the directory that contains the database
- directory (i.e. where the package hierarchy starts), and just:
-
- javac database/Table.java
- javac database/DBTest.java
-
-
- and it should all compile fine.
-
- 19. (Sect. 19) I have a program with keyboard input and a button. When the
- user hits the space bar, the button gets pressed as it is in focus!
-
- [*] The VM sets the focus on the first traversible object in the UI. If
- you want the button not to be assigned focus by default, you must
- subclass the button and override the isFocusTraversable() method to
- return false.
-
- Another approach is to manually set the focus on some other component
- (say the Frame) when you show the window. To do so you have to jump
- through hoops to outsmart the VM that is trying to set it on the
- button. One approach is to listen for the windowActivated event and set
- a Swing Timer to do a requestFocus() on the frame about 0.1 seconds
- after the activated message. This seems convoluted, but it is the only
- thing found that consistently works cross platform.
-
- Another reader suggests that if the frame normally gets the focus
- first, you can override its gotFocus() event and set the focus to the
- component you want. Don't forget to return true!
-
- 20. (Sect. 19) What's the hidden size limitation of String serialization?
-
- [*] If you wish to Serialize a string, be alert to the restriction
- that:
- The size of the String, when UTF-encoded, must be < 64Kb
- So for robust code you have to examine the String once to ensure that
- it will be less than 64Kb after encoding, and then have the JVM
- effectively repeat that work in the process of encoding, when you write
- it to an ObjectOutputStream.
-
- A possible workaround that is to strip the string down to "byte[]" and
- pass it around in RMI that way. The code with this restriction is in
- DataOutputStream
-
- public final void writeUTF(String str)
- ...
- [perform the size-after-conversion-to-UTF computation]
- ...
- if (utflen > 65535)
- throw new UTFDataFormatException();
- ...
-
- RMI relies on serialization, so RMI has the same String size
- limitation.
-
- 21. (Sect. 19) When I change a field in just one object in my array, that
- field changes in all the objects in my array!
-
- [*] Here the problem is probably that you have initialized the array
- with N references to the same one object.
-
- This is easy to overlook, because arrays in Java only contain
- references to objects, not objects. (Or they can contain primitives).
-
- 22. (Sect. 19) Do DrawRect and FillRect work on rectangles of the same
- size?
-
- [*] No. java.awt.Graphics.drawRect draws a rectangle that's 1 pixel
- wider and 1 pixel taller than a rectangle drawn by fillRect.
-
- 23. (Sect. 19) My executable Jar files don't work!
-
- [*] It is possible to exactly follow the instructions given in the
- documentation and yet still get the following error message when
- attempting to run the .jar file: "Failed to load Main-Class manifest
- attribute from myapp.jar"
-
- There has to be a carriage return after the Main-Class definition in
- the manifest file, otherwise it does not work! Example, in a file
- called manifest.txt:
-
- Main-Class: MyClass // does not work
-
- Main-Class: MyClass
- // does work
-
- Then, when the manifest file is merged into the jar file like this:
-
- jar cmfv manifest.txt myapp.jar *.class
-
- it works fine.
-
- 24. (Sect. 19) Why do I get the error message "Wrong number of arguments in
- constructor"
-
- [*] Almost certainly, you have written your constructor with a return
- type or void or something. I.e. you have written:
-
- public MyClass Myclass() { ...}
-
- instead of:
-
- public Myclass() { ...}
-
- Giving a constructor a return type makes it into a regular method that
- happens to have the same name as the class. The language should ideally
- outlaw this, but it doesn't.
-
- -------------------------------
-
- 20. Further Resources
-
- 1. (Sect. 20) Will Java ever be fast enough for games like Quake?
-
- [*] Some people originally thought not.
-
- Please see the site http://fragisland.fragzone.se/ which has the Frag
- Island game (a quake-style game) written in 100% Java. You play it as
- an applet, by browsing the above site. Watch out -- it's noisy!
-
- 2. (Sect. 20) Are there any commercial/shareware/free Java libraries?
-
- [*] Take a look at the Java Collection Framework, a group of classes
- that are part of Java 1.2. These classes implement general-purpose data
- structures, and they will become widely used.
-
- The documentation for JDK 1.2 explains that the Collection Framework
- defines three kinds of things:
- o Standard interfaces representing data structures of various kinds
- for you to implement. Since these are interfaces, you can use them
- in your code before you have implemented them.
- o Partial implementations of those interfaces, saving you some work.
- o Complete implementations, ready to use for data in your programs.
-
- The standard interfaces are Collection, Set, List and Map, plus the
- more specialised SortedSet and SortedMap. Lists have duplicate elements
- whereas Sets do not. Finer distinctions such as immutability are
- defined in the implementor classes, enforced by throwing runtime
- exceptions. See the JDK 1.2 documentation for a full discussion.
-
- For more about sorting prior to JDK 1.2, look at the class SortDemo in
- the demo directory of the JDK. Alternatively, use one of the several
- classic sorts available from Roedy Green. They are supplied free with
- heavily commented Java source code.
-
- See "QuickSort", "HeapSort" and "RadixSort" in the Java glossary at
- http://mindprod.com/index.html.
-
- Also, try the Java Generic Library. This library (JGL) is freely
- downloadable from http://www.objectspace.com/
-
- Also Visual Engineering has JChart at: http://www.ve.com. No licensing
- fees.
-
- Visual Numerics has its Java Numeric Library available for download at
- http://www.vni.com/products/wpd/jnl/jnl_1_0.html. They offer the JNL as
- a proposed standard library for numerical functions missing from Java.
-
- 3. (Sect. 20) Why doesn't somebody write a shell in Java? Then they could
- use it on all platforms!
-
- [*] Somebody has done just that. Look at http://www.jsh.net/
-
- 4. (Sect. 20) Are there any URLs for other libraries?
-
- [*] Indeed, there are. The Java3D Repository http://java3d.sdsc.edu/
-
- 5. (Sect. 20) Are there any URLs for regular expression handlers in Java?
-
- [*] There is one from ORO Inc. They dissolved as a corporation, but one
- of the founders maintains the software at http://www.oroinc.com/.
- For other sources, see
- http://www.meurrens.org/ip-Links/Java/regex/index.html
-
- And don't forget to check out Lava -- a set of Java classes designed to
- support programmers who develop console-mode applications and/or C
- programmers who are converting to Java. The first release of Lava has
- printf and other text formatting, encryption, parsing and miscellaneous
- I/O. Lava can be downloaded from http://www.newbie.net/sharky/lava/
-
- Also consider the Java version of the Unix find command. It offers
- Regex filename matching, mindepth, maxdepth, symlink follow / no
- follow, file type matching all cross-platform. The package is at
- http://www.rule-of-eight.com/en/components/
-
- 6. (Sect. 20) Are there any installers for Java? Preferably
- platform-neutral ones.
-
- [*] There are several possibilities.
- o InstallAnywhere 2 from ZeroG software. See
- http://www.zerog.com/html/installanywhere_2.html
- They have a free version for shareware authors.
- o InstallShield makes a Java version of their installation package.
- See http://www.installshield.com/java/default.asp
- o IBM offers a comprehensive Java installer through its alphaworks
- site http//www.alphaworks.ibm.com/formula/installtoolkit
- o Denova offers the J'Express installer. There is a free trial
- version available for download at http://www.denova.com
- Freeware authors can receive a completely free license to
- J'Express Standard. Simply fill in the application at
- http://www.denova.com/JExpress/freeware.html.
-
- 7. (Sect. 20) What is "Jazilla"?
-
- [*] Jazilla is Mozilla (Netscape Communicator free source) ported to
- Java. In other words, a free source browser that supports Java and
- Javascript, written in Java!
-
- You can get more information, and volunteer to help with the project at
- http://www.jazilla.org/
-
- 8. (Sect. 20) Where can I get Java for my Palm Pilot PDA?
-
- [*] There is a translator allowing you to compile Java programs for the
- Palm Pilot PDA! This is an astonishing piece of work as the Pilot has
- such a small memory footprint. The translator is in an early stage of
- development, but is available at:
- http://www.cs.washington.edu/homes/mcdirmid/ghost
-
- Try it, or even better, volunteer to help with the project. Details at
- the website above.
-
- There is a Java-PalmPilot Project called "jSyncManager" which allows
- PalmPilot synchronization and jConduit development in pure Java. See
- http://yaztromo.idirect.com/java-pilot.html.
- If you can run Java 1.1 and Sun's Communications API, you can run
- jSyncManager.
-
- 9. (Sect. 20) What is "Dippy Bird" and where can I get it?
-
- [*] Dippy Bird is Java documentation in WinHelp format, which can be
- used directly on Windows desktops, and has a searching utility. The
- developer of the Dippybird project, Bill Bercik, has stopped further
- work on the project due to lack of time and funds. Instead you can use
- http://www.confluent.fr/javadoc/JavadocE.htm which has a more up to
- date Java WinHelp doc.
- You can get still get the Dippy Bird download at
- http://www.dippybird.com/jdk111.exe (JDK 1.1). Note that on NT 4.0 you
- need to change the generated shortcut to point to NT's 32-bit WinHelp.
-
- 10. (Sect. 20) Are there any Java graphing tools?
-
- [*] Take a look at GraphMaker -- a complete full-featured Java
- application for creating and searching graphs. It is available under
- GPL with source, and uses the latest Swing JFC features. See
- http://home.earthlink.net/~nfiedler/graph/
-
- 11. (Sect. 20) Where can I get icons for use with Java?
-
- [*] Public spirited programmer and Java supporter Dean S. Jones has
- created a collection of over 100 icons for use in Java freeware. They
- are available on the Java Lobby site at
- http://webart.javalobby.org/jlicons/.
-
- 12. (Sect. 20) What is "UML"?
-
- [*] UML is the Unified Modeling Language. It is unified in the sense
- that it draws together ideas from a couple of earlier software design
- languages. UML is an emerging standard for diagrams of object-oriented
- classes. It was devised by Grady Booch, Ivar Jacobsen, and James
- Rumbaugh, and it unifies several popular existing notations.
-
- A UML product is available from Rational Software, who also offer a
- tutorial CD for free. See http://www.rational.com/uml/index.jtmpl There
- are some whitepapers too, but there don't seem to be any free online
- tutorials.
-
- See http://www.togetherj.com/ for information on Together/J. That is a
- platform-independent UML product that supports round-trip engineering
- for Java. Whiteboard version is free.
-
- 13. (Sect. 20) Where can I get info on Java college courses?
-
- [*] The JCampus site at http://www.jcampus.org has links and
- connections to Java CS Dept. courses, assignments, academic papers and
- Java-related events. JCampus is a non-profit, online Community for CS
- Dept. professors, students and staff who are teaching, learning and
- using the Java programming language.
-
- 14. (Sect. 20) What is the Java IFAQ?
-
- [*] It is the Java list of Infrequently Answered Questions, a FAQ
- maintained by Peter Norvig, author of the book "Artificial Intelligence
- - A Modern Approach". Take a look at the Java IFAQ at
- http://www.norvig.com/java-iaq.html There's a lot of good information
- in that document.
-
- 15. (Sect. 20) Are there any Java tools for PDF?
-
- [*] PDF (Portable Document Format) is the text publishing format
- defined by Adobe. Acrobat is the technology to display and print PDF
- files. Abode supplies the client (document reading) software for free.
- There is a PDF toolkit written in Java at http://www.etymon.com. Even
- better it is GPL'd. It is more a toolkit for programmers embedding PDF
- in their products, than an end-user technology though. It doesn't have
- a GUI for displaying PDF for example.
-
- 16. (Sect. 20) Are there any Java info search tools?
-
- [*] IBM has a very good search engine for java developers
- http://www.ibm.com/java
-
- 17. (Sect. 20) What other languages compile to bytecode?
-
- [*] Quite a lot of languages compile to Java bytecode, more than 60 at
- the last count. See the webpage
- http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html
-
- 18. (Sect. 20) Has anyone written a Java-to-RPC interface, to talk to
- legacy code?
-
- [*] See www.distinct.com. It implements a subset of RPC, and is a
- commercial, supported product. You can review RFCs 1831 and 1832 for
- information on the full protocol. Java uses the same endianness as
- RPC's external data representation (network byte order), so all the
- Java file reads/writes can be used directly.
-
- Netbula recently released Java RPC, a fully compatible port of ONC RPC
- to Java. The binary package can be downloaded for evaluation from
- http://netbula.com/javarpc/
-
- The specifications are in RFC 1831 (the RPC protocol spec) and RFP 1832
- (the XDR spec).
-
- 19. (Sect. 20) Are there any automated tools for Javadoc?
-
- [*] Yes. See http://www.mindspring.com/~chroma/docwiz/docwizApplet.html
- for a Java development tool called DocWiz. It is the easiest way to add
- JavaDoc comments to your Java code.
-
- 20. (Sect. 20) Is there any information on XML and Java?
-
- [*] Yes. See http://developerlife.com
- It shows you how to use:
- o the Sun parser (Sun ProjectX EA2)
- o the DOM (org.w3c.dom.*) interfaces
- o JFC/Swing with XML
- o Servlets with XML
- and more.
-
- 21. (Sect. 20) How can I find the format of a .class file/a JPG/a PNG
- file/any file?
-
- [*] There is a great website that maintains descriptions and links to
- descriptions of hundreds of file formats. The site is at:
- http://www.wotsit.org/
- It shows you how the files are structured, and makes it a lot simpler
- for you to write code that creates/decodes such a file.
-
- 22. (Sect. 20) Why not start up one copy of the JVM and share it among many
- Java programs?
-
- [*] If the JVM takes about 15MB (say) in overhead, and a program takes
- 3MB, then starting up a fresh JVM for each program is slow and
- wasteful. If a single copy of the JVM and libraries could instead be
- shared among multiple Java applications there would be less overhead
- and everything would run faster.
-
- That observation was the guiding force behind the echidna project to
- support a JVM that could run multiple applications. See the site
- http://www.javagroup.org/echidna/ for more details.
-
- 23. (Sect. 20) How can I edit sound files?
-
- [*] The JaWavedit java code lets you edit .wav and .au files. It can be
- found at http://www.bome.com/JaWavedit/. It's free to use.
-
- If you are inspired to write freeware like this yourself, many file
- formats are explained and described at http://www.wotsit.org
-
- -------------------------------
-
- 21. Acknowledgements
-
- A jolly little song that explains how to solve commonly-encountered problems
- in Java.
-
- The FAQ Melody
- by Antranig Basman.
-
- On the First Day of Christmas, my true-love said to me:
- Read the F-A-Q.
-
- On the Second Day of Christmas, my true-love said to me:
- My Image isn't drawing;
- Read the F-A-Q.
-
- On the Third Day of Christmas, my true-love said to me:
- My Pixels are not grabbing,
- My Image isn't drawing,
- Read the F-A-Q.
-
- On the Fourth Day of Christmas, my true-love said to me:
- My Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Fifth Day of Christmas, my true-love said to me:
- Null - Pointer - Exception!
- My Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Sixth Day of Christmas, my true-love said to me:
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Seventh Day of Christmas, my true-love said to me:
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Eighth Day of Christmas, my true-love said to me:
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Ninth Day of Christmas, my true-love said to me:
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Tenth Day of Christmas, my true-love said to me:
- Time-zone's in Pacific,
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Eleventh Day of Christmas, my true-love said to me:
- Docs are not specific,
- Time-zone's in Pacific,
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Twelfth Day of Christmas, my true-love said to me:
- File I/O's horrific,
- Docs are not specific,
- Time-zone's in Pacific,
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing;
-
- You Should Read The-e F-A-Q!
-
- FAQ copyright 1997, 1998, 1999 by Peter van der Linden. Contributions and
- help from:
-
- Matt Kennel, Patric Jonsson, Brad Van Tighem, Tony Hursh, Glenn L
- Vanderburg, Peter Jones, John McDowall, Jim Driscoll, Uday, Dave Harris,
- Bill Wilkinson, Tom Valesky, Dan Drake, Giles Thomas, Mitch Baltuch, Guy
- Ruth Hammond, Gordon Keith, Jason Brome, Shani Kerr, Steve Chapel, Timothy
- Wolters, Robert Lynch, Jake Cormier, Sean C Sullivan, Joseph A. Millar, Jim
- Frost, Jim Balter, Jeff Bauer, John Kochmar, Carl Burke, William Stubbs,
- Mark Smith, Volker Turau, Real Gagnon, Russell Gold, Max Hailperin, Bill
- Tschumy, Marco Nijdam, Marc Pawlowsky, Laurence Vanhelsuwe, Ian Macgregor,
- Mike Faulkner, Rich Koch, Will Clark, Govind Seshadri, Rich Simkin, Ian
- Stiles, Kieren, Darren Christie, Tom Lane, Michael Jungmann, Rob Mayoff,
- George Ruban, Tom McCann, David Hopwood, Thomas Phan, Kai Stuke, Rolf
- Howarth, Derek Snider, David Boydston, Andy Godwin, John F. Dumas, Doug
- Bell, David J. Biesack, Tiger Quimpo, Martin Hugh Rogers, Brian Krahmer, Ian
- Burrell, Nikki Locke, Bin Li, Jackson Thompson, Steve Odendahl, Greg Smith,
- Jeffrey C. Ollie, Mark Halvin, Jeremy Cook, Lak Ming Lam, Peter S. Morris,
- Mark Halvin, Juergen Keil, Alex Stewart, Mike Abney, Rodney Stephenson, Mark
- Gritter, Satish Talim, Tamminen Eero, Alexander Gridnev, Eric Hodges, Jamey
- Graham, Will Lockhart, Scott Plante, Tom Sanfilippo, Jan Newmarch, Sean
- Breslin, Stuart D. Gathman, rhino@wwdc.com, C Matthew Curtin, Tor Iver
- Wilhelmsen, A.N.Pryke, Phil Race, David Holmes, David Rodal, Dominique
- Plante, Trent Jarvi, Ingrid Biery, Gopal Unni Krishnan, Grant Lewis, Tov Are
- Jacobsen, Gary McGath, Marty Hall, Will Forster, Colin Mummery, Darin
- McBride, Mayank Shah, Jens Alfke, Glen Stampoultzis, Philip Brown, Peter
- Steiner, Kurt Spaugh, Rasmus Ekman, Jonathan Revusky, Ken Kalish, Dave
- Sanders, Bill Hyden, James Cloughley, Philip "diodes" Gustafson, Paul
- Kinnucan, Juan ValdΘz, Antranig Basman, Felix Pahl, David N. Still, Simon
- Arthur, Mark Hammond, Dan Kegel, Thomas Weidenfeller, Pavel Shvartsman,
- Christen Monberg, George Reese, Ian Macgregor, John Sublett, David
- Zimmerman, Tony Dahlman, Druid, Chris Kelly, Patricia Shanahan, Paul Hill,
- Lyne Lamoureux, Don Kennedy, Alec Muffett, Andrew Mickish, Pavel Shvartsman,
- Neil of Parkway Consultants, Chris Thiessen, David Michaels, Bob Sutherland,
- Michael Allen Latta, Joshy, Eric Albert, Wes Isberg, Lisa Retief, Michael
- Park, Dave Postill, Thomas Weidenfeller, Konstantin Laufer, Hσkan
- Gustavsson, James Stauffer, Reuben Firmin, David Lim, Eamonn Maher, Craig
- West, Pavel Shvartsman, Jay Dunning, Kevin Swan, Grant Gainey, Dan Schmitt,
- Benjamin Goldberger, Jake Hamby, Yaakov Itzhaki, Robert Lynch, Laura Werner,
- Tomm Hoeft, King Dale, Joe Halpin, Daniel M. Pomerantz, Kevin Kelley,
- misnomer@earthling.net, Peter Seibel, Werner Zsolt, Hank Stuck, David M.
- Karr, John J. Bartholdi, III, Garry Turkington, John Bokma, Frank McCreedy,
- Nat Pryce, Jeff Luszcz, Brent Callaghan, Neil Allen, Joe Preston, Tim Bell,
- Rajesh, Jeffrey Galyan, Nick Matsakis, Larry Hamel, David Lamb, Mr Tines,
- Bill McHardy, Phillip Lord, Jon K. Hellan
-
- ------------------------------------------------------------------------
-
- I am maintaining a FAQ list to address specifically programming issues
- (not a general tutorial on Java). Please mail suggested FAQ entries
- including answer to faqidea on the site afu.com.
- Question with answer gets you a credit in the FAQ.
- Peter van der Linden, Sun Certified Java Programmer.
- ------------------------------------------------------------------------
-
- Cross references
-
- Most cross reference links inside this document are still to be filled in
- after the great FAQ re-org. If you'd like to contribute a few, send me the
- new text for the NAME= and the HREF=, and I'll fold them in as time permits.
- Look at the FAQ source for the style to follow.
-
- Copyright
-
- Copyright (c), 1997,1998,1999 Peter van der Linden. Permission to copy all
- or part of this work is granted for individual use, and for copies within a
- scholastic or academic setting. Copies may not be made or distributed for
- resale. The no warranty, and copyright notice must be retained verbatim and
- be displayed conspicuously. You need written authorization before you can
- include this FAQ in a book and/or a CDROM archive, and/or make a
- translation, and/or publish/mirror on a website (scholastic and academic use
- excepted). If anyone needs other permissions that aren't covered by the
- above, please contact the author.
-
- No Warranty
-
- This work is provided on an "as is" basis. The copyright holder makes no
- warranty whatsoever, either express or implied, regarding the work,
- including warranties with respect to merchantability or fitness for any
- purpose. Furthermore the author has been known to wear socks that don't
- match his pants, and to commit other egregious lapses of good fashion sense.
-
- ------------------------------------------------------------------------
-