CGLIB

A Constraint-based Graphics Library for B-Prolog

(Version 6.5)

 

 

 

 

 

 

 

 

 

 

 

 

By Neng-Fa Zhou

Afany Software & CUNY

Copyright © Afany Software, 2000-2003

 

 


Preface

 

The widespread use of window systems has made a graphics package indispensable for any programming languages. Prolog is not an exception, although graphics is not part of the ISO standard. Some efforts have been made to introduce graphics programming into Prolog. One widely used approach is to adopt an external language interface with a language that supports graphics programming. For example, JIPL is an interface developed by KLS Inc. that bridges Prolog and Java bi-directionally. A Prolog system that adopts an interface like this will be able to access the graphics library of Java. This approach is not satisfactory for the following two reasons. First, you have to write code in two languages. This is especially daunting when there are interactions involved. Second, the graphics library in the adopted language, whether it is C, C++, Java, VB, or Tcl/Tk, is at such a low level that it does not match well with a high-level language like Prolog. Prolog, and CLP (Constraint Logic Programming) languages in general, should have a graphics library that provides high-level abstraction for specifying the states, layouts, and behaviors of graphical objects.

 

Motivated by the observations, we designed and implemented a high-level and constraint-based graphics library, called CGLIB, for B-Prolog. The library provides primitives on graphical objects and provides various kinds of constraints that facilitate the specification of layouts of graphical objects. The constraint solver of B-Prolog serves as a general-purpose layout manager that is significantly more flexible than the special-purpose layout managers used in Java and Tck/Tk. The library adopts a construct called action rules available in B-Prolog for programming interactions. An action rule consists of a pattern for agents, a pattern for events that can activate the agents, and an action the agents carry out when activated. Agents can communicate with each other through logical variables or global variables. Agents can behave concurrently and sequentially as well.

 

CGLIB enables you to use the Java graphics package without the need to write any code in Java. CGLIB, however, is not just another syntactical sugar for Java’s graphics package. It has a significantly higher abstraction level and is much easier to learn and use than Java’s graphics package. One of prominent features of CGLIB is the use of constraints in the specification of layouts.  In graphics languages such as PostScript and Tex, you have to specify every single detail about the graphical objects, including their sizes and positions. In languages such as Java and Tcl/Tk, the layout managers help determine the layouts of objects for certain applications, but the layout algorithms lack flexibility and are difficult to learn and use. The use of action rules to describe event handling is another feature of CGLIB. Action rules can be used to describe sophisticated and dynamic behaviors of graphical objects in a simple and straightforward manner.

 

CGLIB can be used in many areas such as drawing editors, interactive user interfaces, animation, information visualization, intelligent agents, and games. This manual describes the library and its usage. More example programs are available at www.probp.com.

 


Table of Contents

 

Preface. 0

Table of Contents.. 1

1. Getting Started.. 3

1.1 An illustrative example. 3

1.2 Installation.. 3

1.3 Start and quit B-Prolog with CGLIB.. 4

1.4 Open and close windows. 4

1.4 Draw graphics and clean windows. 5

2. Creating Objects.. 6

2.1 Attribute objects. 7

2.2 Windows. 7

2.3 Graphical objects. 9

2.4 Menu bars, menus and menu items. 19

2.5 File dialogs. 20

3. Constraints.. 22

3.1 Position constraints. 22

3.2 Same property constraints. 22

3.3 Grid and table constraints. 22

3.4 Tree constraint.. 24

3.5 Not overlap constraint.. 25

4. Operations on Objects.. 26

4.1 Packing and Showing Objects. 26

The primitive cgShow(O) shows O, and the primitive cgPack(O) packs O, where O can be one object or a list of objects. 26

4.2 Altering and Moving Objects. 26

5. Animation.. 28

6.    Generating Java Applets.. 29

7.    Event Handling.. 30

7.1 Action rules. 30

Agent ConditionSeq {Event} => ActionSeq.. 30

7.2 Events. 31

Action events. 31

Focus events. 31

Key events. 31

Mouse events. 32

Window events. 32

Window resize and move events. 33

Item events. 33

Adjustment events. 33

Text events. 33

Timer events. 33

8.    Examples.. 34

8.1 Drawing a flag.. 34

8.2      Drawing binary trees. 35

8.3      Drawing a diagram of Java AWT’s classes. 36

8.4      Building a calculator.. 38

8.5      Building a digital clock.. 41

8.6      Demonstrating a geometry theorem on quadrilaterals. 42

Appendix-I. Built-in Components.. 46

Appendix-II. Built-in Events.. 50

Appendix-III. Built-ins for Testing Key Codes.. 51

Index.. 52


1. Getting Started

 

1.1 An illustrative example

Let us start with the following program to taste the flavor of CGLIB:

go:-

        cgButton(B,“Hello World”),         (1)

        handleButtonClick(B),              (2)

        cgShow(B).                    (3)

 

handleButtonClick(B),{actionPerformed(B)} => abort.

 

 
 

 

 

 

 

 

 

 

 


The call cgButton(B,“Hello World”) in line (1) creates a button B with the label “Hello World”. Line (2) creates an event handler, which will be activated when the button B is clicked. The call cgShow(B) in line (3) packs the button, i.e., determines the size and position of the button, and shows the button in the default window. In our example, nothing is mentioned about the color and font of the text, the size of the button and the position of the button in the window. The system will determine the attribute values for us either by using the constraints we provided or by using the default values. The rule

 

handleButtonClick(B),{actionPerformed(B)} => abort.

 

defines the event handler handleButtonClick(B). The term enclosed in the pair of braces, actionPerformed(B), is called an event, and the right hand side of the rule, abort, is called an action. When an event actionPerformed(B)is posted, i.e, when the button B is clicked, the program execution terminates. In general, an action can be any sequence of sub-goals.

 

1.2 Installation

Currently CGLIB runs on Windows only. To install the system, follow the following steps:

 

1.      Make sure that Java is installed already. The library was tested with J2SDK1.4.1.

2.      Download the package bp6x_win.zip and save it the directory c:\.

3.      Extract the files from the archive by using jar in JSDK as

 

jar xfv bp6x_win.zip

 

4.  Add the following settings to C:\autoexec.bat:

set BPDIR=c:\BProlog

set path=%BPDIR%;%path%

set CLASSPATH=.;%BPDIR%\plc.jar;%BPDIR%\cg.jar

 

On Windows 2000/NT/XP, you need to open Control Panel, click on "system", then "details", and then "environment variables" to add the setting.

 

5.      Restart your computer.

 

Notice that the environment variable BPDIR must be reset correctly if the system is installed in a directory other than c:\.

 

1.3 Start and quit B-Prolog with CGLIB

To start B-Prolog with CGLIB, double click the file bpp.bat in the folder c:\BProlog\bin. You can use the predicate chdir to change the working directory. For example,

 

            chdir(‘c:\BProlog\examples\cg’).

 

You can use the predicate system to execute an OS command. For example,

 

            system(‘dir *.pl’).

 

 

Another way to start B-Prolog is to open an MS-DOS terminal and type bpp in the command line. After the system is started, it responds with the prompt |?- and is ready to accept Prolog queries.

 

To quit the system, use the query:

 

               halt

 

or simply enter ^D (control-D) when the terminal has the focus.

1.4 Open and close windows

To open a window, type the command:

 

     ?- cgWindow(W),cgShow(W)

 

cgWindow(W) creates a window and cgShow(W) shows the window. There is a default window to which all graphical objects will be sent if the window is not specified explicitly. To open the default window, type:

 

     ?- cgDefaultWindow(W),cgShow(W)

 

or

     ?- cgShowDefaultWindow

 

A window has the default title UntitledWindow if no title is given explicitly. A window can be given a title. For example, the following command shows a window with the title MyWindow.

 

     ?- cgWindow(W,“MyWindow”),cgShow(W)

 

To close a window W, simply use the primitive cgClose(W). For example, the following command opens a window and closes it immediately.

 

     ?- cgWindow(W),cgShow(W),cgClose(W)

 

The primitive cgCloseDefaultWindow closes the default window.

 

1.4 Draw graphics and clean windows

There are primitives for creating and showing various kinds of graphical objects. The following command draws a five-point star whose outer circle is 100 pixels wide.

 

     ?-cgStar(S),S^width #= 100,S^n #= 5,cgShow(S)

 

The default size for each object is 20 by 20 pixels and the default position is left-upper corner of the window, i.e., (0,0). So, if the constraint S^width #= 100 were missing, the star would be covered by the window’s title bar.

 

The constraint S^n #= 5 states that the number of points in the star is five. The default value for the attribute n of a star is 5. So, the following command has the same effect:

 

     ?-cgStar(S),S^width #= 100,cgShow(S)

 

The area of the star is filled with the default color, which is black. To draw a star with a different color or other attribute values, you have to specify so by using constraints. For example,

 

     ?-cgStar(S),S^width #= 100,S^fill #= 0,cgShow(S)

 

draws an unfilled 5-point star, and

 

     ?-cgStar(S),S^width #= 100,S^color #= red,cgShow(S)

 

draws a filled red star.

 

If no window is given, then all objects will be drawn on the default window. The following command draws a star on a designated window.

 

     ?-cgWindow(W), cgStar(S), S^window #= W, cgShow(S)

 

The constraint S^window #= W specifies the window to which the star is to be sent. When the system draws an object on a window, it automatically opens the window.

 

If multiple objects are drawn on the same window and the objects overlap, then part of the previously drawn objects will be overwritten by the objects drawn later. So, the following command

 

            ?-cgCircle([C1,C2]),cgShow([C1,C2]).

 

draws two circles, but only one will be visible. Constraints can be used to restrict the layout for objects. For example, the following command draws two circles that do not overlap.

 

            ?-cgCircle([C1,C2]),cgNotOverlap([C1,C2]),cgShow([C1,C2]).

 

To clean a window, use the primitive cgClean(W). For example, the following command draws a star on a window and then cleans the window immediately.

 

     ?-cgWindow(W),cgStar(S),S^window #= W,cgShow(S),cgClean(W)

 

To clean the default window, use the primitive cgCleanDefaultWindow. The following command cleans the default window before drawing a star onto it.

 

     ?-cgCleanDefaultWindow, cgStar(S), cgShow(S)

           

2. Creating Objects

Each object is represented as a structure of Prolog. Each object has a certain number of attributes and each attribute has a name and a domain. There are two kinds of attributes, namely constrainable and non-constrainable. Constrainable attributes can be referenced by the notation O^attr where O is an object and attr is the name of an attribute. Constrainable attributes can occur in constraints. For example, the equality constraint O1^x #= O2^x enforces the two objects O1 and O2 to have the same x coordinate, and the inequality constraint O^width #> 20 ensures that the width of O is greater than 20 pixels.  Notice that in other contexts this notation is treated just as a normal Prolog term! Non-constrainable attributes must be accessed and updated by using get and set primitives. For example, the primitive

 

