This article is old and is being consolidated into
the book.
Please refer to the corresponding chapter(s) therein. If the chapters or
sections are not completed yet, you can use this article. Refer to the
examples as they are tested against the latest code.
Abstract
Building GUI applications in JudoScript is achieved by its superb capability
of using Java classes and the event handler statement, gui::events.
GUI components are created and glued together in JudoScript. Embedded Java
class and adapter are important mechanisms to create new components.
If they are to be re-used, they can reside in their own source file.
Modern GUI systems are the best examples of object-based systems, where
GUI components are encapsulated in reusable classes and used in a cohesive
event-driven framework. GUI programs become assemblies of components.
There is no significant differences whether those components are glued by
Java or other languages like JudoScript.
The following is the simplest Java Swing GUI writtin in JudoScript.
It demonstrates two key elements in JudoScript GUI programming: a) invoking
Java classes to assemble the GUI, and b) GUI event handling.
Line 2 establishes a javax.swing.JFrame frame and make it
visible on line 3. Lines 6 through 8 is a event handler. Line 7 basically
reads: component frame listens for Window
events and handles the windowClosing message. As you see,
JudoScript provides a new way of specifying your GUI application but does not
introduce any new GUI concepts; all it does is supporting the underlying
Java GUI packages. Therefore, you should be well familiar with Java GUI
programming in order to do GUI programming in JudoScript, and Java AWT/Swing
programming is not covered here; you can find many literatures on these.
So why JudoScript GUI? Two possiblities. The first possibility is you just want
to. JudoScript programs are more direct, intuitive, and there are so many
applications features ready for use. JudoScript supports threads, embedded Java
classes and Java interface adapters, there is no limitation to building
GUI applications. The other possibility is to have a GUI for tools
implementing in JudoScript. The following is another example.
This program sets up three buttons; when the left one is clicked, it
disables the middle one (which has a image), and the right button does
the opposite. The middle button does nothing. In lines 37 through 41,
both left and right buttons b1 and b3 share a same
event handler. GUI programs tend to have many lines but most of them
are rather simple statements. The crux is event handling.
Review Questions
How are GUI applications constructed in JudoScript?
Do you need to learn a new paradigm for building GUI
applications in JudoScript? What you must know?
GUI programs typically involve large number of Java classes. Declaring
them one by one is tedious, because they spread across many different
packages. JudoScript provides a mechanism called standard Java class declaration
shortcut, which are three directives used to easily declare a large
number of standard J2SE and J2EE classes:
gui::events is an event-driven statement for specifying event
handlers. It may appear multiple times in a program. Each handler has a
label and a series of statements associated. The gui::events
statements for specified components must follow the code that the
components are created. The label has three parts (line 37 in
listing 0): the first part is one or more origins of
the event; the second is the event type; the last is one or more messages
of that type of event. The event type corresponds to a Java listener
interface (such as java.awt.event.ActionListener), and the
messages are its methods. All the GUI event messages have one parameter,
an instance that extends java.util.EventObject, which is
stored in the internal variable $_ (line 38).
When multiple components share a same handler, use $_.getSource()
or other more specific methods to find out where the current event is
from. Multiple messages can share a same handler, too, for instance,
a common handler may be specified for mouseEntered() and
mouseExited(). Use $_.getID() or other more specific
methods to find out the type of message for the current event.
Sometimes event handlers are applied to variable components such as menu
items, so the first part of the message label (components) do not make
any sense. In this case, use a name followed by ? in place of
the components to define a named event handler, then use the
setGuiListner() system function to associate a handler with a
component, as shown in the following program. If a gui::events
only has named handoers, it can appear anywhere in the code.
1: !JavaGuiClass #JCheckBoxMenuItem, #JFrame, #JMenu, #JMenuBar
2: !JavaGuiClass #JRadioButtonMenuItem, #JScrollPane, #JTextArea
3: !JavaGuiClass #ActionEvent, #BorderLayout, #ButtonGroup, #ImageIcon
4: !JavaGuiClass #ItemEvent, #KeyEvent, #KeyStroke, #JMenuItem
5:
6: demoFrame = javanew #JFrame('MenuDemo');
7: gui::events { <demoFrame : Window : windowClosing> : exit(0); }
8:
9: //Add regular components to the window, using the default BorderLayout.
10: contentPane = demoFrame.getContentPane();
11: $output = javanew #JTextArea(5, 30);
12: $output.setEditable(false);
13: scrollPane = javanew #JScrollPane($output);
14: contentPane.add(scrollPane, #BorderLayout.CENTER);
15:
16: //Create the menu bar.
17: menuBar = javanew #JMenuBar;
18: demoFrame.setJMenuBar(menuBar);
19:
20: //Build the first menu.
21: menu = javanew #JMenu("A Menu");
22: menu.setMnemonic(#KeyEvent.VK_A);
23: menu.getAccessibleContext().setAccessibleDescription(
24: "The only menu in this program that has menu items");
25: menuBar.add(menu);
26:
27: //a group of JMenuItems
28: menuItem = javanew #JMenuItem("A text-only menu item", #KeyEvent.VK_T);
29: menuItem.setAccelerator(
30: #KeyStroke.getKeyStroke(#KeyEvent.VK_1, #ActionEvent.ALT_MASK));
31: menuItem.getAccessibleContext().setAccessibleDescription(
32: "This doesn't really do anything");
33: setGuiListener(menuItem, 'ACTION');
34: menu.add(menuItem);
35:
36: menuItem = javanew #JMenuItem("Both text and icon",
37: javanew #ImageIcon("images/middle.gif"));
38: menuItem.setMnemonic(#KeyEvent.VK_B);
39: setGuiListener(menuItem, 'ACTION');
40: menu.add(menuItem);
41:
42: gui::events {
43: < ?ACTION : Action : actionPerformed> :
44: local source = $_.getSource();
45: local s = [[*
46: Action event detected.
47: Event source: (* source.getText() *)
48: (an instance of (* getClassName(source) *))
49: *]];
50: $output.append(s);
51:
52: < ?ITEM : Item : itemStateChanged> :
53: local source = $_.getSource();
54: local s = [[*
55: Item event detected.
56: Event source: (* source.getText() *)
57: (an instance of (* getClassName(source) *))
58: New state: (* (($_.getStateChange()==#ItemEvent.SELECTED)
59: ? "selected" : "unselected")
60: *)
61: *]];
62: $output.append(s);
63: }
64:
65: menuItem = javanew #JMenuItem(javanew #ImageIcon("images/middle.gif"));
66: menuItem.setMnemonic(#KeyEvent.VK_D);
67: setGuiListener(menuItem, 'ACTION');
68: menu.add(menuItem);
69:
70: //a group of radio button menu items
71: menu.addSeparator();
72:
73: $group = javanew #ButtonGroup;
74: $rbMenuItem = javanew #JRadioButtonMenuItem("A radio button menu item");
75: $rbMenuItem.setSelected(true);
76: $rbMenuItem.setMnemonic(#KeyEvent.VK_R);
77: $group.add($rbMenuItem);
78: setGuiListener($rbMenuItem, 'ACTION');
79: menu.add($rbMenuItem);
80:
81: $rbMenuItem = javanew #JRadioButtonMenuItem("Another one");
82: $rbMenuItem.setMnemonic(#KeyEvent.VK_O);
83: $group.add($rbMenuItem);
84: setGuiListener($rbMenuItem, 'ACTION');
85: menu.add($rbMenuItem);
86:
87: //a group of check box menu items
88: menu.addSeparator();
89:
90: $cbMenuItem = javanew #JCheckBoxMenuItem("A check box menu item");
91: $cbMenuItem.setMnemonic(#KeyEvent.VK_C);
92: setGuiListener($cbMenuItem, 'ITEM');
93: menu.add($cbMenuItem);
94:
95: $cbMenuItem = javanew #JCheckBoxMenuItem("Another one");
96: $cbMenuItem.setMnemonic(#KeyEvent.VK_H);
97: setGuiListener($cbMenuItem, 'ITEM');
98: menu.add($cbMenuItem);
99:
100: //a submenu
101: menu.addSeparator();
102: submenu = javanew #JMenu("A submenu");
103: submenu.setMnemonic(#KeyEvent.VK_S);
104:
105: menuItem = javanew #JMenuItem("An item in the submenu");
106: menuItem.setAccelerator(
107: #KeyStroke.getKeyStroke(#KeyEvent.VK_2, #ActionEvent.ALT_MASK));
108: setGuiListener(menuItem, 'ACTION');
109: submenu.add(menuItem);
110:
111: menuItem = javanew #JMenuItem("Another item");
112: setGuiListener(menuItem, 'ACTION');
113: submenu.add(menuItem);
114: menu.add(submenu);
115:
116: //Build second menu in the menu bar.
117: menu = javanew #JMenu("Another Menu");
118: menu.setMnemonic(#KeyEvent.VK_N);
119: menu.getAccessibleContext().setAccessibleDescription(
120: "This menu does nothing");
121: menuBar.add(menu);
122:
123: // Returns just the class name -- no package info.
124: function getClassName o {
125: classString = o.getClass().getName();
126: dotIndex = classString.lastIndexOf(".");
127: return classString.substring(dotIndex+1);
128: }
129:
130: demoFrame.setSize(450, 260);
131: demoFrame.setVisible(true);
First of all, we see two gui::events statements on lines 7 and 39.
Starting on lines 42 and 52, there are two named event handlers, "ACTION"
and "ITEM". On lines 33, 39, 67, 78, 84, 97, 108 and 112, the
setGuiListener() system function associates them to various
menu items.
Java Swing set has a class, javax.swing.Timer, that causes
action to occur at a predefined rate. It can take a number of
ActionListener's; in JudoScript terms, it can be associated with
event handlers for event type Action. The following slider demo
uses a timer. See line 42 and on for how it is used, and line 58 for how
its events are handled.
Look at the screen of the next program. There are two rulers; a button in
the upper-left corner toggles the rules between inches and cm's. The rulers
are new components not found in the standard Swing packages, and the
scrolling pane responds to them. Such custom components are create by
extending base components. The only way to extend Java classes in JudoScript is
through embedded Java. Embedded Java classes (lines 5, 13 and 121) are
contained in the script, since at this moment nobody cares about them
beyond the script itself. See the other article
for more on embedded Java classes in JudoScript.
Modern GUI applications are object or component based. While GUI programming
in Java is like creating new components, building GUI in JudoScript is a matter of
gluing components together. Event handling is done by the gui::events
statement, which can statically or dynamically attach event handlers to
components, including timers. When new components are needed, they can be
implemented as embedded Java within the script.
JudoScript does not introduce its own GUI paradigm. All it does is using Java AWT
and/or Swing classes to construct GUI. Hence, to create GUI applications in
JudoScript, you need to be familiar with Java GUI programming. This articles
contains some pretty long source code listings. This is the characterisitcs
of GUI programs: they are typically long but fairly simple in structure for
the most part.