Базы данныхИнтернетКомпьютерыОперационные системыПрограммированиеСетиСвязьРазное
Поиск по сайту:
Подпишись на рассылку:

Назад в раздел

Chapter 8 -- The Order Entry System: Entry Fields, Labels, and Validation

Chapter 8

The Order Entry System: Entry Fields, Labels, and Validation


CONTENTS


This chapter is going to cover much information. First, it further explores the concepts of containers in the Java AWT. It covers how to implement the different container types and how they interact with each other. Remember, containers are components which function to contain other components. The different containers available allow you to create stand-alone window applets, and also clean up the appearance of the Order Entry System. The chapter also describes pop-up dialog boxes and the means to incorporate them into your applets.

Second, the chapter covers the five different AWT layout managers. These allow you, the programmer, to place your components in containers in an orderly fashion while you still maintain platform independence. The five layout managers are: FlowLayout, BorderLayout, CardLayout, GridLayout, and GridBagLayout. The GridBagLayout is the layout manager that is used to reorganize the Order Entry System applet panel later in this chapter.

More About Containers

The first concept to understand is the idea that containers are components. Containers are components and they also hold components. Containers can hold other containers. When you embed containers inside of containers, you are subdividing the applet (or application) display area. By doing this, you can apply different layouts to each separate subdivision of the display face.

It is beneficial to have different groups of components laid out in different ways. This way, you don't have to settle on a layout that is mediocre for all of your components. Instead, you can choose the layout that is best and apply that to each subdivision (container) of the applet face. This process is how you create appealing interfaces and still maintain platform independence. This concept is covered again when you add to the Order Entry System later on in this chapter.

The simplest containers are panels. In terms of simplicity, they are to containers what labels are to interface components. But in terms of power, the Panel class is infinitely more powerful and useful than the Label class.

Panels

Panels are AWT components that hold other components. By themselves, panels are basically nothing. One usually expects a container as known in the real world to have some visible form; however, panels are invisible. They have no visible boundaries or characteristics to visually separate them from other components or containers. If you try to display an empty instance of the Panel class you get what you expect when you display something that is made completely of nothing: nothing. In a nutshell, panels are classes whose sole purpose is to group other components together.

To declare a panel, use the following code:

Panel APanel = new Panel();

To insert components, including other containers, into a panel, use the same method that you use when inserting components onto applet faces, the add method. To insert a component named SomeComponent into your new panel declared above, use the following code:

APanel.add(SomeComponent);

The add method takes an instance of the Component class as a parameter. Each container, including Applet, has an add method. This is inherited from the java.awt.Container class found in the AWT package. To insert a component into another container, you should do what you did above, call the container's add method and include the component as a parameter. To simply insert something onto the main panel, such as you do with the Applet class, simply add(SomeComponent) without specifying it as a method of another container.

The add method has so far appeared in two seemingly unrelated sections of the book (inserting components into an applet and also into a container). This should raise some questions in your head. If you look back at the inheritance hierarchy of the java.awt.Applet class in Chapter 5, "Writing a Java Applet: The Order Entry System," you see that the Applet class is actually a subclass of the Panel class. This is why the chapter refers to the applet face as the "applet panel." This is because applets themselves are actually specialized Panels that have included more methods so they are able to be executed in an html document by a Web browser. Here is the inheritance path of the java.awt.Applet class in Figure 8.1. Pay attention to the fact that applets are themselves subclasses of the Panel class.

Figure 8.1: The inheritance path of the java.awt.Applet class

Later, the chapter covers the concept of layout managers in the AWT. These layout managers can be applied to set the layout inside of Panels and other containers.

Frames

Frames are another subclass of java.awt.Container. They share the same two major operators: add and a method to be named later (sounds like baseball), and also do quite a bit more. Frames are the means by which you can incorporate stand-alone windows into your Java applets or create windowing Java applications.

Note:
java.awt.Frame and java.awt.Dialog (covered in the next section) are both actually subclasses of the Window class. The Window class is the means to implement a stand-alone window in Java. However, it is non-functional for our purposes. While the Panel class can be readily embedded inside of other containers, the java.awt.Window class generally is not. For this reason, the children of the Window class are separated to ease explanation and understanding because of the functional difference.

To create a new instance of a Frame, there are two constructors you will find useful. They are of the format as follows:

Frame AFrame = new Frame();
Frame BFrame = new Frame("This one has a title, man.");

Both constructors declare instances of the Frame class and then allocate space for them. The difference is that the BFrame frame is declared to have a title from the start. You can also set the title of the AFrame frame. If you want to set the title of the AFrame frame to be the String "So do I.", use the setTitle() method:

AFrame.setTitle("So do I.");

The setTitle method takes an instance of the String class to be its parameter which it then sets to be the title of the window.

In the AWT, the sizing of windows is not done by measurement or proportion of the screen. Instead, it is accomplished through counting the number of pixels in a direction. To set the size of a frame in pixels, use the resize method of instances of the Frame class. To set AFrame to be 100 pixels wide by 150 pixels high, you can use the following declaration:

AFrame.resize(100, 150);

The resize method accepts two integers: the width first, and then the height in the second parameter position.

Caution:
You must call the resize method on your frames. Otherwise, the default is a height of zero and a width of zero which means you get absolutely nothing when you display them unless the resize method is called with non-zero values.

Listing 8.1 is a small application, FrameCrazee, that displays a frame from inside an application.


Listing 8.1. The FrameCrazee application code.
1.  import java.awt.*;
2.  import java.applet.Applet;
3.
4.  public class FrameCrazee extends Object {
5.
6.  public static void main(String[] arg) {
7.
8.  Frame AFrame = new Frame();
9.  Frame BFrame = new Frame("This one has a title, man.");
10.
11. // Set the title of the AFrame.
12. AFrame.setTitle("So do I.");
13.
14. // Resize the BFrame to width of 300 pixels,
15. // And a height of 250 pixels.
16. BFrame.resize(300, 250);
17.
18.  // Display the BFrame.
19.  BFrame.show();
20.
21. }
22.
23. }

Figure 8.2 is the output resulting from this application when run using the java command-line interpreter.

Figure 8.2: Output from the FrameCrazee application in Listing 8.1.

Caution:
Notice that this is a Java application and not an applet. If you try to do this with an applet and expect it to work, you will be a little surprised. Instead, you have to do a little dancing to get frames incorporated with applets. This is covered a few pages further on.

Lines 1 through 6 do the typical stuff you expect in a applet. But remember, this is an application, so we can simply execute it using the Java interpreter included in the JDK.

Lines 8 and 9 declare and initialize two instances of the Frame class using the constructors described previously. Line 12 sets the title for the AFrame frame and line 16 resizes the BFrame frame to be 300 pixels wide by 250 pixels high. And finally, line 19 displays the BFrame using the show method of the frame class. But where is the AFrame declared and initialized in line 8? All you can see is the BFrame frame displayed in the output in Figure 8.2. The show() method of the frame isn't invoked to set it visible.

But importantly, why is this an application and not an applet like all of the others? Isn't this a book focusing on the creation of Java programs for the Web? Well, the problem is that instances of the Frame class are not allowed to be owned by a derivative of the Applet class. Instead, you have to override the Frame class and then use that class when defining frames in your applets. Otherwise, you discover that frames owned by applets usually appear, but functionality disappears. Using frames in applets is covered after the next section on the show() method.

Showing and Hiding Frames

The show() method of the Frame class is the means by which you set a frame to show itself to the world and be active. To set a frame named CFrame to display itself, use the following code:

CFrame.show();

If defined correctly, the CFrame is displayed. The opposite of the show() method is the hide()method. It is called in the same manner as the show() method except it causes the frame to become invisible again.

Frames and Applets

As noted before, frames cannot belong to applets directly. Instead, you have to sidestep this a bit. The process to do so is not difficult. It involves the following process.

In your applet, after you close your last "}", declare another class called something like FrameJr. Set this class to extend the frame class. Inside of the class body, you declare that you want to construct the FrameJr class. Constructors are covered in Chapter 7, "The Order Entry System: Entry Fields, Labels, and Validation." Constructors function to set the properties and do some initial setup when called. To set the FrameJr class, use the following declaration:

class FrameJr extends Frame {

FrameJr (String InTitle) {
  super(InTitle);
  .
  .
}
}

When an instance of your class FrameJr is declared in your applet using the following statement,

