/////////////////////////////////////////////////////////////////////
//
// File: depend.java
//
// Purpose: (proj2) Depend (Dependencies) class.
//
// Authors: txe Travis Emmitt
//
// Modifications:
// 18-SEP-1998 txe Initial creation
// 19-SEP-1998 txe Incorporated changes in specs, added comments.
// 21-SEP-1998 txe Added comments.
//
/////////////////////////////////////////////////////////////////////
import java.applet.*;
import java.awt.*;
public class depend extends Applet {
// Dependency-related data //
private static final int MIN_SIZE = 1;
private static final int MAX_SIZE = 2 << (4 - 1); // 16
private int size;
private int init_mode;
private int time;
private boolean parameters[];
private boolean dependencies[][];
private boolean new_parameters[];
// Widgets //
private TextField w_status;
private Choice w_size;
private Choice w_init_mode;
private Button w_go;
private TextField w_time;
private TextField w_parameters;
private TextArea w_dependencies;
private TextArea w_help;
//////////////////////////////////////////////////////////////////////
// This sets up the applet interface; it places all the widgets on the
// screen and sets them to their initial values. I use Panels in order
// to better control the layout of the widgets.
//////////////////////////////////////////////////////////////////////
public void init () {
// The Status field is used to print status and error messages.
Panel p = new Panel ();
p.add (new Label ("Status:"));
p.add (w_status = new TextField ("Welcome, read Instructions at bottom.", 60));
w_status.setEditable (false);
add (p);
// The Size field lets the user specify the number of parameters.
p = new Panel ();
p.add (new Label ("Size:"));
w_size = new Choice (); // good for small numbers
for (int i = MIN_SIZE; i <= MAX_SIZE; i++) {
w_size.addItem ("" + i);
}
w_size.select (4);
p.add (w_size);
add (p);
// The Initialization Mode fields determines how we setup the Dependencies
p = new Panel ();
p.add (new Label ("Initialization Mode:"));
w_init_mode = new Choice ();
w_init_mode.addItem ("False Everywhere");
w_init_mode.addItem ("True Everywhere");
w_init_mode.addItem ("True On Diagonal");
w_init_mode.addItem ("True On or Above Diagonal");
w_init_mode.addItem ("True in Block Diagonal");
w_init_mode.addItem ("Random");
w_init_mode.select (5); // default to random
p.add (w_init_mode);
add (p);
// The Go button and Time field deal with progression through the execution
p = new Panel ();
p.add (w_go = new Button ("Start"));
p.add (new Label ("Time:"));
p.add (w_time = new TextField ("" + time, 5));
w_time.setEditable (false);
add (p);
// The Parameters field lets the user view and edit parameters
p = new Panel ();
p.add (new Label (" Parameters:"));
p.add (w_parameters = new TextField ("", 40));
add (p);
// The Dependencies field lets the user view and edit parameters
p = new Panel ();
p.add (new Label ("Dependencies:"));
p.add (w_dependencies = new TextArea ("", 16, 40));
add (p);
// The Instructions field displays instructions on how to run the program
p = new Panel ();
p.add (new Label ("Instructions:"));
p.add (w_help = new TextArea (
"Manipulate Size or Initialize Mode to start a new execution.\n"
+ "Edit Parameters and Dependencies (0=false, 1=true, be careful\n"
+ "to maintain the same format) and then hit the Start button.", 3, 50));
w_help.setEditable (false);
add (p);
InitializeArrays ();
}
///////////////////////////////////////////////////////////////////////////
// This is called each time repaint() is called. It updates the Time field.
///////////////////////////////////////////////////////////////////////////
public void paint (Graphics g) {
w_time.setText ("" + time);
}
///////////////////////////////////////////////////////////////////////////
// This is a shortcut routine, sets the status field to the specified value.
///////////////////////////////////////////////////////////////////////////
private void Println (String string) {
w_status.setText (string);
}
///////////////////////////////////////////////////////////////////////////
// Whenever the user manipulates a widget, we handle it in this routine.
///////////////////////////////////////////////////////////////////////////
public boolean action (Event e, Object arg) {
// Whenever the size or initialization mode is manipulated, we
// immediately resize the Parameters[] and Dependencies[][]
// arrays, update the corresponding text fields, and enter the
// Ready state.
if (e.target.equals (w_size) || e.target.equals (w_init_mode)) {
InitializeArrays ();
}
// The user steps through the main while loop by repeatedly
// hitting the Go button. This button is labeled "Start"
// when in the ready state (time = 0), and is labeled "Next"
// during execution (time > 0). When the execution stops,
// the Go button reads "Done" and is greyed out.
else if (e.target.equals (w_go)) {
RunUntilAllFalse ();
}
return true;
}
///////////////////////////////////////////////////////////////////////
// This initializes the Parameters[] and Dependencies[][] arrays
// according to the currently specified Size and Initialization Mode.
// It automatically updates the appropriate text fields on the screen,
// and puts the program in the Ready state (time = 0). We start with
// Parameters[] set to all true, but the user can edit this before
// hitting "Start".
///////////////////////////////////////////////////////////////////////
private void InitializeArrays () {
size = w_size.getSelectedIndex () + 1;
init_mode = w_init_mode.getSelectedIndex ();
parameters = new boolean[size]; // let java garbage collect
dependencies = new boolean[size][size];
new_parameters = new boolean[size];
for (int index = 0; index < size; index++) {
parameters[index] = true; // start true; user can edit this
for (int dep = 0; dep < size; dep++) {
dependencies[index][dep] = (
(init_mode == 1) // true everywhere
|| (init_mode == 2 && dep == index) // on diagonal
|| (init_mode == 3 && dep >= index) // on or above diagonal
|| (init_mode == 4 && (dep + index) % 2 == 0) // in block diagonal pattern
|| (init_mode == 5 && Math.random () < .5) // random - 50% chance
);
}
}
UpdateArrayFields (); // update appropriate text fields
IndicateReady (); // get ready to run (time = 0)
}
/////////////////////////////////////////////////////////////////////
// This indicates that the program is ready to execute, but hasn't
// yet started to execute. It does this by enabling the Go button
// (which reads "Start") and by allowing the user to edit the text
// areas representing Parameters[] and Dependencies[][]. It also
// resets the clock.
/////////////////////////////////////////////////////////////////////
private void IndicateReady () {
w_go.setLabel ("Start");
w_go.enable ();
w_go.requestFocus ();
w_parameters.setEditable (true);
w_dependencies.setEditable (true);
time = 0;
repaint ();
}
/////////////////////////////////////////////////////////////////////
// This updates the text fields on the screen that are responsible
// for displaying the Parameters[] and Dependencies[][] arrays.
// A "1" means true, a "0" means false.
/////////////////////////////////////////////////////////////////////
private void UpdateArrayFields () {
String string1 = "", string2 = "";
for (int index = 0; index < size; index++) {
string1 += (parameters[index] ? "1 " : "0 ");
for (int dep = 0; dep < size; dep++) {
string2 += (dependencies[index][dep] ? "1 " : "0 ");
}
string2 += "\n";
}
w_parameters.setText (string1);
w_dependencies.setText (string2);
}
/////////////////////////////////////////////////////////////////////
// This examines the contents of the text fields on the screen and
// updates the contents of Parameters[] and Dependencies[][]
// accordingly. The user needs to be careful to maintain the same
// format; exact whitespace needs to be maintained. I put a note to
// that effect on the applet itself.
/////////////////////////////////////////////////////////////////////
private void ReadArrayFields () {
char str1[] = w_parameters.getText() . toCharArray ();
char str2[] = w_dependencies.getText() . toCharArray ();
for (int index = 0; index < size; index++) {
parameters[index] = (str1[index*2] == '1');
for (int dep = 0; dep < size; dep++) {
dependencies[index][dep] = (str2[dep*2 + index*(size*2+1)] == '1');
}
}
}
//////////////////////////////////////////////////////////////////////
// This is called each time the user hits the (enabled) Go button
// (either labeled "Start" of "Next"). It handles one step through
// the main while loop.
//////////////////////////////////////////////////////////////////////
private void RunUntilAllFalse () {
// If we are at the start of execution, read in the values
// of the text fields for Parameters[] and Dependencies[][]
// and then disable the editability of the text fields during
// execution.
if (time == 0) {
ReadArrayFields ();
w_go.setLabel ("Next");
w_parameters.setEditable (false);
w_dependencies.setEditable (false);
}
// While any element of Parameters is true do the following: //
if (AnyParametersTrue ()) {
int index;
// Initialize all elements of NewParameters to false //
for (index = 0; index < size; index++) {
new_parameters[index] = false;
}
// For all integer index in the range 1..Size //
// If Parameter[index] is true then //
// For all integers dep such that Dependencies[index,dep] is true //
// with a 50% chance, NewParameter[dep] BECOMES true //
for (index = 0; index < size; index++) { // indexes minus 1
if (parameters[index]) {
for (int dep = 0; dep < size; dep++) {
if (dependencies[index][dep] && Math.random() < .50) {
new_parameters[dep] = true;
}
}
}
}
// Overwrite the value of Parameters with the value of NewParameters //
for (index = 0; index < size; index++) {
parameters[index] = new_parameters[index];
}
// Increment Time [End of While loop] //
time++;
UpdateArrayFields ();
repaint ();
}
// Output Time. //
// We re-test whether or not any parameters are true, because we want to
// be able to "freeze" by disabling the Go button and printing the end
// time.
if (!AnyParametersTrue ()) {
Println ("End time = " + time);
w_go.setLabel ("Done");
w_go.disable ();
w_size.requestFocus ();
}
}
///////////////////////////////////////////////////////////////////////////////
// This returns whether or not any parameters are still true.
///////////////////////////////////////////////////////////////////////////////
private boolean AnyParametersTrue () {
for (int index = 0; index < size; index++) {
if (parameters[index]) {
return true;
}
}
return false;
}
}
/////////////////////////////////////////////////////////////////////////////////