·        cgGetBackground(O,Color)

 

succeeds if the background color of O is Color, and the primitive

 

·        cgSetBackground(O,Color)

 

sets the background color of O to be Color. Updates of attribute values through the set primitive are destructive and will not be undone upon backtracking.

 

Objects are classified into the following different types:

·        Attribute objects          

·        Windows

·        Graphical objects

·        Menus and menu items

·        File dialogs

Attribute objects such as fonts and points serve as attribute values of other objects. Windows and graphical objects are treated in a different way in the sense that every graphical object has a window as its container but a window does not have a container.

 

2.1 Attribute objects

The following object types are introduced to facilitate constraining the attribute values of graphical objects: dimension, point, font, and color.

 

·         cgDimension(D): Create or test a dimension object or a list of dimension objects D. A dimension object has two constrainable attributes, namely, width and height.

·         cgPoint(P): Create or test a point object or a list of point objects P. A point object has two constrainable attributes, namely, x and y.

 

·        cgFont(F): Create or test a font object or a list of font objects F. A font object has three constrainable attributes:

·        name: A font name may be one of the following:

[“Dialog”,”TimesRoman”,”Helvetica”,”DialogInput”,
 “ZapfDingbats”
]

 

·        size: An integer greater than 6. The default size is 10.

·        style: The domain is:

[plain, bold, italic, bold_italic].

 

·        cgColor(C): Create or test a RGB object or a list of RGB objects. A RGB object has the following three constrainable attributes:

 

·        red: The redness of the color, which is an integer from 0 to 255.

·        green: The greenness of the color, which is an integer from 0 to 255.

·        blue: The blueness of the color, which is an integer from 0 to 255.

2.2 Windows

A window has the following constrainable attributes:

·        x: The x-coordinate of the top-left corner of the window on the screen.

·        y: The y-coordinate of top-left corner of the window on the screen.

·        width: The width of the window.

·        height: The height of the window.

·        leftMargin: The width of the left margin. No objects will be placed by the packer in the margins unless the x-coordinates are set explicitly.

·         topMargin : The height of the top margin.

·        color: The color of the window.

The domains of the integer attributes are non-negative.

 

The following primitives are provided for accessing and updating non-constrainable attributes: title, visible, and menuBar.

·        cgGetTitle(W,Title): The title of the window W is Title.

·        cgSetTitle(W,Title): Set the title of the window W to Title.

·        cgIsVisible(W):  Window W is visible.

·        cgSetVisible(W,OneOrZero): Show or hide the window W where OneOrZero must be either 1 or 0.

·        cgSetMenuBar(W,MenuBar): Set the menu bar of the window W to MenuBar (see menu bar below).

 

In addition to the get and set primitives, the following primitives are available on windows:

 

·        cgWindow(W): Create  or test a window or a list of windows.

·        cgWindow(W,Title): Create a window W with a title.

·        cgShow(W): Show the window W.

·        cgClose(W): Close the window W. No object in a window can be re-shown once the window is closed.

·        cgClean(W): Clean the window W by removing all the components from the window.

·        cgCleanDrawing(W): Clean the window W by removing all the graphics components from the window. Control components (see below) are not removed.

 

For example, the following command creates a 100 by 100 window:

 

     ?-cgWindow(W),W^width #= 100, W^height #= 100,cgShow(W)

 

 

The default window is created when the system is started. To access it, use the primitive

 

·        cgDefaultWindow(W)

 

The following primitives manipulate the default window without explicitly referencing it.

 

·        cgShowDefaultWindow

·        cgCloseDefaultWindow

·        cgCleanDefaultWindow

 

2.3 Graphical objects

The following primitives are provided for creating and testing various kinds of graphical objects:

 

·        cgArc(O)

·        cgButton(O)

·        cgCheckbox(O)

·        cgChoice(O)

·        cgCircle(O) 

·        cgImage(O) 

·        cgLabel(O) 

·        cgLine(O)

·        cgList(O) 

·        cgOval(O) 

·        cgPolygon(O) 

·        cgRectangle(O) 

·        cgRoundRectangle(O) 

·        cgScrollbar(O) 

·        cgSquare(O)

·        cgStar(O) 

·        cgString(O) 

·        cgTextArea(O) 

·        cgTextBox(O) 

·        cgTextField(O) 

·        cgTriangle(O) 

 

Where O is a variable, an object, a list of variables, or a list of objects. For example, cgArc(A) creates an arc A  and cgArc([A1,A2,A3])creates a list of arcs A1, A2, and A3. Figure 1 shows how each object type looks like.

 

Each object has the following constrainable attributes:

·        window: The containing window of the object.

·        x: The x-coordinate of the top-left corner of the object. Let LM be the left margin of the enclosing window. The value of this attribute is no less than LM.

·         y: The y-coordinate of top-left corner of the object. Let TM be the top margin of the enclosing window. The value of this attribute is no less than TM.

·        width: The width of the object. The domain of this attribute is the set of positive integers.

·        height: The height of the object. The domain of this attribute is the set of positive integers.

·        color: The value is a color object created by cgColor or one of the following constants.

[black, blue, cyan, darkGray, gray, lightGray, magenta, orange,  pink, red, white, yellow]

 

For object types such as Button, List, TextArea, and TextField, the color attribute indicates the foreground color. The primitives cgGetBackground and cgSetBackground can be used to access and update the background color.

 

The object types Button, Checkbox, Choice, Label, List, String, TextField, TextBox, and TextArea have the following attributes in addition to the attributes listed above:

·        font: The font used for the text.

·        fontName:  For each object O, O^font #= F, O^fontName #= F^name.

·        fontSize: For each object O, O^font #= F, O^fontSize #= F^size.

·        fontStyle: For each object O, O^font #= F, O^fontStyle #= F^style.

 

The following attributes, called virtual attributes, are provided to facilitate the description of object layouts.

 

·        size: For each object O,
O^size #= D, D^width #= O^width, D^height #= O^height.

·        centerX: For each object O,  O^centerX #= O^x+O^width//2, where the operator // indicates integer division.

·        centerY: For each object O, O^centerY #= O^y+O^height//2.

·        rightX: For each object O, O^rightX #= O^x+O^width.

·        bottomY: For each object O, O^bottomY #= O^y+O^height.

·        center: For each object O,
       
O^center #= P, P^x #= O^centerX, P^y #= O^centerY.

·        leftTopPoint: The left-top point.

·        leftBottomPoint: The left-bottom point.

·        rightTopPoint: The right-top point.

·        rightBottomPoint: The right-bottom point.

 

These attributes are constrainable. They are called virtual since they are derived from the base attributes x, y, width, and height. Virtual attributes are created on the fly when they are accessed. For instance, when the attribute centerX of an object O is accessed, the system creates a variable V as the value of the attribute and generates the constraint

V #= O^x+O^width//2.

Virtual attributes cannot be destructively updated by the operator #:= (see below).

 

Figure 1. Primitive graphical objects.

 

Each object has a non-constrainable attribute, called visible, which can be tested by using the primitive cgIsVisible(O) and updated by using the primitive cgSetVisible(O,OneOrZero).

 

In addition to the get and set primitives for non-constrainable attributes, the following primitives are provided on all graphical objects:

·        cgShow(O): Show O, which can be a graphical object or a list of graphical objects.

·        cgPack(O): Pack O, i.e., determine the attribute values of O based on the constraints on O.

·        cgClean(O): Remove O from its window.

 

The following types of objects are called AWT control components: Button, Checkbox, Choice, List, Scrollbar, TextField, and TextArea. These types of objects have the following two additional non-constrainable attributes: enabled and cursor. The following primitives are provided for accessing and updating the attribute values:

·        cgSetEnabled(O,OneOrZero): Enable the component if OneOrZero is 1 and disable it if 0. Only enabled control components can post events.

·        cgIsEnaled(O): The component O is enabled.

·        cgSetCursor(O,Cursor):Set the current cursor to Cursor when the component has the focus, where Cursor must be one of the following:

 

o       crosshair_cursor

o       default_cursor

o       e_resize_cursor

o       hand_cursor

o       move_cursor

o       n_resize_cursor

o       ne_resize_cursor

o       nw_resize_cursor

o       s_resize_cursor

o       se_resize_cursor

o       sw_resize_cursor

o       text_cursor

o       w_resize_cursor

o       wait_cursor

·        cgGetCursor(O,Cursor):The current cursor set to the component O is Cursor.

 

Each object type has some additional attributes and primitives as described in the following. The complete specification of attributes and primitives is given in Appendix I.

 

·        Arc

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

·        startAngle: The starting angle of the arc. O^startAngle in 0..360.

·        arcAngle: The size of angle. O^arcAngle in 0..360.

 

·        Button

Get and set primitives

·        cgSetText(O,Text): Set the text to be shown on the button O to be Text, which must be a string. Notice that a string in Prolog is represented as a list of codes of the characters in the string. For example, “123”, “hello”, and [98,97] are valid strings.

·        cgGetText(O,Text): The text shown on the button O is Text.

 

Other primitives

·        cgButton(O,Text): Create a button and set its text to be Text.

·        cgButton([O1,...,On],[T1,...,Tn]): Create a list of buttons whose ith button has Ti as the text.

 

·        Checkbox

Get and set primitives

·        cgSetText(O,Text): Set the text of the checkbox O to be Text.

·        cgGetText(O,Text): The text of the checkbox O is Text.

·        cgSetState(O,OneOrZero): Set the state of the checkbox O to be checked if OneOrZero is 1 and to be unchecked if OneOrZero is 0.

·        cgGetState(O,State): The state of the checkbox O is State.

 

 

Other primitives

·         cgCheckbox(O,Text): Create a checkbox with the text Text.

·         cgCheckbox([O1,...,On],[T1,...,Tn]): Create a list of checkboxes with the texts T1,..., and Tn, respectively.

·         cgCheckboxGroup([O1,…,On]):The checkboxes O1,…,On form a group in which only one can be checked.

 

·        Choice

Constrainable attributes

·         count: The number of items in the choice.

·         item(I): The Ith item, where I must be an integer between 1 and the count.
 

Other primitives

·         cgChoice(O,[T1,…,Tn]): Create a choice with a list of items where T1,…,Tn must be strings .

·         cgAdd(O,T): Add a string or a list of strings to the choice object O.

·         cgAdd(O,T,Index): Add a string to the choice object O at the specified position.

·         cgRemove(O,T): Remove an item or a list of items from the choice object.

·         cgSelect(O,T): Set the selected item to be T.

·         cgSelectedItem(O,T): The selected item of choice O is T.

 

·        Circle 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

·        diameter: O^width #= O^height and O^diameter #= O^width.

 

·        Image 

Constrainable attribute

·        name: The name of the image file.

 

·        Label 

Get and set primitives

·        cgGetText(O,Text): The text of the label O is Text.

·        cgSetText(O,Text): Set the text of the label.

·        cgGetAlignment(O,Align): The current alignment of the label O is Align.

