System, method and article of manufacture for creating hierarchical folder components for use in a java application or applet5913065Abstract Method, system and article of manufacture for creating hierarchical folder components for use with in holding other object oriented based components, including other folder components, and component assemblies. Each hierarchical folder is provided with an editor that pops up upon its instantiation and permits a user to edit the folder component name as well as the number and type of ports assigned to the folder component. Claims What is claimed is: Description COPYRIGHT NOTIFICATION
__________________________________________________________________________
import java.awt.*;
import java.util.*;
public class VJVScrollbar extends VJNode {
/ / Attributes of this component
public AWTVScrollbar bar;
static int instanceCount = 0;
vscrollbarEditor edit;
static Image normalImage;
static Image selectedImage;
final static String out = "out.sub.-- vsb.gif";
final static String in = "in.sub.-- vsb.gif";
final static String port0.sub.-- info = "for setting/getting minimum
value";
final static String port0.sub.-- name = "Pin 0";
final static String port1.sub.-- info = "for setting/getting maximum
value";
final static String port1.sub.-- name = "Pin 1";
final static String port2.sub.-- info = "for setting/getting the current
value";
final static String port2.sub.-- name = "Pin 2";
final static String url.sub.-- name = "hscrollbar.html";
final static String info.sub.-- name = "A simple AWT horizontal
scrollbar";
VJ vj;
int send.sub.-- index0 = -1;
int request.sub.-- index0 = 0;
int send.sub.-- index1 = -1;
int request.sub.-- index1 = 0;
int send.sub.-- index2 = -1;
int request.sub.-- index2 = 0;
/ / Constructor
public VJVScrollbar(VJv){
super(v);
vj = (v);
VJNode dup( ) {
VJVScrollbar vj.sub.-- comp = new VJVScrollbar(vj);
try {
int i = x+40;
int j = y+40;
AWTVScrollbart = new AWTVScrollbar(vj.sub.-- comp);
vj.sub.-- comp.bar = t;
t.setValues(bar.getValue( ), bar.getVisible( ),bar.getMinimum(
),bar.getMaxi
mum( ));
vj.sub.-- comp.setNormalIcon(out);
vj.sub.-- comp.setSelectedIcon(in);
vj.sub.-- comp.setName("VScrollbar");
vj.sub.-- comp.setComponent((Component)t);
vj.sub.-- comp.setComponentURL(url.sub.-- name);
vj.sub.-- comp.setComponentInfo(info.sub.-- name);
vj.sub.-- comp.VJNodeInit(false,i,j,true);
vj.sub.-- comp.addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOut
put,VJPort.No
rthLeftCenter); / / Pin 0
vj.sub.-- comp.addPort(port1.sub.-- info,port1.sub.-- name,VJPort.InputOut
put,VJPort.No
rthRightCenter); / / Pin 1
vj.sub.-- comp.addPort(port2.sub.-- info,port2.sub.-- name,VJPort.InputOut
put,VJPort.So
uthCenter); / / Pin 1
vj.sub.-- comp.setXPt(0,getXPt(0)+40);
vj.sub.-- comp.setYPt(0,getYPt(0)+40);
vj.sub.-- comp.setXPt(1,getXPt(1)+40);
vj.sub.-- comp.setYPt(1,getYPt(1)+40);
vj.sub.-- comp.setXPt(2,getXPt(2)+40);
vj.sub.-- comp.setYPt(2,getYPt(2)+40);
vj.sub.-- comp.setImages(normalImage,selectedImage); / / Pass references
to the static images down to the node
vj.sub.-- comp.nodeRect = new Rectangle(i-3 ,j-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
vj.sub.-- comp.setSelected(true);
vj.theDocument.add(vj.sub.-- comp.comp);
vj.sub.-- comp.comp.validate( );
vj.sub.-- comp.comp.reshape(comp.bounds( ).x+50,comp.bounds(
).y+50,comp.
bounds( ).width,comp.bounds( ).height+1);
vj.sub.-- comp.comp.show( );
return vj.sub.-- comp;
}catch(Exception e) {
System.out.println(e);
return null;
}
}
public static void getImages(GIFFactoryf){
normalImage = f.GetGIF(out);
selectedImage = f.GetGIF(in);
}
/ / Component Initialization
public void VJVScrollbarInit(intx.sub.-- pt, int y.sub.-- pt) {
try {
String theText = new String("VScrollbar
"+String.valueOf(instanceCount++));
setNormalIcon(out);
setSelectedIcon(in);
bar = new AWTVScrollbar(this);
setName(theText);
setComponent((Component)bar);
setComponentURL(url.sub.-- name);
setComponentInfo(info.sub.-- name);
VJNodeInit(false,x.sub.-- pt,y.sub.-- pt,true);
addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,VJPort.Nort
hLeftCe
nter); / / Pin 0
addPort(port1.sub.-- info,port1.sub.-- name,VJPort.InputOutput,VJPort.Nort
hRight
Center); / / Pin 1
addPort(port2.sub.-- info,port2.sub.-- name,VJPort.InputOutput,VJPort.Sout
hCente
r); // Pin 1
setImages(normalImage,selectedImage); / / Pass references to the
static images down to the node
nodeRect = new Rectangle(x.sub.-- pt-3,y.sub.-- pt-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
} catch(Exception e) {
System.out.println(e);
}
}
public void request(int port,int time) {}
public int componentID( ) {return 3;}
public void disconnecting(int port) {
switch(port){
case 0: request.sub.-- index0= -1; send.sub.-- index 0 = -1;
break;
case 1: request.sub.-- index1 = -1; send.sub.-- index1 = -1;
break;
case 2: request.sub.-- index2 = -1; send.sub.-- index2 = -1;
break;
}
}
public void connecting(int port) {
switch(port){
case 0: request.sub.-- index0=0; send.sub.-- index 0 = 0;
vj.request(0,request.sub.-- index0++,this);
break;
case 1: request.sub.-- index1=0;send.sub.-- indexl = 0;
vj.request(1,request.sub.-- index1++,this);
break;
case 2: request.sub.-- index1=0;send.sub.-- index2 = 0;
vj.request(2,request.sub.-- index2++,this);
break;
}
}
public void load(String s) {
StringTokenizer tokenStream = new StringTokenizer(s);
int max =
Integer.valueOf(tokenStream.nextToken( )).intValue( );
int min =
Integer.valueOf(tokenStream.nextToken( )).intValue( );
int value =
Integer.valueOf(tokenStream.nextToken( )).intValue( );
int visible =
Integer.valueOf(tokenStream.nextToken( )).intValue( );
bar.setValues(value,visible,min,max);
}
public String save( ) {
int max = bar.getMaximum( );
int min = bar.getMinimum( );
int value = bar.getValue( );
int visible = bar.getVisible( );
return max+""+min+" "+value+""+visible;}
public void set(Object o,int port,int time) {
int max,min,cur;
boolean ok = false;
max = bar.getMaximum( );
min = bar.getMinimum( );
cur = bar.getValue( );
switch(port){
case 0:
if(time==0){
if(o instanceof String)
{ min = Integer.valueOf((String)o).intValue( );
ok=true; }
if(o instanceof Integer) { min=((Integer)o).intValue( );
ok=true; }
if(o instanceof Double) { min=((Double) o).intValue( );
ok=true; }
if(o instanceof Long) { min=((Long)o).intValue( ); ok=true;
}
if(o instanceof Float) { min=((Float)o).intValue( );
ok=true; }
}
break;
case 1:
if(time==0){
if(o instanceof String)
{ max = Integer.valueOf((String)o).intValue( );
ok=true;; }
if(o instanceof Integer) { max=(Integer)o).intValue( );
ok=true; }
if(o instanceof Double) { max=((Double)o).intValue( );
ok=true; }
if(o instanceof Long) { max=((Long)o).intValue( );ok=true;
}
if(o instanceof Float) { max=((Float)o).intValue( );ok=true;
}
}
break;
default:
if(o instanceof String)
{ cur = Integer.valueOf((String)o).intValue( );ok=true; }
if(o instanceof Integer) { cur=((Integer)o).intValue( );
ok=true; }
if(o instanceof Double) { cur=((Double)o).intValue( );
ok=true; }
if(o instanceof Long) { cur=((Long)o).intValue( ); ok=true; }
if(o instanceof Float) { cur=((Float)o).intValue( );ok=true; }
if(ok) vj.request(2,request.sub.-- index2++,this);
break;
}
ok = false;
bar.setValues(cur,bar.getVisible( ),min,max);
}
public boolean handleEvent(Event e) {
if(send.sub.-- index2>=0&&e.id<606&&e.id>600)vj.set((Object)(new
Integer(bar.getValue( ))),2,send.sub.-- index2++,this);
return false;
}
public void propertiesEditor( ){
if(edit==null){
edit = new vscrollbarEditor((Frame)(vj.theFrame),this);
edit.pack( );
edit.resize(10*32,5*32);
edit.show( );
}
}
public void init( ){};
public void start( ){};
public void stop( ){};
public void destroy( ){};
public void reset( ){
request.sub.-- index0=0; vj.request(0,request.sub.-- index0++,this);
};
} / / end class
class vscrollbarEditor extends Frame
{
VJVScrollbar vjsb;
TextField max;
TextField min;
TextField visible;
TextField current;
Button ok;
Button cancel;
boolean dirty = false;
public vscrollbarEditor (Frame parent,VJVScrollbar c)
{
super("Vertical Scrollbar Editor");
setBackground(Color.lightGray);
setLayout(new BorderLayout( ));
Panel p = new Panel( );
vjsb = c;
/ / p.setLayout(new BorderLayout( ));
Panel centerPanel = new Panel( );
p.add(new Button("OK"));
p.add(new Button("Cancel"));
add("South",p);
dirty = false;
centerPanel.setLayout(newGridLayout(2,4));
centerPanel.add(newLabel("Current"));
centerPanel.add(newLabel("Visible"));
centerPanel.add(newLabel("Maximum"));
centerPanel.add(newLabel("Minimum"));
current = new TextField(String.valueOf(vjsb.bar.getValue( )));
visible = new TextField(String.valueOf(vjsb.bar.getVisible( )));
max = new TextField(String.valueOf(vjsb.bar.getMaximum( )));
min = new TextField(String.valueOf(vjsb.bar.getMinimum( )));
centerPanel.add(current);
centerPanel.add(visible);
centerPanel.add(max);
centerPanel.add(min);
add("Center",centerPanel);
}
public boolean handleEvent(Event evt)
{
switch(evt.id){
case Event.ACTION.sub.-- EVENT:
FIG. 9 depicts an example of a VJScrollbar object 604b in the logical view 500. The physical view 402 illustrates a simple AWT horizontal scrollbar 902 having diamond shaped I/O pins or ports 904. The diamond shape indicates that the I/O pin is bi-directional or two way in operational nature; that is, they accept inputs or transmit outputs, as they are utilized. The I/O pins can be shaped like a triangle, rather than a diamond. If they are diamond shaped, then those I/O pins will handle an output or an input depending on the direction in which they point. I/O pins 904, which are sometimes referred to as "net pins", can be coded as follows:
______________________________________
import java.awt.*;
public class VJNetPin extends VJNode {
/ / Attributes of this component
static int instanceCount = 0;
static Image normalImage;
static Image selectedImage;
final static String out = "out.sub.-- np.gif";
final static String in = "in.sub.-- np.gif";
final static String port0.sub.-- info = "input or output and object";
final static String port0.sub.-- name = "Pin 0";
final static String url.sub.-- name = "netpin.html";
final static String info.sub.-- name = "Connects components inside a
container to a pin of the container";
VJ vj;
netpinEditor edit=null;
VJContainer theContainer;
boolean connected = false;
boolean requested = false;
int theLocation;
int requestTime = 0;
int theConnection = -1;
/ / Constructor
public VJNetPin(VJ v){
super(v);
vj = v;
VJNode dup() {
return null;
}
public static void getImages(GIFFactoryf){
normalImage = f.GetGIF(out);
selectedImage = f.GetGIF(in);
}
public void setContainer(VJContainerc) {
theContainer = c;
}
public void setConnection(int c) {
theConnection = c;
}
/ / Component Initialization
public void VJNetPinInit(int x.sub.-- pt, int y.sub.-- pt) {
try {
setNormalIcon(out);
setSelectedIcon(in);
setName("VJNetPin");
setComponent(null);
setComponentURL(url.sub.-- name);
setComponentInfo(info.sub.-- name);
VJNodeInit(false,x.sub.-- pt,y.sub.-- pt,false);
addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,VJPort.Sout
hCente
r); //Pin 0
setImages(normalImage,selectedImage); / / Pass references to the
static images down to the node
nodeRect = new Rectangle(x.sub.-- pt-3,y.sub.-- pt-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
} catch(Exception e) {
System.out.println(e);
}
}
public int componentID() { return 6; }
public void disconnecting(int port) {
connected = false;
}
public void connecting(int port) {
connected = true;
if(requested) {
vj.request(0,requestTime,this);
requested = false;
}
}
public void load(String s) {
}
public String save() {
return ""; }
public void reset() {}
public void request(int port,int time) {
/ / what if theConnection <0?
theContainer.requestOUT(theConnection,time);
}
public void requestIN(int time) {
if(connected)vj.request(0,time,this);
else { requestTime = time; requested = true; }
}
public void set(Object o,int port,int time) {
if(theConnection>=0)
theContainer.setOUT(o,theConnection,time);
/ /vj.request(0,request.sub.-- index0++,this);
}
public void setIN(Object o,int time) {
vj.set(o,0,time,this);
}
public void propertiesEditor() {
if(edit==null){
edit = new netpinEditor((Frame)(vj.theFrame),this);
edit.pack();
edit.show();
}
}
public void init(){};
public void start(){};
public void stop(){};
public void destroy(){};
}
class netpinEditor extends Frame
{
VJNetPin vjc;
TextField tf;
Button b;
Button cancel;
public netpinEditor(Frame parent,VJNetPin c)
{
super("Pin Editor");
setLayout(newBorderLayout());
add("North",new Label("Select a pin"));
vjc = c;
tf = new TextField(new Integer(vjc.theLocation).toString());
add("Center",tf);
b = new Button("OK");
cancel = new Button("Cancel");
Panel sp = new Panel();
sp.add(b);
sp.add(cancel);
add("South",sp);
}
public boolean handleEvent(Eventevt)
{ / / System.out.println(evt.toString());
switch(evt.id){
case Event.ACTION.sub.-- EVENT:
{
if("OK".equals(evt.arg))
{
vjc.theLocation =
(Integer.valueOf(tf.getText())).intValue();
/ / vjc.theContainer.addNewPort(vjc, "fred","jim");
vjc.edit = null;
dispose();
return true;
}
if("Cancel".equals(evt.arg))
{ vjc.edit = null;
dispose();
return true;
}
return false;
}
default:
return false;
}
}
}
______________________________________
FIG. 10 shows the two pin capability of scrollbar 604b. Note that each of the pins 902 and 904 are diamond shaped or two way ports. If a value if placed on these ports, it sets the scrollbar to that level. Conversely, if a value is taken from one of these ports, it reflects the position of scrollbar 604b. In practice, the two way or bidirectional ports are first initialized to their two way state. The ports can then function either as an input port or as an output port depending solely on the way they are used. Each bidirectional port is provided with bidirectional capabilty by having a send message method defined for all outgoing transactions and a receive message method defined for all incoming transactions in the component for each bidirectional port. Thus, the method corresponding to the direction is invoked based on the flow of the message through the port. For example, if inputs are connected to the two-way ports 904a or 904b in FIG. 10, they would function as input ports. Two-way port 906 would then function as the output port since it is the only port left that could serve in that role. In the preferred arrangement, components set themselves internally to reflect the status of each of their bidirectional ports, in accordance with the way they are being used. The bidirectional ports permit greater connective flexibility and save screen real estate as well. When a connection to another component is completed, the connecting component sends a message to the component at the other end of the connection indicating how its connecting port is set, input or output. The message receiving component then makes sure that its connection participating port is set accordingly. If the message receiving component's port is bidirectional, the port is set opposite to the status of the first connected port. If the message receiving component's connecting port is bidirectional, that port is set opposite to the status of the first connected port. If the message receiving component's port is unidirectional and as such is in conflict with the status of the first connected port, that is, it is set to "output" when the first connected port is also set to "output", the connection is prohibited and an appropriate error message is displayed. FIG. 11 illustrates the addition of a second vertical scrollbar that will be set to track the range of the Fahrenheit temperature scale. Note that the vertical scrollbar editor 1104 has been adjusted to set scrollbar 1102 to a maximum value of 212 (boiling point) and a minimum value of 32 (freezing point). Prior to being adjusted, scrollbar 1102 has a current value of 71 with only 10 units of its total range actually visible. Dynamic editing is accomplished by providing each component that would have need of an editor with that capability as an integral part of the class template from which it is instantiated. Each customizer window or editor is defined in predetermined class templates as a method corresponding to the customizer method. Thus, when such edit capable components are instantiated in either the logical view 402 or the physical view 500, their built-in customizer or edit widow 1104 is invoked, see FIG. 11, and opens automatically. The editor appears in the view ready for use to change or customize the properties of the component, in this case scrollbar 604b, based on user interaction with the customizer or editing window 1104. As shown in the flowchart of FIG. 11A, editor capability is added at block 1120 to each class template for which an editing capability is desired in component objects instantiated therefrom. An editing window, as indicated by block 1122 is defined as a method corresponding to the editor. The properties and their limits are also defined for each component editor as shown by block 1124. An editing window is opened by block 1126 when the component with which it is associated is dragged and dropped or instantiated for use. After the user finishes editing the component's properties and clicks "OK", the editing window is closed and the property changes are accepted and displayed immediately in the appropriate view by block 1128. After property editing is completed, the editable components are monitored for a user action (usually a mouse click) which indicates that property re-editing is desired for a specific component, as per block 1130. When that occurs, block 1132 opens the editor widow 1104 again to permit component property changes to be made. Thereafter, control is returned to block 1128 and the user re-editing changes are accepted. Finally, monitoring of the editable components resumes as per block 1130. It is important to note that the user is not required to take any action to invoke an editor or be concerned about the suitability or appropriateness of the editor with respect to the component being customized. Moreover, the editor is customized for the specific component with which it is associated. If an editor appears when a component is instantiated, then the user instantaneously knows that that particular component is customizable. In addition, the user sees and knows just which properties of the component are editable and to what limits. Further, the user can make any desired customizing changes without having to write any code to implement those changes. Other uses of a component editor are shown in FIGS. 12 and 15. FIG. 12 shows how VJ Tool is utilized to add text to scrollbars 604b and 1102 so that the function they perform or represent can be labeled and thereby identified to any user. First, the simple text field component 506 is invoked by clicking on its icon and dragging it onto the physical view 500. The text field representation 1202 can then be dropped at any desired location and, as desired, sized to match the element it will identify, in this case scrollbar 604b. The text field or label editor 1204 is then used to generate the actual text or scrollbar label. The label text field component is coded as follows:
______________________________________
import java.awt.*;
import java.util.*;
public class VJLabel extends VJNode {
// Attributes of this component
public AWTLabel label;
static int instanceCount = 0;
labelEditor edit;
static Image normalImage;
static Image selectedImage;
final static String out = "out.sub.-- la.gif";
final static String in = "in.sub.-- la.gif";
final static String port0.sub.-- info = "for setting the text";
final static String port0.sub.-- name = "Pin 0";
final static String url.sub.-- name = "label.html";
final static String info.sub.-- name = "A simple AWT label";
VJ vj;
int send.sub.-- index=0;
int request0.sub.-- index=0;
// Constructor
public VJLabel(VJ v){
super(v);
vj = v;
VJNode dup() {
VJLabel vj.sub.-- comp = new VJLabel(vj);
try {
int i = x+40;
int j = y+40;
AWTLabel 1 = new AWTLabel(label.getText(),vj.sub.-- comp);
vj.sub.-- comp.label = 1;
vj.sub.-- comp.setNormalIcon(out);
vj.sub.-- comp.setSelectedIcon(in);
vj.sub.-- comp.setName(label.getText());
vj.sub.-- comp.setComponent((Component)1);
vj.sub.-- comp.setComponentURL(url.sub.-- name);
vj.sub.-- comp.setComponentInfo(info.sub.-- name);
vj.sub.-- comp.VJNodeInit(false,i,j,true);
vj.sub.-- comp.addPort(port0.sub.-- info,port0.sub.-- name,VJPort.Input,VJ
Port.NorthCe
nter); // Pin 0
vj.sub.-- comp.setXPt(0,getXPt(0)+40);
vj.sub.-- comp.setYPt(0,getYPt(0)+40);
vj.sub.-- comp.setImages(normalImage,selectedImage); //Pass references
to the static images down to the node
vj.sub.-- comp.nodeRect = new Rectangle(i-3,j-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
N
dImage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
vj.sub.-- comp.setSelected(true);
vj.theDocument.add(vj.sub.-- comp.comp);
vj.sub.-- comp.comp.validate();
vj.sub.-- comp.comp.reshape(comp.bounds().x+50,comp.bounds().y+50,comp
.bounds().width,comp.bounds().height);
vj.sub.-- comp.comp.show();
return vj.sub.-- comp;
} catch(Exception e) {
System.out.println(e);
return null;
}
}
public static void getImages(GIFFactory f){
normalImage = f.GetGIF(out);
selectedImage = f.GetGIF(in);
}
// Component Initialization
public void VJLabelInit(int x.sub.-- pt, int y.sub.-- pt) {
try {
String theText = new String("Label
"+String.valueOf(instanceCount++));
label = new AWTLabel(theText,this);
label.setFont(new Font("Courier", Font.PLAIN, 14));
setNormalIcon(out);
setSelectedIcon(in);
setName(theText);
setComponent((Component)label);
setComponentURL(url.sub.-- name);
setComponentInfo(info.sub.-- name);
VJNodeInit(false,x.sub.-- pt,y.sub.-- pt,true);
addPort(port0.sub.-- info,port0.sub.-- name,VJPort.Input,VJPort.NorthCente
r);
// Pin 0
setImages(normalImage,selectedImage); //Pass references to the
static images down to the node
nodeRect = new Rectangle(x.sub.-- pt-3,y.sub.-- pt-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
O
dImage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
} catch(Exception e) {
System.out.println(e);
}
}
public void request(int port,int time) { }
public int componentID() { return 2; }
public void load(String s) {
}
public String save() {
return ""; }
public void disconnecting(int port) {
switch(port){
case 0: request0.sub.-- index= -1;
break;
}
}
public void connecting(int port) {
switch(port){
case 0: request0.sub.-- index=0;
vj.request(0,request0.sub.-- index++,this);
break;
}
}
public void set(Object o,int port,int time) {
boolean ok = false;
if(o instanceof Color) { label.setForeground((Color)o); ok=true; }
if(o instanceof String) { label.setText((String)o); ok = true;}
if(o instanceof Long) {
label.setText((String)(((Long)o).toString())); ok = true;}
if(o instanceof Double) {
label.setText((String)(((Double)o).toString())); ok = true;}
if(o instanceof Float) {
label.setText((String)(((Float)o).toString())); ok = true;}
if(o instanceof Integer) {
label.setText((String)(((Integer)o).toString())); ok = true;}
if(o instanceof Boolean) {
label.setText((String)(((Boolean)o).toString()));ok = true; }
if(ok) {
//System.out.println(name + " has input at "+
String.valueOf(time)+ " = "+ getText());
if(time<199) vj.request(0,request0.sub.-- index++,this);
}
ok = false;
}
public boolean handleEvent(Event e) {
return false;
}
public void propertiesEditor() {
if(edit==null){
edit = new labelEditor((Frame)(vj.theFrame),this);
edit.pack();
//edit.resize(12*32,6*32);
edit.show();
}
}
public void init(){};
public void start(){};
public void stop(){};
public void destroy(){};
} // end class VJLabel
class labelEditor extends Frame
{
VJLabel vjl;
TextField tf;
Button ok;
Button cancel;
boolean dirty;
public labelEditor (Frame parent,VJLabel 1)
{
super("Label Editor");
setLayout(new BorderLayout());
vjl = 1;
tf = new TextField(vjl.label.getText());
add("Center",tf);
ok = new Button("OK");
cancel = new Button("Cancel");
Panel sp = new Panel();
sp.add(ok);
sp.add(cancel);
add("South",sp);
}
public boolean handleEvent(Event evt)
{ // System.out.println(evt.toString());
switch(evt.id){
case Event.ACTION.sub.-- EVENT:
{
if("OK".equals(evt.arg))
{
vjl.label.setText(tf.getText());
vjl.edit = null;
dispose();
return true;
}
if("Cancel".equals(evt.arg))
{ vjl.edit = null;
dispose();
return true;
}
return false;
}
default:
return false;
}
}
}
______________________________________
As shown in FIG. 13, text field 1202 has been made into the "CENTIGRADE" label 1202a above scrollbar 604b through use of the text field editor 1204. Label "FAHRENHEIT" 1302 has been generated in the same manner and positioned above scrollbar 1102 (not shown in FIG. 13). It should be noted that several of the components described herein, vertical scrollbars 604a and 604b and text field 1202 label editor, are provided with their own editors, vertical scrollbar editor 604 and label editor 1204, which permits the predefined properties of the associated components to be directly and dynamically edited. Such editing takes place without the user having to exit VJ Tool or having to write any code to support the desired editorial changes. FIG. 13 also illustrates in logical view 402, representations of scrollbars, text and bicopy objects that will be used to functionally link scrollbars 604b and 1102. Objects 1306 and 1312 logically represent scroll bars 604b and 1102 while label objects 1304 and 1310 represent the labels 1202a and 1302 respectively. Bicopy is a backend component that is only found in the logical view palette. A bicopy object, such as 1308 and 1314, as implemented in accordance with a preferred embodiment of the present invention, will place whatever is input on one of its diamond shaped I/O pins 1308a, 1308b, 1308c or 1398d on the other I/O pins. Bicopy, which functions like a multiplexor, is coded as follows:
______________________________________
import java.awt.*;
import java.util.*;
public class VJBiCopy extends VJNode {
// Attributes of this component
static int instanceCount = 0;
static Image normalImage;
static Image selectedImage;
final static String out.sub.-- bi = "out.sub.-- bi.gif";
final static String in.sub.-- bi = "in.sub.-- bi.gif";
final static String port0.sub.-- info = "Pin 0";
final static String port0.sub.-- name = "Pin 0";
final static String port1.sub.-- info = "Pin 1";
final static String port1.sub.-- name = "Pin 1";
final static String port2.sub.-- info = "Pin 2";
final static String port2.sub.-- name = "Pin 2";
final static String port3.sub.-- info = "Pin 3";
final static String port3.sub.-- name = "Pin 3";
final static String url.sub.-- name = "bicopy.html";
final static String info.sub.-- name = "Whatever is input on one pin is
output
on the others";
VJ vj;
int send.sub.-- index0 = -1;
int send.sub.-- index1 = -1;
int send.sub.-- index2 = -1;
int send.sub.-- index3 = -1;
int request.sub.-- index0 = -1;
int request.sub.-- index1 = -1;
int request.sub.-- index2 = -1;
int request.sub.-- index3 = -1;
// Constructor
public VJBiCopy(VJ v){
super(v);
vj = v;
VJNode dup() {
VJBiCopy b = new VJBiCopy(vj);
try {
int i = x+40;
int j = y+40;
b.setNormalIcon(out.sub.-- bi);
b.setSelectedIcon(in.sub.-- bi);
b.setName("BiCopy");
b.setComponent(null);
b.setComponentURL(url.sub.-- name);
b.setComponentInfo(info.sub.-- name);
b.VjNodeInit(false,i,j,false);
b.addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,VJPort.No
rthCen
ter); // Pin0
b.addPort(port1.sub.-- info,port 1.sub.-- name,VJPort.InputOutput,
VJPort.EastCenter); // Pin 1
b.addPort(port2.sub.-- info,port2.sub.-- name,VJPort.InputOutput,VJPort.So
uthCen
ter); // Pin 2
b.addPort(port3.sub.-- info,port3.sub.-- name,VJPort.InputOutput,
VJPort.WestCenter); // Pin 3
b.setXPt(0,getXPt(0)+40);
b.setYPt(0,getYPt(0)+40);
b.setXPt(1,getXPt(1)+40);
b.setYPt(1,getYPt(1)+40);
b.setXPt(2,getXPt(2)+40);
b.setYPt(2,getYPt(2)+40);
b.setXPt(3,getXPt(3)+40);
b.setYPt(3,getYPt(3)+40);
b.setImages(normalImage,selectedImage); //Pass references to the
static images down to the node
b.nodeRect = new Rectangle(i-3,j-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
b.setSelected(true);
return b;
} catch(Exception e) {
System.out.println(e);
return null;
}
}
public static void getImages(GIFFactoryf){
normalImage = f.GetGIF(out.sub.-- bi);
selectedImage = f.GetGIF(in.sub.-- bi);
}
// Component Initialization
public void VJBiCopyInit(intx.sub.-- pt, int y.sub.-- pt) {
try {
setNormalIcon(out.sub.-- bi);
setSelectedIcon(in.sub.-- bi);
setName("bicopy");
setComponent(null);
setComponentURL(url.sub.-- name);
setComponentInfo(info.sub.-- name);
VJNodeInit(false,x.sub.-- pt,y.sub.-- pt,false);
addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,
VJPort.Northcenter); // Pin 0
addPort(port1.sub.-- info,port1.sub.-- name,VJPort.InputOutput,
VJPort.EastCenter); // Pin 1
addPort(port2.sub.-- info,port2.sub.-- name,VJPort.InputOutput,
VJPort.SouthCenter); // Pin 2
addPort(port3.sub.-- info,port3.sub.-- name,VJPort.InputOutput,
VJPort.WestCenter); // Pin 3
setImages(normalImage,selectedImage); //Pass references to the
static images down to the node
nodeRect = new Rectangle(x.sub.-- pt-3,y.sub.-- pt-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
} catch(Exception e) {
System.out.println(e);
}
}
public void request(int port,int time) { }
public int componentID() { return 5; }
public void disconnecting(int port) {
switch(port){
case 0: send.sub.-- index0 = -1; request.sub.-- index0 = -1;
break;
case 1: send.sub.-- index1 = -1; request.sub.-- index1 = -1;
break;
case 2: send.sub.-- index2 = -1; request.sub.-- index2 = -1;
break;
case 3: send.sub.-- index3 = -1; request.sub.-- index3=-1;
break;
}
}
public void connecting(int port) {
switch(port){
case 0: request.sub.-- index0=0; send.sub.-- index0 = 0;
vj.request(0,request.sub.-- index0++,this);
break;
case 1: request.sub.-- indexl=0; send.sub.-- index1 = 0;
vj.request(1 ,request.sub.-- index1++,this);
break;
case 2: request.sub.-- index2=0; send.sub.-- index2 = 0;
vj.request(2,request.sub.-- index2++,this);
break;
case 3: request index3=0; send.sub.-- index3 = 0;
vj.request(3,request.sub.-- index3++,this);
break;
}
}
public void load(String s) {
}
public String save() {
return ""; }
public void set(Object o,int port,int time) {
switch(port){
case 0: if (request.sub.-- index1 > 0) vj.set(o,1,send.sub.-- index1++,th
is);
if (request.sub.-- index2 > 0) vj.set(o,2,send.sub.-- index2++,this);
if (request.sub.-- index3 > 0) vj.set(o,3,send.sub.-- index3++,this);
vj.request(0,request.sub.-- index0++,this);
break;
case 1: if (request.sub.-- index0 > 0) vj.set(o,0,send.sub.-- index0++,th
is);
if (request.sub.-- index2 > 0) vj.set(o,2,send.sub.-- index2++,this);
if (request.sub.-- index3 > 0) vj.set(o,3,send.sub.-- index3++,this);
vj.request(1,request.sub.-- index1++,this);
break;
case 2: if (request.sub.-- index1 > 0) vj.set(o,1,send.sub.-- index1++,th
is);
if (request.sub.-- index0 > 0) vj.set(o,0,send.sub.-- index0++,this);
if (request.sub.-- index3 > 0) vj.set(o,3,send.sub.-- index3++,this);
vj.request(2,request.sub.-- index2++,this);
break;
case 3: if (request.sub.-- index1 > 0) vj.set(o,1,send.sub.-- index1++,th
is);
if (request.sub.-- index2 > 0) vj.set(o,2,send.sub.-- index2++,this);
if (request.sub.-- index0 > 0) vj.set(o,0,send.sub.-- index0++,this);
vj.request(3,request.sub.-- index3++,this);
break;
}
}
public void propertiesEditor() {
}
public void init(){};
public void start(){};
public void stop(){};
public void destroy(){};
} // end class VJButton
______________________________________
FIG. 13A illustrates a flowchart of the process by which the bicopy component 1308 shown in FIG. 13 functions. The act of dragging and dropping a new bicopy component onto the logical desktop 402 or of dropping an assembly from folder 542, which assembly contains a bicopy component, onto the logical view desktop 402 actually starts the bicopy component as called for in block 1330. A test is next made to see there is a saved, prior state for bicopy element 1308 that needs to be restored by decsion block 1332. If restoration is neded, control is passed to block 1334 which obtains the necessary values and has the ports set accordingly in block 1344. If the bicopy component is new, its two-way ports are initialized or set to zero in bock 1336. Once that has been done, the ports are polled in block 1338 to monitor connection attempts. Decision block 1340 returns control to block 1338 for continued polling if there were no connections made to any of bicopy's component ports. If a proper connection has been made, a connection sufficient to place a value on one of the bicopy componet's ports, control is passed to block 1342 where the type and value of the connection is identified. Thus, if a connection has been made from a text field, a character string is placed on one of the bicopy component's ports and captured by the Bicopy component. Similarly, if an integer value, such as 32, is placed placed on one of the bicopy component's ports, that type and value is also recognized and captured. Once the type and value of an input are known, the remaining ports are set to provide the same type and value as the input by block 1344. Thus, at this point, see FIG. 16, bicopy component 1308 would have its port 1308c set by the output of scrollbar representation 1306 to the current value (position) of the scrollbar. This means that ports 1308a, 1308b and 1308d, which act as output ports, will carry the output value of scrollbar 1306 until the input connection to port 1308c is changed. Decision block 1346, which is advised of the initial connection by block 1342, checks for removal of the input value to bicopy component 1308 and returns control back to block 1344 if it has not been removed or to block 1336 for reinitialization if it has been removed. FIG. 14 shows addition of splitters 1402 and 1404 in the logical view 402. Splitter objects 1402 and 1404 are used to connect I/O pins to components that are functionally involved in a defined relationship appearing in the logical view 402. Splitters are instantiated form the splitter palette component 558 of logical view 402 and are dragged and dropped to a suitable location on the logical view desktop. Splitter objects are formed pursuant to their implementing code (VJSplit) as follows:
______________________________________
import java.awt.*;
import java.util.*;
public class VJSplit extends VJNode {
// Attributes of this component
static int instanceCount = 0;
static Image normalImage;
static Image selectedImage;
final static String out = "OSplit.gif";
final static String in = "ISplit.gif";
final static String port0.sub.-- info = "An input/output pin";
final static String port0.sub.-- name = "Pin 0";
final static String port1.sub.-- info = "An output pin";
final static String port1.sub.-- name = "Pin 1";
final static String port2.sub.-- info = "An input pin";
final static String port2.sub.-- name = "Pin 2";
final static String url.sub.-- name = "split.html";
final static String info.sub.-- name = "A Splitter used to connect
input/output pins to componets that are either input or output";
VJ vj;
int send.sub.-- index2 = 0;
int request.sub.-- index0 = 0;
int request.sub.-- index1 = 0;
// Constructor
public VJSplit(VJ v){
super(v);
vj = v;
VJNode dup() {
VJSplit b = new VJSplit(vj);
try {
int i = x+40;
int j = y+40;
b.setNormalIcon(out);
b.setSelectedIcon(in);
b.setName("Splitter");
b.setComponent(null);
b.setComponentURL(url.sub.-- name);
b.setComponentInfo(info.sub.-- name);
b.VJNodeInit(false,i,j,false);
b.addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,VJPort.No
rthCen
ter); // Pin 0
b.addPort(port1.sub.-- info,port1.sub.-- name,VJPort.Output,VJPort.SouthLe
ftCente
r); // Pin 0
b.addPort(port2.sub.-- info,port2.sub.-- name,VJPort.Input,VJPort.SouthRig
htCente
r); // Pin 0
b.setXPt(0,getXPt(0)+40);
b.setYPt(0,getYPt(0)+40);
b.setXPt(1,getXPt(1)+40);
b.setYPt(1,getYPt(1)+40);
b.setXPt(2,getXPt(2)+40);
b.setYPt(2,getYPt(2)+40);
b.setImages(normalImage,selectedImage); //Pass references to the
static images down to the node
b.nodeRect = new Rectangle(i-3,j-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
b.setSelected(true);
return b;
} catch(Exception e) {
System.out.println(e);
return null;
}
}
public static void getImages(GIFFactoryf){
normalImage = f.GetGIF(out);
selectedImage = f.GetGIF(in);
}
// Component Initialization
public void VJSplitInit(intx.sub.-- pt, int y.sub.-- pt) {
try {
setNormalIcon(out);
setSelectedIcon(in);
setName("Splitter");
setComponent(null);
setComponentURL(url.sub.-- name);
setComponentInfo(info.sub.-- name);
VJNodeInit(false,x.sub.-- pt,y.sub.-- pt,false);
addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,VJPort.Nort
hCente
r); // Pin 0
addPort(port1.sub.-- info,port1.sub.-- name,VJPort.Output,VJPort.SouthLeft
Center);
// Pin 0
addPort(port2.sub.-- info,port2.sub.-- name,VJPort.Input,VJPort.SouthRight
Center);
// Pin 0
setImages(normalImage,selectedImage); //Pass references to the
static images down to the node
nodeRect = new Rectangle(x.sub.-- pt-3,y.sub.-- pt-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
dI
mage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
} catch(Exception e) {
System.out.println(e);
}
}
public int componentID() { return 12; }
public void disconnecting(int port) { }
public void connecting(int port) { }
public void load(String s) {
}
public String save() {
return ""; }
public void propertiesEditor() {}
public void reset() {}
public void request(int port,int time) {
switch(port){
case 0: vj.request(2,time,this);
break;
case 1: vj.request(0,time,this);
break;
}
}
public void set(Object o,int port,int time) {
switch(port){
case 0: vj.set(o,1,time,this);
break;
case 2: vj.set(o,0,time,this);
break;
}
}
public void init(){};
public void start(){
};
public void stop(){
};
public void destroy(){ };
}
______________________________________
FIG. 15 shows the addition of a calculator object 1502. Calculator object 1502 is instantiated from calculator component 572 of the logical view palette when the mouse is clicked over the calculator icon and the resulting image is dragged into the logical view window. When calculator object 1502 is created, evaluator editor 1504 is popped up so that expressions to be evaluated by the calculator can be input thereto. In this particular example, the Fahrenheit to Centigrade conversion expression to be evaluated is entered and the calculator is thereby informed what its computational task will be. FIG. 16 illustrates the interconnections of several objects to achieve the appropriate Centigrade/Fahrenheitrelationship between scroll bars 604b and 1102. Building on to the arrangement depicted in FIG. 15, the user would add two simple text field objects 1602 and 1603 in physical view 500 by clicking on the simple text field icon 506 twice and then dragging and dropping each resultant text field object 1602 and 1603 so that each is located below and adjacent to the scrollbar it contains information for. When the text field objects are created, logical representations thereof, 1604 and 1606 respectively, are created by VJ Tool in the logical window. The appropriate interconnections between and amongst the several objects in the logical view 402 are then made and the results displayed in the text fields 1602 and 1604 as a direct function of where the scrollbars are actually located. Since scrollbar 604b is at its minimum position, which is zero, text field 1602 accurately displays that result. The display of the position results in a text field without the intervening need to write additional code to transform the scrollbar output, an integer or floating point value to an ASCII string. VJ Tool takes care of that task for the user and permits concentration on the problem being solved.
______________________________________
VJTextField is coded as follows:
import java.awt.*;
import java.util.*;
public class VJTextField extends VJNode {
// Attributes of this component
public AWTTextField text;
static int instanceCount = 0;
textfieldEditor edit;
static Image normalImage;
static Image selectedImage;
final static String out = "out.sub.-- te.gif";
final static String in = "in.sub.-- te.gif";
final static String port0.sub.-- info = "for getting or seeting the
current text";
final static String port0.sub.-- name = "Pin 0";
final static String url.sub.-- name = "textfield.html";
final static String info.sub.-- name = "A simple AWT textfield";
VJ vj;
int send.sub.-- index = -1;
int request.sub.-- index = 0;
int c.sub.-- width, c.sub.-- height;
// Constructor
public VJTextField(VJ v){
super(v);
vj = v;
VJNode dup() {
VJTextField vj.sub.-- comp = new VJTextField(vj);
try {
int i = x+40;
int j = y+40;
AWTTextField t = new AWTTextField(text.getText(),vj.sub.-- comp);
vj.sub.-- comp.text = t;
t.setFont(text.getFont());
vj.sub.-- comp.setNormalIcon(out);
vj.sub.-- comp.setSelectedIcon(in);
vj.sub.-- comp.setName(text.getText());
vj.sub.-- comp.setComponent((Component)t);
vj.sub.-- comp.setComponentURL(url.sub.-- name);
vj.sub.-- comp.setComponentInfo(info.sub.-- name);
vj.sub.-- comp.VJNodeInit(false,i,j,true);
vj.sub.-- comp.addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOut
put,VJPort.S
outhCenter); // Pin 0
vj.sub.-- comp.setXPt(0,getXPt(0)+40);
vj.sub.-- comp.setYPt(0,getYPt(0)+40);
vj.sub.-- comp.setImages(normalImage,selectedImage); //Pass references
to the static images down to the node
vj.sub.-- comp.nodeRect = new Rectangle(i-3,j-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
O
dImage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
vj.sub.-- comp.setSelected(true);
vj.theDocument.add(vj.sub.-- comp.comp);
vj.sub.-- comp.comp.validate();
vj.sub.-- comp.comp.reshape(comp.bounds().x+50,comp.bounds().y+50,comp
.bounds().width,comp.bounds().height);
vj.sub.-- comp.comp.show();
return vj.sub.-- comp;
} catch(Exception e) {
System.out.println(e);
return null;
}
}
public static void getImages(GIFFactory f){
normalImage = f.GetGIF(out);
selectedImage = f.GetGIF(in);
}
// Component Initialization
public void VJTextFieldInit(int x.sub.-- pt, int y.sub.-- pt) {
try {
String theText = new String("TextField
"+String.valueOf(instanceCount++));
text = new AWTTextField(theText,this);
text.setFont(new Font("Courier", Font.PLAIN, 14));
setNormalIcon(out);
setSelectedIcon(in);
setName(theText);
setComponent((Component)text);
setComponentURL(url.sub.-- name);
setComponentInfo(info.sub.-- name);
VJNodeInit(false,x.sub.-- pt,y.sub.-- pt,true);
addPort(port0.sub.-- info,port0.sub.-- name,VJPort.InputOutput,VJPort.Sout
hCent
er); // Pin 0
setImages(normalImage,selectedImage); //Pass references to the
static images down to the node
nodeRect = new Rectangle(x.sub.-- pt-3,y.sub.-- pt-
3,selectedImage.getWidth(vj.theContainer.theDesktop.vp.sub.-- w)+3,selecte
N
dImage.getHeight(vj.theContainer.theDesktop.vp.sub.-- w)+3);
} catch(Exception e) {
System.out.println(e);
}
}
public void request(int port,int time) { }
public int componentID() { return 3; }
public void disconnecting(int port) {
send.sub.-- index= -1;
}
public void connecting(int port) {
request.sub.-- index=0;
send.sub.-- index = 0;
vj.request(0,request.sub.-- index++,this);
}
public void load(String s) {
StringTokenizer tokenStream = new
StringTokenizer(s,"@",false);
String data =
tokenStream.nextToken().replace(` `,`.backslash.t`).replace(`&`,` `);
if(data.startsWith(" ")) data = data.substring(1);
text.setText(data);
String family = tokenStream.nextToken();
boolean bold =
Boolean.valueOf(tokenStream.nextToken()).booleanValue();
boolean italic =
Boolean.valueOf(tokenStream.nextToken()).booleanValue();
int size =
Integer.valueOf(tokenStream.nextToken()).intValue();
int theStyle = Font.PLAIN;
if(bold) theStyle = theStyle+Font.BOLD;
if(italic) theStyle = theStyle+Font.ITALIC;
text.setFont(new Font(family, theStyle, size));
if(|vj.isMicrosoft)
vj.doResize(this,text.size().width,text.size().height);
}
public String save() {
String family = text.getFont().getName();
int size = text.getFont().getSize();
boolean bold = text.getFont().isBold();
boolean italic = text.getFont().isItalic();
return text.getText().replace(`
`,`&`).replace(`.backslash.t`,` `)+"@"+family+"@"+bold+"@"+italic+"@"+size
;}
public void set(Object o,int port,int time) {
boolean ok = false;
if(o instanceof Color) { text.setForeground((Color)o); ok=true; }
if(o instanceof String) { text.setText((String)o); ok = true;}
if(o instanceof Long) { text.setText((String)(((Long)o).toString()));
ok = true;}
if(o instanceof Double) {
text.setText((String)(((Double)o).toString())); ok = true;}
if(o instanceof Float) { text.setText((String)(((Float)o).toString()));
ok = true;}
if(o instanceof Integer) {
text.setText((String)(((Integer)o).toString())); ok = true;}
if(o instanceof Boolean) {
text.setText((String)(((Boolean)o).toString()));ok = true; }
if(ok) {
//System.out.println(name + " has input at "+
String.valueOf(time)+ " = "+ getText());
if(time<199) vj.request(0,request.sub.-- index++,this);
}
ok = false;
}
public boolean handleEvent(Event e) {
if(e.id = = 1001) {
if(send.sub.-- index>=0)
vj.set((Object) text.getText(),0,send.sub.-- index++,this);
}
switch(e.id){
case VJEvent.DOUBLECLICK: propertiesEditor(); break;
//case 0: set(e.arg,0); System.out.println("GOT TF 0
"+e.toString()); break;
}
return false;
}
public void propertiesEditor() {
if(edit= =null){
edit = new textfieldEditor((Frame)(vj.theFrame),this);
edit.pack();
edit.resize(12*32,6*32);
edit.show();
}
}
public void init(){};
public void start(){};
public void stop(){};
public void destroy(){};
} // end class VJButton
class textfieldEditor extends Frame
{
VJTextField vjtf;
TextField tf;
Button ok;
Button cancel;
Choice fonts;
Font compFont;
Checkbox bold;
Checkbox italic;
TextField size;
String fontnames›!;
boolean dirty;
public textfieldEditor (Frame parent,VJTextField 1)
{
super("TextField Editor");
setBackground(Color.lightGray);
setLayout(new BorderLayout());
Panel p = new Panel();
Panel centerPanel = new Panel();
p.add(new Button("OK"));
p.add(new Button("Cancel"));
add("South",p);
vjtf = 1;
dirty = false;
Panel PN = new Panel();
fonts = new Choice();
fontnames = vjtf.text.getToolkit().getFontList();
compFont = vjtf.text.getFont();
for (int i = 0; i < fontnames.length; i++) {
fonts.addItem(fontnames›i!);
if(fontnames›i!.equals(compFont.getFamily()))fonts.select(i);
}
fonts.setBackground(Color.lightGray);
bold = new Checkbox("Bold");
bold.setState(compFont.isBold());
italic = new Checkbox("Italic");
italic.setState(compFont.isItalic());
size = new TextField(String.valueOf(compFont.getSize()));
tf = new TextField(vjtf.text.getText());
centerPanel.setLayout(new GridLayout(2,3));
centerPanel.add(new Label("Fonts"));
centerPanel.add(new Label("Text"));
centerPanel.add(new Label("Font Size"));
centerPanel.add(fonts);
centerPanel.add(tf);
centerPanel.add(size);
Panel textP = new Panel();
textP.add(bold);
textP.add(italic);
PN.add(textp);
add("North",PN);
add("Center",centerPanel);
}
public boolean handleEvent(Event evt)
{ //System.out.println(evt.toString());
switch(evt.id){
case Event.ACTION.sub.-- EVENT:
{
if("OK".equals(evt.arg))
{
int theStyle = Font.PLAIN;
if(bold.getState()) theStyle = theStyle+Font.BOLD,
if(italic.getState()) theStyle = theStyle+Font.ITALIC;
vjtf.text.setFont(new Font(fonts.getSelectedItem(),
theStyle, Integer.valueOf(size.getText()).intValue()));
vjtf.text.setText(tf.getText());
if(|vjtf.vj.isMicrosoft)
vjtf.vj.doResize(vjtf,vjtf.c.sub.-- width,vjtf.c.sub.-- height);
dispose();
return true;
}
if("Cancel".equals(evt.arg))
{
dispose();
return true;
}
return false;
}
default:
return false;
}
}
}
The AWTTextField.Java is as follows:
import java.awt.*;
public class AWTTextArea extends TextArea {
VJTextArea vjt;
public AWTTextArea(String n,VJTextArea v){
super(n);
vjt = v;
setFont(new Font("Courier", Font.PLAIN, 14));
}
public boolean handleEvent(Event e) {
return vjt.handleEvent(e);
}
}
______________________________________
In this example, interconnections are made by mouse click, drag and drop operations as follows. The output of scrollbars 1306 and 1308 are connected to the bicopy objects 1308 and 1314 respectively. That value is passed from bicopy object 1308 to splitter 1402 and text field representation 1604 and from bicopy object 1314 to splitter 1404 and text field representation 1606. In addition, the output of splitter 1402 is coupled to the input of calculator 1502a while the output of splitter 1404 is coupled to the input of calculator 1502b. Finally, the outputs of calculators 1502a and 1502b are respectively connected to the inputs of splitters 1402 and 1404. Thus, when scrollbar 604b is moved to a new position, the value of that position is transmitted by the scrollbar object 1306 to bicopy object 1308 and from there to text field component representation 1604. This means that the text fields 1602 and 1603 both display the changing values for their associated scrollbars 604b and 1102 when either one of them is moved to a new position. It is rather important to note that the interconnections described above between objects on the logical view are subject to type and functionality checking in a dynamic manner when they are attempted. Thus, the connection in FIG. 16 that was made between the output port of splitter 1402 and the input port of calculator 1502a is functionally permissible and was permitted to be made in a manner that was transparent to the user. Conversely, if an attempt had been made to connect the output port of splitter 1402 to the output port of calculator 1502a, that attempt would have been denied as functionally impermissible. In a similar manner, had an attempt been made to the output of calculator 1502a to the input of text label object 1304, that connection would have been denied since the input type (a value or number) was mistyped as an input to text label object 1304 which only accepts input of type char or a string of characters. This functional and type compatibility checking is performed by the VJDesktop code as set forth above. The port or netpin type verification works in the following functional manner. When a component or object pin is created by being dropped onto the logical view desktop 402, its presence there and the number and nature of its pins, if any, is logged, stored and tracked by the VJDesktop code. Specifically, the number and types of ports or netpins on the newly instantiated component or object is noted Once a component or object having pins is instantiated, VJDesktop tracks and stores the status of its ports by polling them periodically as depicted by block 1620 in FIG. 16A. The same is true for variables, the information for which is initially stored when a component that can pass, duplicate or manipulate a variable is instantiated. As used herein, the term "initiate a connection" means that the mouse has been clicked over only one port in preparation for tacking the line that appears to another port. Once that other port is clicked on, the connection is deemed to be completed. Decision block 1622 is advised by block 1620 whether or not a connection to one of the ports has been initiated. If no attempt to initiate a connection has been made, polling continues. If a connection has been initiated, the type of port involved (input, output or bidirectional) and, if known, the type of variable expected (character, float, long integer, short integer, string, etc.) on that port are stored as per block 1624 with VJDesktop and control waits for completion of a connection for the involved port while polling continues for the remaining ports. Decision block 1626 sends control back to polling if the pending connection has not yet been made. If the connection is completed, control for the ports involved is passed to decision block 1628 which decides if the attempted complete connection between the ports involved is valid. The type of ports involved and their functional affinity for each other will be checked and verified. Connections directly between an input port on one component will not be allowed to an input port on another component nor will a direct connection between an output port on a first container to an output port on a second container. Also forbidden are connections between ports on the same component regardless of their type. In addition to checking that interport connections are valid, decision block 1628 also ascertains if the variable to be transmitted across the new connection is valid for both ports. By referring to the stored component and object port information, it can be determined, for example, that the variable at the output of calculator 1502a in FIG. 16 is mistyped as to the variable expected at the input of label 1304, a character or string. As a result, when that otherwise valid output to input connection is attempted, it would be prevented by decision block 1628 because of a variable type mismatch. When the attempted connection is invalid, an error message will be sent to the screen for the user to see and notification is sent to block 1620 to keep on polling for completion of the initiated, but not completed connection. If the attempted connection is valid, it is completed and also reflected on the display and the polling block 1620 is so advised. The stored port information is updated and the system waits for the next attempted connection. If a completed connection is ended, decision block 1634 is so advised by polling block 1620 and the stored type information for that connection is appropriately adjusted to reflect that the ports which were involved in the ended connection are now free for other use. FIG. 17 shows the final result of the coupled scrollbars with correct Fahrenheit and Centigrade temperatures shown in text fields 1602 and 1603, respectively. With both scrollbars at their minimum positions, the Centigrade scrollbar 604b position produces the value 0 in text field 1602. In similar fashion, scrollbar 1102 produces a value of 32 in text field 1603. If scrollbar 604b is pulled down to position 1702 where it has a value of 80, as will then be displayed in text field 1602, then scrollbar 1102, because of what are essentially feedback connections made in FIG. 16, will move to position 1704 which will cause text field 1603 to then display its corresponding value of 176 degrees. Because of the cross coupling described in connection with FIG. 16, moving scrollbar 1102 first to a position of 176 would cause scrollbar 604b to be positioned at the point that represents the value 80, which would be displayed in text field 1602.
______________________________________
import java.net.*;
import java.io.*;
import java.util.Vector;
class ServerConnection extends Thread
private Socket
.sub.-- mysocket;
private PrintStream
.sub.-- output;
private DataInputStream .sub.-- input;
String id;
ConnectionManager creator;
int intId;
private Socket some.sub.-- server = null;
private DataInputStream in;
private PrintStream out;
private int clientType;
theClient XXXXserver;
private void doServerWork()
{
Parser p;
String temp;
String command;
while(true){
while(|inputWaiting())
Thread.yield();
String s = receive();
// Dump a copy of rec input to console to see what is happening
// uncomment next line in development
// System.out.println(id + " -> " + s);
// Parse the input string
p = new Parser(s);
// determine the command recieved from the client
command = p.arg(0);
if(|p.isValid()){
send("- -" + command);
}
else if(command.compareTo("Confirm") = = 0){
send("- -" + command + "confirmed");
}
else if(command.compareTo("SendAll") = = 0){
creator.sendToAll(intId + " -> " + p.arg(1));
send("- -" + command + " confirmed");
}
else if(command.compareTo("Connect") = = 0){
send(handleConnect(p, s));
}
else if(command.compareTo("Command1") = = 0){
send(handleFileServer(p, s));
}
else if(command.compareTo("Command2") = = 0){
send(handleFileServer(p, s));
}
else if(command.compareTo("Command3") = = 0){
send(handleFileServer(p, s));
}
else if(command.compareTo("Command4") = = 0){
send(handleFileServer(p, s));
}
// Add more commands as required
else{
send("--Unknown request - " + command);
} }
}
private String handleFileServer(Parser p, String s){
String command = p.arg(0);
XXXXserver.send(s);
return XXXXserver.receive();
}
public DataInputStream getDataInputStream(){
return in;
}
public PrintStream getPrintStream(){
return out;
}
public void handleMessage(String s){
}
private String handleConnect(Parser p, String s){
if(initSocket(p.arg(1),Integer.valueOf(p.arg(2)).intValue())){
clientType = TypesOfClients.CONNECTED.sub.-- CLIENT;
XXXXserver = new theClient(this);
return("- -" + XXXXserver.receive());
}
clientType = TypesOfClients.NORMAL.sub.-- CLIENT;
return ("--Failed connecting to "+ p.arg(1) + ":" + p.arg(2));
}
private boolean initSocket(String addr, int port){
try{
some.sub.-- server = new Socket(addr, port);
in = new DataInputStream(some.sub.-- server.getInputStream());
out = new PrintStream(some.sub.-- server.getOutputStream());
}
catch(Exception e){
try
{
some.sub.-- server.close();
}
catch(Exception e2)
{
System.err.println("Exception: .backslash.n" + e);
return false;
}
return false;
}
return true;
}
public ServerConnection(Socket s, ConnectionManager c, int
id1)
{
.sub.-- mysocket = s;
creator = c;
intId = id1;
clientType = TypesOfClients.NORMAL.sub.-- CLIENT; }
public boolean send(String s){
System.out.println("Sending" + s);
try{
.sub.-- output.println(s);
}
catch(Exception e){
return false;
}
return true;
}
private String receive(){
try{
return.sub.-- input.readLine();
}
catch(Exception e){
}
return "";
}
private boolean inputWaiting(){
try{
return (.sub.-- input.available() |= 0);
}
catch(Exception e){
}
return false;
}
public void run()
{
id = .sub.-- mysocket.getInetAddress() + ":" +
.sub.-- mysocket.getPort();
System.out.println("New Client : " + id);
try
{
.sub.-- output = new
PnntStream(.sub.-- mysocket.getOutputStream());
.sub.-- input = new
DataInputStream(.sub.-- mysocket.getInputStream());
send(" Your id is " + intId);
doServerWork();
.sub.-- mysocket.close();
}
catch ( Exception e )
{
System.err.println( "Exception: .backslash.n" + e);
}
System.out.println("Disconnecting: " + id);
stop();
}
}
class TypesOfClients{
static int NORMAL.sub.-- CLIENT = 1;
static int CONNECTED.sub.-- CLIENT = 2;
}
class Parser{
String args›! = new String›10!;
int n;
boolean valid;
public Parser(String s){
if (parse(s))
valid = true;
else
valid = false;
}
public boolean isValid(){
return valid;
}
public String arg(int i){
if(i <= n)
return args›i!;
else
return "";
}
public int getNumberOfArgs(){
return n;
}
private boolean parse(String s){
String out = "";
int i = 0;
int commas›! = new int›10!;
int start, end;
int count = 0;
int openingB = s.indexOf("(");
if(openingB = = -1){
args›0! = "No Opening Parantheses";
n = 1;
return false;
}
int lastPos = openingB;
args›count! = s.substring(0,lastPos);
out = out + "{" + args›count! + "}";
count = count + 1;
boolean GoOn = true;
while(GoOn){
start = s.indexOf("", lastPos);
if(start = = -1){
GoOn = false;
}
else{
end = s.indexOf("", start+1);
if(end = = -1){
args›0!= "Unmatched apostrophes";
n = 1;
return false;
}
commas›i! = s.indexOf(",", end+1);
if(commas›i! = = -1){
commas›i! = s.indexOf(")", end+1);
if(commas›i! = = -1){
args›0! = "Something's wrong";
n = 1;
return false;
}
}
args›count! = s.substring(start + 1, end);
out = out + "{" + args›count! + "}";
count = count + 1;
lastPos = commas›i!;
i = i + 1;
}
}
System.out.println(out);
n = count;
return true;
}
}
// This is the MAIN routine for the server
// It initializes on a predetermined socket port. There can be many
// sockets for a particular computer that may have a unique IP
address.
// In this case port # 4000
// The corresponding collaborative component must use this
// socket to communicate with this server
// You must make sure that no other services are using this
// socket number.
class GenericServer
{
private static final int DEFAULT.sub.-- PORT=4000;
private ConnectionManager cm = null;
public GenericServer(int port)
{
System.out.println("Server using port " + port);
cm = new ConnectionManager(port);
cm.start();
}
public static void main(String args›!)
{
int server.sub.-- port;
try
{ // See if the user is using a commandline argument
to
// choose a different port for the service
server.sub.-- port = Integer.parseInt(args›0!,10);
}
catch(Exception e)
{
System.out.println("Defaulting to port " +
DEFAULT.sub.-- PORT);
server.sub.-- port = DEFAULT.sub.-- PORT;
}
new GenericServer(server.sub.-- port);
}
}
// Wait for a connection then act on it
class ConnectionManager extends Thread
{
private static int .sub.-- port;
private static Vector .sub.-- my.sub.-- threads = new Vector(5,2);
private ServerSocket .sub.-- main.sub.-- socket = null;
public ConnectionManager(int port)
{
.sub.-- port = port;
}
public void run()
{
serveRequests();
}
public void sendToAll(String msg){
ServerConnection s;
for(int i = 0; i < .sub.-- my.sub.-- threads.size(); i++){
s = (ServerConnection)(.sub.-- my.sub.-- threads.elementAt(i));
// For each client connected send out message
s.send(msg);
}
}
private void serveRequests()
{
try {.sub.-- main.sub.-- socket = new ServerSocket(.sub.-- port);}
catch(Exception e) { System.err.println(e); System.exit(1);}
ServerConnection temp.sub.-- sc = null;
System.out.println(.sub.-- main.sub.-- socket.toString());
while (true)
{
try
{
Socket this.sub.-- connection =
.sub.-- main.sub.-- socket.accept();
temp.sub.-- sc = new
ServerConnection(this.sub.-- connection, this, .sub.-- my.sub.-- threads.s
ize());
temp.sub.-- sc.start();
.sub.-- my.sub.-- threads.addElement(temp.sub.-- sc);
//clean up the vector if needed
for(int
i=0;i<ConnectionManager..sub.-- my.sub.-- threads.size();i++)
if(|((ServerConnection)(.sub.-- my.sub.-- threads.elementAt(i))).isAlive()
)
.sub.-- my.sub.-- threads.removeElementAt(i);
}
catch(Exception e)
{
System.err.println("Exception: .backslash.n" + e);
}
}
}
}
______________________________________
As described above, the VJ Tool provides a live development or authoring environment in which socialization among objects or components can occur immediately upon their creation or instantation without any wait to plan or test their integration. For example, as shown in FIG. 16, once the output of bicopy object 1308 was connected to text field representation 1604, the output value of scrollbar 1306 was displayed in the physical view 500. If this result is not what was desired, the user can change the connection or add another component on the fly without having to debug code or review a flowchart. Similarly, when the output of splitter 1404 is connected to the input of calculator 1502b and displayed via text field representation 1606, the user is able to make an immediate determination that the conversion calculations are correct and that the displayed arrangement is satisfactory. In other words, being able to make connections on the fly immediately proved or disproved the results obtained because VJ Tool creates a "live" environment wherein applet design creation and trial are integrated so that the result is then played out virtually simultaneously with creation. This is analogous to building a hardware prototype or test board by connecting, disconnecting and moving components around the board while the power is on| Component 542 of FIG. 5 is a folder component in which associated components can be stored to act as templates for other applets to be designed in the future. Say, for example, that a user had designed the specific arrangement shown in FIG. 16 and dragged it as a component assembly into an object folder instantiated from folder 542. That object folder can later be opened and the component assembly stored therein be reused or its calculators modified to display Centigrade versus Kelvin or with slightly more modification to the text and label fields, feet versus meters. In fact, a hierarchy of folders can be built up in this manner. Unl | ||||||
