Component based

System, method and article of manufacture for creating an object oriented component having multiple bidirectional ports for use in association with a java application or applet

6557164

Abstract

Method, system and article of manufacture for creating an object oriented component having multiple bidirectional ports for use with an object oriented based applet or application. The component's ports are all first initialized to a predetermined value and thereafter polled to determine if an input has been coupled to any one of the ports. If it has not, polling continues. If an input is present, all of the component's remaining ports are set to output the same type and value as that of the input. Where appropriate, a check is made to determine if a saved state of the component exists, if it does, the component is initialized to the state type and value rather than the predetermined type and value. When the input is removed, the component ports are all reinitialized to the predetermined type and value and polling for a new input commences.


Claims

What is claimed is:

1. A method of creating an object oriented component having multiple bidirectional ports, the component being used in association with an object oriented applet or application, comprising the steps of:

a) initializing the component ports to a predetermined type and value;

b) polling the ports to ascertain whether an input has been connected to one of the ports; and

c) identifying the type and value of the input once it is coupled to a port.

2. The method according to claim 1 which comprises the additional steps of checking to see if the component has a previously saved state prior to the initializing step and initializing its ports to the state type and value rather than the predetermined type and value if it does.

3. The method according to claim 2 which comprises the additional steps of determining if the input type and value has been removed and reinitializing all of the ports of the component to the predetermined type and value if it has.

4. The method according to claim 3 which comprises the additional steps of determining if the input type and value has been removed and maintaining the other ports at the same type and value as that of the input if it has not.

5. The method according to claim 1 which comprises the additional steps of determining if the input type and value has been removed and reinitializing all of the ports of the component to the predetermined type and value if it has.

6. The method according to claim 5 which comprises the additional steps of determining if the type and input value has been removed and maintaining the other ports at the same type and value as that of the input if it has not.

7. The method according to claim 1 which comprises the additional steps of determining if the type and input value has been removed and maintaining the other ports at the same type and value as that of the input if it has not.

8. A system for creating an object oriented component having multiple bidirectional ports, the component being used in association with an object oriented applet or application said system comprising:

a) an initializer that sets the component's ports to a predetermined type and value;

b) a poller that continuously checks the ports to ascertain whether an input has been connected to one of the ports; and

c) an identifier that establishes and saves the type and value of the input once it is coupled to a port.

9. The system according to claim 8 which additionally comprises a verifier that checks to see if the component has a previously saved state prior to its being initialized and what the state type and value is if a saved state is found and a second initializer to set the components ports to the state type and value rather than the predetermined type and value if a saved state is found.

10. The system according to claim 9 which additionally comprises a second poller that determines if the input has been removed and requests the initializer to reinitialize all of the ports of the component to the predetermined type and value if it has.

11. The system according to claim 10 which additionally comprises a second poller that determines if the input has been removed and requests the initializer to reinitialize all of the, ports of the component to the predetermined type and value if it has not.

12. The system according to claim 8 which additionally comprises a second poller that determines if the input has been removed and requests the initializer to reinitialize all of the ports of the component to the predetermined type and value if it has.

13. The system according to claim 12 which additionally comprises a second poller that determines if the input has been removed and requests the initializer to reinitialize all of the ports of the component to the predetermined type and value if it has not.

14. The system according to claim 8 which additionally comprises a second poller that determines if the input has been removed and requests the initializer to reinitialize all of the ports of the component to the predetermined type and value if it has not.

15. A computer program embodied on a computer-readable medium for creating an object oriented component having multiple bidirectional ports, the component being used in association with an object oriented applet or application, said embodied program comprising:

a) first software that initializes the component ports to a predetermined type and value;

b) second software that polls the ports to ascertain whether an input has been connected to one of the ports; and

c) third software that identifies the type and value of the input once it is coupled to a port.

16. The computer program embodied on a computer-readable medium as recited in claim 15 which additionally comprises fourth software for checking to see if the component has a previously saved state prior to its being initialized, means for determining what the state type and value is and means for initializing the components ports to the state type and value rather than the predetermined type and value if it does.

17. The computer program embodied on a computer-readable medium as recited in claim 16 which additionally comprises fifth software for determining if the input type and value has been removed and reinitializing all of the ports of the component to the predetermined type and value if it has.

18. The computer program embodied on a computer-readable medium ask recited in claim 17 which additionally comprises six software for determining if the input type and value has been removed and maintaining the other ports at the same type and value as that of the input if it has not.

19. The computer program embodied on a computer-readable medium as recited in claim 15 which additionally comprises fourth software for determining if the input type and value has been removed and reinitializing all of the ports of the component to the predetermined type and value if it has.

20. The computer program embodied on a computer-readable medium as recited in claim 19 which additionally comprises fifth software for determining if the input type and value has been removed and maintaining the other ports at the same type and value as that of the input if it has not.


Description

Portions of this patent application include materials that are subject to copyright protection. The copyright owner has no objection to the facsimile reproduction by anyone of the patent document itself, or of the patent application, as it appears in the files of the United States Patent and Trademark Office, but otherwise reserves all copyright rights whatsoever in such included copyrighted materials.

FIELD OF THE INVENTION

This invention generally relates to improvements in computer systems and, more particularly, to an improved object oriented component system having multiple bidirectional ports, which ports can be set to mirror the input type and value applied to one of the ports.

BACKGROUND OF THE INVENTION

Object oriented based programming (OOP) is probably the most arresting, stimulating and intriguing aspect of programming in today's software world. Although it has been available for some time in languages such as Simula and SmallTalk and recently in C++ and Java, OOP has only recently taken hold as the hoped for solution to closing the gap between the theoretical capability of hardware and the general performance of software while simultaneously solving problems left over from prior software development approaches.

In the past, programming development which began with a single procedure approach, evolved to modular programming, went from there to structured programming and then branched off into computer aided software engineering (CASE) and program generators. All of these methodologies, while solving some or many of the difficulties inherent in prior approaches, introduced their own limitations and inefficiencies. Program bloat, data corruption and "spaghetti" code were but a few of the problems that were caused or left unsolved by the aforementioned software development approaches.

In the early days of procedural programming, the programmer called libraries provided by the operating system to perform certain tasks, but basically the program executed down the page from start to finish, and the programmer was solely responsible for the flow of control. This was appropriate for printing out paychecks, calculating a mathematical table, or solving other problems with a program that executed in just one way.

The development of graphical user interfaces began to turn this procedural programming arrangement inside out. These interfaces allow the user, rather than program logic, to drive the program and decide when certain actions should be performed. Today, most personal computer software accomplishes this by means of an event loop which monitors the mouse, keyboard, and other sources of external events and calls the appropriate parts of the programmer's code according to actions that the user performs. The programmer no longer determines the order in which events occur. Instead, a program is divided into separate pieces that are called at unpredictable times and in an unpredictable order. By relinquishing control in this way to users, the developer creates a program that is much easier to use. Nevertheless, individual pieces of the program written by the developer still call libraries provided by the operating system to accomplish certain tasks, and the programmer must still determine the flow of control within each piece after it's called by the event loop. Application code still "Sits on top of" the system.

Even event loop programs require programmers to write a lot of code that should not need to be written separately for every application. The concept of an application framework carries the event loop concept further. Instead of dealing with all the nuts and bolts of constructing basic menus, windows, and dialog boxes and then making these things all work together, programmers using application frameworks start with working application code and basic user interface elements in place. Subsequently, they build from there by replacing some of the generic capabilities of the framework with the specific capabilities of the intended application.

Into to this breach, entered Object-Oriented Programming (OOP) techniques which involve the definition, creation, use and destruction of "objects." Objects are self-sufficient software entities comprising data elements and routines, or functions, sometimes called methods, which are used to manipulate the data elements. The object's data and related functions are: treated by the software as an entity and they can be created, used and deleted as if they were a unitary item. Together, the data and functions enable objects to model virtually any real-world entity in terms of its characteristics, which can be represented by the data elements, and its behavior, which can -be represented by its data manipulation functions. In this way, objects can model concrete things like people and computers, and they can also model abstract concepts like numbers or geometrical designs.

Objects are defined by creating "classes" which are not per se objects themselves, but which act as templates that instruct a compiler how to construct an actual object. A class may, for example, specify the number and type of data variables and the steps involved in the functions which manipulate the data. An object is actually created in the program by means of a special function called a constructor which uses the corresponding class definition and additional information, such as arguments provided during object creation, to construct and initialize the object and its data members. Likewise objects are destroyed by a special function called a destructor. Objects are employed by using their data and invoking their functions to accomplish a task.

The concept of an object is predicated on and the benefits of object-oriented programming techniques arise from the use of three basic principles; those of encapsulation, polymorphism and inheritance. These principles work in conjunction with objects as described below. It is noteworthy to distinguish between an object and a class of objects. A class is a type definition or template used to create objects in programs. The objects so created are then merely each a single instance of the class of objects, which is often just called a class. A class has no memory or behavior of its own except to serve as the blueprint from which objects can be created.

An object is a self-sufficient component that includes both data and function. An object is of the same type as the class from which it has been derived. Objects are said to be instantations of their class and use memory for their data and functions, unlike the class template itself which does not.

Objects can be designed to hide, or encapsulate, all, or a portion of, their internal data structure and internal functions. OOP also allows a programmer to create an object that is a part of another object and thereby define assemblies and sub-assemblies, as may be required by a program or the situation or item it is modeling.

More particularly, during program design, a program developer can define objects in which all or some of the data variables and all or some of the related functions are considered "private" or made available for use only by the object itself. Other data or functions can be declared "public" or available for use by other objects or programs.

Further, access to private variables by other objects or programs can be controlled by defining public functions for an object which access the object's private data.. The public functions form a controlled and consistent interface between the private data and the "outside" world. Any attempt to write program code which directly accesses the private variables causes the compiler to generate an error during program compilation which error stops the compilation process and prevents the program from being run.

Polymorphism is capability to conceal the different implementations behind a common interface. This means that separate objects of the same class can have different internal functions and data and implement received messages differently, but still produce uniform or consistent results. For example, an addition function may be defined as variable A plus variable B (A+B) and this same format can be used whether variables A and B represent numbers, characters or monetary units such as dollars and cents. However, the actual program code which performs the addition may differ widely depending on the type of variables that comprise A and B. Polymorphism allows three separate objects that employ different function definitions to be written, one for each type of variable (numbers, characters and dollars). After the functions have been defined, a program can later refer to the addition function by its common format (A+B) and, during compilation, the OOP based compiler will determine which of the three functions needs to be used by examining the variable types. The compiler will then substitute the proper function code in the object it compiles. Polymorphism allows similar functions that produce analogous results to be "grouped" in the program source code to produce a more logical and clearer program flow.

The third principle which underlies object-oriented programming is that of inheritance. Inheritance allows program developers to easily reuse pre-existing programs or portions thereof to avoid creating software from scratch. The principle of inheritance allows a software developer to declare classes (and the objects which are later created from them) as related. Specifically, classes may be designated as subclasses of base classes. A subclass "inherits" and has access to all of the public functions of its base classes just as if these functions appeared in the subclass. Alternatively, a subclass can override some or all of its inherited functions merely by defining a new function with the same form (overriding or modification does not alter the function in the base class, but merely modifies the use of the function in the subclass). The creation of a new subclass which has some of the functionality (with selective modification) of another class allows software developers to easily customize existing code to meet their particular needs while still taking advantage of reusing prior, usually debugged and well behaved code, rather than having to write and qualify new code of their own.

By utilizing the concepts of encapsulation, inheritance and polymorphism, an object can be made to accurately and independently represent just about anything in our world, real or simulated. In fact, the limits of our logical perceptions of such representation is the only restraint on the kinds of things that can become objects in object-oriented software. Some typical categories are as follows:

Objects can represent physical objects, such as airplanes in an air traffic control system, components in a stereo or television system, balance sheet and income statement elements in a fundamental analysis company business model, or stars in the simulated night sky on display at a planetarium;

Objects can represent elements of the computer-user environment such as windows, scrollbars, sliders, menus or other graphical items;

An object can represent a collection of data, such as a personnel file or a table of the latitudes and longitudes of cities; or

An object can represent user-defined data types such as time, angles, and complex numbers, functions or points on the plane.

While object-oriented programming offers significant improvements over other programming concepts in the design and development of programs, program development and program development tools, even within an OOP environment, still require significant outlays of time and effort. This is particularly true where the developer has to write a significant amount of code from scratch and is unable to take full advantage of the benefits of object oriented programming. The ability of development tools to negate or reduce the need to write code in the traditional sense and permit a developer to concentrate on development and visually interact with an enriched development tool is the focus and goal of the present invention.

It is usually the case that proponents of a particular type of programming language or of a specific language of that type are best able to advance their cause and the popularity and vitality of the language type or specific implementation or dialect of the language they support.

This is usually done by directly or indirectly providing appropriate tools that make use of the language type or a specific implementation of the language easy, practical and efficient. Visual Basic and Visual C++ are examples of two current programming environments with an object oriented foundation that have been developed and made available for programmers to use in creating applications for the Windows 3.x, Windows 95 and Windows NT platforms. While Visual Basic and Visual C++ undoubtedly make program development easier by including tools, called Wizards, that relieve the programmer of the necessity to write the underlying Basic or C++ code needed to create and implement such typical graphical user interface (GUI) elements as scrollbars, sliders, buttons or dialog boxes and to define their properties, these tools do not go far enough in easing the programmer's development burden. For example, it is still necessary in either Visual Basic and Visual C++ for the programmer to write code that defines and controls the interrelationship of the elements selected for use in the program under development or to otherwise manually intercede in the object based "point and click" or "drag and drop" aspects of this program development process.