·        cgSetAlignemnt(O,Align): Set the alignment of the label O to Align, which must be left, center, or right.

 

 

Other primitives

·        cgLabel(O,Text): Create a label with the text Text.

·        cgLabel([O1,...,On],[T1,...,Tn]): Create a list of labels with specified texts.

 

·        Line 

Constrainable attributes

·        point1, point2: The starting and ending points.

·        x1,y1,x2,y2: The coordinates of the starting and ending points.
O^x1 #>= O^x, O^y1 #>= O^y,
O^x1 #=< O^rightX, O^y1 #=< O^bottomY
.
The same constraints are also imposed on
x2 and y2.

·        thickness: Thickness of the line.

·        arrow1: There is an arrow at point1 if 1 and none otherwise.

·        arrowLength1: The length of the arrow at point1.

·        arrowThickness1: The thickness of the arrow at point1.

·        arrow2: There is an arrow at point2 if 1 and none otherwise.

·        arrowLength2: The length of the arrow at point2.

·        arrowThickness2: The thickness of the arrow at point2.

 

·        List

Constrainable attribute

·        count: The number of items in the list.

·        item(I): The Ith item, where I must be an integer between 1 and the count.

 

Other primitives

·         cgList(O,[T1,T2,...,Tn]): Create a list O and then add T1,T2,...,Tn to the list as items.

·         cgAdd(O,T): Add a string or a list of strings to O.

·         cgAdd(O,T,Index): Add a string to the list object O at the specified position.

·         cgRemove(O,T): Remove an item or a list of items from the list O

·         cgSelect(O,T): Set the selected item to be T.

·         cgSelectedItem(O,T): The selected item of list  O is T. T is bound to [] if no item or multiple items are selected.

·         cgSelectedItems(O,T): T is the list of selected items of list O.

 

·        Oval 

Constrainable attribute

·        fill: Filled if 1 and unfilled if 0

.

·        Polygon 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

·        n: The number of points.

