PROBLEMS
(Top)
One advantage would be to weight the column and row labels so that they remain fixed in size.
The code for the BorderPanel which is a new type of Container is:
import java.awt.*;Basically, the add method assumes a 3 x 3 grid and places the components in the grid. It assigns appropriate weights so that the center will get all of the increased size in both directions with the marginal components getting increased size in only one direction.class BorderPanel extends Container { private GridBagLayout grid; private GridBagConstraints gbc;
//Constructor
public BorderPanel() { super(); //Create grid layout grid = new GridBagLayout(); gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; //Set panel layout to grid this.setLayout(grid); }
//Helper method to set constraints and add component
private void addComponent(Component comp, int xLoc, int yLoc, int width, int height, double xWeight, double yWeight) { //Set constraints gbc.gridx = xLoc; gbc.gridy = yLoc; gbc.gridwidth = width; gbc.gridheight = height; gbc.weightx = xWeight; gbc.weighty = yWeight; grid.setConstraints(comp,gbc); //Add component to container super.add(comp); }
//Override add method
public Component add(String locate, Component comp) { if (locate.equals("North")) addComponent(comp,0,0,3,1,1.0,0.0); else if (locate.equals("West")) addComponent(comp,0,1,1,1,0.0,1.0); else if (locate.equals("East")) addComponent(comp,2,1,1,1,0.0,1.0); else if (locate.equals("South")) addComponent(comp,0,2,3,1,1.0,0.0); else if (locate.equals("Center")) addComponent(comp,1,1,1,1,1.0,1.0); else throw new RuntimeException ("BorderPanel Location Error " + locate); return(comp); } }
A test program of this class is:
import java.awt.*; import java.awt.event.*;There is little advantage to using this class as it stands. It could be made more useful by adding some additional methods. For example, it might be nice to be able to specify the growth weights so that one of the marginal components could grow in both directions instead of the center component.public class Border extends Frame implements WindowListener { private boolean isMainFrame;
public Border(boolean isMain) { //Construct superclass with title super("Test Border Panel"); isMainFrame = isMain; this.addWindowListener(this); //Create user interface BorderPanel panel = new BorderPanel(); panel.add("North",new Button("North")); panel.add("South",new Button("South")); panel.add("West",new Button("West")); panel.add("East",new Button("East")); panel.add("Center",new Button("Center")); this.add(panel); //Pack and validate this.setSize(300,200); this.validate(); }
//------------------------------------------------------------ // WindowListener //------------------------------------------------------------
public void windowOpened(WindowEvent eve) { }
public void windowActivated(WindowEvent eve) { }
public void windowClosing(WindowEvent eve) { //Exit if is main window if (isMainFrame) System.exit(0); //Must be applet or child window dispose(); }
public void windowClosed(WindowEvent eve) { }
public void windowDeactivated(WindowEvent eve) { }
public void windowIconified(WindowEvent eve) { }
public void windowDeiconified(WindowEvent eve) { }
//------------------------------------------------------------ // MAIN EXECUTION //------------------------------------------------------------
public static void main(String[] args) { Frame frame = new Border(true); frame.show(); } }
public class NumbPad extends Frame
{
see assignment
The following image is the actual keypad that is produced by the frame running as an application:
Note the kludge of putting extra space in the number buttons. This was done to force the default minimum size to approximate the width of the "Clear" and "Enter" buttons. The correct way to handle this problem is to use the ipadx member variable to force a wider button. The original code should have been:
//Make enter and clear X Y W H
buttonClr = makeButton("Clear", grid,gbc,0,0,1,1);
buttonEnter = makeButton("Enter", grid,gbc,3,3,1,2);
//Pad width to approximate width of Clear
gbc.ipadx = 50;
//Create operations X Y W H
buttonDiv = makeButton("/",grid,gbc,1,0,1,1);
buttonMul = makeButton("*",grid,gbc,2,0,1,1);
buttonSub = makeButton("-",grid,gbc,3,0,1,1);
buttonSub = makeButton("+",grid,gbc,3,1,1,2);
buttonDot = makeButton(".",grid,gbc,2,4,1,1);
//Make digits
button0 = makeButton("0",grid,gbc,0,4,2,1);
button1 = makeButton("1",grid,gbc,0,3,1,1);
button2 = makeButton("2",grid,gbc,1,3,1,1);
button3 = makeButton("3",grid,gbc,2,3,1,1);
button4 = makeButton("4",grid,gbc,0,2,1,1);
button5 = makeButton("5",grid,gbc,1,2,1,1);
button6 = makeButton("6",grid,gbc,2,2,1,1);
button7 = makeButton("7",grid,gbc,0,1,1,1);
button8 = makeButton("8",grid,gbc,1,1,1,1);
button9 = makeButton("9",grid,gbc,2,1,1,1);
The setSize() is used to make the keypad larger than it would be using the default preferred sizes of the buttons. The ratio of 200 wide by 250 high is (4 * 50) by (5 * 50) to match the grid size. This should make the number buttons square. Setting ipady to 50 should accomplish the same effect if pack() is used instead of setSize().
Write a Java class called MainWindow that extends Frame to implement this interface. Assume that the main display is a text area that uses the monospaced Courier font. The main display should get all of the additional height if the window is resized. Include a main() method that can be used to quickly test the appearance of the interface.
The first step is to lay a grid over the user interface to guide our layout efforts. As the diagram shows, the grid cells can be different heights by assigning zero height weights to all but the text area. Use this button to see the resulting interface.
The solution is similar to the button bag example. The setGbcGrid() and makeButton() helper methods are the same. This code includes a new makeLabel() helper method:
private Label makeLabel(String text,
GridBagLayout grid, GridBagConstraints gbc,
int xLoc, int yLoc, int width, int height,
int alignment)
{
//Create label
Label label = new Label(text,alignment);
//Set grid parameters
setGbcGrid(gbc,xLoc,yLoc,width,height);
grid.setConstraints(label,gbc);
//Add label to frame
this.add(label);
//Return label reference so it can be saved
return(label);
}
Then, the constructor can build the interface:
//User interface components
private Label screenTitle;
private Label systemDate;
private TextArea mainDisplay;
private Label promptMess;
private Label statusMess;
private Button[] actionButton;
public MainWindow(boolean isMain)
{
//Construct superclass with title
super("MainWindow Interface");
isMainFrame = isMain;
this.addWindowListener(this);
//Create grid bag layout
GridBagLayout grid = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
//Set frame layout to grid bag
this.setLayout(grid);
//Assume grow in both directions
gbc.fill = GridBagConstraints.BOTH;
//Let all grow equally in horizontal direction
gbc.weightx = 100.0;
gbc.weighty = 0.0;
//Make top labels
screenTitle = makeLabel(" Screen Title",grid,gbc,0,0,3,1,Label.LEFT);
screenTitle = makeLabel("System Date ", grid,gbc,3,0,3,1,Label.RIGHT);
//Make text area with high vertical weight
gbc.weighty = 100.0;
mainDisplay = new TextArea(21,80);
mainDisplay.setFont(new Font("Courier",Font.PLAIN,14));
setGbcGrid(gbc,0,1,6,1);
grid.setConstraints(mainDisplay,gbc);
this.add(mainDisplay);
gbc.weighty = 0.0;
//Make prompt and status labels
promptMess = makeLabel("Prompt Message",grid,gbc,0,2,6,1,Label.CENTER);
statusMess = makeLabel("Status Message",grid,gbc,0,3,6,1,Label.CENTER);
//Make action buttons
actionButton = new Button[6];
for (int col = 0; col < 6; col++)
{
actionButton[col] = makeButton("Action",grid,gbc,col,4,1,1);
}
//Pack and validate
this.setSize(480,360);
this.validate();
}
In reality, the labels and buttons would not include the text shown here.
The label and button text would dynamically change as the application
was executing.
The complete source code is
available.
Prepared by David L. March -- Last Revised on October 19, 1998
COPYRIGHT © 1998 BY DAVID L. MARCH