This is true in the development of general OOP based applications and also in development environments for creating Applets in a JAVA system. As the Java system and applet creation becomes more widely used, the need to simplify the development of these applications becomes desirable. In addition, while the developer in these prior art visual programming environments is given a Wizard that writes the underlying code to make an event involving one or more of the selected elements occur, the ability to simultaneously view and experience that interrelationship is not provided.

It would be desirable to provide the tool's objects or components with a component that can function as a multiplexor wherein an input applied to one of the components bidirectional ports is dynamically duplicated as an output on all the remaining ports of the component.

SUMMARY OF THE INVENTION

The present invention provides a programming environment and appropriate tools and components therefor that promote greater ease of use than is presently available in typical programming environments and wherein an object.

The present invention also provides such a multiport component having multiple bidirectional ports that can be set to duplicate an input thereto on its remaining ports.

The present invention additionally initializes such a multiport component to a predetermined type and value or to the type and value of a saved state if one exists.

The present invention further provides the user with means to utilize such a component in an effective, non-intrusive manner.

The above objectives are achieved by utilizing an object oriented component having multiple bidirectional ports that is adapted for use with an object oriented based applet or application. The component's ports are all first initialized to a predetermined value and thereafter polled to determine if an input has been coupled to any one of the ports. If it has not, polling continues. If an input is present, all of the component's remaining ports are set to output the same type and value as that of the input. Where appropriate, a check is made to determine if a saved state of the component exists if it does, the component is initialized to the state type and value rather than the predetermined type and value. When the input is removed, the component ports are all reinitialized to the predetermined type and value and polling for a new input commences.

BRIEF DESCRIPTION OF THE DRAWINGS

The above and further advantages of the invention may be better understood by referring to the following description in conjunction with the accompanying drawings, in which:

FIG. 1 is a block schematic diagram of a typical computer system, for example, a personal computer system on which inventive object oriented based programming tools or development environment functions can operate in accordance with the present invention;

FIG. 2 depicts a block diagram of a Java platform development tool in accordance with a preferred embodiment;

FIG. 3 illustrates a block diagram showing the initialization process for the Visual Java Tool applet in accordance with a preferred embodiment;

FIG. 4A shows: an example of an illustrative World Wide Web home page as loaded by a Java enabled browser in accordance with a preferred embodiment;

FIG. 4B illustrates the same web page with its main pull-down menu activated in accordance with a preferred embodiment;

FIG. 4C depicts the "Open File" pull-down menu of the home page shown in FIG. 4B in accordance with a preferred embodiment;

FIG. 4D shows the VJ Tool applet after it has been initialized and is ready to run in accordance with a preferred embodiment;

FIG. 5 illustrates the physical or end user view screen portion in accordance with a preferred embodiment;

FIG. 6 shows the creation of a scrollbar which will be used to indicate Centigrade temperatures in an example of how the present invention can be utilized in accordance with a preferred embodiment;

FIG. 6A illustrates registering a component being instantiated;

FIG. 7 visually describes an example of marqueing or sizing of a vertical scrollbar in accordance with a preferred embodiment;

FIG. 8 depicts another example of marqueing or adjusting the size of a vertical scrollbar to a shorter, slightly wider, outline in accordance with a preferred embodiment;

FIG. 9 illustrates an example of a scrollbar object matching the same object in FIG. 8, but created in the logical view in accordance with a preferred embodiment;

FIG. 10 shows the two pin value setting and getting capability of the scrollbar of FIG. 8 in accordance with a preferred embodiment;

FIG. 11 illustrates the addition of a second vertical scrollbar that will be set to track the range of the Fahrenheit temperature scale in accordance with a preferred embodiment;

FIG. 11A is a flowchart of the detailed logic of the editor component in accordance with a preferred embodiment'

FIG. 12 depicts how label text is added to the scrollbars of FIG. 11 to label the scrollbar in accordance with a preferred embodiment;

FIG. 13 shows how text from a label editor has been placed as a label above the first scrollbar of FIG. 11 in accordance with a preferred embodiment;

FIG. 13A illustrates a flowchart for the process by which the bicopy component shown in FIG. 13 functions in accordance with a preferred embodiment;

FIG. 14 illustrates the addition and use of splitters in the logical view in accordnace with in accordance with a preferred embodiment;

FIG. 15 shows the addition of a calculator object to the logical view in accordance with a preferred embodiment;

FIG. 16 depicts an additional calculator and the interconnections of several objects to achieve the appropriate Centigrade/Fahrenheit relationship between scrollbars of FIG. 11 in accordance with a preferred embodiment;

FIG. 16A is a flowchart of the detailed logic for port connection in accordance with a preferred embodiment;

FIG. 17 show the final result of the conecteded scrollbars with correct Fahrenheit and Centigrade temperatures shown in the text fields in accordance with a preferred embodiment;

FIG. 18 is a diagram in block format of an arrangement adapted to provide collaboration between components or portions of components of an applet as designated by the user in accordance with a preferred embodiment;

FIG. 19 presents a flowchart of the collaboration process in accordance with a preferred embodiment;

FIG. 20 illustrates a screen with the logical view in accordance with a preferred embodiment;

FIG. 21 illustrates a screen with the logical and physical view preparing a hierarchial component in accordance with a preferred embodiment;

FIG. 22 illustrates a screen with a connection made for playing a sound in accordance with a preferred embodiment;

FIG. 23 illustrates an edit screen for a folder component utilized to prepare a hierarchial component in accordance with a preferred embodiment;

FIG. 23A illustrates a folder class with options for unidirectional and directional ports and an editor is first created;

FIG. 24 illustrates a hierarchial component creation customization in accordance with a preferred embodiment; and

FIG. 25 illustrates the completed physical view of a hierarchial component in accordance with a preferred embodiment.

DETAILED DESCRIPTION

The invention is preferably practiced in the context of a suitable operating system resident on a workstation or desktop computer, such as a SUN, IBM, PS/2, or Apple, Macintosh, computer. A representative hardware environment is depicted in FIG. 1, which illustrates a typical configuration for a computer system 100 that can be utilized to practice the subject invention. The computer 100 is controlled by a central processing unit 102 (which may be a conventional microprocessor). A number of other units, all interconnected via a system bus 108, are provided to accomplish specific tasks. Although a particular computer may only have some of the units illustrated in FIG. 1, or may have additional components not shown, most computers will include at least the units shown.

Specifically, computer system 100 shown in FIG. 1 includes a random access memory (RAM) 106 for temporary storage of information, a read only memory (ROM) 104 for permanent storage of the computer's configuration and basic operating commands and an input/output (I/O) adapter 110 for connecting peripheral devices such as a disk drive unit 113 and printer 114 to the bus 108, via cables 112 and 115, respectively. A user interface adapter 116 is also provided for connecting input devices, such as a keyboard 120, and other known interface devices including a microphone 124, a mouse 126 and a speaker 128, to the bus 108. Visual output is provided by a display device 122, such as a video monitor, which is connected via display adapter 118 to bus 108. Lastly, a communications adapter 134, connected to bus 108, provides access to a network 136.

The computer 100 has resident thereon and its basic operations are controlled and coordinated by operating system software such as the SUN Solaris, Windows/95, Windows NT or the Java OS operating system. For purposes of the preferred embodiment as described herein, regardless of the operating system being used, computer 100 is provided, at the very least, with the Java run time environment and an optional Just-In-Time (JIT) Java compiler.

In a preferred embodiment, the invention is implemented in the Java programming language, relying substantially on its object-oriented programming techniques. Java is a compiled language, that is, Java based programs are typically written in a human-readable script which script is eventually provided as input to another program called a compiler. The compiler generates a byte code version of the script that can be loaded into, and directly executed by, any computer which contains a Java virtual machine. Java objects are compiled to class files that include bytecodes representative of the original source code program with references to methods and instance variables of the Java objects. The bytecodes are not specific to particular machines or operating systems and don't have to be recompiled or rearranged to run on different hardware/software platforms. Rather, the bytecodes can be run in the Java Virtual Machine or passed to a (JIT) compiler that converts them into native code for a target platform on the fly.

This means that the original Java application or applet bytecode, which isn't specific or native to any one hardware platform or architecture, can be run without recompilation on any hardware or software platform that has a Java Run-Time Environment. In other words, a Java program's native architecture is the Java VM which is or will soon be available in both software and hardware implementations, making Java applications and applets multi-platform capable as long as the target system is Java enabled. As described below, the Java language has certain characteristics which allow a software developer to easily use and reuse programs written by himself or others while still providing a reason for reuse of programs or portions of programs to prevent their destruction or improper use.

Sun's Java language has emerged as an industry-recognized language, not only for "programming the Internet, but also as ". . . a serious programming language capable of tackling the most sophisticated business applications." Sun defines Java as: "a simple, object-oriented, distributed, interpreted, robust, secure, architecture-neutral, portable, high-performance, multithreaded, dynamic, buzzword-compliant, general-purpose programming language. Java supports programming for the Internet in the form of platform-independent Java applets." Java applets are small, specialized applications that comply with Sun's Java Application Programming Interface (API) allowing developers to add "interactive content" to Web documents (e.g. simple animation, page adornments, basic games, etc.). Applets execute within a Java-compatible browser (e.g. Netscape Navigator) by copying code from the server to client. From a language standpoint, Java's core feature set is based on C++. Sun's Java literature states that Java isbasically "C++, with extensions from Objective C for more dynamic method resolution".

Another technology that has function and capability similar to JAVA is provided by Microsoft and its ActiveX technology, to give developers and Web designers the wherewithal to build dynamic content for the Internet and personal computers. ActiveX runs only the so-called Wintel platform (a combination of a version of Windows and an Intel microprocessor), as contrasted with Java which is a compile once, run anywhere language.

ActiveX includes tools for developing animation, 3-D virtual reality, video and other multimedia content. The tools use Internet standards, work on multiple platforms, and are being supported by over one hundred companies. The group's building blocks are called ActiveX Controls, small, fast components that enable developers to embed parts of software in hypertext markup language (HTML) pages. ActiveX Controls work with a variety of programming languages including Microsoft's Visual C++, Borland's Delphi, Microsoft's Visual Basic programming system and, in the future, Microsoft's development tool for Java, code named "Jakarta." ActiveX Technologies also includes ActiveX Server Framework, allowing developers to create server applications. One of ordinary skill in the art will readily recognize that ActiveX and ActiveX components could be substituted for JAVA and its components as their use is described herein without undue experimentation to practice the invention.

Further explanation of the Java programming language, its characteristics and advantages is not deemed necessary. Java is now well-known and many articles and texts are available which describe the language in great detail. In addition, compilers and development kits are commercially available from several vendors including SunSoft Inc., Borland International, Inc. and Microsoft Corporation. Accordingly, for reasons of brevity and clarity, additional details of the Java language and the operation of the Run-Time Environment or the JIT compilers will not be discussed further in herein since this information can be readily obtained elsewhere. One appropriate source can be found in Gosling, Joy & Steele, The Java Language Specification (1996), the disclosure of which is hereby incorporated by reference. Another source for Java VM information is Sun Microsystems' Java Virtual Machine Specification, Release 1.0 Beta DRAFT (Aug. 21, 1995), the disclosure of which is also hereby incorporated by reference.

The arrangement described above concerning the running of Java applets and applications is illustrated in FIG. 2. This block diagram shows how a Java application or applet can-be run on one or more hardware/software platform combinations. The applets can be obtained, along with the static information (text and/or graphics) of the web page they are resident on, by either an ordinary web browser or one that is Java enabled. If the applet is obtained by a non-Java enabled browser, as depicted in block 202, it is passed via connection 203 to the Java Run-Time Environment 206 where the applet code is compiled into Java bytecode class files. The bytecode is then checked for security purposes by the bytecode verifier and then run on the Java VM by the bytecode interpreter to yield Java derived code that can be input to the optional: JIT compiler 208 via connection 207 for conversion to platform native code.

Java source is compiled into bytecodes in an intermediate form instead of machine code (like C, C++, Fortran, etc.) to enable and facilitate portability. The bytecodes execute on any machine with a bytecode interpreter. Thus, Java applets and applications can and do run on a variety of client machines. Further, since the bytecodes are compact and designed to transmit efficiently over a network, Java enhances a preferred embodiment with universal clients and server-centric policies.

The output of the JIT compiler 208 is passed therefrom via connection 209 to a target platform 210. Target platform 210 could be, for example, a Windows combination, a Macintosh System 7/PowerPC combination or a Unix/RISC combination. If the Operating System (OS) of the target platform is Java enabled, that is, if it includes its own Java Run-Time environment, then the Environment 206 output could be passed directly via connector 211 to the target platform 210 avoiding the Java JIT compiler 208 whose services would not be needed.

