Widgets

  1. Definition: A widget is a small, interactive, application-independent object that either:

    1. performs some editing or input task, or
    2. displays application state information or describes the input task

  2. Taxonomy of Widgets

    1. informative displays: displaying application state information or giving some information about an input

      1. text labels (JLabel)
      2. images (JLabel)
      3. progress bars (JProgressBar)
      4. tool tips (JToolTip)
      `
    2. choice widgets: select one or more items from a set of choices

      1. Radio buttons (JRadioButton)--They are mutually exclusive (i.e., they only allow one choice): For example, small, medium or large
      2. Check boxes (JCheckBox): make one or more choices, for example, bold, italic, underline
      3. Command buttons (JButton): allow you to execute a command (e.g., OK, CANCEL)

    3. Number widgets: used to input a number in a bounded range

      1. Sliders (JSlider): used to input a numeric value
        1. range of values is limited by the number of pixels on the screen (i.e., screen resolution)
        2. rule of thumb: max number of values = number pixels / (2 or 3)
      2. Scroll Bars (JScrollBar): used to control what you see in a window
        1. typically you don't directly use scroll bars. For example, Java provides a JScrollPane container object if you want scrolled windows
      3. Spinners (JSpinner): good for iterating through an enumerated collection of values, not just numbers

    4. Text Widgets (JTextField, JFormattedTextField, JTextArea)-- used to input/display a text string

      1. most flexible type of widget since you can enter any value you wish
      2. use labels (JLabel) to label the text field
      3. reasons to prefer any widget over a text widget (i.e., why you try to avoid text widgets if at all possible
        1. other widgets use recognition memory, whereas text uses recall memory
        2. avoid typos
        3. avoid invalid values (although JFormattedTextField can help eliminate invalid values)
      4. JFormattedTextField: Provides both pre-formatted and custom formatted objects that restrict a user what a user can input
        1. DateFormat, NumberFormat: Supertype classes that define a variety of ways to restrict the type of date or number that the user inputs
        2. javax.swing.text.MaskFormatter allows you to specify a pattern for a string. It is not as powerful as regular expressions but it can allow you to specify simple patterns, like ###-##-#### for a social security number.

    5. Container Widgets: Widgets that are collections of other widgets

      1. Dialog boxes (JDialog)
      2. Menu (JMenu)
        1. only the menu's title is displayed until the user selects the menu, at which time all options become visible
        2. menu is really a choice widget: use radio buttons/check boxes/jbuttons when there are roughly 5-7 choices, otherwise use a menu-an adult can store 7 items plus/minus 2 in working memory
      3. List (JList): some options visible at all times--uses a scroll bar to allow user to visit all options
      4. Combo Box (JComboBox): combines a text box with a list and is a nice combination of recognition and recall memory
      5. Color Chooser
      6. File Chooser

    6. Message Widgets: JOptionPane provides a number of ways to display pop-up message boxes to a user

      1. Messages consist of a text string and one or more buttons, such as "Yes", "No", "Cancel", etc.
      2. JOptionPane provides 4 types of messages--informational, question, warning, and error
      3. JOptionPane.showMessageDialog() pops up the the dialog box. For example:
        JOptionPane.showMessageDialog(frame, "Eggs are not supposed to be green.",
                                      "Egg Warning", JOptionPane.WARNING_MESSAGE);
        		    
        This command specifies that the dialog box is associated with the JFrame pointed to by frame, that the warning message is "Eggs are not supposed to be green.", that the title of the window displaying the message will be "Egg Warning", and that the icon in the message window will denote a warning.
      4. Dialog boxes are typically modal, thus halting execution until the user responds by pressing a button

  3. Event Handling: Each widget provides pre-defined behaviors for handling mouse and keyboard events and typically you will not override these behaviors. Each widget also generates "semantic" events when the widget finishes its operation that communicate what happened.
    1. The principle event types we care about and example widgets that generate them are:
      1. ActionEvents (buttons, text fields, menu items): Indicates that some action has occurred, such as the user completing the edit of a text string. Use the getSource() method to return the object that fired the event.
      2. ChangeEvents (buttons, numerical widgets like sliders, menu items): Indicates that a value has changed. Use the getSource() method to return the object that fired the event.
      3. ItemEvents (buttons, menu items): Provides the new state of the item which is either SELECTED or DESELECTED
      A complete list of events and the types of widgets that generate them can be found here.

    2. You indicate an interest in an event by adding the appropriate event listener to a widget using an addXXXListener() call where XXX is the name of the event. The event listener provides callback methods to be called when the event occurs. Event listeners are declared as interfaces. The three main event listeners we care about are:

      1. ActionListener: public void actionPerformed(ActionEvent e)
      2. ChangeListener: public void stateChanged(ChangeEvent e)
      3. ItemListener: public void itemStateChanged(ItemEvent e)

    3. Ways to implement a listener

      1. Have the class that creates the widget implement the listener and then pass a pointer to the object to the widgets addXXXXListener() method. This is what the book does. For example:
        				      
        class WidgetCreater implements ActionListener {			      
        ...
            JTextField name;
            ...
            public widgetCreater() {
                name = JTextField();
                name.addActionListener(this);
            }
        
            public void actionPerformed(ActionEvent e) { ... }
        }
        
        The drawback of this approach is that you can only easily define one listener per event and if you need to create multiple event listeners for different widgets that generate the same event, then you cannot easily use this approach.

      2. Create an anonymous, in-line listener object when you call the addXXXXListener method. For example:
        				      
        class WidgetCreater {
        ...
            JTextField name;
            ...
            public widgetCreater() {
                name = JTextField();
                name.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) { ... }
                });
            }
        }
        This approach allows you to define a listener for each widget that generates that type of event and it also allows someone reading your code to immediately see what action is being taken in response to the event.

  4. A taxonomy of devices

    1. Logical devices: Like an abstract type (e.g., a choice device)
    2. Physical devices: Function keys, buttons on a mouse
    3. Virtual devices: menu, radio buttons, keyboard on a mobile device

  5. Design Considerations

    1. 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.

      1. Non-container widgets: Always displayed and permanently take up their full allotment of screen space
      2. Container Widgets: Typically acquire screen real estate on activation and release screen real estate on de-activation. Maintain a small screen footprint with some type of label or image

    2. 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
        1. An expert user could not exploit spatial locations
        2. A naive user might search other places for the widget
      3. Best solution is to allow a widget to disable itself.

    3. 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.

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

    5. Design tips

      1. Place related widgets into physical proximity by using structural groupings, such as menus, button groups, or dialog boxes
        1. With horizontal separators you can group items into sets of 7 or fewer items, and take advantage of short-term memory and spatial location to turn the selection into an O(1) human time operation
        2. 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.
      2. Be consistent: Use similar widgets to accomplish similar types of tasks
      3. 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.