Frame AFrameJr = new FrameJr(Title);

the constructor of your super class (which is your class's parent, the one it extended) is called and your Frame is created just like normal. You can also include any other setup tasks you wish to deal with inside of the constructor for your class. For example, you might want to add an "!" to the end of your title before constructing it. To do this, change your InTitle string before you call the super of your class.

Caution:
Notice that there is no constructor with which you can build an instance of FrameJr with no title. If you wish for this to work, you must declare another constructor inside of the class declaration which accepts no parameter and then calls super() with no parameter.

Tip:
This method of reconstruction of your classes is not limited to frames. It works for any class. For example, you might want to create a version of the String class whose constructor accepts a string and removes all of the capital letters. You can write a class to extend the String class and then in the constructor remove all of the capitals before you call the super(), which is the string's original constructor.

Allowing User Resizing of Frames

Another important method you can use with the Frame class is the setResizeable(boolean) method. This method either turns on or turns off the capability for the user to change the size of the frame being displayed. If you send a value of false to the method, the user is no longer permitted to change the size of the frame. A true value allows resizing of the window. The default setting when a frame is initialized is true, indicating that the user can resize the window.

Setting the Frame's Icon

One of the most interesting features of frames in the AWT is the capability to set the icon of the frame. This is accomplished using the setIconImage(AnImage) method, which accepts a parameter which is of the Java type Image. This type is covered in the next chapter, which covers Java-based graphics. At that time, the Order Entry System logo is set to be the icon.

Frame Menu Bars

Menu bars attached to frames are the typical pull-down menus customarily attached to windows on almost every window-based system, including those which are text-based along with the typical graphical-based systems. If you've used Microsoft Windows, X Window, or MacOS, you should be familiar with the typical format of including pull-down menus across the top of a window border. Frame menus are implemented using the MenuBar class. There is one major constructor for the MenuBar class:

MenuBar AMenuBar = new MenuBar();

You must then set your Frame to have its menu bar as the AMenuBar. This is done using the SetMenuBar() method of the Frame class. To set the AMenuBar as the menu bar of the AFrame, use the following code line:

AFrame.setMenuBar(AMenuBar);

Each individual item along the menu bar is constructed from the Menu class. There are two major constructors for the Menu class:

Menu AMenu = new Menu("One");
Menu BMenu = new Menu("Two", true);

Both constructors accept the first parameter as a string which sets what the text label for each menu is across the top of the frame. The second constructor adds another parameter of the Boolean type. If the parameter is true then the menu is removable. If it is false then it is not. The default is false.

The following line adds the AMenu class from above to your menu bar:

AMenuBar.add(AMenu);

This code adds an option labeled "One" to your menu bar. You can also add menu items to your instance of the Menu class as well as adding other menus. It is also possible to add checkboxes to your menus. To do so, declare a checkbox as in Chapter 6, "The Order Entry System: Adding Features and Handling Events." Then, insert it into the menu where you wish it to belong. Also in the same fashion as in Chapter 6, handle the events that the checkbox generates either in the action or handleEvent method of your program.

To add menu items to your menus, you can declare instances of the MenuItem class. The MenuItem constructor accepts a string parameter which is the text label of the item when it appears on the menu:

MenuItem AMenuItem = new MenuItem("Hey!");

You can also add text only to your menus as choices. The format for doing this is:

Menu.add("A choice!");

If you are going to do this, be prepared to use the action method to facilitate handling the event. If you're set on using handleEvent, then use just the MenuItem class.

Menus in a Nutshell

Menus aren't always easy to grasp because of the multiple classes. To summarize, the whole menu bar starts with an instance of the MenuBar class. This instance is then set to be the menu bar for a frame using the setMenuBar method of the frame.

Then, menus are added to the menu bar. (Menus are the list that falls down when you click on a label contained in the menu bar.) Menus can be added to other menus or to instances of the class MenuItem. Menu items function as text labels. Their purpose as separate variables is to give you a target if you decide to use the handleEvent method.

To create a menu bar, follow these steps:

  1. Create an instance of the MenuBar class.
  2. Set your frame's MenuBar to be the instance declared above.
  3. Create multiple Menus to be in your menu bar.
  4. Add and create each MenuItem and sub-menu you wish to include.
  5. Add all of the pieces in Step 4 to their corresponding Menu in Step 3.
  6. Add your menus to the instance of MenuBar.

To visually help you grasp the organization of menu bars, Figure 8.3 is a typical menu hierarchy of insertion.

Figure 8.3 : A typical menu hierarchy of insertion

Tip:
Remember, items added to panels, menus, and so forth are always placed in the order in which they are added. In Java, this is generally left to right or top to bottom.

Events and Menus

Handling events generated by menus is most easily done in the action method of your AWT programs. When an instance of the MenuItem class fires a call to the action method, the first parameter is the Event itself. The second parameter is the string of the menu item generating the event. This can be used for advanced tasks, if need be, such as receiving menu items generated without declaring a MenuItem first. Once you have experience, you can use items like the instanceof operator to simplify your handling of events. But for the time being, going for the simple way is a good idea.

The following if statement block works in either event handling method:

if (evt.target  == SomeMenuItem)  {
  // Do whatcha like . .
} else . . .

If you are using a checkbox or other component in the menu, you can use the same format with a different target.

Setting the Frame Cursor

This is, in my opinion, one of the coolest things about the Frame class. You have the capability of changing the appearance of the cursor of the frame. There are a number of different cursors available. Table 8.1 is a list of the cursor constants that you can use to set the cursor. To find this information, look at javasrcawtFrame.java.

Table 8.1. The multiple cursor constants available to set the cursor of frames.
Cursor Constants
DEFAULT_CURSOR
CROSSHAIR_CURSOR
TEXT_CURSOR
WAIT_CURSOR
SW_RESIZE_CURSOR
SE_RESIZE_CURSOR
NW_RESIZE_CURSOR
NE_RESIZE_CURSOR
N_RESIZE_CURSOR
E_RESIZE_CURSOR
W_RESIZE_CURSOR
S_RESIZE_CURSOR
HAND_CURSOR
MOVE_CURSOR

To set the cursor of a frame, use the setCursor method. To set the cursor of the frame AFrame to the crosshair cursor, use the following code segment:

AFrame.setCursor(CROSSHAIR_CURSOR);

There is also a getCursor method which returns an integer which is one of the above constants. You can use this function to check which cursor is being used. The available Frame class methods are summarized in Table 8.2.

Table 8.2. Frame methods.
MethodDescription
String getTitle() Returns a String which is the title of the window.
setTitle(String) Accepts a String parameter that is then set to be the title of the window.
Image getIconImage() Returns an instance of Image (see next chapter) that is the icon used on the window.
setIconImage(Image) Accepts an instance of Image that is then set as the icon for the window.
MenuBar getMenuBar() Returns the menu bar for the window.
setMenuBar(MenuBar) Sets the menu bar for the window.
remove(MenuComponent) Removes the specified menu bar from the window frame.
dispose() Gets rid of the frame and frees all of the resources it is using.
boolean isResizeable() true or false depending on whether the dialog is set to be resizeable.
setResizeable(boolean) Sets the ability for the user to resize the dialog window.
setCursor(integer) Accepts an integer which is one of the cursor constants listed previously.
integer getCursorType(); Returns an integer which is one of the cursor constants listed previously.

Using Applets as Applications
Web browsers incorporate a Java interpreter to interpret the Java bytecodes to be able to execute applications. The executable called "java" included in the JDK does this also. To execute a Java application, use the command line "Java YourClassHere". To convert your applets to run as stand-alone applications, there are two major methods.
Method one is the simplest of the two. The process involves creating a public void main(String arg[]) in your applet. Then, create a new instance of the Frame class, initialize it and call the applet init() and start() methods, and then add your applet to the frame. Then, show the Frame containing the applet. The following code demonstrates this technique inside an applet called AApplet.
public void main(String arg[]) {

// Create the new instance of the Frame class.
Frame AFrame = new ("Morrissey Fan-Club");

// Initialize the frame and the applet.
AFrame.resize(300, 300);
AApplet.init();
AApplet.start();

// Add the applet to the frame.
AFrame.add(AApplet);

// Show the frame.
AFrame.show(AApplet);
}
.
.
Method two is tough, but you should use it if you want to keep up the efficiency level. First, change the class from extending the applet class to extending the Frame class. Then, modify your applet to run with the knowledge that the main(String arg[]) function is the only one called by the Java runtime. The init(), run(), etc. methods are no longer called because those are specific to the applet class. You, however, can set your main method to call the init() method.
Unless you have a complete understanding, you should probably stick to method one.

Dialogs

Dialogs are another subclass of the java.awt.Window type. They are used for simple alerts, information providing to the user, or simple data entry. You see these every time your windows system can't find a file or the system wants to know what file you want. In fact, the AWT provides a predefined file dialog for your use. Of course, in writing applets it isn't of much use since applets can't load or save local files. But remember, applications do have unlimited local access to the file system.

There are two key states dialogs can be in. In one state, a dialog can demand that it receives attention enough to finish its tasks before any other window is allowed to be active. An applet in this state is typically called "Modal." There are multiple other ways to refer to a window that doesn't demand attention in this manner ranging from non-modal to modeless to unmodal. This book refers to them as non-modal.

Dialogs are declared in the java.awt.Dialog class. As stated before, dialogs are a subclass of the java.awt.Window class. As such, dialogs are "siblings" with the frame class. The two classes share the features of having a title, and of either being resizeable or not. They share these characteristics and you can use the same methods to set their characteristics (setTitle(String), isResizeable(), and so on).

The Dialog class is dependent on the Frame class. When you declare a dialog, you must attach it to an instance of the Frame class. There are two major constructors for the java.awt.Dialog class. The following two lines construct and create two different instances of the Dialog class, ADialog and BDialog:

Dialog ADialog = new Dialog(AFrame, ABoolean);
Dialog BDialog = new Dialog(AFrame, TitleString, ABoolean);

Both of these declarations construct new instances of the Dialog class. The first parameter in each is the frame to which the dialog box belongs. The second constructor takes a string parameter which the system sets to be the dialog box title. And the final parameter in each is a Boolean value or variable which sets the modality of the dialog box. A true value indicates that the dialog box is modal (demands attention and resolution of its desires before any other window is permitted attention) and a false value indicates otherwise.

Dialogs share much with frames in terms of methods. As mentioned before, both the Frame class and the Dialog class use the getResizeable() and setResizeable(boolean) methods. They also share the resize(integer, integer) method which sets the window size.

Table 8.3 summarizes the methods available in the Dialog class.

Caution:
Remember, for every class which is a descendant of the Window class (including Frame, Dialog, and FileDialog), you must specify the window size using the resize(integer width, integer height) method. Otherwise, you get a window of zero width and zero height, which results in a non-existent and invisible window.

Table 8.3. Dialog methods.
MethodDescription
boolean isModal true or false depending on whether the dialog is modal.
String getTitle() Returns a string that is the title of the dialog.
setTitle(String) Sets the dialog title to the String parameter.
boolean isResizeable() true or false depending on whether the dialog is set to be resizeable.
setResizeable(boolean) Sets the ability for the user to resize the dialog window.

Dialog Example Applet

The applet in Listing 8.2 attaches two dialogs to an instance of the Frame class.


Listing 8.2. The DialogCrazee applet code.
import java.awt.*;
import java.applet.Applet;

public class DialogCrazee extends Applet {

// Define and initialize your main frame window.
Frame AFrame = new FrameJr("Dialog Crazee");

// Define an untitled modal dialog.
Dialog ADialog = new Dialog(AFrame, true);

// Define a titled, non-modal dialog.
Dialog BDialog = new Dialog(AFrame, "I've gotta title!", false);

public void init () {

  // Resize the AFrame to width of 100 pixels,
  // And a height of 150 pixels.
  AFrame.resize(100, 150);

  // Resize each of the dialogs so you can see them.
  ADialog.resize(100,100);
  BDialog.resize(200,200);

  // Add a label to each of the dialogs.
  ADialog.add(new Label("I am ADialog."));
  BDialog.add(new Label("I am BDialog."));

  // Display the AFrame.
  AFrame.show();
}

}

class FrameJr extends Frame {

FrameJr (String InTitle) {
  super(InTitle);
}
}

What occurs in this applet is relatively simple. The initial coding declares the different variables. Then, they are set up in the init() method. And finally, the AFrame is told to appear.

But if you execute this applet, you are in for a surprise. Where are the dialogs you have worked to create? Well, they haven't been told to show themselves.

Since dialogs are usually set to appear when some event happens, such as the user wishing to load a file, that prompts the program to display it. This fits in great with the idea of handling events in the AWT. You connect the appearance of each one of the dialogs with an action that takes place in the frame.

To generate these actions in the original AFrame, you create two buttons in the original frame labeled "A" and "B", then set the handleEvent method to display the respective dialog when the user presses the buttons.

The first step is to add a couple of new buttons to the AFrame frame. To do this, use the constructor in Chapter 6:

new AButton = new Button("A");
new BButton = new Button("B");

Then, insert these buttons into the AFrame using the add method. The handleEvent method in the previous example also needs to be created. Insert two if blocks to check and see if one of the buttons is the originator of the event.

The improved DialogCrazee applet follows as Listing 8.3. The output from the DialogCrazee applet appears in Figure 8.4.

Figure 8.4 : The output from the DialogCrazee applet.


Listing 8.3. The improved DialogCrazee applet code.
import java.awt.*;
import java.applet.Applet;

public class DialogCrazee extends Applet {

     // Define and initialize our main frame window.
     Frame AFrame = new FrameJr("Dialog Crazee");

     // Define an untitled modal dialog.
     Dialog ADialog = new Dialog(AFrame, true);

     // Define a titled, non-modal dialog.
     Dialog BDialog = new Dialog(AFrame, "I've gotta title!", false);

     // Define the two new buttons to go into the frame.
     Button AButton = new Button("A");
     Button BButton = new Button("B");

     public void init () {

          // Resize the AFrame to width of 100 pixels,
          // And a height of 150 pixels.
          AFrame.resize(100, 150);

          // Resize each of the dialogs so you can see them.
          ADialog.resize(100,100);
          BDialog.resize(200,200);

          // Add a label to each of the dialogs.
          ADialog.add(new Label("I am ADialog."));
          BDialog.add(new Label("I am BDialog."));

          // Add the two buttons to the frame.
          add(AButton);
          add(BButton);

          // Display the AFrame.
          AFrame.show();
     }

     public boolean handleEvent(Event InEvent)  {

          if (InEvent.target == AButton)  {
               ADialog.show();
          } else

          if (InEvent.target == BButton)  {
               BDialog.show();
          }

          return super.handleEvent(InEvent);
     }

}

class FrameJr extends Frame {

     FrameJr (String InTitle) {
          super(InTitle);
     }
}

Note:
Ideally, you want the dialogs which belong to a frame to be declared inside of that frame. Then, when you handle an event, you call a public method of the FrameJr (or whatever you call it) class which then shows the dialog. However, this seems simpler. It is not difficult to place your dialogs inside your frame constructor so plan on doing that. Even though the code is a little choppier, it is sound coding practice.

Caution:
If you run this applet and then try to close the frame window, you notice that nothing happens. To make the close button functional, you need to add a handleEvent() method to the declaration of an instance of the Frame class since it doesn't include functionality for this feature as a default. If you are creating an application which is an extension of the Frame class, place the handleEvent() method in the class declaration itself. If you are using the method described here to place frames into applets, place the handleEvent() method inside of that class declaration.
To accomplish this inside of your secondary class (for example, one such as the FrameJr class), include the following if block inside of a handleEvent() method for your frames:
if (InEvent.id == Event.WINDOW_DESTROY)
 {
   dispose();
 }
 
.

File Dialogs

A special dialog subclass is dedicated to saving, loading, and dealing with files. Each implementation of the AWT for each different windowing system mimics that system's standard native file dialog. If you implement the FileDialog class in X Window for example, you get the typical X Window file dialog.

There are two major constructors for the FileDialog class:

FileDialog AFileDialog = new (AFrame, AString);
FileDialog BFileDialog = new (AFrame, AString, AInteger);

For both of the constructors, the first two parameters are the same. Just as with the general dialog class, you must specify a frame to which the dialog belongs. You also need to specify the title for the dialog. The second constructor takes a parameter which is one of either FileDialog.LOAD or FileDialog.SAVE. This constant determines whether the dialog is a load file dialog or a save file dialog.

If the first constructor is called, an open file dialog is created. So, in summary, to open a file, use the first constructor. To save a file or load a file, use the second constructor with the different constants available. There is no constant called FileDialog.OPEN; you must use the first constructor.

The FileDialog() class uses many of the same methods common to descendants of the AWT Window class, and some others. Here is a summary of the file dialog methods in Table 8.4.

Table 8.4. Some available file dialog methods.
MethodDescription
int getmode() Returns an integer constant that is one of the different constants signifying load, open, and so forth.
String getDirectory() Returns a string that is the directory of the file dialog's focus.
void setDirectory Sets the current directory focus to the String directory.
void setFile(StringTheFile) Sets the current file for the dialog.
String getFile() Returns a string that is the file name of the current file in focus.
FilenameFilter getFilenameFilter() Returns the current filter of the file listing.
SetFilenameFilter Sets the current file name filter.

Window-to-Window Data Exchange, or Connecting the Object-Oriented Way
In some cases, you run into problems in terms of connecting the two different classes together. For example, you want to send some data that you get in one window to another window. Or your dialog box asks for information and you wish to allow your frame to use it.
A similar dilemma arises when dealing with other classes. You have to "hardwire" the connection between the two classes. This is contrary to one of the primary goals of object-oriented programming which is the re-usability of code. Making one frame class so that it can only send data back to an instance of the Applet class means that you need to rewrite and recompile the sender each time you want to use it with a different class. And also, you have to have a different copy of each version of your class around for every other class it connects with.
The solution to this problem is the idea of interfaces. Interfaces are classes which have not had any method implemented. In other words, instances of interfaces are, except for local constants, a big empty. However, they allow the user to create linkages between classes without having to worry about the different implementations. To use an interface in your applet, you must declare an instance of it. For example, if you want an interface which allows you to relate a value of an integer to another class that uses the interface, declare the following interface:
interface MyInterface {
 abstract public int AnInteger;
}
You can also declare methods inside of your interfaces by using the same abstract public format. Though the abstract isn't needed for methods since it is the only state that methods in an interface are allowed to be. In essence, you are declaring variables and methods with concern for what they do, but saving the "how" for another class to take care of. To create a class which takes care of the implementation of your interface, you use the following class declaration:

class AFrame extends Frame implements MyInterface {

.

.

.

}

The method described first in this section "hardwires" the connection between the two classes. You can also do the following when you want to use information contained in the class which implements the interface:

((MyInterface) getParent()).AnInteger
You can also do the same with methods by being able to call the methods which were declared in the interface and then implemented in the other class:
((MyInterface) getParent()).AVoid();
What is happening in each of these statements is that the result of the function getParent() (which returns the immediate parent of an object) is cast to be an instance of the interface type. Then, the method or variable of the interface, which is implemented by the other class, is accessed.
Well, can't you avoid all of this trouble and hardwire it in? Yes, but there are two reasons you don't want to. For one, Java compilers aren't very fast at the moment. A five hundred line program can take a minute to compile. If you have to rewrite one line of one five hundred line class to get it to connect with another class and then compile it for five different connections, it is going to take time.
Finally, the reason this is included in this section is that it is very useful in terms of the AWT and its windowing capabilities. You want to write your dialogs to be able to be reused with different frames you create.

Adding to the Order Entry System

It is time to apply some of the new concepts covered in this chapter to the Order Entry System. The first topic to cover is the code changes necessary to make the Order Entry System function as a stand-alone window. This includes inserting a button in the applet panel which the user can press to call up the order window. Also, some pop-up dialogs are incorporated into the applet. You want a dialog to appear specifically when the user leaves the name field empty. It is also simple to incorporate other dialogs to appear in response to other events.

Making the Order Entry System a Stand-Alone Window

Using the concepts covered earlier in this chapter, this section covers the method to convert the Order Entry System to a stand-alone window. You add a button to the applet panel which the user can press to bring up the window. Then, the user can fill in the form on the window.

To have a frame belong to an applet, you first have to declare another class inside of the applet file which extends the Frame class. This is because frames cannot belong directly to applets. Instead, sidestep this by declaring your own class which overrides the Frame class. The name for the new class type is called the OrderEntryFrameType. The declaration for this class type is as follows:

class OrderEntryFrameType extends Frame {

 FrameJr (String InTitle) {
  super(InTitle);
  }
 .
 .
 .
}

But instead of adding the components and setting up variables as in the original Order Entry System in the applet's init() method, you need to create a method in the OrderEntryFrame which accomplishes all of the component insertion and setup done in the applet's init() method. To do this, you copy the corresponding code in the init() method to a method you create in the OrderEntryFrameType. Call this method setup(). So, the format for the OrderEntryFrameType class declaration is as follows:

class OrderEntryFrameType extends Frame {

 FrameJr (String InTitle) {
  super(InTitle);
  }

 public void setup() {
  // The init() code body goes here. . .
 .
 .
}
}

The components that were once added to the applet panel in the applet's init() method are now added to the frame itself. Also all of the variables that are used in the Order Entry System are placed into the frame itself. The full code cost listing of this is included in the complete listing of the applet coming up.

Since these variables are moved into another class, shut them off from being accessed by parent classes. Follow this practice of data encapsulation. All accesses to the data contained in the OrderEntryFrameType are done through methods and functions declared in the class itself.

Almost all of the methods of the original applet are moved to the frame class itself. The function of the system is encapsulated. This makes it easy to actually run the system as an application if need be.

The newly changed Order Entry System follows as Listing 8.4. Here are the major improvements as of this iteration:

  1. The majority of the function is now transferred to a separate frame. This frame is declared in a separate class in the applet file. All of the functions and variables which had been in the applet are moved to the frame itself. Notice that the applet code is translated to an instance of the Frame class which belongs to the applet class. The action and handleEvent methods are also transferred. The new frame instance is completely independent of the applet. (In fact, two instances of the OrderEntryFrameType can just as easily be declared and both of them implemented.)
  2. Also, a button is added to the applet face. The user's activation of this button results in the initialization and display of the frame and also deactivates the button so that another order entry frame cannot be activated.

Listing 8.4. Another iteration of the Order Entry System.
import java.awt.*;
import java.applet.*;

public class OrderEntrySystem extends Applet {

 // Declare an instance of your frame class defined later in the // file.
 OrderEntryFrameType OESFrame;

 // Declare and initialize the button which will be on the applet
 // face and the user can click to activate the order frame.
 Button Order = new Button("Click to Order");

 public void init() {
    add(Order);
  }

 public boolean handleEvent(Event InEvent) {
  if (InEvent.target == Order) {

    // Disable the order button.
    Order.disable();

    // Construct the OESFrame.
    OESFrame = new OrderEntryFrameType("Order Entry System");

    OESFrame.resize(340,400);

    // The setup method which initializes the frame face and
    // the components in it.
    OESFrame.setup();

    // Display the order frame.
    OESFrame.show();
  }

  // Let the parent handle the event.
  return super.handleEvent(InEvent);
 }
}

/* This class declares the new extension of the frame class which
   will allow you to utilize a frame in the applet.  */

class OrderEntryFrameType extends Frame {

 // This is the constructor for your new class.
 OrderEntryFrameType (String InTitle) {

  // Call the Frame constructor.
  super(InTitle);

  // Set the layout of the frame (this has to be done to make things work).
  // This concept will be covered later on in this chapter.
  setLayout(new FlowLayout());
 }

 // This method does the construction of the frame panel.
 public void setup() {

    // Add and create three buttons.
      SubmitButton = new Button("Submit");
    add(SubmitButton);
    ClearButton = new Button("Clear");
    add(ClearButton);
     QuitButton = new Button("Quit");
    add(QuitButton);

    // Add and create the repeat customer checkbox.
     Checkbox RepeatCustCheckBox = new Checkbox("Repeat Customer?");
    add(RepeatCustCheckBox);

    // Add a label to the ContactMethodGroup.
    add(new Label("How would you like to be contacted? "));

    // Declare the CheckboxGroup, and allocate space.
    CheckboxGroup ContactMethodGroup;
    ContactMethodGroup = new CheckboxGroup();

    // Create some checkboxes to put in the group.
      Checkbox EmailBox = new Checkbox("Email",ContactMethodGroup,true);
    Checkbox PhoneBox = new
   Checkbox("Phone",ContactMethodGroup,false);
    Checkbox MailBox = new
   Checkbox("US Mail",ContactMethodGroup,false);

    // Add the checkboxes into the applet panel.
    add(EmailBox);
    add(PhoneBox);
    add(MailBox);

    // Label the item list.
    add(new Label("Products"));

    // Create the list, 4 items visible, no multiple
    // selections.
    ProductList = new List(4, false);

    // Add items to the List.
    ProductList.addItem("Oscar");
    ProductList.addItem("Lionhead");
    ProductList.addItem("Jack Dempsey");
    ProductList.addItem("Angelfish");

    // Add the List to the Applet panel.
    add(ProductList);

    // Add a label to the choice of sizes.
    add(new Label("Size:"));

    // Create the Choice box.
    SizeChoice = new Choice();

    // Add items to the List.
    SizeChoice.addItem("Jumbo");
    SizeChoice.addItem("Large");
    SizeChoice.addItem("Medium");
    SizeChoice.addItem("Small");

    // Add the Choice to the Applet panel.
    add(SizeChoice);

    // Add a label to the slider.
    add(new Label("Amount:"));

    // Create a vertical slider, initial value of 0,
    // minimum value of 0, maximum value of 144.
      OrderAmountSlider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 144);
    // Insert the slider to the Applet panel.
    add(OrderAmountSlider);

          // Insert the label which says how many are set to be ordered
          // of the item.
          add(AmountLabel);

          // Add the subtotal label and a label saying that it is
          // the subtotal.
          add(new Label("Subtotal: "));
          add(SubTotalLabel);

          // Add the total label and a label saying that it is the total.
          add(new Label("Total: "));
          add(TotalLabel);


   // Insert a label to signify that this is the personal information
// (address, etc.) section and also insert text fields to prompt
   // for that information.
     add(new Label("Your information: "));
     add(new Label("Name:"));
    add(NameEntryField);
    add(new Label("Street:"));
    add(StreetEntryField);
    add(new Label("City:"));
    add(CityEntryField);
    add(new Label("Zip:"));
    add(ZipEntryField);

    // Add a label to the comment text area.
    add(new Label("Comments:"));

   // Add the comment box.
    add(CommentTextArea);

  // Method which resets all of the internal values.
   resetValues();


  }

 // The subtotal and total variables.
 private double SubTotalOne = 0.0;
 private double Total = 0.0;

 // The price multipliers for each different product size.
 private double multiplierSmall = 0.5;
 private double multiplierMedium = 1.0;
 private double multiplierLarge = 1.5;
 private double multiplierJumbo = 2.25;

 // The local constant base prices.
 static double ProdOneBaseValue = 1.0;
 static double ProdTwoBaseValue = 1.33;
 static double ProdThreeBaseValue = 1.75;
 static double ProdFourBaseValue = 8.75;

 // Declare all of the variables you'll use.
 private Button SubmitButton;
 private Button ClearButton;
 private Button QuitButton;
 private Checkbox RepeatCustCheckBox;

 private Checkbox MailBox;
 private Checkbox EmailBox;
 private Checkbox PhoneBox;

 private List ProductList;
 private Choice SizeChoice;
 private Scrollbar OrderAmountSlider;

 // The labels which will be variable and change when
 // the other selections are changed.
 private Label SubTotalLabel = new Label("$0.0 ");
 private Label TotalLabel = new Label("$0.0 ");
 private Label AmountLabel = new Label("$0.0 ");
 private Label PricePerItemLabel = new Label("$0.0 ");

 // The entry field for the user to enter a name.
 private TextField NameEntryField = new TextField(25);
 private TextField ZipEntryField = new TextField(5);
 private TextField StreetEntryField = new TextField(25);
 private TextField CityEntryField = new TextField(25);
 // The comment entry area.
 private TextArea CommentTextArea = new TextArea(4, 25);

 private void updateValues() {

        int WhichChoice = SizeChoice.getSelectedIndex();
        int AmountSelected = OrderAmountSlider.getValue();
        int WhichProduct = ProductList.getSelectedIndex();
        double CurrentBasePrice = 0.0;
        double CurrentModifier = 0.0;


        switch (WhichProduct) {
            case 0:
                CurrentBasePrice = ProdOneBaseValue;
                break;
            case 1:
                CurrentBasePrice = ProdTwoBaseValue;
                break;
            case 2:
                CurrentBasePrice = ProdThreeBaseValue;
                break;
            case 3:
                CurrentBasePrice = ProdFourBaseValue;
                break;

        }

        switch (WhichChoice) {
            case 3:
                CurrentModifier = multiplierSmall;
                break;
            case 2:
                CurrentModifier = multiplierMedium;
                break;
            case 1:
                CurrentModifier = multiplierLarge;
                break;
            case 0:
                CurrentModifier = multiplierJumbo;
                break;
        }

        AmountLabel.setText(Integer.toString(AmountSelected)+ " ");
        double PricePerItem = (CurrentBasePrice*CurrentModifier);
        PricePerItemLabel.setText(Double.toString(PricePerItem)+ " ");
        double SubTotal = (CurrentBasePrice*CurrentModifier*AmountSelected);
        SubTotalLabel.setText(Double.toString(SubTotal)+ " ");
        TotalLabel.setText(SubTotalLabel.getText());
 }

 // This method will be called when the user presses the "Clear" button and
 // also when the applet is initialized in the init() method.
 public void resetValues() {

  // Reset all of these labels to zero.
  SubTotalLabel.setText("$0.0 ");
  TotalLabel.setText("$0.0 ");
  AmountLabel.setText("0 ");
  PricePerItemLabel.setText("$0.0 ");

  // Clear all of the lists and choices.
  ProductList.select(0);
  SizeChoice.select(0);
  OrderAmountSlider.setValue(0);

  // Clear all of the text fields.
  NameEntryField.setText("");
  StreetEntryField.setText("");
  CityEntryField.setText("");
  ZipEntryField.setText("");
 }

 public boolean handleEvent(Event InEvent) {
  if (InEvent.id == Event.SCROLL_LINE_UP ||
      InEvent.id == Event.SCROLL_LINE_DOWN)  {
     updateValues();
  } else
  if (InEvent.target == ProductList) {
        updateValues();
  } else
  if (InEvent.target == ClearButton) {
              resetValues();
  } else
  if (InEvent.target == QuitButton)  {
  // Quit the applet.
   System.exit(0);
  } else
  if (InEvent.target == SubmitButton) {
   // Submit the order.
  }
  return super.handleEvent(InEvent);
 }

 public boolean action (Event InEvent, Object SomeObject) {
  if (InEvent.target == SizeChoice) {
   updateValues();
  return true;
  }
  else
  if (InEvent.target == NameEntryField) {
   // Is the field empty?  If so, we will later add a pop-up dialog
   // box to alert the users that they have not entered their name.
   return true;
   } else
  return false;
 }
}

