Widgets

I. Definition: A widget is a small interactive object that performs some
    editing or input task. In some situations, it may be an output only
    object, such as a label or an image. The model is typically so simple,
    such as a boolean, number, or text string, that a widget is often 
    implemented as a single class.

    A. Simple Widgets

        1. Buttons

            a. Command Buttons: When pushed they call a method
	    b. Radio Buttons: They typically allow one option to be chosen from
	       a set of choices (e.g., small, medium, large)
	    c. Check Boxes: They typically allow multiple options to be chosen
	       from a set of choices (e.g., bold-italic-underline)

        2. Sliders and Scroll Bars: Designed to manipulate a discrete bounded 
            range of values

            a. Typically provide controls for both fine and course adjustments

        3. Text Boxes: Allow the user to enter a string of characters.

        4. Special Widgets: Special purpose widgets, such as color choosers,
	   file choosers, calendar choosers, etc. have been designed for
	   many toolkits, including Java.

    B. Container Widgets

        1. Menus: Designed to select a choice from a potentially large
           number of possibilities

        2. Dialog Boxes: Collections of widgets organized into a pane 
		(often called a form)

	3. Tabbed Panes: Organize collections of related widgets when there
		is not enough screen space to accommodate all of them

	4. Toolbars: Frequently collections of frequently chosen commands
	 	and/or properties (e.g., line justification in a word
		processor or bold/italic)

II. Abstract Devices

    A. A taxonomy of devices

        1. Physical devices
	2. Virtual devices: a screen simulation of a device
	3. Logical devices: an abstract model of an input (e.g, a logical
		Quit button could be implemented as a function button on
		the keyboard, a Ctrl-Q key press, or a Quit menu item).

    B. Acquire/Release: Because screen space is limited, not all widgets
        may be displayable simultaneously. In this case widgets may need
	to share screen space or physical devices. This sharing requires
	that they acquire and release resources.

    C. Enable/Disable: Even if a widget acquires resources, it may not
        be acceptable as input. 

	1. UI design principle: Prevent errors rather than report errors

	2. We could force the widget to release its resources but that would 
	    make for an inconsistent presentation of widgets

	    a. An expert user could not exploit spatial locations
	    b. A naive user might search other places for the widget

	3. Best solution is to allow a widget to disable itself.

    D. Active/Inactive: When a widget is being acted on, it should provide
        feedback that allows the user to know that it is accepting the
	user's input and acting on it.

    E. Feedback (Echo): When a user is finished acting on a widget, the
        widget should display its current state using some visual means.

III. Design tips

    A. Place related widgets into physical proximity by using structural
        groupings, such as menus, button groups, or dialog boxes

    B. Be consistent: Use similar widgets to accomplish similar types
        of tasks

    C. When designing presentations of any type, keep the following items
        in mind
	
	1. Light objects take precedence over dark objects
	2. Objects with detail and texture take precedence over plain
	    or uniform objects.
	3. Objects with high contrast take precedence over objects with
	    little contrast.
	4. Large objects take precedence over small objects.
	5. Varied objects take precedence over regular or uniform objects.

    D. Menu Design

    -Semantically similar commands should be grouped together
    -If there are a large number of menu items, it may be best to
	put the most commonly occuring ones on one menu and have
	a second display that shows the rest (generally a human keeps
	5-7 items in short term memory).
    -If multiple items can be selected, there should be some visual
	or verbal way of expressing this to the user (e.g., Apple has
	a certain look for multiple item menus). If there is a limit
	to the number of selections, this should also be indicated.
    -Multiple menus: If they can all be placed on the screen at once
	in a comfortable way, that is preferable to popping them up
	one at a time.
    -Menu trees: Breadth, the number of items per level, is preferable
	to depth, the number of levels. In general, try to limit menu
	trees to no more than three levels.

	-If space permits, using a menu map that shows the first few
		levels of the tree is helpful.

IV. Notes on Java Widgets

    A. Revalidate/pack methods

    	1. In order to get a window to resize itself properly if a
	   subcomponent is resized by the user (e.g., you load a new
	   board with a new size), you must call both revalidate and
	   pack. If you do not call pack then revalidate will try to
	   resize the component while keeping the size of the window
	   constant. The pack command cause the window to both layout
	   its components and resize itself if necessary.

	2. Make sure that when calling revalidate that you call it on the
	   correct component. It is easy to call revalidate on the wrong
	   component, in which case the window may not resize at all or
	   may resize in a strange way.

V. Race Conditions

    A. Sometimes widgets and your models generate circular notification
	events. For example, a JTextField generates an ActionEvent whenever
	its text property is changed. That could generate a notification event
	to your model, which might then notify the JTextField of the change,
	which causes the JTextField to generate another ActionEvent, and so
	on.

	1. You can stop this cycle with a state flag in the widget which
		indicates whether or not the widget is currently handling
		a notification event, and if so, simply returns, rather than
		generating another model change event

        2. Example for a JTextField (but the Java developers have changed
		JTextField so it no longer generates an ActionEvent when
		the text field is changed under programmatic control-so this
		example is illustrative of what had to be done in the past):

		public void actionPerformed(ActionEvent e) {
		    if (activeAction) return; 
		    activeAction = true;
		    model notification
		    activeAction = false;
		}