This section provides the source code and detailed discussion of the NetWorKs and NWKFrame classes. The NetWorKs class is the public class that provides a main() function so that the applet can be run as an application. The main() function accepts width and height parameters and creates an appropriately sized NWKFrame object which provides an environment in which an applet can function. The NWKFrame then creates and ``runs'' the applet. In effect, the NetWorKs and NWKFrame classes act together as a simple browser capable of displaying a NetWorKsPanel applet.
The NWKFrame class is a non-public class that resides in the same file as the NetWorKs class. The NWKFrame class extends the Java awt Frame class, which is basically a window. So a NWKFrame provides the event driven multi-threaded environment necessary to run an applet. This means that the NWKFrame must handle events generated by the Frame base class.
The NWKFrame class also includes a file menu which allows users to store and retrieve graphs. The graphic functionality is provided by Java library objects, but the NWKFrame has to handle the actual file I/O, and respond to file menu selection events.
To fetch filenames, a NWKFrame uses a FileDialog object.
This is a very useful
Java object which provides the look and feel of the native platform.
It is supposed to accept a FileNameFilter object to use for
restricting file selections to particular files, but would not
work correctly on the Sun platform. Also, the Sun
platform FileDialog box does not display file names well, and the FileDialog
class does not provide any methods related to display. But the most annoying
problem with the FileDialog objects, was that the methods that set the initial
file and directory names do not work as given in the documentation
. The
reasons for not writing a FileDialog class are that
later implementations will certainly correct these problems, and the FileDialog
objects do fetch a filename in spite of being annoying.
To separate file I/O from the applet, writes are accomplished by writing a text
representation of the Graph object to the requested file, while reads consist
of converting the requested file to text and passing the resulting String to
the GraphPanel. The reason for this is because the Graph
and GraphPanel objects reside in an applet, and of course applets are very
restricted about writing to files. If a Graph cannot write to a file, it makes
sense to have Graphs produce text representations and be able to
reconstruct themselves from that text.
import GraphStuff.*;
import MyUtil.*;
import MyAwt.*;
import java.awt.*;
import java.io.*;
import MyIO.*;
public class NetWorKs extends NetWorKsPanel {
public static void main(String args[]) {
String usage = "Usage: java NetWorKs <width> <height> \n"+
" or java NetWorKs \n" +
"(defaults are width=800, height=600) \n";
if (args.length!=0 && args.length!=2) {
System.out.println("Error: invalid number of parameters \n" + usage);
System.exit(0);
}
int d[] = new int[2];
if (args.length==0) {
d[0]=800;
d[1]=600;
} else {
for(int i=0;i<2;i++) {
try { d[i] = Integer.parseInt(args[i]); }
catch(NumberFormatException ex) {
System.out.println("Error: " + args[i] + " is not an integer\n"
+ usage);
}
}
}
NWKFrame app = new NWKFrame("NetWorKs");
app.resize(d[0],d[1]);
app.setResizable(false);
app.show();
}
public NetWorKs() { super(); }
}
class NWKFrame extends Frame {
private final MenuBar menuBar = new MenuBar();
private Menu fileMenu = new Menu("File",false);
private MenuItem newMI = new MenuItem("New"),
openMI = new MenuItem("Open"),
saveMI = new MenuItem("Save"),
quitMI = new MenuItem("Quit");
private FileDialog fdOpen = new FileDialog(this,"GraphStuff",
FileDialog.LOAD),
fdSave = new FileDialog(this,"GraphStuff",
FileDialog.SAVE);
private EndsWithFilter nwkFilter = new EndsWithFilter(".nwk");
private String[] fileName = new String[2];
private String[] dirName = {fdOpen.getDirectory(),fdOpen.getDirectory()};
private NetWorKs applet;
public NWKFrame(String title) {
super(title);
fileMenu.add(newMI);
fileMenu.add(openMI);
fileMenu.add(saveMI);
fileMenu.addSeparator();;
fileMenu.add(quitMI);
menuBar.add(fileMenu);
applet = new NetWorKs();
applet.init();
applet.start();
add("Center",applet);
setMenuBar(menuBar);
fdOpen.setFilenameFilter(nwkFilter);
fdSave.setFilenameFilter(nwkFilter);
}
private void fdSetup() {
if (dirName[applet.gp().currentGraph()]!=null)
fdOpen.setDirectory(dirName[applet.gp().currentGraph()]);
if (fileName[applet.gp().currentGraph()]!=null)
fdOpen.setFile(fileName[applet.gp().currentGraph()]);
if (dirName[applet.gp().currentGraph()]!=null)
fdSave.setDirectory(dirName[applet.gp().currentGraph()]);
if (fileName[applet.gp().currentGraph()]!=null)
fdSave.setFile(fileName[applet.gp().currentGraph()]);
}
public boolean handleEvent(Event evt) {
if (evt.id == Event.WINDOW_DESTROY)
System.exit(0);
else if (evt.target instanceof MenuItem) {
if (evt.target==newMI) {
} else if (evt.target==openMI) {
fdSetup();
fdOpen.show();
String tfileName = fdOpen.getFile(),
tdirName=fdOpen.getDirectory();
if (tfileName!=null) {
try {
xFileInputStream f = new xFileInputStream(
new File(tdirName,tfileName));
String str = f.readString();
f.close();
if (applet.gp().load(str) ) {
dirName[applet.gp().currentGraph()]=tdirName;
fileName[applet.gp().currentGraph()]=tfileName;
} else {
System.out.println("NetWorKs: "
+tfileName+" not loaded\n");
}
}
catch(FileNotFoundException e) {}
catch(IOException e) {
System.out.println("NetWorKs: I/O error, "
+tfileName+" not loaded\n");
}
}
return true;
} else if (evt.target==saveMI) {
if (applet.gp().graph.numVertices()==0)
return true;
fdSetup();
fdSave.show();
String tfileName=fdSave.getFile(),
tdirName=fdSave.getDirectory();
if (tfileName!=null) {
try {
String str = applet.gp().graphString();
FileOutputStream f = new FileOutputStream(
new File(tdirName,tfileName));
DataOutputStream d = new DataOutputStream(f);
d.writeBytes(str);
d.flush();
f.close();
dirName[applet.gp().currentGraph()]=tdirName;
fileName[applet.gp().currentGraph()]=tfileName;
} catch(IOException e) {
System.out.println("NetWorKs: I/O error, "
+tfileName+" not saved\n");
}
}
} else if (evt.target==quitMI) {
System.exit(0);
}
return true;
}
return false;
}
}
Note that the NWKFrame class uses an xFileInputStream object to convert the contents of a file to a String.