The Order Entry System is still growing. Next, the ability to display a dialog box in response to a user action is added. Notice that the framework for this ability is built in the action method of the OrderEntryFrameType class that has been created.

Figure 8.5 is the Order Entry System when viewed from the Appletviewer utility.

Figure 8.5 : The Order Entry System from the Appletviewer utility.

The disable() and enable() Methods
These two methods allow you, the programmer, to deactivate and activate your components. It is used in the latest version of the Order Entry System to disable the button which calls the Order Entry System window. You can use these methods to enable and disable your components when you wish.

Adding Pop-Up Dialogs to the Order Entry System

Adding a pop-up dialog to the Order Entry System is simpler than converting to a stand-alone window. The framework for displaying the dialog window is already completed. Now, create a new class which extends the Dialog class as you create a new class to create the OrderEntryFrameType. Then, declare an instance of your new dialog box type and implement it in the frame type.

When the name text field creates an event, it is handled by the action method. The action method is set to recognize this event, except it is not set to do anything when it gets the event. You are going to change this.

The first step is to declare an extension of the Dialog class.

class WarningDialog extends Dialog {

 private Button OkButton = new Button("OK");
 private Label ALabel;

 WarningDialog(Frame HostFrame, String Message)  {
  super(HostFrame, "Warning!", false);

  ALabel = new Label(Message);
  resize(180,100);

  setLayout(new FlowLayout());
  add(ALabel);
  add(OkButton);
 }

