GUI part 1

>> << Ndx Usr Pri Phr Dic Rel Voc !: wd Help Primer

# Graphical user interface

These days almost no programming task is complete until it is packaged in a graphical user interface (GUI).

Let's add a GUI to your `centigrade` and `fahrenheit` verbs.

There are many steps in building a form and an application. The exact steps you should follow are contained in the series of indented, bulleted items. General discussion and background information is provided in text between these bulleted items.

Run your cf.ijs script and make sure that centigrade and fahrenheit work.

The first step in creating a GUI is to create a form definition. A form definition is stored in a script file just as are all your other definitions.

Create a new script file, save it as a permanent file in the user directory, and start the form editor. The form editor is covered in more detail in the J Online Documentation available on the help menu and you should refer to that if you have problems with the following steps, or want more information at this time.

- create a new script file with File|New IJS

- save it in the user directory as cfgui.ijs with File|Save As...

- start the form editor with Edit|Form Edit

You should now have the Form Edit dialog box on the screen.

- type `cfgui` for your form name

- select the empty form item in the listbox

- press OK to close the dialog

You should now have two new windows on the screen, one in the upper left corner and one in the center of the screen that look something like:

The small form in the corner is the new form you are editing. The Design dialog allows you to customize the form and is in the middle of the screen. The script file cfgui.ijs has had text added to it that defines the form.

Create a static control in your form with the text centigrade. A static control is used to label other controls.

- press the New... button in the Design dialog

- in the New Control dialog select static from the listbox

- type `centigrade` into the caption edit box

- press OK

New controls are created in the upper left corner of the form. You can drag a control with the mouse. To drag a control, point at it with the mouse, hold down the left mouse button and move it.

- drag the centigrade label down and to the right a bit

Create an edit control with an id of `cid` for the centigrade value. The id is very important as it is used as the name of the noun used for the control as well as being used in commands to indicate which control they affect.

- press the New... button

- select a class of edit

- type in `cid` as the control id

- press OK

- drag the `cid` edit control to the right of the label control

Create a static control with the text Fahrenheit and an edit control with an id of `fid`.

- repeat steps similar to the above to create a Fahrenheit static label and an fid edit control

Experiment a bit with moving the controls around. Grab edges or corners to resize them. If you make a mistake you can select a control with the mouse and press the Delete key to delete it and then recreate it.

Your form should now look something like the following:

The form design is finished. Let's exit the form editor and try running the form.

- press OK in the Design dialog

The form definition is now in the cfgui.ijs script. Let's take a look at what the form editor put into the script. The numbers giving screen coordinate will be different, but your script should look something like:

    NB. base form

    CFGUI=: 0 : 0
    pc cfgui;
    xywh 12 18 40 10;cc ccstatic static;cn "centigrade:";
    xywh 56 16 40 14;cc cid edit ws_border es_autohscroll;
    xywh 12 40 40 10;cc ccstatic static;cn "Fahrenheit:";
    xywh 56 36 40 14;cc fid edit ws_border es_autohscroll;
    pas 6 6;pcenter;
    rem form end;
    )

    cfgui_run=: 3 : 0
    wd CFGUI
    NB. initialize form here
    wd 'pshow;'
    )

    cfgui_close=: 3 : 0
    wd'pclose'
    )

All interactions with forms are done with the `wd` (Window Driver) verb. The `wd` argument is always a string that starts with a command. A string can contain multiple commands separated by semicolons.

The noun `CFGUI` is defined by the conjunction `:` in a manner similar to how verbs are defined. The left argument of `0` creates a noun. It is defined as the lines of characters up to the line which contains only the `)`. It contains the commands that will create the form. Don't worry about the details now, but most of it should make some sense. Commands are followed by parameters and multiple commands on a line are separated by `;`. The `pc` command is a parent create (a form is referred to as a parent). The next line has an `xywh` command that sets a rectangular area on the form and is followed by a `cc` command (create child) that creates one of the controls you put on the form.

After the definition of `CFGUI` you will see that the editor has created a verb called `cfgui_run`. This verb ignores its argument. It executes the `wd` verb with `CFGUI` as an argument. This creates the form, but doesn't show it. The final `wd` with the argument `'pshow;'` will show the parent (form).

At this point the cfgui.ijs script has not been run so the definitions are just text in the script file and have not been defined. After you run the script you are ready to run your application.

- run the cfgui.ijs script with Run|Window

- in the ijx window:`cfgui_run 0`

When you execute `cfgui_run 0` you should see your form in the middle of the screen. Typing into the controls and pressing Enter has no effect because you have no code connected to the events yet.

