User Interface Design Patterns

Login Example

For this lecture, we will use the application with interface as
The UI code is

package ui;

import java.awt.*;
import javax.swing.*;

class Login extends JFrame {

    static final int TEXT_WIDTH = 15;

    JTextField uid;
    JPasswordField passwd;

    public static void main(String argv[]) {
        new Login();
    }

    Login() {
	super("Login Form");

	Container contents = getContentPane();;

	JPanel loginPanel = getLoginPanel();
	contents.add(loginPanel, BorderLayout.CENTER);

	JPanel buttonsPanel = getButtonsPanel();
	contents.add(buttonsPanel, BorderLayout.SOUTH);

	pack();
	setVisible(true);
    }

    JPanel getLoginPanel() {
	JPanel panel = new JPanel();

	GridBagLayout gridbag = new GridBagLayout();
	panel.setLayout(gridbag);

	GridBagConstraints c = new GridBagConstraints();
	c.weightx = 0.0;
	c.anchor = GridBagConstraints.EAST;

	GridBagConstraints c2 = new GridBagConstraints();
	c2.gridwidth = GridBagConstraints.REMAINDER;
	c2.weightx = 1.0;
	c2.fill = GridBagConstraints.HORIZONTAL;

	JLabel uidLabel = new JLabel("Uid");
	uid = new JTextField(TEXT_WIDTH);
	JLabel passwdLabel = new JLabel("Password");
	passwd = new JPasswordField(TEXT_WIDTH);

	panel.add(uidLabel);
	panel.add(uid);
	panel.add(passwdLabel);
	panel.add(passwd);

	gridbag.setConstraints(uidLabel, c);
	gridbag.setConstraints(uid, c2);
	gridbag.setConstraints(passwdLabel, c);
	gridbag.setConstraints(passwd, c2);

	return panel;
    }

    JPanel getButtonsPanel() {
	JPanel panel = new JPanel();
	panel.setLayout(new FlowLayout());
	JButton okButton = new JButton("OK");
	panel.add(okButton);
	return panel;
    }
}
Note that this only gives the GUI objects and their layout, no behaviour is associated with them

Validation

Validator Pattern

Validator Example

Implementation of third option


package ui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DigitsOnlyTextField extends JTextField 
                   implements FocusListener, Validator {

    final int LENGTH;
    String errorMsg = null;

    public  DigitsOnlyTextField(int length) {
	LENGTH = length;
	addFocusListener(this);
    }

    public void focusGained(FocusEvent e) {
	// empty
    }

    public void focusLost(FocusEvent e) {
	if (e.isTemporary()) {
	    return;
	}
	String text = getText();
	if (! isValid(text)) {
	    JOptionPane.showMessageDialog(this, errorMsg,
				"Input Format Error",
			        JOptionPane.WARNING_MESSAGE);
	}
    }

    public boolean isValid(Object obj) {
	String text = (String) obj;
	if (text.length() != LENGTH) {
	    errorMsg = "Text must be " + LENGTH + "characters long";
	    return false;
	}
	for (int n = 0; n < LENGTH; n++) {
	    if (! Character.isDigit(text.charAt(n))) {
		errorMsg = "Text must be all digits";
		return false;
	    }
	}
	return true;
    }

    public String getErrorMsg() {
	return errorMsg;
    }
}
Using this option means that the JTextField just needs to be replaced by DigitsOnlyTextField.

Facade again

Initialising the listener

Adapter pattern

Changes in the business objects

PropertyChange events

PropertyChange list management


Jan Newmarch (http://pandonia.canberra.edu.au)
jan@ise.canberra.edu.au
Last modified: Mon Oct 23 14:56:47 EST 2000
Copyright ©Jan Newmarch