Apr 97 Top 10
Volume Number: 13 (1997)
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);
public void loadFile() {
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.