You can close the form manually by executing the `wd` command reset that closes all forms.

- in the ijx window: wd 'reset'

When you type a value in the centigrade edit control and press Enter you cause an event. An event is identified by the form and the control in which it occurs and the type of the event. An Enter in an edit control is a button event (pressing enter in an edit field is analogous to pressing a button control). So, the event of interest here is for form `cfgui`, control `cid`, and is a button event.

When an event occurs, a verb called the event handler is executed. The name of the verb that is executed is determined by the event. The name of an event handler is made up of three parts: `formid_controlid_event`. So, the event handler of interest has the name `cfgui_cid_button`.

The event handler `cfgui_cid_button` should convert the value from the `cid` edit control to Fahrenheit and then display that result in the `fid` edit control.

The form editor can automatically create a skeleton of this event handler for you. In the form editor, hold down the Ctrl key and click a control, and you will be switched to editing in the script at the definition of the verb that handles the event for that control.

You closed the form editor, so the first thing is to restart the form editor. Select the cfgui.ijs script and start the form editor with Edit|Form Edit.

- select cfgui.ijs (titlebar highlighted)

- start form editor with Edit|Form Edit

Your form should again appear open for editing in the corner of your screen.

- hold down the Ctrl key and click the cid control

You should be positioned at the skeleton definition of `cfgui_cid_button` in the cfgui.ijs script. You need to define that verb. When the event handler is executed the noun `cid` will automatically have the value of the contents of the edit field. It will be a string and you need to convert that to a number with the `".` primitive.

    t =. 0 ". cid

The next thing is to convert that centigrade value to Fahrenheit.

    t =. fahrenheit t

The noun `t` is the number you want to display in the `fid` edit control. The number must be converted to a string before it can be shown in an edit field. Use `":` (format) for this.

    t =. ": t

Finally, write the text string to the `fid` edit field.

    wd 'set fid ' , t

The `wd` argument has a command of `set`, the id of the control to set, and `t` contains the data to set. The `*` indicates all the following data is the text to set in the control.

Add these sentences to the definition in the cfgui.ijs script.

    cfgui_cid_button=: 3 : 0
    t =. 0 ". cid
    t =. fahrenheit t
    t =. ": t
    wd 'set fid *', t
    )

Be careful to type this correctly into your script.

You return to the form editor by holding down the Ctrl key and clicking the script window.

- add the sentences to the definition of `cfgui_cid_button`

- hold the Ctrl key and click the script to return to the form editor

- press OK in the Design dialog

At this point the cfgui.ijs script has not been run so the changes are just text in the script file.

- run the script with Run|Window

- in the ijx window run the application: `cfgui_run 0`

You should see your form in the middle of the screen. Type a number into the centigrade field and press Enter. The Fahrenheit value should display in its field.

If you type into the Fahrenheit field and press Enter nothing happens. This is because you have not provided a handler for that event. If an event handler verb is not defined, the event is ignored. Let's define the event handler for Enter in the Fahrenheit field now. Start the form editor and hold down the Ctrl key and click the fid control to get to the definition of the verb for that event. The definition for `cfgui_fid_button` is similar to that of `cfgui_cid_button`.

    cfgui_fid_button=: 3 : 0
    t =. 0 ". fid
    t =. centigrade t
    wd'set fid *', ": t
    )

- select cfgui.ijs (titlebar highlighted)

- start the form editor with Edit|Form Edit

- hold down the Ctrl key and click the fid control

- add the `cfgui_fid_button` definition to the script

- hold the Ctrl key and click the script to return to the form editor

- press OK in the Design dialog

- run the script with Run|Window

- in the ijx window: `cfgui_run 0`

Now when you type a value in the Fahrenheit field and press Enter it will be converted and display in the centigrade field.

Finally, add a close button so that the form will be able to close itself. The event handler will be as follows:

    cfgui_close_button=: 3 : 0
    wd 'pclose'
    )

The wd command pclose (parent close) closes the form.

- in the ijx window: `wd 'reset'`

- start the form editor with Edit|Form Edit

- press the New... button

- select a class of button

- type close as the control id

- type Close in the caption field

- press OK

- drag the Close button to the right side of the form

- hold down the Ctrl key and click the Close button

- add the `wd 'pclose'` sentence to the definition

- hold the Ctrl key and click the script to return to the form editor

- press OK in the Design dialog

- run the script with Run|Window

- in the ijx window: cfgui_run 0

When you tire of doing conversions you can press the Close button to close your form.

Congratulations! you have written a GUI application in J. It is simple and has rough edges, but you are over the high hurdles.

>> << Ndx Usr Pri Phr Dic Rel Voc !: wd Help Primer