13. Creating Graphical User Interfaces in the Jess Language
Jess, being just a set of Java classes, is easily incorporated as a library into graphical applications written in Java. It is also possible, though, to write graphical applications in the Jess language itself. The details of this are outlined in this chapter.13.1. Handling Java AWT events
It should now be obvious that you can easily construct GUI objects from Jess. For example, here is a Button:Jess> (defglobal ?*b* = (new java.awt.Button "Hello"))
What might not be obvious is how, from Jess, you can arrange to have something happen when the button is pressed. This section of this manual shows how to implement an interface using only Jess code. Therefore, all you need to do to create event handlers in Jess is to implement the appropriate interface.
An example should clarify matters. Let's say that when a Hello button is pressed, you would like the string Hello, World! to be printed to standard output (how original!). Here's a complete program in Jess that demonstrates how to do it:
Jess> (import java.awt.*)
Jess> (import java.awt.event.*)
Jess> ;; Create the widgets (defglobal ?*f* = (new Frame "Button Demo"))
Jess> (defglobal ?*b* = (new Button "Hello"))
Jess> ;; Add a listener to the button (?*b* addActionListener (implement ActionListener using (lambda (?name ?evt) (printout t "Hello, World!" crlf))))
Jess> ;; Assemble and display the GUI (?*f* add ?*b*)
Jess> (?*f* pack)
Jess> (set ?*f* visible TRUE)
Jess> ;; Add a WINDOW_CLOSING listener (import java.awt.event.WindowEvent) (?*f* addWindowListener (implement WindowListener using (lambda (?name ?event) (if (= (?event getID) (WindowEvent.WINDOW_CLOSING)) then (exit)))))
Jess> (import javax.swing.*)
Jess> (import java.awt.event.*)
Jess> (import javax.swing.JFrame)
Jess> (defglobal ?*f* = (new JFrame "Button Demo"))
Jess> (defglobal ?*b* = (new JButton "Hello"))
Jess> (defglobal ?*p* = (get ?*f* contentPane))
Jess> (?*b* addActionListener (implement ActionListener using (lambda (?name ?event) (printout t "Hello, World!" crlf))))
Jess> (?*p* add ?*b*)
Jess> (?*f* pack)
Jess> (set ?*f* visible TRUE)
Jess> (?*f* setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE))
13.2. Screen Painting and Graphics
As you may know, the most common method of drawing pictures in Java is to subclass either java.awt.Canvas or javax.swing.JPanel, overriding the void paint(Graphics g) or void paintComponent(Graphics g) method, respectively, to call the methods of the java.awt.Graphics argument to do the drawing. Well, Jess can't help you to subclass a Java class (at least not yet!), but it does provide adaptor classes, much like the event adaptors described above, that will help you draw pictures. The classes are named jess.awt.Canvas and jess.swing.JPanel. They can be used as normal Java GUI components: Canvas in AWT applications, and JPanel with Swing. When you construct an instance of these classes, you pass in the name of a Jess function and a reference to a jess.Rete object. Whenever the Java painting method is called to render the Jess component, the Jess component in turn will call the given function. The function will be passed two arguments: theJess> ;; A painting deffunction. This function draws a red 'X' between the ;; four corners of the Canvas on a blue field. (import java.awt.Color) (deffunction painter (?canvas ?graph) (bind ?x (get-member (?canvas getSize) width)) (bind ?y (get-member (?canvas getSize) height)) (?graph setColor (Color.blue)) (?graph fillRect 0 0 ?x ?y) (?graph setColor (Color.red)) (?graph drawLine 0 0 ?x ?y) (?graph drawLine ?x 0 0 ?y))
Jess> ;; Create a canvas and install the paint routine. (bind ?c (new jess.awt.Canvas painter (engine)))