 public boolean action (Event InEvent, Object Param)  {
  if (InEvent.target == OkButton)  {
   hide();
  }
  return true;
 }
}

Add this class declaration to the Order Entry System class declaration file. Then, declare an instance of it inside of the OrderEntryFrameType:

WarningDialog WDialog = new WarningDialog(this, "You have not entered a name. ");

To display the warning dialog, call the show() method, which is inherited from the dialog class when the dialog class is extended:

WDialog.show();

Figure 8.6 shows what happens when the user of the Order Entry System leaves the name field blank.

Figure 8.6 : The Order Entry System with the WarningDialog class included.

The new extension of the Dialog works great, but look at what happens when the dialog box window is resized in Figure 8.7.

Figure 8.7 : The WarningDialog box resized.

The layout of the components in the dialog box is at fault. For now, the default layout (which is the FlowLayout manager) has been used. But it is obvious that this isn't going to work. The next section covers the different AWT layout managers and applies one to the Order Entry System.

Tip:
The this keyword is very useful in Java. It refers to the current class. For example, you want to attach a dialog to a frame and declare that dialog in the frame. You say,

Dialog D = new Dialog(this, "Sample", true);

Layout Managers in the AWT

AWT layout managers are the means by which you, the programmer, can give a set of general rules to determine how your components in a container are arranged. Remember, applets are standard with an initial panel incorporated so you can set the layout of your applet face.

