This issue presents tips, techniques, and sample code for the following topics:
Menu Shortcuts
The ability to specify menu shortcuts is one of the features in
JDKTM 1.1 -- where menu choices can be
selected via the keyboard instead of with the mouse.
For example:
import java.awt.*;
import java.awt.event.*;
public class menu implements ActionListener {
public void actionPerformed(ActionEvent e)
{
String lab = ((MenuItem)e.getSource()).getLabel();
System.out.println("label = " + lab);
if(lab.equals("Exit"))
{
System.exit(0);
}
}
public static void main(String args[])
{
Frame f = new Frame("testing");
Menu m = new Menu("File");
menu acl = new menu();
MenuItem mi1 = new MenuItem("Open");
mi1.addActionListener(acl);
m.add(mi1);
MenuItem mi2 = new MenuItem("Save");
mi2.addActionListener(acl);
m.add(mi2);
MenuShortcut ms3 = new MenuShortcut(KeyEvent.VK_E);
MenuItem mi3 = new MenuItem("Exit", ms3);
mi3.addActionListener(acl);
m.add(mi3);
MenuBar mb = new MenuBar();
mb.add(m);
f.setMenuBar(mb);
f.setSize(200, 200);
f.setVisible(true);
}
}
The example sets up a frame, which is a top-level application window.
The frame contains a menu bar, and the menu bar contains a single
pull-down menu named "File." The menu offers choices for
Open, Save, and Exit, with Exit having a keyboard shortcut set up for
it that specifies the virtual key code "E."
How the shortcut gets invoked varies, depending on the platform in question.
For example, with Windows you use Ctrl-E so that when a user types Ctrl-E
within the window containing the menu bar, the Exit command is invoked.
One last thing: this example doesn't actually have a command structure set up
for it, but instead invokes actionPerformed to demonstrate that the command
processing structure is in place.
Command dispatching
In C and C++, programmers often use a set of global functions and function
pointers to represent a series of commands or operations and then dispatch
to them via a table. For example:
#include <stdio.h>
void func1() {printf("func1\n");}
void func2() {printf("func2\n");}
typedef void (*fp)(void);
fp funcs[] = {&func1, &func2, 0};
int main()
{
int i = 0;
while (funcs[i])
funcs[i++]();
return 0;
}
Java, though, does things differently. It doesn't use pointers and doesn't
have global functions. Instead, Java uses a technique of creating and
referencing object instances through which the objects call a method
known to be implemented by an object of a given type.
How does the technique work in practice? Consider this example:
interface Action {
public void doit();
}
class func1 implements Action {
public void doit() {System.out.println("func1");}
}
class func2 implements Action {
public void doit() {System.out.println("func2");}
}
public class call {
private static Action alist[] = {
new func1(),
new func2()
};
public static void main(String args[])
{
for (int i = 0; i < alist.length; i++)
alist[i].doit();
}
}
In this example, an interface Action is defined, and any class that
implements the interface must define a method doit (this notion, by the way,
is basic to the meaning of interfaces). Objects of the class can be referred
to with a reference to the implemented interface name type, so that a
reference of type Action can refer to an object of a class that implements
Action.
In C++ programming Action would be a base class, with func1 and func2 being
derived classes, and object manipulation would be performed via a base class
pointer. With Java, an Action reference supports a similar manipulation,
although Action is not a superclass of func1 and func2.
The Java technique given here sometimes goes by the name "method
wrappers," and is quite different from the C/C++ approach. There
are some tradeoffs, of course, as to which approach works the best in
a given situation.
A second example
Another example of the method wrappers technique is used fairly often in the
Abstract Windowing Toolkit (AWT). Consider the following:
import java.awt.*;
import java.awt.event.*;
public class buttonlistener implements ActionListener {
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
public static void main(String args[])
{
Frame f = new Frame("testing");
Button b = new Button("OK");
b.addActionListener(new buttonlistener());
f.add(b);
f.pack();
f.setVisible(true);
}
}
The example creates a frame and adds an OK button to it. When the button is
selected, the program terminates. An action listener is added to the button.
The action listener is guaranteed to implement a method actionPerformed,
because an instance of buttonlistener implements the ActionListener
interface. Selecting the button results in a call to the action listener for
the button.
Finally, the listeners concept is extremely important in the AWT. The
underlying basis of listeners involves implementing specified interfaces and
thereby guaranteeing that a listener will be able to respond to a particular
known method invocation on it.
|