·        x(I): The x-coordinate of the Ith point (1 #=< I, I #=< O^n).

·        y(I): The y-coordinate of the Ith point (1 #=< I, I #=< O^n).

·        point(I): The Ith point (1 #=< I, I #=< O^n).

 

·        Rectangle 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

 

·        RoundRectangle 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

·        arcWidth: The width of the round angle.
O^arcWidth #>=0, O^arcWidth #=< O^width/2.

·        arcHeight: The height of the round angle.
O^arcHeight #>=0, O^arcHeight #=< O^height/2.

 

·        Scrollbar 

Get and set primitives

·         cgGetBlockIncrement(O,Val): The block increment of the scroll bar O is Val.

·         cgSetBlockIncrement(O,Val): Set the block increment of the scroll bar O to be Val.

·         cgGetMaximum(O,Max): The maximum value of the scroll bar O is Min.

·         cgSetMaximum(O,Max): Set maximum value of the scroll bar O to be Min.

·         cgGetMinimum(O,Min): The minimum value of the scroll bar O is Min.

·         cgSetMinimum(O,Min): Set the minimum value of the scroll bar O to be Min.

·         cgGetOrientation(O,Orient): The orientation of the scroll bar O is Orient.

·         cgSetOrientation(O,Orient): Set the orientation of the scroll bar O to be Orient, which must be either horizontal or vertical.

·         cgGetUnitIncrement(O,Val): The unit increment of the scroll bar O is Val.

·         cgSetUnitIncrement(O,Val): Set the unit increment of the scroll bar O to be Val.

·         cgGetValue(O,Val): The current value  minimum value of the scroll bar O is Val.

·         cgSetValue(O,Val): Set the current value  minimum value of the scroll bar O to be Val.

·         cgGetVisibleAmount(O,Val): The visible amount of the scroll bar O is Val.

·         cgSetVisibleAmount(O,Val): Set the visible amount of the scroll bar O to be  Val.

 

Other primitives

·         cgScrollbar(O,Orient): Create a scrollbar that has the orientation Orient, which  must be either horizontal or vertical.

·         cgScrollbar(O,Orient,Value,VisibleAmount,Min,Max): Create a new scroll bar with the specified orientation, initial value, page size, and minimum and maximum values.

 

·        Square 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

 

·        Star 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

·        n: The number of points. O^n #>=0.

·        x0,y0: The coordinate of the first point.

·        angle0: The angle between the x-axis and the line going from the center of the star to the first point.

·        innerDiameter: The diameter of the inner circle.

 

·        String 

Get and set primitives

·        cgSetText(O,Text): Set the text of the string.

·        cgGetText(O,Text): The text of the string O is Text.

·        cgSetAlignemnt(O,Align): Set the alignment of the string O to Align, which must be left, center, or right.

·        cgGetAlignment(O,Align): The current alignment of the string O is Align.

 

Other primitives

·        cgString(O,Text): Create a string object with the text Text. A string object is similar to a label but is drawn by using drawString in Java.

·        cgString([O1,...,On],[T1,...,Tn]): Create a list of string objects with specified texts.

 

·        TextArea 

Get and set primitives

·        cgSetText(O,Text): Set the text of the area.

·        cgGetText(O,Text): The text of the text area O is Text.

·        cgSetRows(O,NumOfRows): Set the number of rows of the the area.

·        cgGetRows(O,NumOfRows): The number of rows of the the area is NumOfRows.

·        cgSetColumns(O,NumOfColumns): Set the number of columns of the the area.

·        cgGetColumns(O,NumOfColumns): The number of columns of the the area is NumOfColumns.

·        cgSetEditable(O,OneOrZero): Set the flag that determines whether or not the text area is editable.

·        cgIsEditable(O): The text area O is editable.

 

Other primitives

·         cgTextArea(O,T): Create a text area with text T in it.

·        cgAppend(O,T): Append the string T to the end of the current text of the text area O.

·        cgInsert(O,T,Pos): Insert the text T into the text area at the specified position.

 

·        TextBox

Get and set primitives

·        cgSetText(O,Text): Set the text of the text box.

·        cgGetText(O,Text): The text of the text box O is Text.

·        cgSetAlignemnt(O,Align): Set the alignment of the text box O to Align, which must be left, center, or right.

·        cgGetAlignment(O,Align): The current alignment of the text box O is Align.

 

Other primitives

·        cgTextBox(O,Text): Create a text box with the text Text. A text box is similar to a string but it is surrounded by a rectangle.

·        cgTextBox([O1,...,On],[T1,...,Tn]): Create a list of text boxes with specified texts.

 

·        TextField 

Get and set primitives

·        cgSetText(O,Text): Set the text of the area.

·        cgGetText(O,Text): The text of the text area O is Text.

·        cgSetColumns(O,NumOfColumns): Set the number of columns of the text field.

·        cgGetColumns(O,NumOfColumns): The number of columns of the text field is NumOfColumns.

·        cgSetEditable(O,OneOrZero): Set the flag that determines whether or not the text field is editable.

·        cgIsEditable(O): The text field O is editable.

 

Other primitives

·         cgTextField(O,T): Create a text field with text T in it.

 

·        Triangle 

Constrainable attributes

·        fill: Filled if 1 and unfilled if 0.

·        point1,point2,point3: The three points.

·        x1,y1,x2,y2,x3,y3: The xy-coordinates of the three points.

 

2.4 Menu bars, menus and menu items

Each window has a menu bar to which menus can be attached. Each menu contains a list of menu items which themselves can be menus.

 

·        Menu items
A menu item has
a name. A menu item with the name “-“ will serve as a separator. Menu items can be created and tested by the following primitives:

 

·        cgMenuItem(I): Create or test a menu item or a list of menu items.

·        cgMenuItem(I,Text): Created a menu item named Text.

·        cgMenuItem([I1,...,In],[T1,...,Tn]): Create a list of menu items with specified names.

·        cgSetText(I,Text): Set the text of the menu item I to Text.

·        cgGetText(I,Text): The text of the menu item I is Text.

 

·        Checkbox menu items
A checkbox menu item is a menu item, and can be checked or unchecked.

 

·        cgCheckboxMenuItem(I): Create or test a checkbox menu item or a list of checkbox menu items.

·        cgCheckboxMenuItem(I,Text): Create a checkbox menu item named Text.

·        cgCheckboxMenuItem([I1,...,In],[T1,...,Tn]): Create a list of checkbox menu items with the specified names.

·        cgSetText(I,Text): Set the text of the checkbox menu item I to Text.

·        cgGetText(I,Text): The text of the checkbox menu item I is Text.

·        cgSetState(I,OneOrZero): Set the state of the checkbox menu item to checked if OneOrZero is 1 and to unchecked if 0.

·        cgGetState(I,State): State is 1 if the state of the checkbox menu item is checked and 0 if unchecked.

 

·        Menus
A menu is a menu item to which other menu items can be added.

 

·        cgMenu(M): Create or test a menu or a list of menus.

·        cgMenu(M,Text): Create a menu with a specified name.

·        cgMenu([M1,...,Mn],[T1,...,Tn]): Create a list of menus with the specified names.

·        cgSetText(I,Text): Set the text of the menu to Text.

·        cgGetText(I,Text): The text of the menu is Text.

·        cgAdd(Menu,Items) : Add Items, a list of menus or menu items, to Menu.

·        cgRemove(Menu,Items) : Remove Items, a list of menus or menu items, from Menu.

 

·        Menu bars
The primitive cgSetMenuBar(Win,MenuBar) sets the menu bar MenuBar to the window Win. The following primitives are available on menu bars.

·        cgMenuBar(B): Create or test a menu bar B.

·        cgMenuBar(B,Menus): Create a menu bar B with the list of menus Menus.

·        cgAdd(MenuBar,Items) : Add Items, a list of menus, to MenuBar

·        cgRemove(MenuBar,Items) : Remove Items, a list of menus, from MenuBar

 

 

Example
The following program builds the menu shown in Figure
2.

go:-

    cgMenuItem([Iopen,Iprint,Ijpeg,Igif,Sep],
               ["Open","Print","JPEG","GIF","-"]),

    cgMenu([Mfile,Medit,Mhelp,Msave],["File","Edit","Help","Save"]),

    cgCheckboxMenuItem(Icheck,"Checkme"),

 

    cgAdd(Msave,[Ijpeg,Sep,Igif]),

    cgAdd(Mfile,[Iopen,Msave,Iprint,Icheck]),

    %

    cgDefaultWindow(Win),

    cgSetMenuBar(Win,MB),

    cgAdd(MB,[Mfile,Medit,Mhelp]),

    cgShow(Win).

 

 


2.5 File dialogs

A file dialog is a window that allows you to input file names. To create a file dialog, use the primitive:

 

·        cgFileDialog(F): Create or test a file dialog F.

 

A file dialog has the following attributes:

·        parent: the parent window of the dialog, which will be the default window if no window is explicitly given.

·        mode:  the value is either save or load.

 

The following primitives are available on file dialogs:

·        cgSetTitle(F,Title): Set the title of the file dialog to Title.

·        cgGetTitle(F,Title): The current title of the file dialog is Title.

·        cgGetFile(F,File): The file name input by the user is File.

·        cgGetDirectory(F,Directory): The directory the file resides is Directory.

 


3. Constraints

As we have already seen, we can use the notation O^a to access constrainable attributes of objects and use equality (#=), disequality (#\=), and inequality (#>, #>=, #<, #=<) constraints to constrain the values of attributes. In addition to these constraints, there are symbolic constraints that can be used to constrain attributes of objects without referencing the attributes directly.

3.1 Position constraints

Constraints in this group restrict the relative positions of objects.

 

·        cgInside(O1,O2): O1 is located inside O2. 

·        cgOutside(O1,O2): equivalent to cgInside(O2,O1).

·        cgLeft(O1,O2): O1 is located to the left of O2.

·        cgRight(O1,O2): equivalent to cgLeft(O2,O1).

·        cgAbove(O1,O2): O1 is placed above O2.

·        cgBelow(O1,O2): equivalent to cgAbove(O2,O1).

 

The argument O1 or O2 can be one object or a list of objects.

3.2 Same property constraints

Constraints in this group force a list of objects to have the same value for a constrainable attribute.

 

·        cgSame(L,AttributeName): The values of AttributeName of the objects in list L are all the same.

·        cgSame(L,AttributeName,Value): The values of AttributeName of the objects in list L are all the same as Value.

 

For example, the constraint cgSame([O1,O2,O3],size) enforces the three objects O1,O2, and O3 to have the same size.

3.3 Grid and table constraints

The grid and table constraints may be the most powerful constraints in CGLIB. The grid constraint enforces objects to be placed on a grid board where all the grid cells are of the same size. The table constraint is not as restrictive as the grid constraint. It forces objects to be placed in a tabular form where each row or each column may have a different size from the others.

 

·         cgGrid(L,PadX,PadY): L must be a list of lists of objects in the form:

 [[O11,...,O1m],[O21,...,O2m],...,[On1,...,Onm]]

 

or a two-dimensional array in the form of:

      $array($array(O11,...,O1m),$array(O21,...,O2m),...,$array(On1,...,Onm))

 

where each Oij is an object. This constraint ensures that the objects are placed on an n by m (n rows and m columns) grid board and the object Oij occupies the grid cell at <i,j>. PadX and PadY specify the size of the space between each two neighboring objects. Both of them can be variables.




Notice that an object may occur multiple times in L. In that case, the object will cover all the corresponding grid cells. For example, the following constraint


           
cgGrid([[B1,B2],[B3,B3],[B4,B5]],0,0)

ensures that
B1 and B2 occupy the first row, B3 occupies the second row, and B4 and B5 occupy the third row (see Figure 3).

Text Box: Figure 3. Grid constraint.

Another nice feature of the grid constraint is that it accepts dummy objects, i.e., dummy variables of Prolog. This makes it unnecessary in certain circumstances to create objects just for layout purposes. For instance, consider the dominos in Figure 4. Let S1,S2,S3,S4, and S5 be the squares that contain, respectively, 1, 2, 3, 4, and 5 circles. The layout of the five squares can be specified by using one grid constraint as follows:

 


     cgGrid([[_, S1,_],

             [S2,S3,S4],

             [_, S5,_]])

 

 

 

 

 


 

Text Box: Figure 4. A domino.

 


The grid constraint can also be used to specify the layout of the circles in each of the domino. For example, consider the domino with five circles. Let C1, C2, C3, C4, and C5 be the circles. The layout must satisfy the following constraint:

 

     cgGrid([[C1, _, C2],

            [ _,C3,  _],

             [C4, _, C5]])

 

Notice that you must make sure each object has the size of one or multiple grid cells. For objects that do not fit in squares, cgTable should be used.

 

·        cgGrid(L): equivalent to cgGrid(L,0,0).

·        cgTable(L,PadX,PadY): Similar to cgGrid(L,PadX,PadY) but two different rows may be of different heights and two different columns may be of different widths.

·        cgTable(L): equivalent to cgTable(L,0,0).

 

3.4 Tree constraint 

The tree constraint, which takes the following form, is useful for arranging components into tree structures.

 

·        cgTree(Tree,Type,DisX,DisY,Centered)

 

where

·        Tree is a term in the form node(Node,Children) where Node is a graphical component and Children is a list of sub-trees in the same form as Tree.

·         Type indicates how the tree grows. It can be one of the following: top_down, left_right, bottom_up, and right_left.

·        Centered:

·        centered: the root of each sub-tree is placed in the middle of its children

·        itemized: the children are itemized.

·        DisX is the x-distance between two leaves or the x-distance between a root and its children depending on the type of the tree.

·        DisY is the y-distance between two leaves or the y-distance between a root and its children depending on the type of the tree.

 

Figure 5 shows eight different ways to visualize the following term where each node is a square:

 

    node(C0,[node(C1,[node(C3,[]),

                 node(C4,[])]),

              node(C2,[node(C5,[]),

                 node(C6,[])])]).

      

Figure 5. Eight different ways to visualize a tree.

3.5 Not overlap constraint 

 

·        cgNotOverlap(L): Ensures that the list of objects do not overlap each other.

 

Without this constraint, you would have to implement the constraint by using the built-in constraints provided by B-Prolog. For example, to ensure that two objects O1 and O2 do not overlap each other, you would have to give the following constraints:

 

(O1^rightX #=< O2^x #\/

 O1^x #>= O2^rightX #\/

 O1^bottomY #=< O2^y #\/

     O1^y #>= O2^bottomY)

 

The description is not only lengthy but also inefficient.

 


4. Operations on Objects

4.1 Packing and Showing Objects

The primitive cgShow(O) shows O, and the primitive cgPack(O) packs O, where O can be one object or a list of objects.

 

One may need some knowledge about the packing algorithm in order to help the algorithm pack objects efficiently. The algorithm determines the attributes in the following order:

 

·        fonts: for those objects that have texts on them such as buttons and labels, the fonts are determined first. The justification for this strategy is that the preferable sizes for objects with texts can only be known after the fonts are known.

·        sizes: the sizes of objects are determined next. Objects that have the largest preferable sizes are selected first.

·        positions: the positions are determined after the sizes are fixed. Large objects are selected before small objects.

·        others: the final phase is to determine the values for the remaining attributes such as colors, fill, etc.

 

The primitive cgShow(O) calls cgPack(O)to pack O before showing it. One may wonder, if cgShow(O) packs O  automatically, why do we need cgPack(O). cgPack is provided to let you have some control over what objects need be packed and when objects should be packed. Packing is an NP-hard problem in general and may take a long time if objects are not packed in an appropriate order. It is always a good practice to determine the layout areas for objects before fixing the objects. For instance, recall the dominos shown in Figure 4. It is fast to first pack the squares and then pack the circles inside the squares.

 

4.2 Altering and Moving Objects

A special operator, #:=, is provided to update constrainable attributes of objects. Let O be an object, Attr be an attribute, the following resets the attribute value to NewValue:

 

O^Attr #:= NewValue

 

The update is destructive and is not undone upon backtracking.

 

CGLIB also provides primitives for scaling and moving objects.  Rotation is not yet supported.

 

·        cgScale(O,F): scale the object or list of objects O by the factor F. The top-left corner of the objects will serve as the reference point. In addition to the change of sizes, the positions of the objects will also change proportionally. Figure 6 illustrates this operation. The rectangle in thick lines is the original one and the rectangle in dotted lines is the one obtained after scaling the original one by a factor of ½ . Notice that the top-left corner remains unchanged.

 

 

 


 


·        cgResize(O,Width,Height): resize the object or list of objects O such that the object or list of objects can be covered by a rectangle of size Width by Height. Just as for cgScale, the top-left corner of the objects will serve as the reference point.

 

·        cgMove(O,X,Y): Move the object or list of objects O to the position (X,Y), which will become the new top-left corner of the object.

 

Currently, only finite-domain constraints are supported and no constraints can be optional or approximate. A solution must satisfy all given constraints. A set of constraints may appear to be satisfiable but not. For example, the following set of constraints

 

{104*W #= 53*H ,H #=<100, H#>0}

 

is not satisfiable. This may be a source of frustration to you. Sometimes it is fast to give a relaxed specification of a layout and then alter it to make it satisfactory.

 


5. Animation

An animation is a sequence of images that are rendered along a time line. Animation is better than text or static image for presenting many kinds of materials because of its dynamic nature.

 

To construct animations, we not only need to construct the static images but also need to decide the order in which the images are rendered and the rate at which changes of images take place. To suspend an image for a certain time, use the following primitive:

 

·        cgSleep(T): Suspend T milliseconds before continuing the execution.

 

With this primitive, it is very easy to construct animations. The following shows how to render a list of objects in an animated fashion.

 

animate([],_).

animate([O|Os],[T|Ts]):-

     cgCleanDefaultWindow,

          cgShow(O),

          cgSleep(T),

          animate(Os,Ts).

 

An animation may consists of thousands of frames. It would be very space consuming if we construct all frames first, and then show them. In most cases, when we show a frame, the previous frame will become useless and thus can be discarded. Therefore, it is suggested that the following scheme be used to construct animations.

 

     repeat,

     construct the next frame Frame,

     determine the time T for the frame,

     cgCleanDefaultWindow,

     cgShow(Frame),

     cgSleep(T),

     fail.

 

In this way, backtracking will reclaim all the space taken by the previous frame and only space that is big enough for storing one frame is needed. You must make sure that all the calls between repeat and fail leave no choice point, otherwise execution will backtrack to that choice point rather than to repeat.

 


6.    Generating Java Applets

There are demands for images or animations that can be embedded in Web.  In CGLIB, it is possible to record the graphics into a Java applet. The following primitives are provided for this purpose.

 

·        cgStartRecord(Name): Turn the recorder on. All the objects shown after this call will be sent to the recorder. Name is the file name for the Java applet to be generated when cgStopRecord is executed.

·        cgStartRecordAnimation(Name): The same as cgStartRecord(Name), but the generated Java applet will show the recorded objects repeatedly.

·        cgStopRecord: Stop the recorder and generate two files, one called Name.java and the other Name.html where Name is the file name given by cgStartRecord or cgStartRecordAnimation. The file named Name.java is a Java applet that shows the recorded objects.

 

Here is an example.

 

go:-

Circles=[C1,C2,C3,C4,C5],

  cgCircle(Circles),

     cgSame(Circles,width,100),

  Colors=[red,black,green,blue,gray],

setColor(Circles,Colors),

  cgStartRecordAnimation(animateCircles),

  member(Circle,Circles),

  cgCleanDefaultWindow,

  cgShow(Circle),

  cgSleep(1000),

  fail.

go:-

  cgStopRecord.

 

setColor([],[]).

setColor([Circle|Circles],[Color|Colors]):-

  Circle^color #= Color,

  setColor(Circles,Colors).   

 

The generated applet animateCircles.java repeatedly shows the five circles of different colors. If cgStartRecord were used rather than cgStartRecordAnimation, then the applet would show the circles at the speed of one second each and stop after the last circle.

 

 

 

7.    Event Handling

 

The specification of responsive objects is important for building interactive user-interfaces. CGLIB provides a new language construct, called action rules that can be used to program interactions.

 

7.1 Action rules

An action rule takes the following form:

Agent ConditionSeq {Event} => ActionSeq

 

where Agent is an atomic formula that represents a pattern for agents, ConditionSeq is a sequence of conditions on the agents, Event is a pattern for events that can activate the agents, and ActionSeq is a sequence of actions the agents perform when activated.

 

Recall the action rule in our first example:

 

handleButtonClick(B),{actionPerformed(B)} => abort.

 

There is no condition specified on the agent handleButtonClick(B). When an event actionPerformed(B)is posted, i.e., when the button B is clicked, the action halt will be executed, which terminates the execution.

 

There is no primitive for killing agents. For an agent, if the condition of an action rule in its definition is not satisfied, the next alternative rule will be tried. If that rule does not contain an event, then the agent will be killed automatically after the action is executed. For example,

 

handleButtonClick(B,Flag),var(Flag),{actionPerformed(B)}

=> Flag=1.

handleButtonClick(B,Flag) => true.

 

The agent haddleButtonClick(B,Flag)will disappear after the button B is clicked once. Notice that the second rule is necessary here. Without it, the agent would fail after the Flag becomes non-variable.

 

An agent can be defined by multiple action rules, but the second rule will be tried only after the condition of the first one fails. Therefore, for the following definition,

 

handleButtonClick(B),{actionPerformed(B)} => p(B).

handleButtonClick(B),{actionPerformed(B)} => q(B).

 

the second rule will never be tried because the condition for the first rule always succeeds. To let both of the actions p(B) and q(B) be executed when B is clicked,  one has to either put these two actions into one rule or create two agents, one executing p(B) and the other executing q(B) when the button is clicked.

 

Each rule can handle one event. To handle multiple events on a component, one has to create one agent for each of the events.

 

7.2 Events

 

Each time when an event is posted, all the agents that are waiting for the event will be activated. If there are multiple agents waiting for one event, then the agent generated first will be activated first.

 

Appendix II summarizes all the events. An event is a structure with one or two arguments. The first argument is the source component from which the event originates. The second argument, if there is any, contains some supplementary information about the event. For example, the following rule

 

handleMouseEvent(O),{mousePressed(O,E)} =>

     E^x #= X, E^y #= Y,

     write((X,Y)),nl.

 

handles mouse button presses. Each time a mouse button is pressed, it prints out the location of the event.

 

The following describes all the events CGLIB can handle.

Action events

·        actionPerformed(O) This event occurs on buttons, menu items, and text fields. If O is a button, it is posted when O is clicked. If O is a menu item, the event is posted when the item is selected. If O is a text field, the event is posted when the enter key is typed on the text field.

Focus events

·        focusGained(O)

·         focusLost(O)
These two events occurs when O gains or loses the focus. O can be any window or any component that has the
enabled attribute (i.e., Button, Choice, Checkbox, List , Scrollbar, TextField, and TextArea).

 

Key events

·        keyPressed(O,E)

·        keyReleased(O,E)

·         keyTyped(O,E)
These three kinds of events are posted when a key is pressed, released, and typed, respectively, while O has the focus. O can
a window or an AWT control component. E has the following attributes:

·         code: the code of the pressed key. For printable key C, the notation 0’C tells the code. For instance, the code for ‘A’ is 0’A, and the code for ‘1’ is 0’1. For non-printable keys such as arrow and function keys, built-in predicates are provided to test their codes. For example, the call vk_F1(Code) succeeds if Code is the code of the F1 key. See Appendix III for the complete list of the built-ins.

·         char: the char of the typed key. Notice that this attribute is meaningful only for the event keyTyped and the typed key corresponds to a printable character.

·         modifiers: an integer that tells the supplementary information about the key stroke, e.g., whether the shift key is pressed. You should consult the Java’s API for the meaning of this field. The following primitives are provided to facilitate the access of this field:

·        cgShiftIsDown(E)

·        cgControlIsDown(E)

·        cgMetaIsDown(E)

·         cgAltIsDown(E)

 

Mouse events

·        mousePressed(O,E)

·        mouseReleased(O,E)

·        mouseEntered(O,E)

·        mouseExited(O,E)

·        mouseClicked(O,E)

·        mouseDragged(O,E)

·         mouseMoved(O,E)
These mouse events occur on windows. The argument E has the following attributes:

·         x,y : the location at which the mouse event occurs.

·         count: number of mouse clicks

·         modifier: An integer that conveys more information about the event., e.g., which mouse button is pressed. The following primitives are provided to facilitate the use of this field:

·        cgIsLeftButton(E)

·         cgIsRightButton(E)

 

Window events

·        windowClosing(O)

·        windowOpened(O)

·        windowIconified(O)

·        windowDeiconified(O)

·        windowClosed(O)

·        windowActivated(O)

·         windowDeactivated(O)
These events occurs on windows.

Window resize and move events

·        componentResized(O,E) 

·        componentMoved(O,E)
These two events occur when window O is resized or moved. E has the following attributes:

·        x, y, width, height: The new position and size of the window.

 

Item events

·        itemStateChanged(O,E)
This event occurs on checkbox menu items, checkboxes, lists, and choices. The event object E has the following attributes:

 

·        index: the index of the item that was selected or deselected         

·        state: the new state of the item

 

Adjustment events

·        adjustmentValueChanged(O,E)

   This event occurs on scrollbars. The event object E has the following attributes:

 

·        value: the current value of the scrollbar   

·        adjustmentType:  The type of the adjustment which caused the value change. The returned type is one of the following: unit_increment, unit_decrement, block_decrement, block_increment, and track.

Text events

·        textValueChanged(O,E)
This event occurs on text fields and text areas.

 

Timer events

·        time(T)
This event is posted after the time interval of the timer T elapses. See B-Prolog’s manual for the description of timers.

 

8.    Examples

CGLIB can be used in many areas such as drawing editors, interactive user interfaces, animation, information visualization, intelligent agents, and games.  This chapter describes the following list of sample programs:

 

·        Drawing the flag of Antigua and Barbuda

·        Drawing binary trees

·        Drawing a diagram of Java AWT’s classes

·        Building a calculator

·        Building a digital clock

·         Demonstrating a geometry theorem on quadrilaterals

 

These examples illustrate the use of most of the constraints and events. More examples can be found at the web site www.probp.com.

 

8.1 Drawing a flag

We consider as the first sample program how to write a program to draw the flag of Antigua and Barbuda as shown in Figure 7. The flag is composed of a red rectangle, a black triangle, a yellow 16-pointed star, a blue triangle and a white triangle. The order in which components are shown is very important. When two components overlap, the component shown later will overwrite the one shown earlier. So, for the flag, the red rectangle must be shown first and the white triangle must be shown last.

 

 

     

 

 

Text Box: Figure 7. The flag of Antigua and Barbuda.

 

 


go:-

    antiguabarbuda(Os), %create the list of components Os

    cgWindow(Win,"antiguaAndBarbuda"), %create a window with a title

    cgSame(Os,window,Win), %the containing window of Os is Win

    cgShow(Os).S

 

antiguabarbuda([R,TR1,S,TR2,TR3]):-

    cgRectangle(R), R^color #= red, 2*R^width #= 3*R^height,

 

    cgTriangle(TR1), TR1^color #= black,

    TR1^point1 #= R^leftTopPoint,

    TR1^point2 #= R^rightTopPoint,

    TR1^x3 #= R^centerX, TR1^y3 #= R^bottomY,

 

    cgStar(S), S^color #= yellow, S^n #= 16,

    S^centerX #= R^x+R^width/2,

    35*S^diameter #= 24*R^height,

    7*S^innerDiameter #= 2*R^width,

   

    cgTriangle(TR2), TR2^color #= blue,

    210*(TR2^x1-R^x) #= 41*R^width,

    28*(TR2^y1-R^y) #= 11*R^height,

    TR2^y1 #= S^centerY,

    210*(TR2^x2-R^x) #= 169*R^width,

    TR2^y2 #= TR2^y1,

    TR2^point3 #= TR1^point3,

   

    cgTriangle(TR3), TR3^color #= white,

    10*(TR3^x1-R^x) #= 3*R^width,

    28*(TR3^y1-R^y) #= 17*R^height,

    10*(TR3^x2-R^x) #= 7*R^width,

    TR3^y2 #= TR3^y1,

    TR3^point3 #= TR1^point3.

 


8.2 Drawing binary trees

In this example, we build a binary tree of some depth and use the tree constraint to visualize it. Figure 8 shows a complete binary tree of seven levels. The tree constraint

  

cgTree(Tree,top_down,1,5,centered),

 

states that the tree grows from top down, the x-distance between each two neighboring leaves is 1 pixel, the y-distance between each level is 5 pixels,  and the root is in the middle of its children along the x-axis. 

 

 

                             

Figure 8. A compelete binary tree.

 

 


go:-

    cgWindow(Win,"binaryTree"),

    N=6, %depth of the tree

    generateTree(Tree,N,Os,[],Ls,[]), %Os - nodes, Ls - lines

    cgTree(Tree,top_down,1,5,centered), %use the tree constraint

    cgSame(Os,window,Win), cgSame(Ls,window,Win),

    cgShow(Os), cgShow(Ls).

 

generateTree(node(C,[]),0,[C|OsR],OsR,Ls,Ls):-!,node(C).

generateTree(node(Root,[C1,C2]),N,[Root|Os],OsR,[L1,L2|Ls],LsR):-

    node(Root),

    N1 is N-1,

    cgLine([L1,L2]),

    generateTree(C1,N1,Os,Os1,Ls,Ls1),C1=node(Circle1,_),

    generateTree(C2,N1,Os1,OsR,Ls1,LsR),C2=node(Circle2,_),

    L1^point1 #= Root^centerPoint,

    L1^point2 #= Circle1^centerPoint,

    L2^point1 #= L1^point1,

    L2^point2 #= Circle2^centerPoint.

 

node(C):-cgCircle(C),C^color #= red,C^width #= 5.

 

 


8.3 Drawing a diagram of Java AWT’s classes

This program draws the diagram (see Figure 9) that depicts the hierarchy of the Java AWT’s classes. The diagram is a tree where each node is a text box and the root of each sub-tree is centered with respect to its children. The tree constraint

 

    cgTree(Tree,left_right,20,0,centered),

 

specifies this layout. The root of each sub-tree is connected to its children by line segments. As the positions for the lines depend on the text boxes, it is important to lay out the text boxes first.

 

Figure 9. Java AWT's class hierarchy.

 

 


go:-

    cgWindow(Win,"java awt’s classes"),

    generateNodes(Tree,Os),

    connectTree(Tree,Ls,[]),

    cgTree(Tree,left_right,10,2,centered),

    cgSame(Os,window,Win),cgSame(Ls,window,Win),

    cgShow(Os),cgShow(Ls).

 

generateNodes(Tree,Os):-

    Os=[Object,Component,Button,Canvas,Checkbox,CheckboxMenuItem,

        Choice,Container,Dialog,FileDialog,Frame,Label,List,

        MenuComponent,Menu,MenuBar,MenuItem,Panel,Applet,PopupMenu,

        Scrollbar,ScrollPane,TextArea,TextComponent,TextField,Window],

    Labs=["Object","Component","Button","Canvas","Checkbox",

          "CheckboxMenuItem","Choice","Container","Dialog",

          "FileDialog","Frame","Label","List","MenuComponent",

          "Menu","MenuBar","MenuItem","Panel","Applet",

          "PopupMenu","Scrollbar","ScrollPane",TextArea",

          "TextComponent","TextField","Window"],

    cgTextBox(Os,Labs),

    Tree=node(Object,

              [node(Component,

                    [node(Button,[]),

                     node(Canvas,[]),

                     node(Checkbox,[]),

                     node(Choice,[]),

                     node(Container,

                          [node(Window,

                                [node(Frame,[]),

                                 node(Dialog,

                                      [node(FileDialog,[])])]),

                           node(Panel,

                                [node(Applet,[])]),

                           node(ScrollPane,[])]),

                     node(Label,[]),

                     node(List,[]),

                     node(Scrollbar,[]),

                     node(TextComponent,

                          [node(TextArea,[]),

                           node(TextField,[])])]),

               node(MenuComponent,

                    [node(MenuBar,[]),

                     node(MenuItem,

                          [node(Menu,[node(PopupMenu,[])]),

                     node(CheckboxMenuItem,[])])])]).

 

 

connectTrees([],Ls,LsR):-Ls=LsR.

connectTrees([C|Cs],Ls,LsR):-

    connectTree(C,Ls,Ls1),

    connectTrees(Cs,Ls1,LsR).

 

connectTree(node(Box,[]),Ls,LsR):-!,Ls=LsR.

connectTree(node(Box,Children),[Vl,Hl|Ls],LsR):-

    getFirst(Children,node(FirstC,_)),

    getLast(Children,node(LastC,_)),

    cgLine(Vl),

    Vl^y1 #= FirstC^centerY, Vl^y2 #= LastC^centerY,

    Vl^x1 #= Vl^x2, Vl^x1 #= Box^rightX+4,

    %

    cgLine(Hl),

    Hl^x1 #= Box^rightX, Hl^x2 #= Vl^x1,

    Hl^y1 #= Box^centerY, Hl^y2 #= Hl^y1,

    %

    connectChildren(Vl,Children,Ls,Ls1),   

    connectTrees(Children,Ls1,LsR).

 

getFirst([X|Xs],X).

 

getLast(L,X):-

    reverse(L,RL),

    getFirst(RL,X).

 

connectChildren(Line,[],Ls,LsR):-Ls=LsR.

connectChildren(Line,[node(C,_)|Cs],Ls,LsR):-

    cgLine(L),

    Ls=[L|Ls1],

    L^x1 #= Line^x1, L^x2 #= C^x-2,

    L^y1 #= C^centerY, L^y2 #= L^y1,

    connectChildren(Line,Cs,Ls1,LsR).

   

 

8.4 Building a calculator

In this example, we consider how to build a working calculator with the interface as depicted in Figure. The calculator consists of a display and a keyboard. The display is a text field, which is a built-in component. The keyboard consists of several keys. The layout of the keys are specified by the grid constraint given in Figure 10.

 

cgGrid([[Bc,Bdiv,Bmul,Bsub],

        [B7,B8,  B9,  Badd],

        [B4,B5,  B6,  Badd],

        [B1,B2,  B3,  Beq],

        [B0,B0,  Bdot,Beq]],1,1),

 
                        

Figure 10. The interface of the calculator and the constraint.

 

This example illustrates a nice feature of the grid constraint: a component can occupy multiple grid squares. In this example, the keys labeled “=” (Beq), “+” (Badd), and “0” (B0) are twice as big as the other keys.

 

To carry out calculation, the calculator has to memorize the accumulated result and the operator to be applied. After each operation is applied, the display should show the current result. When you continue to type the next operand, the display should turn to show the operand. For this purpose, the calculator should also memorize whether the number on display is a result or an operand.  We use a structure to represent all the information that has to be memorized:

 

     cal(Display, Acc, Op, OnDisplay)

 

where Display is the text field, Acc is the accumulated result, Op is the operator to be applied next, and OnDisplay tells whether the number on display is a result or an operand.

 

Prolog is not an object-oriented language, but this does not prevent us from writing programs in the object-oriented style. A graphical user interface usually generates many handlers each of which carrries the objects it manipulate when activated. In the calculator, there is an event handler, defined as follows, for each key on the keyboard.

 

     keyInput(Key,Cal),{actionPerformed(Key)} => 

Key^text #= KeyLab, process(KeyLab,Cal).

 

The handler takes the object Cal and updates it when activated. The predicate process(KeyLab,Cal) processes a click of the button labeled  KeyLab . Different actions are taken according to the types of keys. For example, when a digit key is clicked, if the number on display is a result, then the calculator cleans the display and shows the digit as part of the next operand; if the number on display is an operand, then the calculator appends the digit to the end of the operand.

 

 


go:-

    calculator(Display,Os),

    cgWindow(Win,"calculator"),Win^topMargin #= 30, Win^leftMargin #= 10,

    handleWindowClosing(Win),

    cgSame(Os,window,Win),

    cgJava(calculator,Os).

 

handleWindowClosing(Win),{windowClosing(Win)} => cgClose(Win).

 

calculator(Display,Os):-

    % components

    cgTextField(Display), Display^fontSize #= 16,

    cgSetEditable(Display,0),

    %

    Buttons=[B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,Bc,Bdiv,Bmul,Bsub,Badd,Beq,Bdot],

    Ts=["0","1","2","3","4","5","6","7","8","9","C","/","*","-","+","=","."],

    cgButton(Buttons,Ts),

    Display^width #= B0^width*2,

    B0^width #>50,

    %

    cgFont(F),F^size#=20,F^style#=bold,

    cgSame(Buttons,font,F),

    cgAbove(Display,Bc),

    cgGrid([[Bc,Bdiv,Bmul,Bsub],

          [B7,B8,  B9,  Badd],

          [B4,B5,  B6,  Badd],

          [B1,B2,  B3,  Beq],

          [B0,B0,  Bdot,Beq]],1,1),

    %

    Cal=cal(Display,0,"+",result_is_on),

    handleButtons(Buttons,Cal),

    Os=[Display|Buttons].

 

%%

handleButtons([],Cal).

handleButtons([B|Bs],Cal):-

    handleButton(B,Cal),

    handleButtons(Bs,Cal).

 

handleButton(B,Cal),{actionPerformed(B)} =>

    cgGetText(B,Text),

    catch(handleButtonAction(Text,Cal),_,true).

 

handleButtonAction("C",Cal):-!, 

    Cal=cal(Display,_Acc,_Op,_OnDisplay),

    setarg(2,Cal,0),   % acc

    setarg(3,Cal,"+"), % op

    setarg(4,Cal,result_is_on), % result on display

    cgSetText(Display,""),

    cgShow(Display).

handleButtonAction(Op,Cal):-operator(Op),!,

    (Cal=cal(_Display,_Acc,_Op,operand_is_on)->applyOperation(Cal);true),

    setarg(3,Cal,Op).

handleButtonAction("=",Cal):-!,

    applyOperation(Cal).

handleButtonAction(X,Cal):-

    appendInput(X,Cal).

 

%% operations on Cal

appendInput(X,Cal):-

    Cal=cal(Display,_Acc,_Op,result_is_on),!, % result is on display

    cgSetText(Display,""),

    setarg(4,Cal,operand_is_on),

    appendInput(X,Cal).

appendInput(".",Cal):-

    Cal=cal(Display,_Acc,_Op,OnDisplay),

    cgGetText(Display,Operand),

    member(0'.,Operand),!.  %0'.=X -> [X]="0"

appendInput([D],Cal):-

    Cal=cal(Display,_Acc,_Op,OnDisplay),

    cgGetText(Display,CurText),

    append(CurText,[D],NewText),

    cgSetText(Display,NewText),

    cgShow(Display).

 

applyOperation(Cal):-

    Cal=cal(Display,Acc,Op,OnDisplay),

    cgGetText(Display,String), number_codes(Operand,String),

    applyOperation(Op,Acc,Operand,NewAcc),

    number_codes(NewAcc,NewString), cgSetText(Display,NewString),

    setarg(2,Cal,NewAcc),       

    setarg(4,Cal,result_is_on),

    cgShow(Display).

   

operator("+").

operator("-").

operator("/").

operator("*").

 

applyOperation("+",Op1,Op2,Res):-Res is Op1+Op2.

applyOperation("-",Op1,Op2,Res):-Res is Op1-Op2.

applyOperation("*",Op1,Op2,Res):-Res is Op1*Op2.

applyOperation("/",Op1,Op2,Res):-Res is Op1/Op2.

 

 


8.5 Building a digital clock

An animation is a sequence of frames of objects that change along a time line. Animation is better than static graphics for presenting many kinds of data because of its dynamic nature. In this example, we consider how to build the digital clock as shown in Figure 11.

 

 The display shows three integers separated by colons that represents respectively the hour, minute, and second of the current time.  Both the integers and the colons are drawn as labels. In order to let the packer determine the sizes of the labels, the program initializes integer labels to “00”.   The predicate tick(Hour,Minute,Second) repeatedly updates the time and shows it every one second. Notice that whenever a graphical component is shown, its previous image is cleaned automatically. Therefore, the program does not need to clean the display before showing the next clock time.                                                 

                                                                 

Figure 11. A digital clock.

 

 


go:-

    cgWindow(Win,"clock"), Win^topMargin #= 30, Win^leftMargin #= 10,

    cgLabel([Hour,Minute,Second,Sep1,Sep2],["00","00","00",":",":"]),

    cgSame([Hour,Minute,Second,Sep1,Sep2],fontSize,36),

    cgTable([[Hour,Sep1,Minute,Sep2,Second]]),

    cgSame([Hour,Minute,Second,Sep1,Sep2],window,Win),

    cgPack([Hour,Minute,Second,Sep1,Sep2]),

    cgShow([Sep1,Sep2]),

    handleWindowClosing(Win,Flag),

    tick(Hour,Minute,Second,Flag).

 

handleWindowClosing(Win,Flag),{windowClosing(Win)} =>

    Flag=1,

    cgClose(Win).

 

tick(Hour,Minute,Second,Flag):-

    timer(T,1000), % create a timer

    timer_start(T),

    tick(T,Hour,Minute,Second,Flag).

 

tick(Timer,Hour,Minute,Second,Flag),var(Flag),

    {time(Timer)}

    =>

    time(H,M,S), %get the current time

    number_codes(H,HString), addZero(HString,HString1),

    cgSetText(Hour,HString1),

    number_codes(M,MString), addZero(MString,MString1),

    cgSetText(Minute,MString1),

    number_codes(S,SString), addZero(SString,SString1),

    cgSetText(Second,SString1),

    cgShow([Hour,Minute,Second]).

tick(Timer,Hour,Minute,Second,Flag) => true.

 

addZero([D],String1):-!,String1=[0'0,D].

addZero(String,String1):-String1=String.

 


   

8.6 Demonstrating a geometry theorem on quadrilaterals

This example program demonstrates the following geometry theorem on quadrilaterals: The quadrilateral formed by the four edges that connect the middle points of the edges of another quadrilateral is always a parallelogram. Figure 12 shows two snapshots. You can move any point of the outer quadrilateral by dragging it. Wherever the outer point moves, the four points of the inner quadrilateral always stay at the middle points of the four edges of the outer quadrilateral.

Figure 12. Demonstrating a geometry theorem.

 

The program generates and shows two quadrilaterals, and generates three agents that handle mouse events and maintain the constraints. Let Q be the outer and P be the inner quadrilaterals. The agent handleMouseDown is triggered when the mouse is pressed. It detects whether a point of Q is selected. The agent handleMouseUp is triggered when the mouse is released. It deselects the point selected if any. The agent handleMouseDrag is activated when a point is dragged. If the mouse drag occurs while a point is selected, the agent moves the point and re-computes Q’s points. The three agents are defined in Figure 13.

All the of three agents share the window Win and an object O that is a Prolog term of the following structure:

 

            quadrilaterals(Q,P,Selected)

 

where Q and P are two polygons, and Selected takes for the form of pointSelected(I) where I is the index of the selected point (0 if no point of Q is selected). The predicate selectPoint(X,Y,O) in line (3) sets Selected to I if the Ith point of Q is close enough to <X,Y>. The predicate deselectPoint(O) in line (5) sets Selected to 0. The predicate selectedPoint(O,I) in line (7) succeeds if I is the selected point. The predicate updatePoint(O,I,X,Y)in line (10) updates the Ith point of Q to <X,Y>, which is defined as follows:

 

updatePoint(O,I,X,Y):-

O=quadrilaterals(Q,P,Selected),

          Q^xs(I) #:= X,

          Q^ys(I) #:= Y.

 

The notation Q^xs(I) refers to the Ith element of the attribute xs of O, which is an array.

 

The predicate recomputeP(O) in line (11) re-computes the points of the quadrilateral P such that the points remain at the middles of the edges of Q. After the attributes of an object are updated, it is drawn again. When drawing an object that is already on a window, the system automatically cleans the object before re-drawing it.

handleMouseDown(Win,O),{mousePressed(Win,E)} => (1)

     E^x #= X, E^y #= Y,                        (2)

    selectPoint(X,Y,O).                        (3)

 

handleMouseUp(Win,O),{mouseReleased(Win,E)} =>  (4)

    deselectPoint(O).                          (5)

 

handleMouseDrag(Win,O),{mouseDragged(Win,E)} => (6)

    (selectedPoint(O,I) ->                     (7)

      E^x #= X,                                 (8)

      E^y #= Y,                                 (9)

 updatePoint(O,I,X,Y),                     (10)

 recomputeP(O);                            (11)

 true).

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 13. Definitions of mouse event handlers.

 

 


go:-

    cgWindow(Win,"geometryTheorem"),

    Win^topMargin #= 100, Win^leftMargin #= 100,

    handleWindowClosing(Win), Win^width #>600, Win^height #> 700,

    cgRectangle(R),R^fill #=0,R^window #= Win,

    R^width #= 400, R^height #= 500,

    cgPack(R),

    cgPolygon(Q), Q^n #= 4, Q^fill #= 0,

    Q^point(1) #= R^leftTopPoint,

    Q^point(2) #= R^leftBottomPoint,

    Q^point(3) #= R^rightBottomPoint,

    Q^point(4) #= R^rightTopPoint,

    cgPolygon(P),P^n #= 4,P^fill #= 0,

    cgSame([P,Q],window,Win),

    cgPack(Q),

    middle(P,Q),

    State=pointSelected(0),

    handleChange(Win,Q,P,State),

    cgShow([P,Q]).

 

handleWindowClosing(Win),{windowClosing(Win)} => cgClose(Win).

 

middle(P,Q):-   

    middle(P,Q,1,2),

    middle(P,Q,2,3),

    middle(P,Q,3,4),

    middle(P,Q,4,1).

 

middle(P,Q,I,J):-

    P^xs(I) #:= (Q^xs(I)+Q^xs(J))//2,

    P^ys(I) #:= (Q^ys(I)+Q^ys(J))//2.

 

handleChange(Win,Q,P,State):-

    handleMouseMove(Win,Q),

    handleMouseDown(Win,Q,P,State),

    handleMouseUp(Win,Q,P,State),

    handleMouseDrag(Win,Q,P,State).

   

handleMouseMove(Win,Q),{mouseMoved(Win,E)} =>

    E^x #= X, E^y #= Y,

    ((closeEnough(X,Y,1,Q);

      closeEnough(X,Y,2,Q);

      closeEnough(X,Y,3,Q);

      closeEnough(X,Y,4,Q))->

     changeCursor(Win,move_cursor);

     changeCursor(Win,default_cursor)).

 

handleMouseDown(Win,Q,P,State),{mousePressed(Win,E)} =>

    critical_region(selectPoint(E,Q,State)).

 

handleMouseUp(Win,Q,P,State),{mouseReleased(Win,E)} =>

    setarg(1,State,0).

 

handleMouseDrag(Win,Q,P,State),{mouseDragged(Win,E)} =>

    arg(1,State,I),

    (I>0 ->

     E^x #= X,

     E^y #= Y,

     Q^xs(I) #:= X,

     Q^ys(I) #:= Y,

     middle(P,Q),

     cgShow([P,Q]),

     changeCursor(Win,move_cursor);

     true).

 

selectPoint(E,Q,State):-

    E^x #= X,

    E^y #= Y,

    (closeEnough(X,Y,1,Q)->setarg(1,State,1);true),

    (closeEnough(X,Y,2,Q)->setarg(1,State,2);true),

    (closeEnough(X,Y,3,Q)->setarg(1,State,3);true),

    (closeEnough(X,Y,4,Q)->setarg(1,State,4);true).

 

closeEnough(X,Y,I,Q):-

    Q^xs(I) #= X1,

    Q^ys(I) #= Y1,

    sqrt((X-X1)*(X-X1)+(Y1-Y)*(Y1-Y)) < 5.

 

changeCursor(Win,CursorType):-

    cgGetCursor(Win,CursorType),!.

changeCursor(Win,CursorType):-

    cgSetCursor(Win,CursorType).

 



Appendix-I. Built-in Components

Table 1. Summary of components.

Object

Constrainable attributes

Primitives

All

bottomY

center

centerX

centerY

color

height

leftBottomPoint

leftTopPoint

location

rightBottomPoint

rightTopPoint

rightX

size

width

window

x

y

cgClean(O)

cgGetBackground(O,Color)

cgMove(O,X,Y)

cgPack(O)

cgResize(O,Width,Height)

cgScale(O,Factor)

cgSetBackground(O,Color)

cgSetVisible(O,lOr0)

cgShow(O)

Arc

fill

StartAngle

arcAngle

cgArc(O)

 

Button

font

fontName

fontSize

fontStyle

cgButton(O)

cgButton(O,T)


cgGetCursor(O,Cursor)

cgSetCursor(O,Cursor)

cgGetText(O,T)

cgIsEnabled(O)

cgSetEnabled(O,OneOrZero)

cgSetText(O,T)

Checkbox

font

fontName

fontSize

fontStyle

cgCheckbox(O)

cgCheckbox(O,T)

cgGetCursor(O,Cursor)

cgCheckboxGroup(Os)

cgGetText(O,T)

cgGetState(O,S)

cgIsEnabled(O)

cgSetCursor(O,Cursor)

cgSetEnabled(O,OneOrZero)

cgSetState(O,S)

cgSetText(O,T)

Choice

font

fontName

fontSize

fontStyle

cgChoice(O)

cgChoice(O,Items)

cgAdd(O,Items)

cgAdd(O,Item,Index)

cgGetCursor(O,Cursor)

cgIsEnabled(O)

cgRemove(O,Items)

cgSelect(O,Item)

cgSelectedItem(O,Item)

cgSetCursor(O,Cursor)

cgSetEnabled(O,OneOrZero)

Image

name

cgImage(O)

cgImage(O,Name)

Label

font

fontName

fontSize

fontStyle

cgLabel(O)

cgLabel(O,T)

 

cgGetAlignment(O,Align)

cgGetText(O,T)

cgSetAlignment(O,Align)

cgSetText(O,T)

Line

arrow1

arrowLength1

arrowThickness1

arrow2

arrowLength2

arrowThickness2

point1

point2

thickness

x1

x2

y1

y2

cgLine(O)

List

font

fontName

fontSize

fontStyle

cgList(O)

cgList(O,Items)

cgAdd(O,Items)

cgAdd(O,Item,Index)

cgGetCursor(O,Cursor)

cgIsEnabled(O)

cgRemove(O,Items)

cgSelect(O,Item)

cgSelectedItems(O,Items)

cgSetCursor(O,Cursor)

cgSetEnabled(O,OneOrZero)

Oval

fill

cgOval(O)

Polygon

fill

n

point(I)

x(I)

y(I)

cgPolygon(O)

Rectangle

fill

cgRectangle(O)

RoundRectangle

arcWidth

arcHeight

fill

cgRoundRectangle(O)

Scrollbar

 

cgScrollbar(O)

cgScrollbar(O,Or,V,VA,Min,Max)

 

cgGetBlockIncrement(O,Val)

cgGetMaximum(O,Max)

cgGetMinimum(O,Min

 

cgGetOrientation(O,Orient)

cgSetOrientation(O,Orient)

cgGetUnitIncrement(O,Val)

cgGetValue(O,Val)

cgGetVisibleAmount(O,Val)

cgSetBlockIncrement(O,Val)

cgSetMaximum(O,Max)

cgSetMinimum(O,Min)

cgSetUnitIncrement(O,Val)

cgSetValue(O,Val)

cgSetVisibleAmount(O,Val)

Square

fill

cgSquare(O)

Star

angle0

diameter

fill

innerDiameter

n

x0

y0

cgStar(O)

String

font

fontName

fontSize

fontStyle

cgString(O)

cgString(O,T)

 

cgGetAlignment(O,Align)

cgGetText(O,T)

cgSetAlignment(O,Align)

cgSetText(O,T)

TextArea

font

fontName

fontSize

fontStyle

cgTextArea(O)

cgTextArea(O,T)

 

cgAppend(O,Text)

cgGetCursor(O,Cursor)

cgGetColumns(O,NumOfColumns)

cgGetRows(O,NumOfRows)

cgGetText(O,Text)

cgInsert(O,Text,Pos)

cgIsEditable(O)

cgIsEnabled(O)

cgSetColumns(O,NumOfColumns)

cgSetCursor(O,Cursor)

cgSetEditable(O,OneOrZero)

cgSetEnabled(O,OneOrZero)

cgSetRows(O,NumOfRows)

TextField

font

fontName

fontSize

fontStyle

cgTextField(O)

cgTextField(O,T)

 

cgGetColumns(O,NumOfColumns)

cgGetCursor(O,Cursor)

cgGetText(O,Text)

cgIsEditable(O)

cgIsEnabled(O)

cgSetColumns(O,NumOfColumns)

cgSetCursor(O,Cursor)

cgSetEditable(O,OneOrZero)

cgSetEnabled(O,OneOrZero)

TextBox

font

fontName

fontSize

fontStyle

cgTextBox(O)

cgTextBox(O,T)

 

cgGetAlignment(O,Align)

cgGetText(O,T)

cgSetAlignment(O,Align)

cgSetText(O,T)

Triangle

fill

point1

point2

point3

x1,x2,x3

y1,y2,y3

cgTriangle(O)

 

 

 


 

Appendix-II. Built-in Events

Table 2. Summary of events.

Event
Event sources
E’s Attributes
Primitives on E

actionPerfromed(O)

Button, 

MenuItem,

TextField

 

 

focusGained(O)

focusLost(O)

Component

Window

 

 

keyPressed(O,E)

keyReleased(O,E)

keyTyped(O,E)

Component

Window

code

char

modifiers

cgShiftIsDown(E)

cgControlIsDown(E)

cgMetaIsDown(E)

cgAltIsDown(E)

mousePressed(O,E)

mouseReleased(O,E)

mouseEntered(O,E)

mouseExited(O,E)

mouseClicked(O,E)

mouseDragged(O,E)

mouseMoved(O,E)

Component

Window

x

y

count

modifiers

cgIsLeftButton(E)

cgIsRightButton(E)

cgShiftIsDown(E)

cgControlIsDown(E)

cgMetaIsDown(E)

cgAltIsDown(E)

windowClosing(O)

windowOpened(O)

windowIconified(O)

windowDeiconified(O)

windowClosed(O)

windowActivated(O)

windowDeactivated(O)

Window

 

 

componentResized(O,E)

componentMoved(O,E)

Window

x

y

width

height

 

textValueChanged(O)

TextField

TextArea

 

 

itemStateChanged(O,E)

Checkbox

CheckboxMenuItem

Choice

List

index

state

 

adjustmentValueChanged(O,E)

Scrollbar

adjustmentType

value

 

 

time(T)

Timer

 

 

 

 


Appendix-III. Built-ins for Testing Key Codes


vk_0(C)


vk_1(C)

vk_2(C)

vk_3(C)

vk_4(C)

vk_5(C)

vk_6(C)

vk_7(C)

vk_8(C)

vk_9(C)

vk_A(C)

vk_B(C)

vk_C(C)

vk_D(C)

vk_E(C)

vk_F(C)

vk_G(C)

vk_H(C)

vk_I(C)

vk_J(C)

vk_K(C)

vk_L(C)

vk_M(C)

vk_N(C)

vk_O(C)

vk_P(C)

vk_Q(C)

vk_R(C)

vk_S(C)

vk_T(C)

vk_U(C)

vk_V(C)

vk_W(C)

vk_X(C)

vk_Y(C)

vk_Z(C)

vk_ACCEPT(C)

vk_ADD(C)

vk_ALT(C)

vk_BACK_QUOTE(C)

vk_BACK_SLASH(C)

vk_BACK_SPACE(C)

vk_CANCEL(C)

vk_CAPS_LOCK(C)

vk_CLEAR(C)

vk_CLOSE_BRACKET(C)

vk_COMMA(C)

vk_CONTROL(C)

vk_CONVERT(C)

vk_DECIMAL(C)

vk_DELETE(C)

vk_DIVIDE(C)

vk_DOWN(C)

vk_END(C)

vk_ENTER(C)

vk_EQUALS(C)

vk_ESCAPE(C)

vk_F1(C)

vk_F10(C)

vk_F11(C)

vk_F12(C)

vk_F2(C)

vk_F3(C)

vk_F4(C)

vk_F5(C)

vk_F6(C)

vk_F7(C)

vk_F8(C)

vk_F9(C)

vk_FINAL(C)

vk_HELP(C)

vk_HOME(C)

vk_INSERT(C)

vk_KANA(C)

vk_KANJI(C)

vk_LEFT(C)

vk_META(C)

vk_MODECHANGE(C)

vk_MULTIPLY(C)

vk_NONCONVERT(C)

vk_NUM_LOCK(C)

vk_NUMPAD0(C)

vk_NUMPAD1(C)

vk_NUMPAD2(C)

vk_NUMPAD3(C)

vk_NUMPAD4(C)

vk_NUMPAD5(C)

vk_NUMPAD6(C)

vk_NUMPAD7(C)

vk_NUMPAD8(C)

vk_NUMPAD9(C)

vk_OPEN_BRACKET(C)

vk_PAGE_DOWN(C)

vk_PAGE_UP(C)

vk_PAUSE(C)

vk_PERIOD(C)

vk_PRINTSCREEN(C)

vk_QUOTE(C)

vk_RIGHT(C)

vk_SCROLL_LOCK(C)

vk_SEMICOLON(C)

vk_SEPARATER(C)

vk_SHIFT(C)

vk_SLASH(C)

vk_SPACE(C)

vk_SUBTRACT(C)

vk_TAB(C)

vk_UNDEFINED(C)

vk_UP(C)



Index


actionPerformed(O), 31

animation, 28

Arc, 12

AWT control components, 12

black, 10

blue, 10

bottomY, 10

cColor(C), 7

center, 10

centerX, 10

centerY, 10

cgAbove(O1,O2), 22

cgAdd, 13, 15

cgAppend, 18

cgArc(O), 9

cgArcs, 9

cgBelow(O1,O2), 22

cgButton, 3, 9, 13

cgCheckbox, 13

cgCheckboxGroup, 13

cgCheckboxMenuItem, 19

cgCircle(O), 9

cgClean, 6, 9, 11

cgClean(W), 8

cgCleanDefaultWindow, 9

cgCleanDrawing, 8

cgClose, 5

cgClose(W), 8

cgCloseDefaultWindow, 8

cgDefaultWindow, 4

cgDefaultWindow(W), 8

cgFont(F), 7, 19

cgGetAlignment, 14, 17, 18

cgGetBackground, 10

cgGetColumns, 17, 18

cgGetCursor, 12

cgGetRows, 17

cgGetText, 13, 14, 17, 18

cgGetTitle(W,Title), 8

cgGrid(L), 24

cgGrid(L,PadX,PadY), 22

cgImage(O), 9

cgInsert, 18

cgInside(O1,O2), 22

cgIsAltDown(E), 32

cgIsControlDown(E), 32

cgIsEditable, 17, 18

cgIsEnabled, 12

cgIsLeftButton(E), 32

cgIsMetaDown(E), 32

cgIsRightButton(E), 32

cgIsShiftDown(E), 32

cgLabel(O), 9

cgLeft(O1,O2), 22

cgLine(O), 9

cgMenuBar, 20

cgMenuItem, 19

cgMove(OrigO,NewO,X,Y), 27

cgNotOverlap(L), 25

cgOutside(O1,O2), 22

cgOval(O), 9

cgPack, 11

cgPack(O), 26

cgPoint(P), 7

cgPolygon(O), 9

cgRectangle(O), 9

cgRemove, 13, 15

cgResize(OrigO,NewO,Width,Height, 27

cgRight(O1,O2), 22

cgRoundRectangle(O), 9

cgSame(L,AttributeName), 22

cgSame(L,AttributeName,Value), 22

cgScale(OrigO,NewO,F), 26

cgSelect, 15

cgSelectedItem, 13, 15

cgSelectedItems, 15

cgSetAlignment, 14, 17, 18

cgSetBackground, 10

cgSetColumns, 17, 18

cgSetCursor, 12, 46, 47, 48

cgSetEditable, 17, 18

cgSetEnabled, 12

cgSetMenuBar(W,MenuBar), 8

cgSetRows, 17

cgSetText, 12, 13, 14, 17, 18

cgSetTitle(W,Title), 8

cgSetVisible(W,OneOrZero), 8

cgShow, 4, 11

cgShow(O), 26

cgShow(W), 8

cgSleep(T), 28

cgSquare(O), 9

cgStar, 5

cgStar(O), 9

cgStartRecord (Name), 29

cgStartRecordAnimation(Name), 29

cgStopRecord, 29

cgTable(L), 24

cgTable(L,PadX,PadY), 24

cgTextArea(O), 9

cgTextField(O), 9

cgTriangle(O), 9

cgWindow, 4

cgWindow(W), 4, 8

Checkbox menu items, 19

Circle, 13

color, 10

componentMoved(O,E), 33

componentResized(O,E), 33

Cursor, 12

cyan, 10

darkGray, 10

Dialog, 7

DialogInput, 7

disequality, 22

equality, 22

focusGained(O), 31

focusLost(O), 31

font, 10

fontName, 10

fontSize, 10

fontStyle, 10

gray, 10

height, 8, 10

Helvetica, 7

Image, 14

inequality, 22

Installation, 3

itemStateChanged(O,E), 33

keyPressed(O,E), 31

keyReleased(O,E), 31

keyTyped(O,E), 32

Label, 14

leftBottomPoint, 10

leftTopPoint, 10

lightGray, 10

Line, 14

magenta, 10

Menu bars, 20

Menu items, 19

Menus, 19

mouseClicked(O,E), 32

mouseDragged(O,E), 32

mouseEntered(O,E), 32

mouseExited(O,E), 32

mouseMoved(O,E), 32

mousePressed(O,E), 32

mouseReleased(O,E), 32

name, 7

orange, 10

Oval, 15

pink, 10

Polygon, 15

Rectangle, 15

red, 10

rightBottomPoint, 10

rightX, 10

RoundRectangle, 15

size, 7, 10

Square, 16

Star, 17

String, 17

style, 7

TextArea, 17

TextField, 18

time(T), 33

Timer, 33

TimesRoman, 7

Triangle, 18, 19

white, 10

width, 8, 9

windowActivated(O), 33

windowClosed(O), 33

windowClosing(O), 32

windowDeactivated(O), 33

windowDeiconified(O), 33

windowIconified(O), 32

windowOpened(O), 32

x, 7, 9

y, 7, 9

yellow, 10

ZapfDingbats, 7