In other windowing systems such as Microsoft Windows, the programmer specifies actual coordinates for different components of the window to be arranged. However, this is impossible in Java since the goal is platform independence. The window you create under Solaris should work on a Macintosh, a DEC Alpha, and an NeXT. This goal of independence makes some tasks more difficult. As for the layout of components in general, it is one of the tougher concepts in Java. It is much easier to set the exact coordinates like other systems. While container layout is difficult, it has been designed to be powerful and relatively convenient to implement.

In any case, the following sections outline the five Java AWT layout managers.

FlowLayout

The FlowLayout manager is the default layout manager for applets. If you look back, you notice that the applets constructed earlier follow a general layout pattern. Components are inserted left to right until the end of a row is reached. Then, the same process begins on the next line until that row is filled also. If an attempt is made to place too many components in a panel, the ones that didn't fit are left out.

To set the layout manager you wish to use, the setLayout() method is available. The following code line sets the layout in a panel APanel to the FlowLayout manager:

APanel.setLayout(new FlowLayout());

There are multiple options you can use with the FlowLayout manager. First, the manager allows you to specify the alignment of the layout. There are three constants available in the FlowLayout class: FlowLayout.LEFT, FlowLayout.CENTER (the default), and FlowLayout.RIGHT.

You can also set the vertical and horizontal "padding" between different components. This is done in one version of the FlowLayout constructors. The default value for this padding is 5 pixels vertical and 5 pixels horizontal.