Alternatively, if an applet is obtained by a Java enabled browser (such as Sun's HotJava, Netscape's Navigator 3.0 or Microsoft's Internet Explorer 3.0) which includes and has already installed the Java Run-Time Environment on the computer where it resides, there is no need to utilize the separate Environment 206. Applets so captured are passed via connector 213 through by the Java enabled browser at 212 to the Java Environment, also logically part of block 212, where such applets are handled as described above in connection with function block 206. Lastly, stand-alone Java applications are passed directly to the Java Environment block 206 where they are handled and processed in a similar manner to the Java applets. The Java applications do not need to be obtained nor do they work in conjunction with a browser. However, if a Java enabled browser is loaded on the developer's hardware, as is probable, a Java application can be passed directly to the browser of function block 212 via connector 215 and handled in the same manner as an applet would have been.

A preferred embodiment of an applet that will be known as the Visual Java Tool (or VJ Tool hereafter) takes the concept of objects and applies it through the entire development system to provide a development or authoring tool that is robust, easy to use and one that minimizes the amount of code a developer needs to write. VJ Tool is described herein in the context of an applet, but as it has been noted, VJ Tool could also be provided as a full application and handled in the manner described above. The user of VJ Tool would not have to be knowledgeable about Java or OOP and could build or create a Java applet or application from scratch just by using VJ Tool in the manner described herein.

FIG. 3 is a block diagram that shows the initialization process for the Visual Java Tool applet in accordance with a preferred embodiment of the invention. The applet 302 is seen by a Java enabled browser 304, such as Sun's HotJava or Netscape's Navigator, via link 305 and then downloaded via connection 303 to the client computer on which the browser resides. Alternatively, the VJ Tool can be obtained from local storage as an application. When browser 304 is activated, it also initializes and makes the Java Run-Time Environment 306 active thereby initiating and readying the Java Virtual Machine for the eventual arrival of an applet.

Once obtained from its web page or local storage, the VJ Tool is itself initialized as shown in block 308 and made ready for interaction with a user, see block 310. Initialization of the applet includes initialization of the desktop (VJContainer) and the web page view (VJDocument). VJContainer and VJDesktop are tightly coupled. VJContainer is a container API. The details of applet initialization for VJ Tool are included in VJContainer and VJDesktop.

For each component, a template is initially used to define the particular characteristics of the component. The template includes a start, stop, initialize, destroy, connect, disconnect, customize (edit), save, load and one or more component specific task methods. These methods are customizable for each of the components so that the sliderbar component has a different disconnect method then a button component. The C++ source code enabling VJContainer is presented below.

    import java.awt.*;
    import java.util.*;
    public class VJContainer extends VJNode {
    // Attributes of this component
    VJDesktop theDesktop = null; // if NOT null the window (frame)
    associated with this container node
                // if null this is a primitive node
    final static int cut = 1;
    final static int copy = 2;
    final static int paste = 3;
    int lastCommand = 0;
    final static String out  = "out_nd.gif";
    final static String in = "in_nd.gif";
    Vector port_info;
    Vector port_name;
    // final static String port1_info = "output from contaner";
    // final static String port1_name = "Pin 1";
    final static String url_name = "container.html";
    final static String info_name = "A VJ Folder or container";
    boolean open;
    int nodeCount;           // the number of nodes
    static int instanceCount = 0;
    // containerNode container;
    // the panel in which contains a hierarchcal node's nodes
    //
    // 1) instantiate a new component on either physical or logical display
    // and an optional customizer (edit) window appears.
    // 2) each customizer (edit) window is defined in the template as a
    // method corresponding to the customizer (edit) method.
    // 3) Properties of the component are dynamically updated based on
    // user interaction with the customizer (edit) window.
    //
    //
    containerEditor edit;
    protected Vector nodes;    // if null this is a primitive node
                       // otherwise the nodes contained in this
    hierarchical node
    int thisInstance;
    static Image normalImage;
    static Image selectedImage;
    VJ vj;
    boolean outConnect[];
    boolean request[];
    boolean outRequest[];
    int outRequestTime[];
    int requestTime[];
    VJNetPin thePin[];
    int nextPort = 0;
    VJContainer theParent;
    // Constructor
    public VJContainer(VJ v){
        super(v);
        vj = v;
    }
    public static void getImages(GIFFactory f){
        normalImage = f.GetGIF("out_nd.gif");
        selectedImage = f.GetGIF("in_nd.gif");
    }
    VJNode dup() {
        return null;
    }
    // Component Initiaiization
    public void VJContainerInit(int x_pt, int y_pt) {
        thisInstance = instanceCount++;
        setName(new String("Container"+String.valueOf(thisInstance)));
        nodes = new Vector();
        outConnect = new boolean[20];
        request = new boolean[20];
        outRequest = new boolean[20];
        outRequestTime = new int[20];
        requestTime = new int[20];
        thePin = new VJNetPin[20];
        for(int k=0; k<20; k++) {
          outConnect[k]=false;
          request[k]=false;
          outRequestTime[k] = 0;
          requestTime[k] = 0;
          thePin[k]=null;
        }
        setNormalIcon("out_nd.gif");
        setSelectedIcon("in_nd.gif");
        setComponentURL("container.html");
        setComponentInfo("A simple VJ container");
        VJNodeInit(true,x_pt,y_pt,false);
        setImages(normalImage,selectedImage); // Pass references to the
    static images down to the node
        theDesktop = new VJDesktop(vj,this);
        theDesktop.pack();
        if(instanceCount==1){
          theDesktop.setTitle("VJ Desktop");
          theDesktop.reshape(10,30,400,640);
          theDesktop.show();
          open = true;
        } else {
          theDesktop.setTitle(getName());
          theDesktop.reshape(instanceCount*20,instanceCount*20,400,460);
            }
            port_info = new Vector();
            port_name = new Vector();
            nodeRect = new Rectangle(x_pt-3,y_pt-3,
          selectedImage.getWidth(vj.theContainer.theDesktop.vp_w)+3,selected
          Image.getHeight(vj.theContainer.theDesktop.vp_w)+3);
          }
          public void addNewPort(VJNetPin addedPin, int i, String info, String
          name){
            port_info.addElement(info);
            port_name.addElement(name);
            thePin[i] = addedPin;
            addedPin.setConnection(i);
            addPort(info,name,VJPort.InputOutput,addedPin.theLocation); //
          Pin 0
          }
          public void setParent(VJContainer p) {
            theParent = p;
          }
          public void request(int port,int time) {
            if(thePin[port]!=null) thePin[port].requestIN(time); else {
            System.out.println("Pin connection problem");
          }
        }
        public void requestOUT(int port,int time) {
          if(outConnect[port]) vj.request(port,time,this);
          else {
          if(outRequest[port]) System.out.println("Losing previous out
        request");
          outRequest[port] = true;
          outRequestTime[port] = time;
        }
    }
    public int componentID() {return 500;}
    public void disconnecting(int port) {
          if(port<20){
            request[port] = false;
            outConnect[port] = false;
            requestTime[port] = 0;
          }
    }
    public void connecting(int port) {
          if(outRequest[port]) {
            outRequest[port] = false;
            vj.request(port,outRequestTime[port],this);
          }
    }
    public void load(String s) {
    }
    public String save() {
        return "";
    }
    public void set(Object o,int port,int time) {
        // System.out.println("set IN port "+port);
        if(port< 20){
          thePin[port].setIN(o,time);
        }
    }
    public void setOUT(Object o,int port,int time) {
        // System.out.println("set OUT port "+port);
        if(port< 20){
          vj.set(o,port,time,this);
        }
    }
    public void propertiesEditor() {
        if(!theDesktop.isShowing().vertline..vertline.!theDesktop.isVisible())
    theDesktop.show();
        if(edit==null && thisInstance > 0){
          edit = new containerEditor((Frame)(vj.theFrame),this);
          edit.pack();
          edit.resize(6*32,6*32);
          edit.show();
        }
    }
    public void init(){
          for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) {
            VJNode vjn = (VJNode) e.nextElement();
            vjn.init();
        }
    };
    public void start(){
        if(open) theDesktop.show();
        for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) {
          VJNode vjn = (VJNode) e.nextElement();
          vjn.start();
        }
    };
    public void stop(){
        if(open) theDesktop.hide();
        for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) {
          VJNode vjn = (VJNode) e.nextElement();
          vjn.stop();
        }
    };
    public void destroy(){};
    public synchronized void addNode(Object o) {
        // System.out.println("Adding node");
        nodes.addElement(o);
    }
    public void doSelectAll(){
        for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) {
          VJNode vjn = (VJNode) e.nextElement();
          vjn.setSelected(true);
        }
        theDesktop.vp_w.repaint();
        vj.theDocument.repaint();
    }
    public void editComponent(){
        for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) {
          VJNode vjn = (VJNode) e.nextElement();
          if(vjn.getSelected()) vjn.propertiesEditor();
        }
    }
    public void doCut(){
        lastCommand = cut;
        vj.nodePasteBoard.removeAllElements();
        getSubnet(true);
    }
    public void doCopy(){
        lastCommand = copy;
        vj.nodePasteBoard.removeAllElements();
        getSubnet(false);
    }
    public void doPaste(){
        int k,vCount=0;
        VJNode theSRCNode = null;
        if(lastCommand==copy){
          vCount = theDesktop.vp_w.container.nodes.size();
        }
        for(Enumeration e = vj.nodePasteBoard.elements() ;
    e.hasMoreElements() ;) {
        VJNode vjn = (VJNode) e.nextElement();
        VJNode vjn_c;
        if(lastCommand==copy) {
          vjn_c = vjn.dup();
          if(vjn_c==null) {
            System.out.println("duplication failed in doPaste");
            return;
          }
          for(k=0; k<vjn.getNumberOfPorts();k++){
            VJNode tn = vjn.getConnectingNode(k);
            if(tn!=null && tn.getSelected()){
              vjn_c.setConnectingPort(k,vjn.getConnectingPort(k));
              vjn_c.setToDraw(k,vjn.getToDraw(k));
            } else {
              vjn_c.setConnectingPort(k,0);
              vjn_c.setConnectingNode(k,null);
              vjn_c.setToDraw(k,false);
            }
          }
          if(vjn.isUINode)
    vj.theDocument.clearLite(vj.theDocument.getGraphics(),vjn.comp.bounds());
        } else {
          vjn_c = vjn;
        }
        theDesktop.vp_w.container.addNode(vjn_c);
        if(vjn_c.isUINode) vj.theDocument.add(vjn_c.comp);
        }
        if(lastCommand==copy){
          int where = vCount;
          for(Enumeration e1 = vj.nodePasteBoard.elements() ;
    e1.hasMoreElements() ;) {
          VJNode vjn1 = (VJNode) el.nextElement();
          for(k=0; k<vjn1.getNumberOfPorts();k++){
            VJNode cn = vjn1.getConnectingNode(k);
            if(cn!=null){
              int m = vj.nodePasteBoard.indexOf(cn);
              if(m>=0)
              try{
                theSRCNode = (VJNode) nodes.elementAt(where);
                VJNode theDSTNode = (VJNode)
    nodes.elementAt(vCount+m);
                theSRCNode.setConnectingNode(k,theDSTNode);
              } catch(Exception e) {
                System.out.println("doPaste "+ e);
              }
            }
          }
          where++;
        }
        for(Enumeration e1 = vj.nodePasteBoard.elements() ;
    e1.hasMoreElements() ;) {
          VJNode vjn1 = (VJNode) e1.nextElement();
            vjn1.setSelected(false);
          }
        }
        theDesktop.vp_w.repaint();
        vj.theDocument.repaint();
        doCopy();
        //DUMP();
    }
    public synchronized void DUMP() {
        for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) {
            VJNode vjn = (VJNode) e.nextElement();
            System.out.print("Node"+vjn.name);
            for(int k=0; k<vjn.getNumberOfPorts();k++){
              System.out.print(" port "+k);
              System.out.print(" XPt["+k+"]="+vjn.getXPt(k));


System.out.print(" YPt["+k+"]="+vjn.getYPt(k)); if(vjn.getToDraw(k))System.out.print(" ToDraw=true"); else System.out.print(" ToDraw=false"); System.out.print(" ctpt "+vjn.getConnectingPort(k)); if(vjn.getConnectingNode(k)==null) System.out.print(" NO cn "); else System.out.print(" cn "+vjn.getConnectingNode(k).name); } System.out.println(" "); } } public synchronized void getSubnet(boolean isCut) { for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) { VJNode vjn = (VJNode) e.nextElement(); if(vjn.getSelected()){ vj.nodePasteBoard.addElement(vjn); if(isCut){ if(vjn.isUINode){ vj.theDocument.clearLite(vj.theDocument.getGraphics(),vjn.comp.bounds()); } theDesktop.vp_w.clearArea(vjn.nodeRect); if(vjn.isUINode){ vj.theDocument.remove(vjn.comp); } } for(int k=0; k<vjn.getNumberOfPorts();k++){ int cp = vjn.getConnectingPort(k); VJNode vj_c = vjn.getConnectingNode(k); if(vj_c!=null && isCut){ Graphics g = theDesktop.vp_w.getGraphics(), int xbeg = vjn.getXPt(k); int ybeg = vjn.getYPt(k); int xend = vj_c.getXPt(cp); int yend = vj_c.getYPt(cp); if(xbeg<xend) { if(ybeg<yend) g.clearRect(xbeg,ybeg,xend-xbeg,yend-ybeg); else g.clearRect(xbeg,yend,xend-xbeg,ybeg-yend); } else { if(ybeg<yend) g.clearRect(xend,ybeg,xbeg-xend,yend-ybeg); else g.clearRect(xend,yend,xbeg-xend,ybeg-yend); } } if(vj_c!=null&&isCut) if(!vj_c.getSelected()){ vj_c.setConnectingNode(cp,null); vj_c.setConnectingPort(cp,0); vj_c.setXPt(cp,0); vj_c.setYPt(cp,0); vj_c.setToDraw(cp,false); vjn.setConnectingNode(k,null); vjn.setConnectingPort(k,0); vjn.setXPt(k,0); vjn.setYPt(k,0); vjn.setToDraw(k,false); } } if(isCut){ if(!nodes.removeElement(vjn)) System.out.println("VJ Error unable remove deleted node"); getSubnet(isCut); return; } } } if(isCut)theDesktop.vp_w.repaint(); } public synchronized void deleteNode() { for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) { VJNode vjn = (VJNode) e.nextElement(); if(vjn.getSelected()){ if(vjn.isUINode){ vj.theDocument.clearLite(vj.theDocument.getGraphics(),vjn.comp.bounds()); } theDesktop.vp_w.clearArea(vjn.nodeRect); if(vjn.isUINode){ vj.theDocument.remove(vjn.comp); } for(int k=0; k<vjn.getNumberOfPorts();k++){ int cp = vjn.getConnectingPort(k); if(cp>=0){ VJNode vj_c = vjn.getConnectingNode(k); { Graphics g = theDesktop.vp_w.getGraphics(); int xbeg = vjn.getXpt(k); int ybeg = vjn.getYPt(k); int xend = vj_c.getXPt(cp); int yend = vj_c.getYPt(cp); if(xbeg<xend) { if(ybeg<yend) g.clearRect(xbeg,ybeg,xend-xbeg,yend-ybeg); else g.clearRect(xbeg,yend,xend-xbeg,ybeg-yend); } else { if(ybeg<yend) g.clearRect(xend,ybeg,xbeg-xend,yend-ybeg); else g.clearRect(xend,yend,xbeg-xend,ybeg-yend); } yj_c.setConnectingNode(cp,null); vj_c.setConnectingPort(cp,-1); vj_c.setXPt(cp,-1); vj_c.setYPt(cp,-1); vj_c.resetToDraw(cp); } } } if(!nodes.removeElement(vjn)) System.out.println("VJ Error unable remove deleted node"); deleteNode(); return; } } theDesktop.vp_w.repaint(); } public synchronized void selectNode() { } public synchronized void drawNet(Graphics g) { Image img; for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) { VJNode vjn = (VJNode) e.nextElement(); if(vjn.getSelected()) img = vjn.getSelectedIcon(); else img = vjn.getNormalIcon(); if(img!=null) theDesktop.drawNode(img,vjn.x,vjn.y); for(int i=0;i<vjn.getNumberOfPorts();1++)HOTSPOTS.drawHotspot(vjn,i,g); //System.out.println("The name = "+vjn.name); } for(Enumeration e1 = nodes.elements() ; e1.hasMoreElements() ;) { VJNode vjn = (VJNode) e1.nextElement(); for(int j=0; j<vjn.getNumberOfPorts(); j++) if(yjn.getToDraw(j)){ g.drawLine(vjn.getXPt(j), vjn.getYPt(j), vjn.getConnectingNode(j).getXPt(vjn.getConnectingPort(j)), vjn.getConnectingNode(j).getYPt(vjn.getConnectingPort(j)) ); } } } public synchronized void resetSelected() { for(Enumeration e = nodes.elements() ; e.hasMoreElements() ;) { VJNode vjn = (VJNode) e.nextElement(); if(vjn.getSelected()){ vjn.setSelected(false); } } } } // end class VJContainer


The source code enabling the container editor for modifying properties of the container is presented below. When a new component is instantiated on either the physical or logical display, an optional customizer (edit) window is presented if a containerEditor method is defined for the component. The customizer (edit) window is defined in the template as a method corresponding to the customizer (edit) method. The method contains the logic facilitating the dynamic definition of properties of the component and the update of the properties based on user interaction with the customizer (edit) window.
    class containerEditor extends Frame
    {
    // Attributes
    VJContainer vjc;
    Button ok;
    Button cancel;
    boolean dirty;
    Panel centerPanel;
    Polygon p_v[ ];
    boolean selected[ ];
    TextField tf;
    public containerEditor (Frame parent,VCContainer 1)
     {
        super("Click to select pins");
        vjc = 1;
          setBackground(Color.lightGray);
        setLayout(new BorderLayout( ));
        Panel p = new Panel( );
        Panel n = new Panel( );
        n.add(new Label("Name"));
        tf = new TextField(vjc.getName( ));
        n.add(tf);
        add("North",n);
        centerPanel = new Panel( );
        p_v = new Polygon[20];
        selected = new boolean[20];
        for(int m=0; m<20;m++) if(vjc.thePin[m]!=null) selected[m]=true;
    else selected[m]=false;
        p.add(new Button("OK"));
        p.add(new Button("Cancel"));
        add("South",p);
        int xport[ ] = new int[5];
        int yport[ ] = new int[5];
        int xStart = 90-1;
        int yStart = 45-1;
        int x,y;
        int i_width =
    (vjc.normalImage.getWidth(vjc.vj.theContainer.theDesktop.vp_w))*3-6;
        int i_height =
    (vjc.normalImage.getHeight(vjc.vj.theContainer.theDesktop.vp_w))*3-6;
        for(int direction=0; direction<4; direction++)
          for(int k = 0; k<5; k++) {
            switch(direction){
              case 0: x = xStart+7+i_width;
                y = yStart+3+k*(i_height/4);
                break;
              case 1: x = xStart+3+k*(i_width/4);
                y = yStart;
                break;
              case 2: x=xStart;
                y = yStart+3+k*(i_height/4);
                break;
              default: x = xStart+3+k*(i_width/4);
                y = yStart+i_height+7;
                break;
            }
            for(int i=0;i<5;i++){
              xport[i] = HOTSPOTS.IOx_offset[direction][i]+x;
              yport[i] = HOTSPOTS.IOy_offset[direction][i]+y;
            }
            p_v[k+direction*5] = new Polygon(xport,yport,5);
          }
    }
    public void paint(Graphics g){
    g.drawImage(vjc.normalImage,90,45,vjc.normalImage.getWidth(vjc.vj.t
    heContainer.theDesktop.vp_w)*3,
    vjc.normalImage.getHeight(vjc.vj.theContainer.theDesktop.vp_w)*3,
            this);
        for(int k=0;k<20;k++) if(selected[k]) g.fillPolygon(p_v[k]);
                else g.drawPolygon(p_v[k]);
    }
    public boolean handleEvent(Event evt)
        { int k,x,y;
         switch(evt.id){
          case Event.MOUSE_DOWN:
            for(k=0;k<20;k++)
    if(p_v[k].getBoundingBox( ).inside(evt.x,evt.y)) {
             selected [k]=!selected[k];
    repaint(p_v[k].getBoundingBox( ).x,p_v[k].getBoundingBox( ).y,p_v[k].get
    BoundingBox( ).width,p_v[k].getBoundingBox( ).height);
            }
            return true;
            case Event.ACTION_EVENT:
            if("OK".equals(evt.arg))  {
              vjc.edit = null;
              vjc.setName(tf.getText( ));
              vjc.theDesktop.setTitil(tf.getText( ));
              vjc.resetSelected( );
              int nextPort = 0;
              for(int direction=0; direction <4; direction++)
               for(k = 0; k<5; k++) {
               switch(direction){
                case 0: x = 290;
                      y = 100+k*(200/4);
                      break;
                case 1: x = 50+k*(200/4);
                      y = 70;
                      break;
                case 2: x = 10;
                      y = 100+k*(200/4);
                      break;
                default: x = 50+k*(200/4);
                      y = 340;
                      break;
               }
    if(selected [k+direction*5]&&vjc.thePin[k+direction*5]==null){
                VJNetPin vjnp = new VJNetPin(vjc.vj);
                vjnp.setContainer(vjc);
                vjnp.theLocation = k+direction*5;
                vjc.addNewPort(vjnp,nextport++, "fred", "jim");
                vjnp.VJNetPinInit(x,y);
                vjnp.init( );
                vjc.addNode((Object)vjnp);
                vjnp.setSelected(true);
               }
              }
              vjc.theDesktop.show( );
              vjc.open = true;
              vjc.theParent.theDesktop.vp_w.repaint( );
               dispose( );
               return true;
              }
             if("Cancel".equals(evt.arg)){
              vjc.edit = null;
              vjc.theDesktop.show( );
              dispose( );
              return true;
              }
              return false,
            default
                return false;
          }
    }
    } // end class containerEditor
    class HOTSPOTS extends Object {
          final static int Ix_offset[][] = { {0,4,4,0},
     {0,4,-4,0},{0,-4,-4,0},{0,-4,4,0}};
          final static int Iy_offset[][] = { {0,4,-4,0},
     {0,-4,-4,0},{0,-4,4,0},{0,4,4,0}};
          final static int Ox_offset[][] = { {0,0,4,0,0},
     {0,4,0,-4,0},{0,0,-4,0,0},{0,4,0,-4,0}};
          final static int Oy_offset[][] = { {0,4,0,-4,0},
     {0,0,-4,0,0},{0,-4,0,4,0},{0,0,4,0,0}};
          final static int IOx_offset[][] = { {0,4,8,4,0},
     {0,4,0,-4,0},{0,-4,-8,-4,0},{0,-4,0,4,0}};
          final static int IOy_offset[][] = { {0,4,0,-4,0},
     {0,-4,-8,-4,0},{0,-4,0,4,0},{0;4,8,4,0}};
          final static int xport[] = new int[5];
          final static int yport[] = new int[5];
          final staticint East  = 0;
          final static int North = 1;
          final static int South = 3;
          final static int West  = 2;
        public HOTSPOTS( ) { }
         public static int getSide(int i){
         if(i<5) return East; //North;
         if(i<10) return North; //South;
         if(i<15) return West; //East;
         return South; //West;
        }
        public static void drawHotspot(VJNode node, int 1, Graphics g){
          Dimension hotSpot = new Dimension( );
          hotSpot = getHotspot(node.nodeRect,node.x-1,node y-
    1,node.getPortLocation(1));
          int direction = getSide(node.getPortLocation(1));
          int port_type = node.getPortType(1);
          int x = hotSpot.width;
          int y = hotSpot.height;
          int i;
          switch(port_type){
           case 0:
            for(i=0;i<4;i++)
             xport[i] = Ix_offset[direction][i]+x;
             yport[i] = Iy_offset[direction][i]+y;
            };
           break;
          case 1:
            for(i=0;i<5;i++)
             xport[i] = Ox_offset[direction][i]+x;
             yport[i] = Oy_offset[direction][i]+y;
            };
            break;
          case 2:
            for(i=0;i<5;i++)
             xport[i] = IOx_offset[direction][i]+x;
             yport[i] = IOy_offset[direction][i]+y;
            };
            break;
          default: System.out.println("Unknown type "+port_type); break;
        }
        if(port_type==0)
          g.drawPolygon(xport,yport,4);
        else
          g.drawPolygon(xport,yport,5);
    }
    // public static Dimension getHotSpot(VJNode node,int location){
     public static Dimension getHotSpot(Rectangle nRect,int xNode,int
    yNode, int location){
    //      int xNode = node.x;
    //      int yNode = node.y;
    //      Rectangle nRect = node.nodeRect;
          int left = (nRect.width+1)/4;
          int center = (nRect.width+1)/2;
          int right = center+left;
          int top = (nRect.height+1)/4;
          int middle = (nRect.height+1)/2;
          int bottom = top+middle;
          int x,y;
           switch(location){
            case VJPort.NorthLeft:   x = xNode;
    y=yNode; break;
            case VJPort.NorthLeftCenter:   x = xNode+left;
    y=yNode; break;
            case VJPort.NorthCenter:   x = xNode+center;
    y=yNode; break;
            case VJPort.NorthRightCenter:   x = xNode+right;
    y=yNode; break;
            case VJPort.NorthRight:   x = xNode+nRect.width;
    y=yNode; break;
            case VJPort.SouthLeft:   x = xNode;
    y=yNode+nRect.height; break;
            case VJPort.SouthLeftCenter:   x = xNode+left;
    y=yNode+nRect.height; break;
            case VJPort.SouthCenter:   x = xNode+center;
    y=yNode+nRect.height; break;
            case VJPort.SouthRightcenter:   x = xNode+right;
    y=yNode+nRect.height; break;
            case VJPort.SouthRight:   x = xNode+nRect.width;
    y=yNode+nRect.height; break;
            case VJPort.EastTop:   x = xNode+nRect.width;
    y=yNode; break;
            case VJPort.EastTopCenter:   x = xNode+nRect.width;
    y=yNode+top; break;
            case VJPort.EastCenter:   x = xNode+nRect.width;
    y=yNode+middle; break;
            case VJPort.EastBottomCenter:   x = xNode+nRect.width;
    y=yNode+bottom; break;
            case VJPort.EastBottom:   x = xNode+nRect.width;
    y=yNode+nRect.height; break;
            case VJPort.WestTop:   x = xNode;
    y=yNode; break;
            case VJPort.WestTopCenter:   x = xNode;
    y=yNode+top; break;
            case VJPort.WestCenter:   x = xNode;
    y=yNode+middle; break;
            case VJPort.WestBottomCenter:   x = xNode;
    y=yNode+bottom; break;
            default:      x = xNode;
    y=yNode+nRect.height; break; /*
            case VJPort.NorthLeft:   x = xNode;
    y=yNode; break;
            case VJPort.NorthLeftCenter:   x = xNode+left;
    y=yNode; break;
            case VJPort.NorthCenter:   x = xNode+center;
    y=yNode; break;
            case VJPort.NorthRightCenter:   x = xNode+right;
    y=yNode; break;
            case VJPort.NorthRight:   x = xNode+nRect.width;
    y=yNode; break;
            case VJPort.SouthLeft:   x = xNode;
    y=yNode+nRect.height; break;
            case VJPort.SouthLeftCenter:   x = xNode+left;
    y=yNode+nRect.height; break;
            case VJPort.SouthCenter:   x = xNode+center;


y=yNode+nRect.height; break; case VJPort.SouthRightCenter: x = xNode+right; y=yNode+nRect.height; break; case VJPort.SouthRight: x = xNode+nRect.width; y=yNode+nRect.height; break; case VJPort.EastTop: x = xNode+nRect.width; y=yNode; break; case VJPort.EastTopCenter: x = xNode+nRect.width; y=yNode+top; break; case VJPort.EastCenter: x = xNode+nRect.width; y=yNode+middle; break; case VJPort.EastBottomCenter: x = xNode+nRect.width; y=yNode+bottom; break; case VJPort.EastBottom: x = xNode+nRect.width; y=yNode+nRect.height; break; case VJPort.WestTop: x = xNode; y=yNode; break; case VJPort.WestTopCenter: x = xNode; y=yNode+top; break; case VJPort.WestCenter: x = xNode; y=yNode+middle; break; case VJPort.WestBottomCenter: x = xNode; y=yNode+bottom; break; default: x = xNode; y=yNode+nRect.height; break;*/ } return new Dimension(x,y); } } VJDesktop is coded as follows: import java.util.*; import java.awt.*; public class VJDesktop extends Frame{ final String FILEMENU = "File"; final String NEWMENUITEM = "New"; final String OPENMENUITEM = "Open . . ."; final String SAVEMENUITEM = "Save"; final String SAVEASMENUITEM = "Save As . . ."; final String CLOSEMENUITEM = "Close"; final String EXITMENUITEM = "Exit"; final String SEPARATORMENUITEM = "--"; final String INFOMENUITEM = "View catalogue entry for current component . . . "; final String EDITMENU = "Edit"; final String UNDOMENUITEM = "Undo"; final String EDITMENUITEM = "Edit Component"; final String CUTMENUITEM = "Cut"; final String COPYMENUITEM = "Copy"; final String PASTEMENUITEM = "Paste"; final String ALLMENUITEM = "Select All"; final String CLEARMENUITEM = "Clear All"; final String APPLETMENU = "Environment"; final String RESETMENUITEM = "Reset all components"; final String COMPILEMENUITEM = "Create standalone applet"; final String HELPMENU = "Help"; final String ABOUTMENUITEM = "About Visual Java"; final String HELPTOPICSMENUITEM = "Help Topics"; final static String EMPTY = " "; Image in_controls[ ] = new Image[21]; Image out_controls[ ] = new Image[21]; Image xy,wh; int current; int cnt; Toolbar tools; int status=0; containerNode vp_w; VJContainer container; VJ applet_w; boolean editorOpen=false; String user = EMPTY; String password = EMPTY; Vector nodePasteBoard; public VJDesktop(VJ v, VJContainer n) { Panel centerPanel = new Panel( ); applet_w = v; container = n; MenuBar mb = new MenuBar( ); Menu m = new Menu(FILEMENU); m.add(new MenuItem(NEWMENUITEM)); m.add(new MenuItem(OPENMENUITEM)); m.add(new MenuItem(SAVEMENUITEM)); m.add(new MenuItem(SAVEASMENUITEM)); m.add(new MenuItem(SEPARATORMENUITEM)); m.add(new MenuItem(CLOSEMENUITEM)); m.add(new MenuItem(EXITMENUITEM)); mb.add(m); Menu m1 = new Menu(EDITMENU ); m1.add(new MenuItem(UNDOMENUITEM)); m1.add(new MenuItem(SEPARATORMENUITEM)); m1.add(new MenuItem(CUTMENUITEM)); m1.add(new MenuItem(COPYMENUITEM)); m1.add(new MenuItem(PASTEMENUITEM)); m1.add(new MenuItem(ALLMENUITEM)); m1.add(new MenuItem(CLEARMENUITEM)); m1.add(new MenuItem(EDITMENUITEM)); mb.add(m1); Menu m2 = new Menu(APPLETMENU); m2.add(new MenuItem(INFOMENUITEM)); m2.add(new MenuItem(RESETMENUITEM)); m2.add(new MenuItem(COMPILEMENUITEM)); mb.add(m2); Menu m3 = new Menu(HELPMENU); m3.add(new MenuItem(ABOUTMENUITEM)); m3.add(new MenuItem(SEPARATORMENUITEM)); m3.add(new MenuItem(HELPTOPICSMENUITEM)); mb.add(m3); setMenuBar(mb); tools = new Toolbar(applet_w,true); doImages( ); add("West",tools); vp_w = new containerNode(applet_w, container); add("Center",vp_w); setBackground(new Color(0,190,255)); } public void paint(Graphics g) { int h_off,v_off if(appletpgd p13 pk w.isMicrosoft){ h_off = 0; v_off=0; } else { h_off=insets( ).left; v_off=insets( ).top; } for(int i=0;i<cnt;i++) int h = (i%12)*23+h_off int v =(i/12)*22+v_off if(i == current && i <= (cnt-1)) g.drawImage(in controls[i] ,h,v,this); else g.drawImage(out controls[i],h,v,this); } } public boolean handleEvent(Event evt) { int h,v; if (evt.id == Event.ACTION_EVENT){ if (evt.target instanceof MenuItem) { String label = (String)evt.arg; if (label.equals(NEWMENUITEM)) { } else if (label.equals(OPENMENUITEM)) { } else if (label.equals(SAVEMENUITEM)) { } else if (label.equals(SAVEASMENUITEM)) { } else if (label.equals(CLOSEMENUITEM)) { if(container.thisInstance>0) { container.open = false; hide( ); } } else if (label.equals(EXITMENUITEM)) { } else if (label.equals(INFOMENUITEM)) { } else if (label.equals(UNDOMENUITEM)) { doPaste( ); } else if (label.equals(CUTMENUITEM)) { doCut( ); } else if (label.equals(COPYMENUITEM)) { doCopy( ); } else if (label.equals(PASTEMENUITEM)) { doPaste( ); } else if (label.equals(ALLMENUITEM)) { do SelectAll( ); } else if (label.equals(CLEARMENUITEM)) { do SelectAll( ); doCut( ); } else if (label.equals(EDITMENUITEM)) { editComponent( ); } else if (label.equals(RESETMENUITEM)) { } else if (label.equals(COMPILEMENUITEM)) { } else if (label.equals(ABOUTMENUITEM)) { } else if (label.equals(HELPTOPICSMENUITEM)) { } return true; } } if (evt.id == Event.WINDOW_DESTROY) { return true; } if (evt.id==Event.MOUSE_EXIT){ } if (evt.id==Event.MOUSE MOVE){ } if (evt.id==Event.MOUSE DOWN){ } //System.out.print(evt.toString( )); return super.handleEvent(evt); } public void doSelectAll( ){ if(applet_w.loading) { System.out.println("Loading VJ"); return; } container.doSelectAll( ); } public void doCut( ){ if(applet_w.loading) { System.out.println("Loading VJ"); return; } container.doCut( ); } public void editComponent( ){ if(applet_w.loading) { System.out.prinfln("Loading VJ"); return; } container.editComponent( ); } public void doCopy( ){ if(applet_w.loading) { System.out.println("Loading VJ"); return; } container.doCopy( ); } public void doPaste( ){ if(applet_w.loading) { System.out.println("Loading VJ"); return; } container.doPaste( ); } public void doImages( ) GiFFactory factory = new GiFFactory(applet_w); VJCInterface.getImages(factory); VJContainer.getImages(factory); VJNetPin.getImages(factory); VJPlus.getImages(factory); VJBiCopy.getImages(factory); VJEquals.getImages(factory); VJConstant.getImages(factory); VJRandom.getImages(factory); VJCounter.getImages(factory); VJURLOpener.getImages(factory); VJSplit.getImages(factory); tools.addItem(factory.GetGIF("in_cu.gif"),factory.GetGIF("out_cu.gif")); tools.addItem(VJContainer.selectedImage,VJContainer.normalImage); //tools.addItem(VJNetPin.selectedImage,VJNetPin.normalImage); tools.addItem(VJPlus.selectedImage,VJPlus.normalImage); tools.addItem(VJBiCopy.selectedImage,VJBiCopy.normalImage); tools.addItem(VJEquals.selectedImage,VJEquals.normalImage); tools.addItem(VJCon tant.selectedImage,VJConstant.normalImage); tools.addItem(VJRandom.selectedImage,VJRandom.normalImage); tools.addItem(VJCounter.selectedImage,VJCounter.normalImage); tools.addItem(VJURLOpener.selectedImage,VJURLOpener.normalImag e); tools.addItem(VJSplit.selectedImage,VJSplit.normalImage); } public String deskInfo(int ii){ switch(ii){ case 3: return "GGGG"; //VJButton.quickinfo; default: return EMPTY; } } public String browserInfo(int ii){ switch(ii) { case 3: return "KKKKKKK"; //VJTextField.quick_info; default: return EMPTY; } } public void update(Graphics g) { paint(g); } public void drawNode(Image img,int x, int y){ vp_w.drawNode(img,x,y); } } class containerNode extends Panel boolean marquee; boolean drag; boolean connecting; boolean disconnecting; int xbeg,xend,ybeg,yend; int left,top;right,bottom; int xleft,xright,ytop,ybottom; int current_i; int current_port; int portInfo; VJNode current_node; int current_comp_node; int downType; int inset_h,inset_v; boolean firstTime = true; boolean portInfoDrawn = false; boolean nodeInfoDrawn = false; static long lastTime=0; VJ app; VJContainer container; public containerNode(VJ v, VJContainer n) { super( ); setLayout(null); disconnecting = false; app = v; container = n; } public boolean closeEnough(int fx, int ft,int x, int y,int epsilon){ return x <fx+epsilon && x >fx-epsilon && y <fy+epsilon && y >fy-epsilon; } public void doNodeSelection(VJNode vjn,boolean cntDwn,int x, int y){ if(!cntDwn) { beginDrag(x,y); if(!vjn.getSelected( )) { app.theDocument clearlight(app.theDocument.getGraphics( )); container.resetSelected( ); // reset all nodes in container to unselected vjn.setSelected(true); // select the current node app.theDocument.highlight(app.theDocument.getGraphics( )); } current_node = vjn; repaint( ); } else {

if(vjn.getSelected( )) { Rectangle r = vjn.nodeRect; vjn.setSelected(false); if(vjn.isUINode) app.theDocument.clearLite(app.theDocument.getGraphics( ),vjn.comp. bounds( )); getGraphics( ).clearRect(r.x-4,r.y-4,r.width+12,r.height+12); for(Enumeration e2 = container.nodes.elements( ) e2.hasMoreElements( ) ;) { VJNode vjn2 = (VJNode) e2.nextElement( ); if(vjn2.getSelected( )) { repaint( ); return; } } } else { vjn.setSelected(true); if(vjn.isUINode) app.theDocument.drawLite(app.theDocument.getGraphics( ),vjn.comp. bounds( )); repaint( ); return; } } } public VJNode onNode(int x, int y){ for(Enumeration e = container.nodes.elements( ) e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.nodeRect.inside(x,y)) { // System.out.println("On node "+vjn.name), return vjn; } } return null; } public VJNode onPort(int x, int y){ Dimension d; current_port = -1; for(Enumeration e = container.nodes.elements( ); e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); for(int k=0; k<vjn.getNumberOfPorts( );k++){ d= HOTSPOTS.getHotSpot(vjn.nodeRect,vjn.x,vjn.y,vjn.getPortLocation(k)) ; if(closeEnough(d.width,d.height,x,y,8)){ //System.out.println("On port ="+k+" of Node "+vjn.name); current_port = k; return vjn; } } } return null; } public boolean bigEnough( ){ return xbeg-yend !=0 && ybeg-xbeg!=0; } public void beginConnection(int x, int y){ VJNode cn_beg; int cp_beg; connecting = true; if(disconnecting){ if(current_node == null .vertline. .vertline. current_port== -1){ System.out.printin("VJDesktop/doNodeSelection node or port not set"); return; // May need to do more work before/after return } cn_beg = current_node.getConnectingNode (current_port); cp_beg = current_node.getConnectingPort(current_port); if(cn_beg==null) System.out.println("How can we be disconnecting ?"); xbeg = cn_beg.getXPt(cp_beg); ybeg = cn_beg.getYPt(cp_beg); xend = current_node.getXPt(current_port); yend = current_node.getYPt(current_port); } else { xbeg = x ; ybeg = y ; xend = x ; yend = y ; Graphics g = getGraphics( ); g.setXORMode(Color.white); g.drawLine(xbeg, ybeg, xend ,yend); } } public void doConnection(int x, int y){ // System.out.println("DO CONNECTION"); Graphics g = getGraphics( ); g.setXORMode(Color.white); g.drawLine(xbeg, ybeg, xend ,yend); xend = x ; yend = y ; g.drawLine(xbeg, ybeg, xend ,yend); } public void endConnection(int x, int y){ int srcPort; VJNode srcNode; //System.out.println("END CONNECTION"); Graphics g = getGraphics( ); g.setXORMode(Color.white); g.drawLine(xbeg, ybeg, xend ,yend); xend = x ; yend = y ; connecting = false; srcNode = current_node; if(srcNode==null) System.out.println("srcNode =null?"); srcPort = current_port; current_node=onPort(x,y); VJNode vj_c = srcNode.getConnectingNode(srcPort); if(vj_c==null) System.out.println("vj_c =null?"); int vj_p = srcNode.getConnectingPort(srcPort); if(disconnecting && current_node==null){ int xb = srcNode.getXPt(srcPort); int xe = vj_c.getXPt(vj_c.getConnectingPort(srcPort)); int yb = srcNode.getYPt(srcPort); int ye = vj_c.getYPt(vj_c.getConnectingPort(srcPort)); if(xb < xe) { i(yb < ye) g.clearRect( xb-2, yb-2, xe - xb+4, ye - yb+4 ); else g.clearRect( xb-2, ye-2, xe - xb+4, yb - ye+4 ); } else { if(yv < ye) g.clearRect( xe-2, yb-2, xb - xe+4, ye - yb+4 ); else g.clearRect( xe-2, ye-2, xb - xe+4, yb - ye+4 ); } vj_c.disconnecting(srcNode.getconnectingPort(srcPort)); srcNode.disconnecting(srcPort); vj_c.setConnectingNode(srcNode.getConnectingPort(srcPort),null); vj_c.setConnectingPort(vj_p,0); vj_c.setXPt(vj_p,0); vj_c.setYPt(vj_p,0); vj_c.setToDraw(vj_p,false); srcNode.setToDraw(srcPort,false); srcNode.setConnectingNode(srcPort,null); srcNode.setConnectingPort(srcPort,0) srcNode.setXPt(srcPort,0); srcNode.setYPt(srcPort,0); disconnecting = false; return; } if(current_node!=null && compatible(srcNode,srcPort,current node,current_port)) { if(disconnecting){ int xb = srcNode.getXPt(srcPort); int xe = vj_c.getXPt(vj_p); int yb = srcNode.getYPt(srcPort); int ye = vj_c.getYPt(vj_p); if(xb < xe) { i(yb < ye) g.clearRect( xb-2, yb-2, xe - xb+4, ye - yb+4 ); else g.clearRect( xb-2, ye-2, xe - xb+4, yb - ye+4 ); } else { if(yb < ye) g.clearRect( xe-2, yb-2, xb - xe+4, ye - yb+4 ); else g.clearRect( xe-2, ye-2, xb - xe+4, yb - ye+4 ); } vj_c.setConnectingNode(vj_p,current_node); vj_c.setConnectingPort(vj_p,current_port); vj_c.setToDraw(vj_p,true); current_node.setConnectingNode(current port,vj_c); current_node.setConnectingPort(current_port,vj_p); current_node.setXPt(current_port,xend); current_node.setYPt(current_port,yend); current_node.resetToDraw(current_port); vj_c.connecting(vj_p); current_node.connecting(current_port); srcNode.disconnecting(srcPort); srcNode.resetToDraw(srcPort); srcNode.setConnectingNode(srcPort,null); srcNode.setConnectingPort(srcPort,0); srcNode.setXPt(srcPort,0); srcNode.setYPt(srcPort,0); disconnecting = false; g.drawLine(xbeg, ybeg, xend ,yend); return; } srcNode.setConnectingNode(srcPort, current_node); srcNode.setConnectingPort(srcPort,current_port); srcNode.setXPt(srcPort,xbeg); srcNode.setYPt(srcPort,ybeg); srcNode.setToDraw(srcPort,true); current_node.setConnectingNode(current_port,srcNode); current_node.setConnectingPort(current_port,srcPort); current_node.setXPt(current_port,xend); current_ndde.setYPt(current_port,yend); current_node.connecting(current_port); srcNode.connecting(srcPort); g.drawLine(xbeg, ybeg, xend ,yend); } } public void doAllConnects( ){ } public boolean compatible(VJNode sn, int sp, VJNode dn, int dp){ if(disconnecting){ VJNode cn_s = sn.getConnectingNode(sp); int cp_s = sn.getConnectingPort(sp); if(cn_s.getPortType(cp_s)==VJPort.Input && dn.getPortType(dp)== VJPort.Input) return false; if(cn_s.getPortType(cp_s)==VJPort.Output && dn.getPortType(dp)== VJPort.Output) return false; } else { if(sn.getPortType(sp)==VJPort.Input && dn.getPortType(dp)== VJPort.Input) return false; if(sn.getPortType(sp)==VJPort.Output && dn.getPortType(dp)== VJPort.Output) return false; } if(sn==dn && sp==dp) return false; if(isConnected(dn,dp)) return false; return true; } public boolean isConnected(VJNode node,int port){ return node.getconnectingNode(port)!=null; } public void beginMarquee(int x, int y){ //System.out.println("BEGIN MARQUEE"); marquee = true; xbeg = x ; ybeg = y ; xend = x ; yend = y ; marquee = true; Graphics g = getGraphics( ); g.setXORMode(Color.white); g.drawRect( xbeg, ybeg, 0, 0 ); } public void doMarquee(int x, int y){ //System.out.println("DO MARQUEE"); Graphics g = getGraphics( ); g.setXORMode(Color.white); if(xbeg < xend) { i(ybeg < yend) g.drawRect( xbeg, ybeg, xend - xbeg, yend - ybeg ); else g.drawRect( xbeg, yend, xend - xbeg, ybeg - yend ); } else { if(ybeg < yend) g.drawRect( xend, ybeg, xbeg - xend, yend - ybeg ); else g.drawRect( xend, yend, xbeg - xend, ybeg - yend ); } xend = x ; yend = y ; if(xbeg < xend) { if(ybeg < yend) g.drawRect( xbeg, ybeg, xend - xbeg, yend - ybeg ); else g.drawRect( xbeg, yend, xend - xbeg, ybeg - yend ); } else { if(ybeg < yend) g.drawRect( xend, ybeg, xbeg - xend, yend - ybeg ); else g.drawRect( xend, yend, xbeg - xend, ybeg - yend ); } public void endMarquee(int x, int y){ int j,i,t,l,b,r; boolean emptySelect; //System.out.println("END MARQUEE"); Graphics g = getGraphics( ); g.setXORMode(Color.white); if(xbeg < xend){ if(ybeg < yend) g.drawRect( xbeg, ybeg, xend - xbeg, yend - ybeg ); else g.drawRect( xbeg, yend, xend - xbeg, ybeg - yend ); } else { if(ybeg < yend) g.drawRect( xend, ybeg, xbeg - xend, yend - ybeg ); else g.drawRect( xend, yend, xbeg - xend, ybeg - yend ); } xend = x ; yend = y ; marquee = false; emptySelect = true; if(xbeg < x && ybeg < y) { t = ybeg;

l = xbeg; b = y; r = x; } else if(xbeg < x && ybeg > y) { t = y; l = xbeg; b = ybeg; r = x; } else if(xbeg > x && ybeg < y){ t = ybeg; l = x; b = y; r = xbeg; } else { t = y; l = x; b = ybeg; r = xbeg; } Rectangle r1 = new Rectangle(1,t,r-1,b-t); for(Enumeration e = container.nodes.elements( ) ; e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.nodeRect.intersects(r1)){ if(vjn.getSelected( )) { vjn.setSelected(false); // set current selection here if(vjn.isUINode) app.theDocument.clearLite(app.theDocument.getGraphics( ),vjn.comp. bounds( )); } else vjn.setSelected(true); emptySelect = false; } } app.theDocument.repaint( ); //if(emptySelect) container.resetSelected( ); repaint( ); } public void beginDrag(int x, int y){ //System.out.println("BEGIN DRAG"); xbeg = x ; ybeg = y ; xend = x ; yend = y ; Graphics g = getGraphics( ); g.setXORMode(Color.white); for(Enumeration e = container.nodes.elements( ) ; e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.getSelected( )) { g.drawRect(vjn.nodeRect.x,vjn.nodeRect.y, vjn.nodeRect.width,vjn.nodeRect.height); drag = true; } } } public void doDrag(int x, int y){ //System.out.println("DO DRAG"); Graphics g = getGraphics( ); g.setXORMode(Color.white); for(Enumeration e = container.nodes.elements( ) ; e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.getSelected( )) g.drawRect(vjn.nodeRect.x+xend-xbeg,vjn.nodeRect.y+yend- ybeg, vjn.nodeRect.width,vjn.nodeRect.height); } xend = x ; yend = y ; for(Enumeration e = container.nodes.elements( ) ; e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.getSelected( )) g.drawRect(vjn.nodeRect.x+xend-xbeg,vjn.nodeRect.y+yend- ybeg, vjn.nodeRect.width,vjn.nodeRect.height); } } public void endDrag(int x, int y){ int i; //System.out.println("END DRAG"); Graphics g = getGraphics( ); g.setXORMode(Color.white); for(Enumeration e = container.nodes.elements( ) ; e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.getSelected( )) g.drawRect(vjn.nodeRect.x+xend-xbeg,vjn.nodeRect.y+yend- ybeg, vjn.nodeRect.width,vjn.nodeRect.height); } g.clearRect(0,60,bounds( ).width,bounds( ).height-60); // Clear Everthing for(Enumeration e = container.nodes.elements( ) ; e.hasMoreElements( ) ;) { VJNode vjn = (VJNode) e.nextElement( ); if(vjn.getSelected( )){ if(y>60+inset_v){ vjn.nodeRect.move(vjn.nodeRect.x+xend xbeg,vjn.nodeRect.y+yend-ybeg); vjn.x = vjn.x +xend-xbeg; vjn.y = vjn.y +yend-ybeg; for(int j=0;j<vjn.getNumberOfPorts( ) ;j++) if(vjn.getXPt(j)>=0){ vjn.setXPt(j, vjn.getXPt(j)+xend-xbeg); vjn.setYPt(j, vjn.getYPt(j)+yend-ybeg); } } } } xend = x ; yend = y ; drag = false; } public void clearArea(Rectangle r){ Graphics g = getGraphics( ); g.clearRect(r.x-9,r.y-9 ,r.width+24,r.height+24); repaint(r.x-9,r.y-9,r.width+24,r.height+24); } public void highlight(Graphics g) int i; } public void drawLite(Graphics g, Rectangle r) } public void clearLite(Graphics g, Rectangle r) } public void resetSelected( ) } public void update(Graphics g){ paint(g); public void drawNode(Image img,int x, int y){ Graphics g = getGraphics( ); g.drawImage(img,x,y,this); } public void paint(Graphics g) int i,j; if(firstTime) { if(app.isMicrosoft){ inset_v = 0; inset_h = 0; } else { inset_v = insets( ).top; inset_h = insets( ).left; } firstTime = false; } g.drawLine(0,60+inset_v,bounds( ).width,60+inset_v); container.drawNet(g); } public boolean handleEvent(Event e) { if(app.loading) { System.out.println("Loading VJ"); return true; } switch (e.id) { case Event.MOUSE_MOVE: current_node = onNode(e.x,e.y); if(current_node!=null&&!nodeInfoDrawn) { EraseNodeInfo( ); DrawNodeInfo( ); nodeInfoDrawn = true; } else if(current_node==null&&nodeInfoDrawn) EraseNodeInfo( ); nodIjnfoDrawn = false; } current_node = onPort(e.x,e.y); if(current port>=0&&!portInfoDrawn) { ErasePortInfo( ); DrawPortInfo( ); portInfoDrawn = true; portInfo = current_port; } else if(portInfoDrawn&¤t_port!=portInfo) { ErasePortInfo( ); portInfoDrawn = false; } return true; case Event.KEY_PRESS: if(e.key==127) container.theDesktop.doCut( ); if(e.key==4) container.DUMP( ); if(e.controlDown( )){ switch(e.key){ case 3: container.theDesktop.doCopy( ); break; case 5: container.theDesktop.editComponent( ); break; case 24: container.theDesktop.doCut( ); break; case 22: container.theDesktop.doPaste( ); break; case 1: container.theDesktop.doSelectAll( ); break; default: break; } } return true; case Event.MOUSE_DOWN: if((e.when - lastTime)<1000) { lastTime = e.when; System.out.println("DC"); container.editComponent( ); return false; } lastTime = e.when; current_node = onNode(e.x,e.y); if(current_node!=null){ doNodeSelection(current_node,e.controlDown( ),e.x,e.y); } else { current_node = onPort(e.x,e.y); if(current_node!=null){ if(isConnected(current_node,current_port)) { //System.out.println("BEGIN DISCONNECTING"); disconnecting=true; } connecting=true; } else{ if(!(e.controlDown( ))){ app.theDocument.clearlight(app.theDocument.getGraphics( )); container.resetSelected( ); } current_comp_node = container.theDesktop.tools.getCurrent( ); //System.out.println("current_selection"+current_comp_node); if(current_comp_node>0) { // Add New component VJNode theNode=null; switch(current_comp_node){ case 1: VJContainer vjcnt = new VJContainer(app); vjcnt.setParent(container); vjcnt.VJContainerInit(e.x,e.y); theNode = vjcnt; break; // case 2: VJNetPin vjnp = new VJNetPin(app); // vjnp.setContainer(container); // vjnp.VJNetPinInit(e.x,e.y); // theNode = vjnp; // break; case 2: VJPlus vjp = new VJPlus(app); vjp.VJPlusInit(e.x,e.y); theNode = vjp; break; case 3: VJBiCopy vjb = new VJBiCopy(app); vjb.VJBiCopyInit(e.x,e.y); theNode = vjb; break; case 4: VJEquals vje = new VJEquals(app); vje.VJEqualsInit(e.x,e.y); theNode = vje; break; case 5: VJConstant vjc = new VJConstant(app); vjc.VJConstantInit(e.x,e.y); theNode = vjc; break; case 6: VJRandom vjr = new VJRandom(app); vjr.VJRandomInit(e.x,e.y); theNode = vjr; break; case 7: VJCounter vjct = new VJCounter(app); vjct.VJCounterInit(e.x,e.y); theNode = vjct; break; case 8: VJURLOpener vju = new VJURLOpener(app); vju.VJURLOpenerInit(e.x,e.y); theNode = vju; break; case 9: VJSplit vjs = newVJSplit(app); vjs.VJSplitInit(e.x,e.y); theNode = vjs; break; case 10: theNode = null; break; } if(theNode!=null){ theNode.init( ); theNode.propertiesEditor( ); if(!e.controlDown( )){ container.resetSelected( ); } container.addNode((Object)theNode); theNode.setSelected(true); container.theDesktop.tools.setCurrent(0); current_comp_node =

container.theDesktop.tools.getCurrent( ); container.theDesktop.tools.repaint( ); } } } if(connecting) { beginConnection(e.x,e.y); } else beginMarquee(e.x,e.y); } return true; case Event.MOUSE_UP: //System.out.println("UP"); if(connecting) { endConnection (e.x,e.y); repaint( ); return true;} if(marquee) { endMarquee(e.x,e.y); repaint( ); return true;} if(drag) { endDrag(e.x,e.y); repaint( ); return true;} return true; case Event.MOUSE_DRAG: //System.out.println("DRAG"); if(connecting) { doConnection(e.x,e.y); return true; } if(marquee) { doMarquee(e.x,e.y); return true; } if(drag) { doDrag(e.x,e.y); return true; } return true; default: //System.out.println("Other event "+e.toString( )); return false; } } void DrawPortInfo( ){ Graphics g = getGraphics( ); VJNode vjn; if(current_node==null .vertline. .vertline. current_port<0) return; g.drawString(current_node.name+"Pin:"+current_port+" "+current_node.getPortInfo(current_port),30,40); } void ErasePortInfo( ){ Graphics g = getGraphics( ); g.clearRect(30,29,bounds( ).width,15); } void DrawNodeInfo( ){ Graphics g = getGraphics( ); if(current_node == null) return; g.drawString(current_node.name+":"+current_node.getNodeInfo( ),30,2 2); } void EraseNodeInfo( ){ Graphics g = getGraphics( ); g.clearRect(30,12,bounds( ).width,13); } void Error(String error) { System.out.println("Node: "+ error); System.out.flush( ); } } VJNode is coded as follows: import java.awt.*; import java.awt.image.*; import java.util.*; // A class that is used to represent both primitive and hierarchical VJ nodes abstract class VJNode extends VJCore { // Class attributes private final static String getPortNameError = "get port name error"; private final static String getPortInfoError = "get port info error"; private final static String noQuickInfo = "no quick info available"; private final static String noAuthorInfo = "no author info available"; private final static String noExpirationDate = "no expiration date"; private final static String noVersionInfo = "no version info"; private final static String noCostInfo = "no cost info"; private final static String noName = "no name"; private final static String noComponentURL = "no URL"; private final static String noPortName = "no port name"; //Attributes private String info_url; private String quick_info; private String author_info; private String version_info; private String cost_info; private String expiration_date; private String componentURL; private Vector port_name; private Vector port_info; private Vector port_type; private Vector port_location; private Vector XPts; private Vector YPts; private int numberOfPorts=0; private Image normalImage=null; private Image selectedImage=null; private String normal = null; private String selected = null; private GIFFactory factory=null; boolean isContainer; // true if the node is hierarchical boolean isSelected; // true if the node is currently selected boolean isUINode; // true if the node has a user interface (exits on the web page) int x; // the x position in the parent container int y; // the y position in the parent container Vector drawFromPort; int portCount; // the number of ports the node has VJ vj; // a reference to the VJ applet Rectangle nodeRect; // the rectangle accociated with this nodes image String name; public VJNode(VJ v){ super(v); vj = v; port_name = new Vector( ); port_type = new Vector( ); port_info = new Vector( ); port_location = new Vector( ); drawFromPort = new Vector( ); XPts = new Vector( ); YPts = new Vector( ); } public void VJNodeInit(boolean isCnt,int x,int y,boolean ui){ this.x = x; this.y=y; isSelected = false; isContainer = isCnt; isUINode = ui; portCount = 0; } public void setSelected (boolean b) isSelected = b; } public boolean getSelected( ) return isSelected; } public void setImages(Image ni, Image si){ normalImage = ni; selectedImage = si; } public void setToDraw(int thePort,boolean b) { try { drawFromPort.setElementAt(new Boolean(b) , thePort); } catch(Exception e){ System.out.println(e); } } public boolean getToDraw(int port) { try { return ((Boolean) drawFromPort.elementAt(port)).booleanValue( ); } catch(Exception e){ System.out.println(e); return false; } } public void resetToDraw(int thePort) { try { drawFromPort.setElementAt(new Boolean(false),thePort); } catch(Exception e){ System.out.println(e); } } public int getXPt(int port) { try { return ((Integer) XPts.elementAt(port)).intValue( ); } catch(Exception e){ System.out.println(e); return -1; } } public void setXPt(int port,int val) { try { XPts.setElementAt(new Integer(val),port); } catch(Exception e){ System.out.println(e); } } public int getYPt(int port) { try { return ((Integer) YPts.elementAt(port)).intValue( ); } catch(Exception e){ System.out.println(e); return -1; } } public void setYPt(int port,int val) { try { YPts.setElementAt(new Integer(val) ,port); } catch(Exception e){ System.out.println(e); } } public void addPort(String pi, String pn, int pt, int pl){ port_name.addElement(pn); port_info.addElement(pi); port_type.addElement(new Integer(pt)); port location.addElement(new Integer(pl)); XPts.addElement(new Integer(0)); YPts.addElement(new Integer(0)); connectingNode.addElement(null); connectingPort.addElement(new Integer(0)); drawFromPort.addElement(new Boolean(false)); }; public String getPortInfo(int port){ try { return (String) port_info.elementAt(port); } catch(Exception e){ System.out.println(e); return getPortInfoError; }; } public String getNodeInfo( ){ if(quick info==null) return noQuickInfo; return quick_info } }; public void setComponentInfo(String n){ quick_info=n; }; public Component getComponent( ){ if(comp==null) System.out.println("The component "+name+" is null"); return comp; }; public void setComponent(Component n){ comp=n; }; public String getAuthorName( ){ if(author_info==null) return noAuthorInfo; return author_info }; public void setAuthorName(String n){ author_info=n; }; public String getExpirationDate( ){ if(expiration_date==null) return noExpirationDate; return expiration_date; }; public void setExpirationDate(String n){ expiration_date=n; }; public String getCost( ){ if(cost_info==null) return noCostInfo; return cost_info; }; public void setCost(String n){ cost_info = n; }; public String getVersion( ){ if(version_info==null) return noVersionInfo; return version_info; }; public void setVersion (String n){ version_info = n; }; public void setName(String n){ name = n; }; public String getName( ){ if(name==null) return noName; return name; }; public void setComponentURL(String n){ componentURL = n; }; public String getComponentURL( ){ if(componentURL==null) return noComponentURL; return componentURL; }; public void setNormalIcon(String n){ normal = n; }; public Image getNormalIcon( ) { return normalImage; } public void setSelectedIcon(String n){ selected = n; }; public Image getSelectedIcon( ){ return selectedImage; }; private boolean inRange(int n) { return n >=0 && n < port_type.size( ); } public int getNumberofPorts( ){ return port_type.size( ); } public void setNumberOfPorts(int n){ numberOfPorts = n; } public int getPortType(int port){ try { return ((Integer) port_type.elementAt(port)).intValue( ); } catch(Exception e){ System.out.println(e); return -1; } } public int getPortLocation(int port){ try { return ((Integer) port_location.elementAt(port)).intValue( ); } catch(Exception e){ System.out.println(e); return -1; } } public String getPortName(int port) { try { return (String) port name.elementAt(port); } catch(Exception e){ System.out.println(e); return noPortName; } } abstract VJNode dup( ); abstract void disconnecting(int port); abstract void connecting(int port); abstract void load(String s); abstract String save( ); abstract void propertiesEditor( ) ; }




