System, method and article of manufacture for using multiple bidirectional ports in association with a java application or applet6438615
Abstract
Method, system and article of manufacture for creating object oriented components having one or more bidirectional ports for use with in connecting object oriented based components. The two way or bidirectional ports are first initialized to their two way state. The ports can then dynamically function as either input or output ports based solely on the manner in which they are used. The components set themselves internally to reflect the actual status of their bi-directional ports. When a connection to another component is completed, the connecting component object sends a message to the component at the other end of the connection indicating how its own port is set, input or output. The message receiving component then makes sure that its connection participating port is set oppositely. If the message receiving component's connecting port is bidirectional, that port is set opposite to the status of the first connected port. If the message receiving component's port is unidirectional and as such is in conflict with the status of the first connected port, that is, it is set to "output" when the first connected port is also set to "output", the connection is prohibited and an appropriate error message is displayed.
Claims
What is claimed is:
1. A method of developing software in an object-oriented applet or application developing environment, the method comprising:
providing an application development environment configured to enable construction of software by defining connections between at least two object-oriented software components that are graphally reresented in the application development environmet;
providing a first object-oriented software component having a bidirectional port, the bidirectional port having a graphical reprentation being presented in the application development environment and the bi-directonal port configured to enable the connection of the first object-oriented software component to a second object-oriented software component by allowing connection of the bi-directional port to a second graphical representation in the application development elavironment, the second graphical representation representing a second port that is associated with the second object-oriented software;
initializing the bidirectional port of the first object-oriented software component to a two-way state by assigning a first and a second logic to service inputs and service outputs associated with the bidirectional port respectively;
determining whether the bidirectional port should serve as input or output;
amending a first input output status associated with the bidirectional port to reflect the current status of the bidirectional port as input or output;
sending a message to the second object-oriented software component that is to be connected with the first object-oriented software component, the message indicating the input output status of the bidirectional port of the first object-oriented software component;
comparing the first input output status associated with the bidirectional port of the first object-oriented software to a second input output status associated with the second port of the second object-oriented software component;
permitting the connection of the first object-oriented software component to the second object-oriented software component when the first input output status is opposite to the second input output status of the second object-oriented software component.
2. The method according to claim 1 which includes the step of switching the status of the second connected port to be opposite that of the first connected port if the second connected port is bidirectional.
3. The method according to claim 2 which includes the step of prohibiting the connection if the second connected port is unidirectional and its input output status conflicts with that of the first connected port.
4. The method according to claim 3 which includes the step of sending an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
5. The method according to claim 1 which includes the step of prohibiting the connection if the second connected port is unidirectional and its input output status conflicts with that of the first connected port.
6. The method according to claim 5 which includes the step of sending an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
7. The method according to claim 1 which includes the step of sending an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
8. A software development system operating to provide the ability to connect object-oriented software components in an object-oriented applet or application environment, the software development system comprising:
an application development environment configured to enable the construction of software by defining connections between at least two object-oriented software components that are graphically represented in the application development environment;
a first object-oriented software component having a bidirectional port, the bidirectional port configured to enable the connection of the first object-oriented software component to a second object-oriented software component through a second port that is associated with the second object-oriented software by allowing connection of a graphical representation of the bi-directional port to a second graphical representation of a second port associated with the second object-oriented software;
a port initializer that initializes the bidirectional port of the first object-oriented software component to a two-way state by assigning a first and a second logic to service inputs and service outputs associated with the bidirectional port respectively;
a first input output status associated with the bidirectional port to reflect the current status of the bidirectional port as input or output, the current status of the bidirectional port being set based on the determination of whether the bidirectional port should serve as input or output;
a message transmitter for sending a message to the second object-oriented software component that is to be connected with the first object-oriented software component, the message indicating the input output status of the bidirectional port of the first object-oriented software component;
a comparator for comparing the first input output status associated with the bidirectional port of the first object-oriented software to a second input output status associated with the second port of the second object-oriented software component;
a facilitator for permitting the connection of the first object-oriented software component to the second object-oriented software component when the first input output status is opposite of the second object-oriented software component.
9. The system according to claim 8 which additionally comprises a port switcher that converts the status of the second connected port to be opposite that of the first connected port if the second connected port is bidirectional.
10. The system according to claim 9 which additionally comprises a facilitator that prevents the connection if the second connected port is unidirectional and its input output status conflicts with that of the first connected port.
11. The system according to claim 10 which additionally comprises an error message generator that sends an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
12. The system according to claim 8 which additionally comprises a facilitator that prevents the connection if the second connected port is unidirectional and its input output status conflicts with that of the first connected port.
13. The system according to claim 12 which additionally comprises an error message generator that sends an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
14. The system according to claim 8 which additionally comprises an error message generator that sends an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
15. A computer program embodied on a computer-readable medium for developing software in an object-oriented applet or application environment, the computer program comprising:
computer embodied code for providing an application development environment configured to enable the construction of software by defining connections between at least two object-oriented software components that are graphically represented in the application development environment;
computer embodied code for providing a first object-oriented software component having a bidirectional port, the bidirectional port having a graphical reprentation begin presented in the application development environment and configured to enable the connection of the first object-oriented software component to a second object-oriented software component by allowing connection of the graphical representation of the bidirectional port to a second graphical representation in the application development environment, the second graphical representation representing a second port that is associated with the second object-oriented software;
computer embodied code for initializing the bidirectional port of the first object-oriented software component to a two-way state by assigning a first and a second logic to service inputs and service outputs associated with the bidirectional port respectively;
computer embodied code for determining whether the bidirectional port should serve as input or output;
computer embodied code for amending a first input output status associated with the bidirectional port to reflect the current status of the bidirectional port as input or output;
computer embodied code for sending a message to the second object-oriented software component that is to be connected with the first object-oriented software component, the message indicating the input output status of the bidirectional port of the first object-oriented software component;
computer embodied code for comparing the first input output status associated with the bidirectional port of the first object-oriented software to a second input output status associated with the second port of the second object-oriented software component;
computer embodied code for permitting the connection of the first object-oriented software component to the second object-oriented software component when the first input output status is opposite of the second object-oriented software component.
16. The computer program embodied on a computer-readable medium as recited in claim 15 which additionally comprises sixth software for switching the status of the second connected port to be opposite that of the first connected port if the second connected port is bidirectional.
17. The computer program embodied on a computer-readable medium as recited in claim 16 which additionally comprises seventh software for prohibiting the connection if the second connected port is unidirectional and its input output status conflicts with that of the first connected port.
18. The computer program embodied on a computer-readable medium as recited in claim 17 which additionally comprises eighth software for sending an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
19. The computer program embodied on a computer-readable medium as recited in claim 15 which additionally comprises sixth software for prohibiting the connection if the second connected port is unidirectional and its input output status conflicts with that of the first connected port.
20. The computer program embodied on a computer-readable medium as recited in claim 19 which additionally comprises seventh software for sending an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
21. The computer program embodied on a computer-readable medium as recited in claim 15 which additionally comprises sixth software for sending an error message to the user if the second connected port is not bidirectional and has an input output status that is the same as that of the first connected port.
22. A method as recited in claim 1 wherein when the second port associated with the second object-oriented software component is a bidirectional port, the input output status associated with the second port is set to be the opposite of the input output status of the first bidirectional port.
23. A method as recited in claim 1, wherein when a third bidirectional port is also associated with the first object-oriented software component, a third input output status associated with the third bidirectional port is set to be the opposite of the input output status of the first bidirectional port.
24. A method as recited in claim 22, wherein when a fourth bidirectional port is also associated with the second object-oriented software component, the input output status associated with the second port is set to be the opposite of the input output status of the fourth bidirectional port.
25. A system as recited in claim 8, wherein when the second port associated with the second object-oriented software component is a bidirectional port, the input output status associated with the second port is set to be the opposite of the input output status of the first directional port.
26. A system as recited in claim 8, wherein when a third bidirectional port is also associated with the first object-oriented software component, the input output status associated with the third port is set to be the opposite of the input output status of the first bidirectional port.
27. A system as recited in claim 25, wherein when a fourth bidirectional port is also associated with the second object-oriented software component, the input output status associated with the second port is set to be the opposite of the input output status of the fourth bidirectional port.
28. A computer program as recited in claim 15, wherein when the second port associated with the second object-oriented software component is a bidirectional port, the input output status associated with the second port is set to be the opposite of the input output status of the first bidirectional port.
29. A computer program as recited in claim 15, wherein when a third bidirectional port is also associated with the first object-oriented software component, the input output status associated with the third port is set to be the opposite of the input output status of the first bidirectional port.
30. A computer program as recited in claim 28, wherein when a fourth bidirectional is also associated with the second object-oriented software component, the input output status associated with the second port is set to be the opposite of the input output status of the fourth bidirectional port.
Description
COPYRIGHT NOTIFICATION
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 software and, more particularly, to dynamically settable bidirectional ports for use with object-oriented components
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 which 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 representjust 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 bidirectional ports that can function as input or output pins in a dynamic fashion without specific user designation of their role to thereby conserve screen real estate, reduce clutter and ease use of the design tool for the user.
SUMMARY OF THE INVENTION
It is a primary object of the present invention to provide a programming environment and appropriate tools and components therefor that promote greater ease of use than is presently available in typical programming environments.
It is an additional object of the present invention to provide bidirectional ports that can be dynamically set to be either an input or an output port.
It is a further object of the present invention of the present invention to minimize clutter and preserve screen real estate through the use of bidirectional ports.
It is yet another object of the present invention to provide the user with means to utilize such bidirectional ports in an effective, non-intrusive manner.
The above objectives are achieved by utilizing bidirectional ports in association with object-oriented components. The two way or bidirectional ports are first initialized to their two way state. The ports can then dynamically function as either input or output ports based on the manner in which they are used. The components set themselves internally to reflect the actual status of their associated bi-directional ports. When a connection to another component is completed, the connecting component object sends a message to the component at the other end of the connection indicating how its own port is set, to input or output. The message receiving component insures that its connection participating port is set oppositely. If the message receiving component's connecting port is bidirectional, that port is set opposite to the status of the first connected port. If the message receiving component's port is unidirectional and as such is in conflict with the status of the first connected port, that is, it is set to "output" or "input" when the first connected port is also set to "output"or "input" respectively, the connection is prohibited and an appropriate error message is displayed
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 Virual Java 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. 7 visually describes an example of marqueing or sizing of a vertical scrolibar 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 shows 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. 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 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 (Java VM) 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, buzzwordcompliant, general-purpose programming language. Java supports programming for the Internet in the form of platform-independentJava 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 is basically "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 por_info;
Vector port_name;
/ /final static String port1_info = "output from container";
/ / 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 physicai 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(GlFFactory f){
normalImage = f.GetGIF("out_nd.gif");
selectedImage = f.GetGIF("in_nd.gif");
}
VJNode dup() {
retum null;
}
/ / Component Initialization
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,selecte
dImage.getHeight(vj.theContainer.theDesktop.vp_w) +3);
}
public void addNewPort(VJNetPin addedPin, int i, String info, String
5 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].requestlN(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.printIn("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,vj_n.getConnectingPort(k));
vjnc.setToDraw(k,vjn.getToDraw(k));
} else {
vjn_c.setConnectingPort(k,O);
vjn_c.setConnectingNode(k,null);
vjn_c.setToDraw(k,false);
}
}
if(vjn.isUINode)
vj.theDocument.clearLite(vj.theDocument.getGraphics() ,vj n.comp.bou
nds());
} 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) e1.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 "+
}
}
}
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.printIn(" ");
}
}
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.isUlNode){
vj.theDocument.clearLite(vj.theDocument.getGraphics(),vjn.comp.bou
nds());
}
theDesktop.vp_w.clearArea(vjn.nodeRect);
if(vjn.isUlNode){
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 (y_beg<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.set)(Pt(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.isUJNode){
vj.theDocument.clearLite(vj.theDocument.getGraphics(),vjn.comp.bou
nds());
}
theDesktop.vp_w.clearArea(vjn.nodeRect);
if(vjn.isUlNode){
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);
}
vj_c.setconnectingNode(cp,null);
vj_c.setConnectingPort(cp, -1);
vjc.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() ;i++)HOTSPOTS.drawHotspot(vjn,i,g);
/ / System.out.printIn("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(vjn.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,VJContainer 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.setTitle(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 static int 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==O)
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 = Node+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 newDimension(x,y);
}
}
VJDesktop is coded as follows:
import java.util.*;
import java.awt.*;
public dass 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();
apple_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(ml);
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(FIELPTOPICSMENUITEM));
mb.add(m3);
setMenuBar(mb);
tools = new Toolbar(apple_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) {
inth_off v_off
if(applet_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 control[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(INFOMENUJTEM)) {
}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)) {
doSelectAll();
}else if (label.equals(CLEARMENUITEM)) {
doSelectAll();
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.doSelecAll();
}
public void doCut(){
if(apple_w.loading) {System.out.println("Loading VJ"); return; }
container.doCut();
}
public void editComponent(){
if(applet_w.loading) {System.out.println("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(apple_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("incu.gif") ,factory.GetGIF("out_cu.gi"));
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(VJConstant.selectedImage,VJConstant.normalImage);
tools.addItem(VJRandom.selectedImage,VJRandom.normalImage);
tools.addItem(VJCounter.selectedImage ,VJCounter.normalImage);
tools.addItem(VJURLOpener.selectedImage ,VJURLOpener.normalImage
e);
tools.addItem(VJSplit.selectedImage ,VJSplit.normalImage);
}
public String desklnfo(int ii){
switch(ii) {
case 3: return "GGGG"; / /VJButton.quick_info;
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 xleft,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 fy,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.printIn("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.printIn("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.println("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.get)(Pt(cp_beg);
ybeg = cn_beg.getYPt(cp_beg);
xend = current_node.get)(Pt(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 yj_p = srcNode.getConnectingPort(srcPort);
if(disconnecting && current_node==null){
int xb = srcNode.get)(Pt(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) {
if(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.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.set)(Pt(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) {
if(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.set)(Pt(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.set)(Pt(current_port,xend);
current_node.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) {
if(ybeg < yend)
g.drawRect(xbeg, ybeg, xend - xbeg, yend - ybeg);
else
g.drawRect(xbeg, yend, xend - xbeg, ybeg - yend);
} else {
if(xbeg < 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,1,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;
1 = xbeg;
b = y;
r = x;
}
else
if(xbeg < x && ybeg > y) {
t = y;
1 = xbeg;
b = ybeg;
r = x;
}
else
if(xbeg> x && ybeg < y) {
t = ybeg;
1 = x;
b = y;
r = xbeg;
}
else {
t = y;
1 = 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.isUlNode)
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(vj n.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(vj n.nodeRect.x+xend-xbeg,vj n.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.getNumberOgPorts() ;j ++)
if(vjn.getxPtU) >=0){
vjn.set)(Pt(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&&!nodelnfoDrawn) {
EraseNodeInfo();
DrawNodeInfo();
nodeInfoDrawn = true;
}else
if(current_node==null&&nodeInfoDrawn) {
EraseNodeInfo();
nodeInfoDrawn = 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 = new VJSplit(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_mode.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 porr_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 GlFFactory factory=null;
boolean isContainer; / / true if the node is hierarchical
boolean isSelected; / / true if the node is currently selected
boolean isulNode; / / 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;
isUlNode = 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 set)(Pt(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_same.addElement(pn);
port_info.addElement(pi);
port_type.addElement(new Integer(pt));
porUocation.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 getNodelnfo(){
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 nocostlnfo;
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, 40 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 the 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.
The source code enabling VJDocument is presented below.
importjava.util.*;
importjava.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 grow, wpe;
public VJDocument(VJ v, 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(O);
app.uiTools.repaint( );
}
return;
}
boolean emptySelect;
emptySelect = true;
for(Enumeration e = app.theContainer.nodes.elements( );
e.hasMoreE1ements( );) {
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){
|