Table 8.5 summarizes the FlowLayout constructors.

Table 8.5. The constructors for the FlowLayout class.
ConstructorEffect
FlowLayout() Default constructor.
FlowLayout(align) align is one of FlowLayout.LEFT, FlowLayout.CENTER, or FlowLayout.RIGHT.
FlowLayout(align, HPad, VPad) HPad and VPad are integers specifying the horizontal and vertical padding between components in terms of pixels.

The following r code declares a panel, sets the internal panel layout, and adds a component to that panel:

Panel P = new Panel();
P.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 15);
P.add(new Label("Text.");

BorderLayout

The BorderLayout manager divides a container into five different segments. These are "North," "South," "Center," "West," and "East." Of course, the "North" segment of a container is the top, the "West" is the left and so on. There are two major constructors for the BorderLayout manager:

BorderLayout BLayout = new BorderLayout();
BorderLayout BLayout2 = new BorderLayout(10, 15);

The second constructor sets the horizontal and vertical padding just like in the FlowLayout manager. To add components to a container using this manager, you must specify the region which the component occupies like this:

add("West", AComponent);

This inserts the AComponent into the western (left) region of the container.

The following applet declares an instance of the BorderLayout class and then adds one button to each of the five areas. The code is in Listing 8.5.


Listing 8.5. The BorderExample applet code.
import java.awt.*;
import java.applet.*;

public class BorderExample extends Applet {
public void init()  {
  BorderLayout BLayout = new BorderLayout(5, 5);
  setLayout(BLayout);

  add("West", new Button("west"));
  add("East", new Button("east"));
  add("North", new Button("north"));
  add("South", new Button("south"));
  add("Center", new Button("center"));
}
}

The output from this applet is Figure 8.8.

Figure 8.8 : The BorderExample applet when viewed from the Appletviewer utility.

Notice that the different buttons expand to fill the area they are given under this layout manager.

CardLayout

The CardLayout manager is unique among the different layout managers in the AWT. Instead of placing all of the components next to each other, it allows components to be positioned behind each other. Basically, the idea is that you can define a couple of component groups and then when certain actions occur, you can switch between those groups on the same display area.

To put the CardLayout manager into use, first define an instance of the CardLayout manager in your applet. Then, setLayout of your applet to the instance you just declared. For each separate card you want to have, create a Panel and place in it what you want. Finally, add each of the new panels using the add method.

Table 8.6 shows the methods available for use in the CardLayout manager.

Table 8.6. The available CardLayout manager methods.
MethodsEffect
first(AContainer) Display the first card inserted. The parameter is the name of the parent container which implements the CardLayout manager.
last(AContainer) Same as first except showing the last item in the layout.
next(AContainer) Display the next card inserted. The parameter is the name of the parent container which implements the CardLayout manager.
show(Acontainer, AString) Display the card.

Overall, this manager isn't as functional as it can be. Ideally, the tabbed card layouts found in systems such as Windows 95 can be implemented. However, this isn't possible with the current AWT. Hopefully, the carding features of the AWT will be a feature which is extended in future development of Java.

GridLayout

The GridLayout manager divides a container into uniformly sized rows and columns. Imagine drawing a grid over a container and then each component filling a grid square as you add() them to the container. The placement continues from left to right and top down. There are two major constructors for the GridLayout manager class:

GridLayout GL1 = new GridLayout(IntRows, IntColumns);
GridLayout GL2 = new GridLayout(IntRows, IntColumns, HPad, VPad);

In the first constructor, the two parameters specify the number of grid rows and columns to divide the container into. The second constructor also accepts the number of pixels of horizontal and vertical padding between the grid squares. This manager isn't great for larger layouts, but useful when applied to smaller containers involved in subdividing a large display.

Note:
The "grid" discussed in this section is not represented on the container as any lines or borders. Rather, it is a means to mentally picture the dividing of the container into uniform squares.

The GridBagLayout manager extends the basic idea behind the grid layout manager. The main difference lies in that the components can be different sizes in terms of occupying multiple grid spaces. Where components can only occupy one grid space in the container, there are also a number of parameters to align the components inside of the grid. You are also capable of setting component padding and the anchoring of the components inside of the grid square. This is all great and powerful, but unlike many of the other features of Java, not very intuitive.

To implement the grid bag layout, you need to declare an instance of the GridBagLayout class. Then, set the layout of the container to this variable where GBL is the local instance of the GridBagLayout class:

GridBagLayout GBL = new GridBagLayout();
setLayout(GBL);

The multiple parameters, such as anchoring, alignment, grid position, and so forth are declared in a class called GridBagConstraints. To complete any of these settings for a component, you first declare an instance of the GridBagConstraints class. Then, you change the constants representing these parameters in the instance of the constraints class. For example, if you want to set the anchoring of the component inside the grid space, you say:

Constraints.anchor = GridBagConstraints.NORTH;

where Constraints is an instance of the GridBagConstraints class. To associate these constraints with the component when you add it to your container, you use the following code:

GBL.setConstraints(AComponent, Constraints);
add(AComponent);

And you continue this process for each component you want to add using this layout manager.

Setting the Layout Constraints

As stated previously, for each component you wish to insert, you must set the current constraints under which that component is inserted. This has been demonstrated before when the setConstraints method is used to set the constraints for a component which is then inserted.

There are a large number of settings for you to set in the instance of the GridBagConstraints class. The primary fields of the constraints class are the gridx and the gridy fields. These specify the x and y coordinates of the grid space in which you wish for your component to appear. Note that the grid squares begin at 0,0 (the upper-left corner of your grid).

There are two ways to insert components into the grid. One way is to specify the actual coordinates in which you want your component to appear. The second way, and the way intended by Java's designers, is to specify both of these constants to be the value of GridBagConstraints.RELATIVE. The idea is that you begin placing components into the grid and they are placed left to right, in adjacent squares. Finally, when you want to move down to the next line, you specify the gridx.

Use the second method. Placing components in this manner means that you also need to say when you want to go to the next row to place the next component. To do this, set another of the constraints to a different constant. These settings are the gridwidth and gridheight settings in your instance of the GridBagConstraints class.

gridwidth and gridheight set the amount of grid cells that a component occupies when it gets placed. For example, a gridheight of 2 means that the component occupies two grid cells in terms of height. And if you want the component to occupy three cells in width, set the gridwidth to 3. Your instance of the constraints in the Order Entry System is called Constraints. To set the component to occupy three grid cells in width, use the following line:

Constraints.gridwidth = 3;

The default for these values is 1. Leave them alone until you are ready to begin placing components on a new row. To do this, set the gridwidth to equal GridBagConstraints.REMAINDER. This signals the layout manager that this component is the last on this row.

That takes care of the general placing of the components in the grid. There are also a number of other constraints which allow you to place the components inside of the grid space they are occupying.

The first of these is the anchor value of the GridBagConstraints. This tells the layout manager where the component is positioned inside of the grid box it is occupying. The acceptable values are GridBagConstraints.SOUTH, GridBagConstraints.NORTHEAST, GridBagConstraints.WEST, and so forth. All of the eight directions are covered.

The fill parameter tells the layout manager how components such as buttons fill the grid box that they are in. There are four possible settings. These are demonstrated in Table 8.7.

Table 8.7. The four GridBagConstraints settings.
SettingEffect
GridBagConstraints.NONE No expansion.
GridBagConstraints.HORIZONTAL Expand to fill horizontally.
GridBagConstraints.VERTICAL Expand to fill vertically.
GridBagConstraints.BOTH Expand to fill both vertically and horizontally.

The weightx and weighty settings determine the sizes of the different components relative to each other. This is used to have your components spread out to fill the container. Otherwise your components all cluster in the center of the container. The weights are all relative to each other. A component with a weightx of 3 has a size three times that of a component having a weightx of 1.

If you want to add some pixels around a component to separate it from the other components surrounding it, use the ipadx and ipady settings in the constraints variable. Whatever number you set each of these values to is the number of pixels that the layout manger places as an empty area around your component.

Recipe for Implementing the GridBagLayout Manager

The following steps outline the steps in implementing the GridBagLayout manager for a container:

  1. Declare an instance of the GridBagLayout manager and an instance of GridBagConstraints in your program.
  2. Set the layout of your container to be the instance of the GridBagLayout manager you defined in Step 1.
  3. For each component you wish to add, either declare a new instance of the constraints or modify an old one.
  4. For the constraints made available in Step 3, set the values in that instance. For example, set gridwidth equal to GridBagConstraints.REMAINDER if you want to say that you are finished filling this row. Also set other constraints such as the weightx or fill.
  5. setConstraints for the layout manager using the component name as the first parameter and the second parameter as the constraints.
  6. add the component to the container, sending the first parameter as the constraints from Step 4 and the second as the name of the component.
  7. Repeat Steps 3 through 6 until you are finished.

Fixing the Layout of the Order Entry System

Now you take what there is so far in the Order Entry System and organize its appearance. The plan is to "divide and conquer" the regions of the entry interface that you have already begun constructing. The entire window face is designed with this goal in mind. The primary layout (the layout manager which is used on the window panel itself) is going to be the GridBagLayout manager. As shown, it is by far the most powerful in terms of getting components where you want them. There are a number of sub-panels in use. Each subdivides the main frame window, whose layout is managed by the PrimaryLayout which is an instance of the GridBagLayout class. Each individual sub-panel is named by function, such as InfoPanel which is the sub-panel that gets the user information. Each sub-panel which uses the GridBagLayout manager also has an instance of the GridBagConstraints class to help manage it. A complete inspection of the code isn't really necessary. The most important concept to understand is the process of subdividing the containers to get the layout that you want. While it is tedious (as you can tell from the length of the code), it is the solution to provide both pretty layouts and platform independence. Figure 8.9 is what you end up with after it is all over.

Figure 8.9 : What the Order Entry System looks like after it is completed with this section.

Listing 8.6 is the revised setup() and constructor implementation. It now implements the different AWT layout managers to control the placement of the components in the container.


Listing 8.6. The OrderEntryFrameType class code.
class OrderEntryFrameType extends Frame {

 OrderEntryFrameType (String InTitle) {
  super(InTitle);

  }

 WarningDialog WDialog = new WarningDialog
     (this, "You have not entered a name. ");
public void setup() {

      // Set the initial grid bag layout for the frame.
     GridBagLayout PrimaryLayout = new GridBagLayout();
     setLayout(PrimaryLayout);

     // Set the constraints for the Product Panel, which will contain product
     // choices, sizes, etc.
     GridBagConstraints ProductPanelConstraints = new GridBagConstraints();

     // The Product Panel will take up the rest of the space on this line.
     ProductPanelConstraints.gridwidth = GridBagConstraints.REMAINDER;

     // Declare and initialize the Product Panel.
     Panel ProductPanel = new Panel();

     // Set the layout for the Product Panel and set the constraints for
     // the components inside of the Product Panel.
     GridBagLayout ProductPanelLayout = new GridBagLayout();
     GridBagConstraints InProductPanelConstraints =
        new GridBagConstraints();
ProductPanel.setLayout(ProductPanelLayout);

     // Here we will set the list panel, which will hold the
     // list choice method and insertion.
     Panel ListPanel = new Panel();
     ListPanel.setLayout(new BorderLayout());

     Label ProductLabel = new Label("Products");
     ListPanel.add("North", ProductLabel);

     // Create the list, 4 items visible, no multiple
     // selections.
     ProductList = new List(4, false);

          // Add items to the List.
          ProductList.addItem("Oscar");
          ProductList.addItem("Lionhead");
          ProductList.addItem("Jack Dempsey");
          ProductList.addItem("Angelfish");

          // Add the List to the list panel.
          ListPanel.add("Center",ProductList);

          // Add the embedded panel to the Product Panel.
          InProductPanelConstraints.anchor = GridBagConstraints.NORTH;
          ProductPanelLayout.setConstraints(
               ListPanel, InProductPanelConstraints);
ProductPanel.add(ListPanel);

          // Another panel which will be embedded in the Product Panel.
          Panel SizePanel = new Panel();
          SizePanel.setLayout(new BorderLayout());


          // Add a label to the choice of sizes.
          SizePanel.add("North", new Label("Size:"));

          // Create the Choice box.
          SizeChoice = new Choice();

          // Add items to the List.
          SizeChoice.addItem("Jumbo");
          SizeChoice.addItem("Large");
          SizeChoice.addItem("Medium");
          SizeChoice.addItem("Small");

          // Add the Choice to the Applet panel.
          SizePanel.add("Center",SizeChoice);

          // Add the embedded panel to the Product Panel.
          ProductPanelLayout.setConstraints(SizePanel,
          InProductPanelConstraints);
ProductPanel.add(SizePanel);

          // Another panel which will be embedded in the Product Panel.
          Panel AmountPanel = new Panel();
          AmountPanel.setLayout(new BorderLayout());

          // Add a label to the slider.
          AmountPanel.add("North", new Label("Amount:"));

          // Another embedded panel which will contain the slider and
          // the output label.
          Panel SliderPanel = new Panel();
          SliderPanel.setLayout(new FlowLayout());

          // Insert the label which says how many are set
          // to be ordered of the item.
SliderPanel.add(AmountLabel);

               // Create a vertical slider, initial value of 0,
               // minimum value of 0, maximum value of 144.
               OrderAmountSlider = new
               Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 144);
               // Insert the slider to the Applet panel.
               SliderPanel.add(OrderAmountSlider);

               AmountPanel.add("Center", SliderPanel);

     // Add the embedded panel to the Product Panel.
     ProductPanelLayout.setConstraints(AmountPanel,
         InProductPanelConstraints);
ProductPanel.add(AmountPanel);

          // The last panel which will be embedded in the Product Panel.
          Panel TotalPanel = new Panel();
          TotalPanel.setLayout(new BorderLayout());

          // Add the subtotal label and a label saying
          // that it is the subtotal.
TotalPanel.add("North", new Label("Total: "));
          TotalPanel.add("South",TotalLabel);

          ProductPanelLayout.setConstraints(TotalPanel,
          InProductPanelConstraints);
ProductPanel.add(TotalPanel);

     ProductPanelLayout.setConstraints(TotalPanel,
          InProductPanelConstraints);
// Add the embedded panel to the Product Panel.
     ProductPanel.add(TotalPanel);

     // Set the constraints for the Product Panel's insertion.
     PrimaryLayout.setConstraints(ProductPanel, ProductPanelConstraints);
     // Add the Product Panel to the frame.
     add(ProductPanel);

     // The second panel to be embedded in the frame is the Info panel.
     // This panel gets the information about the user.
     GridBagLayout InfoPanelLayout = new GridBagLayout();
     Panel InfoPanel = new Panel();
     GridBagConstraints InfoPanelConstraints = new GridBagConstraints();
     InfoPanelConstraints.gridwidth = GridBagConstraints.REMAINDER;
     ProductPanelLayout.setConstraints(InfoPanel, InfoPanelConstraints);
     InfoPanel.setLayout(InfoPanelLayout);

                GridBagConstraints InInfoConstraints = new GridBagConstraints();
                InInfoConstraints.gridwidth = GridBagConstraints.REMAINDER;
                InInfoConstraints.anchor = GridBagConstraints.WEST;
                Label InfoLabel = new Label("Your information: ");
                InfoPanelLayout.setConstraints(InfoLabel, InInfoConstraints);
                InfoPanel.add(InfoLabel);

     // The name entry field area.
                Panel NameFieldPanel = new Panel();
                NameFieldPanel.setLayout(new BorderLayout());
                NameFieldPanel.add("West",new Label("Name:"));
                NameFieldPanel.add("East",NameEntryField);
                InInfoConstraints.anchor = GridBagConstraints.EAST;
                InfoPanelLayout.setConstraints(NameFieldPanel,
                    InInfoConstraints);
InfoPanel.add(NameFieldPanel);

     // The Street entry area implementation.
            Panel StreetFieldPanel = new Panel();
            StreetFieldPanel.setLayout(new BorderLayout());
            StreetFieldPanel.add("West",new Label("Street:"));
            StreetFieldPanel.add("East",StreetEntryField);

                InfoPanelLayout.setConstraints(StreetFieldPanel,
                     InInfoConstraints);
                InfoPanel.add(StreetFieldPanel);

                Panel CityFieldPanel = new Panel();
                CityFieldPanel.setLayout(new BorderLayout());
                CityFieldPanel.add("West",new Label("City:"));
                EntryFieldPanel.add("East",CityEntryField);
                InfoPanelLayout.setConstraints(CityFieldPanel,
                     InInfoConstraints);
InfoPanel.add(CityFieldPanel);

     // The zip entry field implementation.
            Panel ZipFieldPanel = new Panel();
            ZipFieldPanel.setLayout(new BorderLayout());
            ZipFieldPanel.add("West",new Label("Zip:"));
            ZipFieldPanel.add("East",ZipEntryField);
            InfoPanelLayout.setConstraints(ZipFieldPanel,
                 InInfoConstraints);
InfoPanel.add(ZipFieldPanel);

     // The comment label.
            InInfoConstraints.anchor = GridBagConstraints.WEST;
            Label CommentLabel = new Label("Comments: ");
            InfoPanelLayout.setConstraints(CommentLabel,
                 InInfoConstraints);
            InfoPanel.add(CommentLabel);

     // Add the comment box.
            InInfoConstraints.anchor = GridBagConstraints.CENTER;
            InfoPanelLayout.setConstraints(CommentTextArea,
                 InInfoConstraints);
InfoPanel.add(CommentTextArea);

     PrimaryLayout.setConstraints(InfoPanel, InfoPanelConstraints);
     // Add the info panel to the frame layout.
     add(InfoPanel);


     // Add and create the repeat customer checkbox.
          Panel ContactPanel = new Panel();
          ContactPanel.setLayout(new BorderLayout());

     // Add a label to the ContactMethodGroup.
     ContactPanel.add("North",new
              Label("How would you like to be contacted? "));

     // Declare the CheckboxGroup, and allocate space.
     CheckboxGroup ContactMethodGroup;
     ContactMethodGroup = new CheckboxGroup();

     // Create some checkboxes to put in the group.
     Checkbox EmailBox = new Checkbox("Email",ContactMethodGroup,true);
     Checkbox PhoneBox = new
         Checkbox("Phone",ContactMethodGroup,false);
     Checkbox MailBox = new
         Checkbox("US Mail",ContactMethodGroup,false);

     // Add the checkboxes into the applet panel.
     ContactPanel.add("West",EmailBox);
     ContactPanel.add("Center",PhoneBox);
     ContactPanel.add("East",MailBox);

     // Sets the constraints for the Contact panel.
         GridBagConstraints ContactPanelConstraints = new GridBagConstraints();
         ContactPanelConstraints.gridwidth = 2;
         GridBagConstraints.RELATIVE;
         ContactPanelConstraints.weightx = 2.0;
         PrimaryLayout.setConstraints(ContactPanel, ContactPanelConstraints);
         add(ContactPanel);

     // Insert the different checkboxes into the panel.
     GridBagConstraints CustCheckBoxConstraints =  new GridBagConstraints();
     CustCheckBoxConstraints.weightx =1.0;
     CustCheckBoxConstraints.gridwidth = GridBagConstraints.REMAINDER;
     Checkbox RepeatCustCheckBox = new Checkbox("Repeat Customer?");
     PrimaryLayout.setConstraints(RepeatCustCheckBox, CustCheckBoxConstraints);
     add(RepeatCustCheckBox);

     GridBagConstraints ButtonConstraints = new GridBagConstraints();
     ButtonConstraints.gridx = GridBagConstraints.RELATIVE;

     // Spreads the buttons out across the window.
     ButtonConstraints.weightx = 1.0;
     ButtonConstraints.weighty = 1.0;

     // Declare, set, and add the "Submit" button.
     SubmitButton = new Button("Submit");
     PrimaryLayout.setConstraints(SubmitButton, ButtonConstraints);
     add(SubmitButton);

     // Declare, set, and add the "Clear" button.
     ClearButton = new Button("Clear");
     PrimaryLayout.setConstraints(ClearButton, ButtonConstraints);
     add(ClearButton);

     // Set the constraints and insert the Quit button.  This button
     // due to the REMAINDER setting will be the last on the line.
     GridBagConstraints LastButtonConstraints = new GridBagConstraints();
     LastButtonConstraints.gridwidth = GridBagConstraints.REMAINDER;
     QuitButton = new Button("Quit");
     PrimaryLayout.setConstraints(QuitButton, LastButtonConstraints);
     add(QuitButton);

     // Method which resets all of the internal values.
     resetValues();
  }

Summary

In this chapter, you covered a good amount of ground. First, you saw the specifics of a number of the different containers available in the AWT, such as the Frame class and the Panel class. You also saw how the Applet class is a descendant of the Panel class. You learned how to manipulate windows from inside your programs and also how to set the menu bar in those windows. Next, you saw how to create dialog boxes using the AWT, and you included these boxes in the Order Entry System. Finally, you learned how to use the different layout managers in the AWT, and you included those in the Order Entry System.

Perhaps the most recognized fact about Java is that it can bring the Web alive. Many lay people believe that Java is "just the motion on the Web." This fact says something about Java and its appeal: graphics and animation. The next chapter covers the basic graphical functions of Java and takes the first steps toward creating animation, covered in depth later in this book.

In the next chapter, the graphical functions and capabilities of Java are added to the Order Entry System, and an imported logo is placed upon the head of the frame. These capabilities are used to incorporate some graphics into the Order Entry System interface.



Next Previous Contents


  • Главная
  • Новости
  • Новинки
  • Скрипты
  • Форум
  • Ссылки
  • О сайте




  • Emanual.ru – это сайт, посвящённый всем значимым событиям в IT-индустрии: новейшие разработки, уникальные методы и горячие новости! Тонны информации, полезной как для обычных пользователей, так и для самых продвинутых программистов! Интересные обсуждения на актуальные темы и огромная аудитория, которая может быть интересна широкому кругу рекламодателей. У нас вы узнаете всё о компьютерах, базах данных, операционных системах, сетях, инфраструктурах, связях и программированию на популярных языках!
     Copyright © 2001-2024
    Реклама на сайте