VJ Tool dispatches start stop and init messages to all active instances of components as start( ), stop( ) and init( ). When VJ is loading, we want to have the user wait until that process is completed, so VJ Tool will ignore events and a splash sheet with a warning message is displayed that says no action will be possible until loading is completed. Once VJ Tool is loaded and initialized completely, the warning screen is dropped and user interaction is enabled.

The initialization process initializes and enables logical view and the physical view. The initialization processing includes VJ Tool's data structures and palettes, which comprise "primitive" or basic building block components coded entirely in Java. Once initialization is completed, the cut, paste, select all, move, drag, drop, point, and other functions are active. These functions associated with the VJ Tool menu bars are defaulted from the VJContainer class. The palettes and menus are created from VJDesktop.

VJ Tool then invokes user requests and such actions as may be appropriate thereto, as indicated in block 312. Once all requests have been satisfied, VJ Tool cycles back through link 314 and waits for subsequent user requests. If there are no further requests to be carried out, the user exits via block 316.

FIG. 4A shows an example of a World Wide Web home page that is displayed when the Netscape Navigator is invoked in accordance with a preferred embodiment. If this page had included a Java enabled applet, that applet would have been downloaded and activated as soon as the user clicked on it. Alternatively, an applet could be locally resident and thus be directly available. FIG. 4B illustrates the same web page with its main pull-down menu activated. FIG. 4C depicts the "Open File" pull-down menu of the home page shown in FIG. 4B. Note that the files found in the local file "saul.htm" include the applet called "DemoRelease", which is actually a back level version of VJ Tool, ready to select and run.

