Apr 97 Top 10
Volume Number: 13
Issue Number: 4
Column Tag: Symantec Top Ten
Symantec Top 10
By Matthew Hopkins
In this month's column, we are focusing on customer issues
pertaining to our C++ and Java development environments,
including the newly released Visual Café. Let's warm up with
a question regarding Visual Page, a dynamic web-authoring
utility
Q: In Visual Page, how do you tell what size a document is before you save it?
A: By selecting Download Statistics... from the Edit menu, you can see a dialog box
which not only tells you the total document size, but also tells you how long (on the
average) it will take to download your page, depending upon the speed of your modem.
Q: I am using Visual Café, and I am having a problem getting the GridLayout to work
properly. For instance, when I set the number of columns to 3 in the Property
Manager, the applet doesn't respond at all visually. What's going on here?
A: Visual Café behaves in this manner because of how GridLayout is implemented in
Java. When the rows and columns are both defined to anything other than 0, the Layout
Manager will ignore the number of columns you have specified and calculate them
based upon the number of rows and the number of elements. If you are interested in
having the Layout Manager organize your elements according to a certain number of
columns, set the number of rows to 0 (meaning "any"), and the Layout Manager will
make the number of rows dependent upon the number of columns.
Q: I am getting an error of type -43 when running my Java application in Symantec
Café. How do I correct this?
A: In an application, the main function needs to be static, and the main class needs to
be set in the Project Options window.
Q: I am running the following program in Symantec Café and it does nothing but
hang. Could you tell me why?
class PrintThread implements Runnable {
String str;
public PrintThread (String str) {
this.str = str;
}
public void run() {
for (;;)
System.out.print(str);
}
}
class ConcurrencyTest {
public static void main(String argv[]) {
new Thread(new PrintThread("A")).start();
new Thread(new PrintThread("B")).start();
}
}
A: This does not actually cause a freeze. It just appears that way because the
System.out.print never receives a "" character, so it never shows you what's going on;
it adds characters to the print stream indefinitely. To achieve the results you intended
(mainly, seeing A and B printed forever), either call PrintThread with "A" and "B", or
change the line reading System.out.print(str) to System.out.println(str).
Q: Which folder do you put packages into in Symantec Café for the Mac?
A: You have two options:
1) Place any additional class packages into the {java libraries} folder.
2) Place them in whatever folder you like as long as you open the Preferences:Paths
window and add the search path to the upper window so that Café will know to search
that folder.
Q: I am developing an application in Café that includes HTML text and embedded
Applets. Some of the applets need to read local files whose names are supplied by the
user, but the applet security rules prevent applets from reading local files. Is there a
standard way of reading user-OK'ed local files that I am missing?
A: The names of the files have to be "fully qualified" (i.e. volume/folder/file), and
there can be no non-standard characters anywhere in the path (like after folder
names.) You can use something like this
FileDialog file_dialog_open;
file_dialog_open = new FileDialog(this, "Open A File",
FileDialog.LOAD);
file_dialog_open.pack();
file_dialog_open.show();
if (file_dialog_open.getFile() != null) {
currentFolder = file_dialog_open.getDirectory();
selectedFile = new String(file_dialog_open.getFile());
fullPath = currentFolder + "/" + selectedFile;
}
}
This lets the user select a file and then pass the fully qualified path name for the
file to the method that actually accesses the data.
Q: Is there a simple way to use ImageMaps for applets in Java? I need to write an
applet that loads a graphic file at the proper coordinates when the mouse is moved over
a certain location.
A: The key to this problem is the Component action method mouseEnter(). This
works for all components, including buttons, windows, etc. In order to implement
ImageMaps, I find the canvas component to work the best, being invisible. Here is a
small snippet of code written in Visual Café that illustrates this
import java.awt.*;
import java.applet.*;
public class Applet1 extends Applet {
public void init() {
super.init();
setLayout(null);
addNotify();
resize(426,266);
theMap = new ImageMap("myMap", 50, 50, getGraphics());
theMap.reshape(60,31,186,150);
add(theMap);
}
public boolean handleEvent(Event event) {
return super.handleEvent(event);
}
ImageMap theMap;
}
class ImageMap extends Canvas {
boolean on;
String label;
Graphics g;
ImageMap(String label, int sizex, int sizey, Graphics g) {
this.label=label;
this.g=g;
resize(sizex, sizey);
}
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) {
if(on) {
this.g.drawString("Hello, World!", 25, 25);
}
}
public boolean mouseEnter(Event evt, int x, int y) {
on=true;
repaint();
return true;
}
}
Here, the text Hello, World! has been substituted for the image that should be
displayed. In case you wish to remove the image when the mouse is removed from the
area, use the method mouseExit() in the same way.
Q: I am using a HashTable to keep track of a number of Button objects in Symantec
Café, but every time I click on the button and look up the corresponding HashTable
entry, it returns null.
import java.applet.*;
import java.awt.*;
import java.util.*;
public class HashTblTest extends Applet {
Hashtable ht = new Hashtable();
Button[] b = new Button[3];
public void init() {
for (int i = 0;i < 3;i++) {
b[i] = new Button("Button " + i);
add(b[i]);
ht.put(b[i], new Integer(i));
}
}
public boolean action(Event e, Object o){
System.out.println(ht.get(o));
return false;
}
}
What am I doing wrong?
A: The problem here is that the Button action method counter-intuitively provides
as its Object parameter a STRING which is the button's name, not the button object
itself. You have entered the buttons themselves into the HashTable, but the action
method is looking up a string, not a button in your table. The best way to work around
this is to change your action code to read: System.out.println(ht.get(e.target)); This
will achieve your desired results.
Q: I have written a program in the Think Project Manager 7.0.5 that runs in the
debugger, but when I try to run it in the Finder or without the debugger, the main
window does not even come up. What do I need to do to get it to work?
A: This usually indicates a failure to initialize the Macintosh toolbox. Your code
seems to work in the debugger because the debugger initializes the toolbox for you.
Q: I have written a program that uses two-dimensional and three-dimensional
arrays. It seems to look fine but I keep getting link errors. What can I do to fix this
problem?
A: It sounds like you are putting some huge arrays on the stack! Space is allocated
for these arrays prior to run-time, and if your arrays are large enough, you could be
causing a stack overflow that is posing some problems for the linker. There is an
excellent example on how to put these arrays on the heap (allocating them at run time)
in the Think Reference under Arrays Bigger than 32k.
Special thanks to Mark Baldwin, Ted Flug, Richard Hill, Steve Howard, Scott
Morrison, Kevin Kenan, and Kevin Quah.