Section 13.9. Menus and Scroll Panes


[Page 641 (continued)]

13.9. Menus and Scroll Panes

Pop-up and pull-down menus allow an application or applet to grow in complexity and functionality without cluttering its interface. Menus are hierarchical in nature. A menu is divided into a number of menu items, which can themselves be further subdivided. Java makes it simple to implement menus.

A JMenuBar is an implementation of a menu bara horizontal list of names that appears at the top of a window (Fig. 13.31).

Figure 13.31. An application with a menu bar that is showing its edit menu. The edit menu contains a cascading drop-down menu that can show recent cuts.


Almost all applications have a menu bar. To construct a menu, you add JMenu objects to a JMenuBar. A JMenu is essentially a clickable area on a menu bar that is associated with a JPopupMenu, a small window that pops up and displays the menu's JMenuItems. A menu can also contain JSeparatorsdividers that can be placed between menu items to organize them into logical groupings.

13.9.1. Adding a Menu Bar to an Application

It is easy to create menus in Swing. The process involves three steps, although you need not perform them in this order:

1.

Create the individual JMenuItems.

2.

Create a JMenu and add the JMenuItems to it.

3.

Create a JMenuBar and add the JMenus to it.


[Page 642]

For example, suppose you're building the interface for a text editor. A text editor typically contains at least two standard menus. The file menu is used to create new documents, open and close files, save your document, and so on. The edit menu is used to cut and paste selected text from the document.

Here's how you would create the file menu for this program. First you create a menu bar and make it the menu bar for the application's JFrame or for the JApplet. This is usually done in the application's constructor or in the applet's init() method:

JMenuBar mBar = new JMenuBar(); // Create menu bar this.setMenuBar(mBar);          // Add it to this window 


The next step involves creating and adding menus and menu items to the menu bar. This is also usually done in the constructor or the init() method. If the menu is large, you should break this task into subtasks and define a method for each subtask.

Effective Design: Method Size

A method that gets longer than 20 to 25 lines is probably trying to do too much and should be divided into separate methods, each with a clearly defined task.


Here is the definition of the file menu for our simple text editor:

private void initFileMenu() {     fileMenu = new JMenu("File");         // Create menu     mBar.add(fileMenu);                   // Add it to menu bar     openItem = new JMenuItem("Open");     // Open item     openItem.addActionListener( this );     openItem.setEnabled(false);     fileMenu.add(openItem);     saveItem = new JMenuItem("Save");     // Save item     saveItem.addActionListener(this);     saveItem.setEnabled(false);     fileMenu.add(saveItem);     fileMenu.addSeparator();              // Logical separator     quitItem = new JMenuItem("Quit");     // Quit item     quitItem.addActionListener(this);     fileMenu.add(quitItem); } // initFileMenu() 


The first two statements in the method create the file menu and add it to the menu bar. The rest of the statements create the individual menu items that make up the file menu. Note the use of a separator item after the save item. This has the effect of grouping the file-handling items (open and save) into one logical category and distinguishing them from the quit item. A separator is represented as a line in the menu (Fig. 13.31).

Effective Design: Logical Design

In designing interfaces, an effort should be made to use visual cues, such as menu item separators and borders, to group items that are logically related. This will help to orient the user.



[Page 643]

Each menu item is given an ActionListener. As we will see shortly, action events for menu items are handled the same way as action events for buttons. Finally, note how the setEnabled() method is used to disable both the open and save menu items. Implementation of these actions is left as an exercise.

13.9.2. Menu Hierarchies

Menus can be added to other menus to create a hierarchy. For example, the edit menu will include the standard cut, copy, and paste menu items. Some edit menus also contain an "Undo" item, which can be used to undo the last editing operation performed. In other words, if you cut a piece of text, you can undo the operation and get the cut back. Many editors allow just a single undo. If you cut two pieces of text, the capability to undo the first piece is lost to the user. This can be an issue, especially if you didn't mean to do the first cut.

To remedy this situation, let's add a feature to our editor that will keep track of cuts by storing them in a Vector. This function will be like an "Unlimited Undo" operation for cuts. For this example, we won't place any limit on the size of the vector. Every cut the user makes will be inserted at the beginning of the vector. To go along with this feature we need a menu that can grow dynamically during the program. Each time the user makes a cut, the string that was cut will be added to the menu.

This kind of menu should occur within the edit menu, but it will have its own items. This is a menu within a menu (Fig. 13.31), an example of a cascading drop-down menu. The edit menu itself drops down from the menu bar, and the recent-cuts menu drops down and to the right of where its arrow points. The following method was used to create the edit menu:

private void initEditMenu() {   editMenu = new JMenu("Edit");                // Create edit menu   mBar.add(editMenu);                          // Add to menu bar   cutItem = new JMenuItem ("Cut");             // Cut item   cutItem.addActionListener(this);   editMenu.add(cutItem);   copyItem = new JMenuItem("Copy");            // Copy item   copyItem.addActionListener(this);   editMenu.add(copyItem);   pasteItem = new JMenuItem("Paste");          // Paste item   pasteItem.addActionListener(this);   editMenu.add(pasteItem);   editMenu.addSeparator();   selectItem = new JMenuItem("Select All");    // Select   selectItem.addActionListener(this);   editMenu.add(selectItem);   editMenu.addSeparator();   cutsMenu = new JMenu("Recent Cuts");         // Cuts submenu   editMenu.add(cutsMenu); } // initEditMenu() 


The main difference between this method and the one used to create the file menu is that here we insert an entire submenu as one of the items in the edit menu. The cutsMenu will be used to hold the strings that are cut from the document. Initially, it will be empty.


[Page 644]

13.9.3. Handling Menu Actions

Handling JMenuItem actions is no different from handling JButton actions. Whenever a user makes a menu selection, an ActionEvent is generated. Programs that use menus must implement the actionPerformed() method of the ActionListener interface. In the text editor example, there are a total of six enabled menu items, including the recent-cuts menu. This translates into a large if-else structure, with each clause handling a single menu item.

The following actionPerformed() method is used to handle the menu selections for the text editor:

public void actionPerformed(ActionEvent e) {   JMenuItem m = (JMenuItem)e.getSource();        // Get selected menu item   if ( m == quitItem ) {                         // Quit     dispose();}   } else if (m == cutItem) {                     // Cut the selected text     scratchPad = display.getSelectedText();      // Copy text to scratchpad     display.replaceRange("",                     // and delete         display.getSelectionStart(),             // from the start of selection         display.getSelectionEnd());              // to the end         addRecentCut(scratchPad);                // Add text to the cuts menu   } else if (m == copyItem)                      // Copy text to scratchpad     scratchPad = display.getSelectedText();   } else if (m == pasteItem) { // Paste scratchpad to document at caret     display.insert(scratchPad, display.getCaretPosition()); // position   } else if ( m == selectItem ) {     display.selectAll();                         // Select the entire document   } else {     JMenuItem item = (JMenuItem)e.getSource();   // Default is cutsMenu     scratchPad = item.getActionCommand();        // Put cut back in scratchpad   } } // actionPerformed() 


The method begins by getting the source of the ActionEvent and casting it into a JMenuItem. It then checks each case of the if-else structure. Because the actions taken by this program are fairly short, they are mostly coded within the actionPerformed() method. However, for most programs it will be necessary to write a separate method corresponding to each menu item and then call the methods from actionPerformed().

Our text editor's main task is to implement the cut/copy/paste functions, which are simple to do in Java. The text being edited is stored in a JTextArea, which contains instance methods that make it very easy to select, insert, and replace text. To copy a piece of text, the program need only get the text from the JTextArea (getSelectedText()) and assign it to the scratchpad, which is represented as a String. To paste a piece of text, the program inserts the contents of the scratchpad into the JTextArea at the location marked by the caret, a cursor-like character in the document that marks the next insertion point.

The structure of this if-else statement is significant. Note how the default case of the if-else is designed. We are using the last else clause as a "catch-all" condition to catch and handle selections from the cutsMenu. All of the other menu items can be referred to by name. However, the menu items in the cutsMenu are just snippets of a string that the user has previously cut from the text, so they can't be referenced by name. Luckily, we don't really need to. For any JMenuItem, the getActionCommand() method returns its text, which in this case is the previously cut text. So we just assign the cut text from the menu to the scratchpad.


[Page 645]

Default logic


Java Programming Tip: Default Cases

Although the order of the clauses in an if-else structure is usually not important, the default clause can sometimes be used to handle cases that can't be referenced by name.


Handling Previously Cut Text

The most difficult function in our program is the cut operation. Not only must the selected text be removed from the document and stored in the scratchpad, but it must also be inserted into the vector that is storing all the previous cuts. The addRecentCut() method takes care of this last task. The basic idea here is to take the cut string and insert it at the beginning of the vector, so that cuts will be maintained in a last-in/first-out order. Then the cutsMenu must be completely rebuilt by reading its entries out of the vector, from first to last. That way the most recent cut will appear first in the menu:

private void addRecentCut(String cut) {   recentCuts.insertElementAt(cut,0);   cutsMenu.removeAll();   for (int k = 0; k < recentCuts.size(); k++) {     JMenuItem item =      new JMenuItem((String)recentCuts.elementAt(k));     cutsMenu.add( item );     item.addActionListener(this);   } } // addRecentCut() 


Algorithm design


The recentCuts Vector stores the cut strings. Note the use of the insertElementAt() method to insert strings into the vector and the elementAt() method to get strings from the vector. (You may find it helpful to review the section on vectors in Chapter 9.)

Note also how menu items are removed and inserted in menus. The cutsMenu is reinitialized, using the removeAll() method. Then the for loop iterates through the strings stored in the vector, making new menu items from them, which are then inserted into the cutsMenu. In this way, the cutsMenu is changed dynamically each time the user cuts a piece of text from the document.

13.9.4. Adding Scrollbars to a Text Area

The design of the SimpleTextEditor class is summarized in Figure 13.32, and its complete implementation is shown in Figure 13.33. It uses a BorderLayout with the JTextArea placed at the center. Note how simple it is to add scrollbars to the text area:

this.getContentPane().add(new JScrollPane(display)); 


Figure 13.32. Design of the SimpleTextEditor.
(This item is displayed on page 646 in the print version)


Figure 13.33. A menu-based SimpleTextEditor application.
(This item is displayed on pages 647 - 648 in the print version)

import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Vector; public class SimpleTextEditor extends JFrame implements ActionListener{   private JMenuBar mBar = new JMenuBar();      // Create the menu bar   private JMenu fileMenu, editMenu, cutsMenu;  // Menu references and items   private JMenuItem cutItem, copyItem, pasteItem, selectItem,recentcutItem;   private JMenuItem quitItem, openItem, saveItem; // File items   private JTextArea display = new JTextArea(); // Here's where the editing occurs   private String scratchPad = "";              // Scratch pad for cut/paste   private Vector recentCuts = new Vector();   public SimpleTextEditor() {     super("Simple Text Editor");               // Set the window title     this.getContentPane().setLayout(new BorderLayout());     this.getContentPane().add("Center", display);     this.getContentPane().add(new JScrollPane(display));     display.setLineWrap(true);     this.setJMenuBar(mBar);                    // Set this program's menu bar     initFileMenu();                            // Create the menus     initEditMenu();   } // SimpleTextEditer()   private void initEditMenu() {     editMenu = new JMenu("Edit");              // Create the edit menu     mBar.add(editMenu);                        // and add it to menu bar     cutItem = new JMenuItem ("Cut");           // Cut item     cutItem.addActionListener(this);     editMenu.add(cutItem);     copyItem = new JMenuItem("Copy");          // Copy item     copyItem.addActionListener(this);     editMenu.add(copyItem);     pasteItem = new JMenuItem("Paste");        // Paste item     pasteItem.addActionListener(this);     editMenu.add(pasteItem);     editMenu.addSeparator();     selectItem = new JMenuItem("Select All");  // Select item     selectItem.addActionListener(this);     editMenu.add(selectItem);     editMenu.addSeparator();     cutsMenu = new JMenu("Recent Cuts");       // Recent cuts submenu     editMenu.add(cutsMenu);   } // initEditMenu()   private void initFileMenu() {     fileMenu = new JMenu("File");              // Create the file menu     mBar.add(fileMenu);                        // and add it to the menu bar     openItem = new JMenuItem("Open");          // Open item     openItem.addActionListener( this );     openItem.setEnabled(false); 
[Page 648]
fileMenu.add(openItem); saveItem = new JMenuItem("Save"); // Save item saveItem.addActionListener(this); saveItem.setEnabled(false); fileMenu.add(saveItem); fileMenu.addSeparator(); // Logical separator quitItem = new JMenuItem("Quit"); // Quit item quitItem.addActionListener(this); fileMenu.add(quitItem); } // initFileMenu() public void actionPerformed(ActionEvent e) { JMenuItem m = (JMenuItem)e.getSource(); // Get selected menu item if ( m == quitItem ) { // Quit dispose(); } else if (m == cutItem) { // Cut the selected text scratchPad = display.getSelectedText();// Copy text to scratchpad display.replaceRange("", // and delete display.getSelectionStart(), // from the start of the selection display.getSelectionEnd()); // to the end addRecentCut(scratchPad); // Add the cut text to the cuts menu } else if (m == copyItem) { // Copy the selected text to the scratchpad scratchPad = display.getSelectedText(); } else if (m == pasteItem) { // Paste the scratchpad to the document at caret display.insert(scratchPad, display.getCaretPosition()); // position } else if ( m == selectItem ) { display.selectAll(); // Select the entire document } else { JMenuItem item = (JMenuItem)e.getSource();// Default is cutsMenu scratchPad = item.getActionCommand(); // Put cut back in the scratchpad } } // actionPerformed() private void addRecentCut(String cut) { recentCuts.insertElementAt(cut,0); cutsMenu.removeAll(); for (int k = 0; k < recentCuts.size(); k++) { JMenuItem item = new JMenuItem((String)recentCuts.elementAt(k)); cutsMenu.add( item ); item.addActionListener(this); } } // addRecentCut() public static void main(String args[]) { SimpleTextEditor f = new SimpleTextEditor(); f.setSize(300, 200); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); // Quit the application } }); } // main() } // SimpleTextEditor class

Scrollbars



[Page 646]

This statement creates a JScrollPane and adds it to the application's container. A JScrollPane is one of Swing's scrollbar classes. Its function is to manage the viewing and scrolling of a scrollable component, such as a JTextArea. A JScrollPane is actually a container, which is why it takes the display as an argument. The display is being added to the JScrollPane.

Just about any Component can be added to a JScrollPane. Once a component is added, the scroll pane will manage the scrolling functions for the component. The default constructor used in this example takes a single Component parameter. This refers to the scrollable componentin this case to the JTextArea. Another constructor that you might use takes the following form:

public JScrollPane(Component comp, int vsbPolicy, int hsbPolicy); 


The two integers refer to the vertical and horizontal scrolling policies. These cover properties such as whether the scrollbars are always present or just as needed. The default policy is to attach scrollbars to the component only when needed. Thus, to see the scrollbars in the SimpleTextEditor, you would have to shrink the window to the point where all of the text cannot be viewed (Fig. 13.34). Because the text area in this example is wrapping the text, the horizontal scrollbar will never be needed.


[Page 649]

Figure 13.34. The scrollbars appear on the text area only when they are needed. In this case, only a vertical scrollbar is necessary.


Self-Study Exercises

Exercise 13.9

Modify the addRecentCut() method so that it limits the cuts stored in the vector to the last 10 cuts.

Exercise 13.10

Modify the addRecentCut() method so that it does not duplicate cuts already stored in the vector. (Hint: Use the indexOf(String) method in the Vector class.)

Are Computers Intelligent?

Contemporary computer interfaces are largely visual and graphical, and many things we use a computer for, such as word processing, still require us to type. Will there come a day when instead of typing a letter or e-mail message, we'll be able to dictate it to our computer? Will computers eventually have the same kind of interface we havethat is, will we someday be able to carry on conversations with our computers? Clearly, a "conversational interface"would require substantial intelligence on the part of the computer. Do computers have any chance of acquiring such intelligence?

The question of machine intelligence, or artificial intelligence (AI), has been the subject of controversy since the very first computers were developed. In 1950, in an article in the journal Mind, Alan Turing proposed the following test to settle the question of whether computers could be intelligent. Suppose you put a person and a computer in another room, and you let a human interrogate both with any kind of question whatsoever. The interrogator could ask them to parse a Shakespearian sonnet, or solve an arithmetic problem, or tell a joke. The computer's task would be to try to fool the interrogator into thinking that it was the human. And the (hidden) human's task would be to try to help the interrogator see that he or she was the human.

Turing argued that someday computers would be able to play this game so well that interrogators would have no better than a 50/50 chance of telling which was which. When that day came, he argued, we would have to conclude that computers were intelligent.

This so-called Turing test has been the subject of controversy ever since. Many of the founders of AI and many of its current practitioners believe that computation and human thinking are basically the same kind of process, and that eventually computers will develop enough capability that we will have to call them intelligent. Skeptics argue that even if computers could mimic our intelligence, there is no way they will be self-conscious, and therefore they can never be truly intelligent. According to the skeptics, merely executing programs, no matter how clever the programs are, will never add up to intelligence.


[Page 650]

Computers have made some dramatic strides lately. In 1997, an IBM computer named Deep Blue beat world chess champion Gary Kasparov in a seven-game chess match. In 1998, a computer at Los Alamos National Laboratory proved a mathematical theorem that some of the best mathematicians had been unable to prove for the past 40 years.

However, despite these achievements, most observers would agree that computers are not yet capable of passing the Turing test. One area where computers fall short is in natural language understanding. Although computers are good at understanding Java and other computer languages, human languages are still too complex and require too much commonsense knowledge for computers to understand them perfectly. Another area where computers still fall somewhat short is in speech recognition. However, an American company recently demonstrated a telephone that could translate between English and German (as well as some other languages) in real time. The device's only limitation was that its discourse was limited to the travel domain. As computer processing speeds improve, this limitation is expected to be only temporary. Thus, we may be closer than we think to having our "conversational user interface."

Natural-language understanding, speech recognition, learning, perception, chess playing, and problem solving are the kinds of problems addressed in AI, one of the major applied areas of computer science. Almost every major research group in AI has a Web site that describes its work. To find some of these, just do a search for "artificial intelligence" and then browse through the links that are returned.





Java, Java, Java(c) Object-Orienting Problem Solving
Java, Java, Java, Object-Oriented Problem Solving (3rd Edition)
ISBN: 0131474340
EAN: 2147483647
Year: 2005
Pages: 275

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net