FIG. 4D shows the VJ Tool applet after it has been initialized and is ready to run. VJ Tool comes up on the user's screen after being initialized and deployed with two main views as shown in FIG. 4D. These views are equivalent to the status depicted by block 310 in FIG. 3. Window 402 shows the active VJ Tool desktop, in particular, its logical view 402. Logical view 402, also called the document view, is created from VJDocument. Window segment 404 is the right hand portion of the base home page shown in FIGS. 4A, 4B and 4C. The other view, the user physical view is shown in FIG. 5.

The source code enabling VJDocument is presented below.
    import java.util.*;
    import java.awt.*;
    class VJDocument extends container {
      VJ app;
      VJContainer container;
      VJNode current_i.
      int current_ui_comp;
      static int xOffset = 40;  // used to define the position on the desktop
      static int yOffset = 100; // at which the new icon corresponding to a
      // component is to be placed.
      int top,left,right,bottom;
      int ytop ,xleft,xright,ybottom;
      boolean grow;
      int growType;
      public VJDocument(VJv,VjContainer c){
      // Set the environment variables
      super(v);
      app = v;
      container = c;
      current_ui_comp = 0;
      current_i = null;
      // Initial Layout for the Applet
      setLayout(null);
      }
    void marqueeAction(boolean cntrDwn,Rectangle r,int x,int y){
      current_ui_comp= app.uiTools.getCurrent();
      if(current_ui_comp>0&& bigEnough()) {
      Graphics g = getGraphics();
      VJNode vjn = newComponent(cntrDwn,x,y);
      if(vjn!=null){;
      if(!cntrDwn) clearlight(g);
      current_ui_comp = 0;
      vjn.setSelected(true);
      container.theDesktop.vp_w.repaint();
      drawLite(g,r);
      app.uiTools.setCurrent(0);
      app.uiTools.repaint();
      }
      return;
      }
      boolean emptySelect;
      emptySelect = true;
      for(Enumeration e = app.theContainer.nodes.elements();
    e.hasMoreElements();) {
      VJNode vjn (VJNode) e.nextElement();
      if(vjn.isUINode&&vjn.comp.bounds().intersects(r)){
      if(cntrDwn){
      if(vjn.getselected()){
      vjn.setSelected(false);
      clearLite(getGraphics() ,vjn.comp.bounds());
      }else vjn.setSelected(true);
      }
      else
      vjn.setSelected(true);
      emptySelect = false;
      }
      }
      if(!emptySelect) {
      repaint();
      container.theDesktop.vp_w.repaint();
      }
    }
    void drawDrag(Graphics g,int i,int j ,int k,int l){
      for(Enumeration e = app.theContainer.nodes.elements();
    e.hasMoreElements();) {
      VJNode vjn = (VJNode) e.nextElement();
      if(vjn.getSelected())
      g.drawRect(vjn.comp.bounds().x-1+xend-
    xbeg,vjn.comp.bounds().y-1+yend-ybeg,
    vjn.comp.bounds().width+1 ,vjn.comp.bounds().height+1);
      }
    }
    void eraseDrag(Graphics g,int i,int j,int k,int l){
      for(Enumeration e = app.theContainer.nodes.elements();
    e.hasMoreElements();)
      VJNode vjn = (VJNode) e.nextElement();
      if(vjn.getSelected()) g.drawRect(vjn.comp.bounds().x-1+xend-
    xbeg,vjn.comp.bounds().y-1+yend-ybeg,
    vjn.comp.bounds().width+1,vjn.comp.bounds().height+1);
      }
    }
    void endDragAction(Graphics g,int i,int j ,int k,int l){
      for(Enumeration e = app.theContainer.nodes.elements(),
    e.hasMoreElements();) {
      VJNode vjn = (VJNode) e.nextElement();
      if(vjn.getselected())
      clearLite(g, vjn.comp.bounds());
      vjn.comp.move(vjn.comp.bounds().x+xend-
    xbeg,vjn.comp.bounds().y+yend-ybeg);
      }
      }
    }
    void containerPaint(Graphicsg){
    }
    void containerMouseMove(Evente){
    }
    void containerKeyPress(Evente){
      if(e.key==127) app.theContainer.doCut();
      if(e.key==4) container.DUMP();
      if(e.controlDown()){
      switch(e.key){
      case 3: System.out.println("copy");
      app.theContainer.doCopy();
      break;
      case 24: System.out.println("cut");
      app.theContainer.doCut();
      break;
      case 22: System.out.println("paste");
      app.theContainer.doPaste();
      break;
      case 1: System.out.println("ail");
      app.theContainer.doSelectAll();
      break;
      default: System.out.println("key "+e.key);
      break;
      }
      }
    }
    void containerMouseDown(Evente){
      }
    void containerMouseUp(Evente){
      if(grow) endGrow(e.x,e.y);
    }
    void containerMouseDrag(Evente){
      if(grow) doGrow(e.x, e.y);
    }
    void containerDoubleClick(){
    }
    boolean mouseDownSelects(Event e) { return true; }
    boolean mouseDownSelection(Event e){
      VJNode vjn = onUIComponent(e.x,e.y);
      if(vjn==null){
      if(!e.controlDown ()) clearlight(getGraphics());
      System.out;printin("Noton a UI Copmponent");
      return false;
      }
      doUISelection(current_i,e.controlDown() ,e.x,e.y);
      return true;
    }
    void mouseDownReset(Event e){
      clearlight(getGraphics());
    }
    boolean doMarquee() { return true; }
    public VJNode onUIComponent(intx, int y){
      for(Enumeration e = app.theContainer.nodes.elements();
    e.hasMoreElements();) {
      VJNode vjn = (VJNode) e.nextElement();
      if(vjn.isUINode){
      Rectangle r = vjn.comp.bounds();
      r.x = r.x-4;
      r.y = r.y-4;
      r.width = r.width+8;
      r.height = r.height+8;
      if(r.inside(x,y)){
      current_i = vjn;
      return vjn;
      }
      }
      }
      return null;
    }
    public boolean closeEnough(int fx; int fy,int x, int y,int epsilon){
    return x <fx+epsilon && .times. >fx-epsilon && y <fy+epsilon && y
     >fy-
    epsilon;
    }
    public int getGrowType(VJNode vjn, int x, int y){
    int top_y, mid_y, bottom_y,left_x, mid_x,right_x;
    Rectangle r = vjn.comp.bounds();
    top_y = r.y-4;
    mid_y = r.y+(rheight+1)/2;
    bottom_y = r.y+r.height+4,
    left_x = r.x-4;
    mid_x = r.x+(r.width+1)/2;
    right_x = r.x+r.width+4;
    if(closeEnough(left_x,top_y, x,y,4))return 0;
    if(closeEnough(mid_x ,top_y, x,y,4))return 1;
    if(closeEnough(right_x,top_y, x,y,4))return 2;
    if(closeEnough(left_x,mid_y, x,y,4))return 3;
    if(closeEnough(right_x,mid_y, x,y,4))return 4;
    if(closeEnough(left_x,bottom_y,x,y,4))return 5;
    if(closeEnough(mid_x ,bottom_y,x,y, 4))return 6;
    if(closeEnough(right_x,bottom_y,x,y,4)return 7;
    return 8;
    }
    public void doUISelection(VJNode vjn,boolean cntDwn,int x, int y){
      growType = getGrowType(vjn,x,y);
      System.out.println("DoUI"+growType);
      if(!cntDwn){
      if(!vjn.getSelected()){
      resetSelected();
      vjn.setSelected(true);
      }
      if(growType==8)
      beginDrag(x,y);
      else
      beginGrow(vjn,x,y);
      //current_component= i;
      repaint();
      container.theDesktop.vp_w.repaint();
      } else {
      if(vjn.getSelected()){
      Rectangle r = vjn.comp.bounds();
      vjn.setSelected(false);
      clearLite(getGraphics(),r);
      for(Enumeration e = app.theContainer.nodes.elements();
    e.hasMoreElements();) {
      VJNode vjn1 = (VJNode)e.nextElement();
      if(vjn 1.getSelected()){
      repaint();
      return;
      }
      }
      } else {
      vjn.setSelected(true);
      container.theDesktop.vp_w.repaint();
      repaint();
      return;
      }
      }
    }
      public boolean bigEnough(){
      //return xbeg-yend !=0 && ybeg-xbeg!=0;
      return true;
      }
    public void beginGrow(VJNode vjn, int x, int y){
      Rectangle r = vjn.comp.bounds();
      xbeg = x;
      ybeg = y;
      xend = x;
      yend = y;
      grow = true;
      Graphics g = getGraphics();
      g.setXORMode(Color.white);
      top = r.y; ytop=top;
      left = r.x; xleft=left;
      bottom = r.y+vj n.comp.bounds().height;ybottom=bottom;
      right = r.x+vjn.comp.bounds().width;xright = right;
      g.drawRect(left, top, r.width, r.height);
    }
    public void doGrow(int x, int y){
      Graphics g = getGraphics();
      g.setXORMode(Color.white);
      g.drawRect(left, top, right-left ,bottom-top);
      xend = x;
      yend = y;
      switch(growType){
      case 0: //top left
      top = ytop+(yend-ybeg);
      left = xleft+(xend-xbeg);
      break;
      case 1: //top middle
      top = ytop+(yend-ybeg);
      break;
      case2: //top right
      top = ytop+(yend-ybeg);
      right = xright+(xend-xbeg);
      break;
      case 3: //middle left
      left = xleft+(xend-xbeg);
      break;
      case 4: //middle right
      right = xright+(xend-xbeg);
      break;
      case 5: //bottom left
      left = xleft+(xend-xbeg);
      bottom = ybottom+(yend-ybeg);
      break;
      case 6: //bottom middle
      bottom = ybottom+(yend-ybeg);
      break;
      case 7: //bottom right
      right = xright+(xend-xbeg);
      bottom = ybottom+(yend-ybeg);
      break;
      }
      g.drawRect(left, top, right-left ,bottom-top);
    }
    public void endGrow(int x, int y){
      Graphics g = getGraphics();
      g.setXORMode(Color.white);
      g.drawRect(left, top, right-left ,bottom-top);
      xend = x;
      yend = y;
      clearLite(g, current_i.comp.bounds());
      current_i.comp.reshape(left,top,right-left,bottom-top);
      //if(current_i.compinstanceofVJChart)
    ((VJChart)(current_i.comp)).doResize(left,top, right-left ,bottom-top);
      drawLite(g, current_i.comp.bounds());
      grow = false;
    }
    public void clearlight(Graphicsg) {
      for(Enumeration e = app.theContainer.nodes.elements();
    e.hasMoreElements();) {
      VJNode vjn = (VJNode) e.nextElement();
      if(vjn.getSelected()&&vjn.isUINode){


clearLite(g,vjn.comp.bounds()); vjn.setSelected(false); } } container.theDesktop.vp_w.repaint(); } public void highlight(Graphics g) { for(Enumeration e = app.theContainer.nodes.elements(); e.hasMoreElements();) { VJNode vjn = (VJNode) e.nextElement(); if(vjn.getSelected()&&vjn.isUINode){ drawLite( g,vjn.comp.bounds()); } } } public void drawLite(Graphics g, Rectangle r) { int top_y, mid_y, bottom_y,left_x, mid_x,right_x, top_y = r.y; mid_y = r.y+(r.height+1)/2- 1; bottom_y =r.y+r.height; left_x=r.x; mid_x=r.x+(r.width+1)/2-1; right_x=r.x+r.width; g.setColor(Color.red); g.fillRect(left_x-4, top_y-4, 4, 4); g.fillRect(left_x-4, mid_y-2, 4, 4); g.fillRect(left_x-4, bottom_y, 4, 4); g.fillRect(right_x top_y-4, 4, 4); g.fillRect(right_x, mid_y-2, 4, 4); g.fillRect(righ_y, bottom_y, 4, 4); g.fillRect(mid_x-2, top_y-4, 4, 4); g.fillRect(mid_x-2, bottom_y, 4, 4); } public void clearLite(Graphics g, Rectangle r) { int top_y, mid_y, bottom_y,left_x, mid_x,right_x; top_y = r.y; mid_y = r.y+(r.height+1)/2-1; bottom_y =r.y+r.height; left_x=r.x; mid_x=r.x+(r.width+1)/2-1; right_x=r.x+r.width; g.clearRect(left_x-4 top_y-4, 4, 4); g.clearRect(left_x-4 mid_y-2, 4, 4); g.clearRect(left_x-4 bottom_y, 4, 4); g.clearRect(righ_y, top_y-4, 4, 4); g.clearRect(right_x, mid_y-2, 4, 4); g.clearRect(right_x, bottom_y, 4, 4); g.clearRect(mid_x-2, top_y-4, 4, 4); g.clearRect(mid_x-2, bottom_y, 4, 4); } public void resetSelected() { } public synchronized VJNode newComponent(boolean cntrDwn , int x, int y){ int j,i,t,l,b,r; if(xbeg < x&&ybeg < y) { t = ybeg; l = xbeg; b = y; r = x; } else if(xbeg < x && ybeg > y) { t = y; l = xbeg; b = ybeg; r = x; } else if(xbeg > x && ybeg < y) { t = ybeg; l = x; b = y; r = xbeg; } else { t = y; l = x; b = ybeg; r = xbeg; } if((r-1)<16 .parallel. (b-t)<16) { return null; } //resetSelected(); VJNode vjn; switch(current_ui_comp){ case 1: VJLabel vjl = new VJLabel(app); vjl.VJLabelInit(xOffset,yOffset); vjn = (VJNode) vjl; break; case 4: VJButton vjb = new VJButton(app); vjb.VJButtonInit(xOffset,yOffset); vjn = (VJNode) vjb; break; case 5: VJCheckbox vjcb = new VJCheckbox(app); vjcb.VJcheckboxInit(xOffset,yOffset); vjn = (VJNode) vjcb; break; case 6: VJChoice vjch = new VJChoice(app); vjch.VJChoiceInit(xOffset,yOffset); vjch.comp.reshape(l,t,r-1,b-t+1); vjn = (VJNode) vjch; break; case 7: VJList vjli = new VJList(app); vjli.VJListInit(xOffset,yOffset); vjh.comp.reshape(l,t,r-1,b+t+1); vjn = (VJNode) vjli; break; case 8: VJHScrollbar vjhsb = new VJHScrollbar(app); vjhsb.VJH ScrollbarInit(xOffset,yOffset); vjn = (VJNode) vjhsb; break, case 9: VJVScrollbar vjvsb = new VJVScrollbar(app); vjvsb.VJVScrollbarInit(xOffset,yOffset); vjn = (VJNode) vjvsb; break; case 10: VJChart vjchart = new VJChart(app); vjchart.VjChartInit(xOffset,yOffset); vjn = (VJNode) vjchart; break; case 2: VJTextField vjt = new VJTextField(app); vjt.VJTextFieldInit(xOffset,yOffset); vjn = (VJNode) vjt; break; case 3: VJTextArea vjta = new VJTextArea(app); vjta.VJTextAreaInit(xOffset,yOffset); vjn = (VJNode) vjta; break; default: System.out.println ("UNKNOWNTYPE!"); return null; } if(!cntrDwn){ container.theDesktop.vp_w.resetSelected(); } container.addNode((Object)vjn); if(yOffset > 220){ yOffset = 100; xOffset = xOffset+60; } else yOffset = yOffset+40; vjn.comp.move(l,t); add(vjn.comp); validate(); vjn.comp.reshape(l,t,r-1,b-t); vjn.comp.show(); vjn.init(); vjn.propertiesEditor(); return vjn; } public void update(Graphics g){ paint(g); } public void paint(Graphics g) { highlight(g); VJDocument works in conjunction with "container.java." The source code for "container.java." appears below. importjava.util.*; importjava.awt.*; abstract class container extends Panel { boolean marquee; boolean drag; int xbeg,xend,ybeg,yend; int inset_h, inset_v; boolean firstTime = true; static long lastTime=0; VJ app; public container(VJ v) { super(); setLayout(null); app = v; marquee = false; drag = false; } public void beginMarquee(intx, int y){ //System.out.Println("BEGINMARQUEE"); xbeg = x; ybeg = y; xend = x; yend = y; marquee = true; Graphics g = getGraphics(); g.setXORMode(Color.white); g.drawRect(xbeg, ybeg, 0, 0); } public void doMarquee(intx, int y){ //System.out.println("DOMARQUEE"); Graphics g = getGraphics(); g.setXORMode(Color.white); if(xbeg < xend) { if(ybeg < yend) g.drawRect(xbeg, ybeg, xend - xbeg, yend - ybeg); else g.drawRect(xbeg, yend, xend - xbeg, ybeg - yend); } else { if(ybeg < yend) g.drawRect(xend, ybeg, xbeg - xend, yend - ybeg); else g.drawRect(xend, yend, xbeg - xend, ybeg - yend); } xend = x; yend = y; if(xbeg < xend) { if(ybeg < yend) g.drawRect(xbeg, ybeg, xend - xbeg, yend - ybeg); else g.drawRect(xbeg, yend, xend - xbeg, ybeg - yend); } else { if(ybeg < yend) g.drawRect(xend, ybeg, xbeg - xend, yend - ybeg); else g.drawRect(xend, yend, xbeg - xend, ybeg - yend); } } public void endMarquee(Event e){ int x = e.x; int y = e.y; int j,i,t,l,b,r; boolean emptySelect; //System.out.println("ENDMARQUEE"); Graphics g = getGraphics(); g.setXORMode(Color.white); if(xbeg < xend){ if(ybeg < yend) g.drawRect(xbeg, ybeg, xend - xbeg, yend - ybeg); else g.drawRect(xbeg, yend, xend - xbeg, ybeg - yend); } else { if(ybeg < yend) g.drawRect(xend, ybeg, xbeg - xend, yend - ybeg); else g.drawRect(xend, yend, xbeg - xend, ybeg - yend); } xend = x; yend = y; marquee = false; emptySelect = true; if(xbeg < x && ybeg < y) { t = ybeg; l = xbeg; b = y; r = x; } else if(xbeg < x && ybeg > y) { t = y; l = xbeg; b = ybeg; r = x; } else if(xbeg > x && ybeg < y){ t = ybeg; l = x; b = y; r = xbeg; } else{ t = y; l = x; b = ybeg; r = xbeg; } Rectangle r1 = new Rectangle(l,t,r-1,b-t); marqueeAction(e.controlDown(),r1,x,y); repaint(); } public void beginDrag(int x, int y){ //System.out.println("BEGINDRAG"); xbeg = x; ybeg = y; xend = x; yend = y; drag = true; Graphics g = getGraphics(); g.setXORMode(Color.white); drawDrag(g,x,y,xend,yend); //if drag begin is valid make drag = true } public void doDrag(int x, int y){