Java Look-and-Feel Design Guidelines - University of Georgia

eyelashesnectarineΛογισμικό & κατασκευή λογ/κού

3 Νοε 2013 (πριν από 3 χρόνια και 10 μήνες)

72 εμφανίσεις

Java Look
-
and
-
Feel
Design Guidelines


Part IV

Eileen Kraemer

University of Georgia

CSCI 4800/600

Previously, we talked about …


Applet v. Application


Placement of applets



Designing for accessibility


Checking for accessibility


Usability testing



Internationalization / localization


Creating/using resource bundles


Designing for accessibility


Provide accessible names, accessible descriptions


Use mnemonics and keyboard shortcuts


All interface components must be keyboard traversable


Assign initial keyboard focus


Specify tab traversal order


Don’t customize fonts or colors unnecessarily


If necessary, use properties to specify colors, fonts


Use dynamic GUI layout


Custom components must implement accessible

Now, …


… let’s look at the “nuts and bolts” of
accomplishing these goals

The Java Accessibility API (JAAPI)


standard extension in all releases of the Java 2 platform


component can utilize this extension by implementing the
Accessible interface


only one method call:
getAccessibleContext()


returns an instance of AccessibleContext


specific to the component


provides the info and functionality to enable accessibility


AccessibleContext


info about the component's role (button, checkbox, etc.)


accessible name (more on this soon)


Number of children, & more


Can generate accessibility events when a noteworthy event has
occurred.


All of the standard JFC/Swing components implement the
Accessible interface

Accessible name, description: how
used


accessible name


succinct explanation of component’s purpose


assistive technology will often present (speak) the
name of each component encountered by a user


accessible description


more verbose explanation


provide in cases where additional info needed


assistive tech retrieves when user requests it

Accessible name: how to set


JFC/Swing components with non
-
editable text (menu items, buttons,
etc.) have accessible name set automatically



Other components need to have accessible name set by developer


If the component has a label:



JTextField text = new JTextField(20);


JLabel label = new Label("Address Line 1");


label.setLabelFor(text);



// ... Add the text and label to a Container




For ImageIcons , create using:


ImageIcon(URL url, String name);



Accessible description: how to set


Accessible descriptions set automatically by setting tooltiptext:







JComponent.setTooltipText( )




If component has no label or tooltip, directly set name & description:


permanently overrides values pulled from label or tooltip



AccessibleContext context = component.getAccessibleContext();
context.setAccessibleName("Zip");
context.setAccessibleDescription("Recipient's Zip Code");




Don’t Customize Fonts or Colors
Unnecessarily



JFC/Swing components/ applications
automatically inherit font and color
properties from desktop and user prefs.


In most cases, get good results by
accepting user's preferences.


But, if you have to specify colors
and fonts ….


Use a properties file


Example:


want flight simulator to have a red "stop" button in
Western countries


define a property,



store it in a file,
flightsim.properties
:


flightsim.stop.color=#ff0000



Then, use the properties:


The program can load properties file as a
ResourceBundle
:



ResourceBundle resources = null;


Color stopColor = Color.red; // the default


try {

resources=ResourceBundle.getBundle("flightsim");

String colorString =
resources.getString("flightsim.stop.color");

stopColor = Color.decode(colorString); // the specified

}

catch (MissingResourceException missingException)

{



// Report the error, according to severity

} // stopColor has now been customized



Use Dynamic GUI Layout


Don’t call setSize() with constant values.


defeats dynamic layout


resulting application won’t adapt properly to users' settings.


Instead, adjust the size of each JFrame, JDialog, and
JWindow at creation and each time its contents change



window.setSize(window.getPreferredSize());



allows all nested layout managers to affect the size
and position of each object at runtime.


If component’s preferred size is not acceptable(rare),
call setSize() with a value between
getMinimumSize() and getMaximumSize
().

Dynamic LayoutManagers


position graphical objects relative to each other


changes in size are handled automatically


components never obscure one another.



All JFC/Swing layout managers are dynamic (BorderLayout,
FlowLayout, GridBagLayout, etc.)



setLayout(null); // Don’t do this!!



Requires manually setting (x,y) of every component.


interface won’t work right with many accessibility options,
internationalization , user
-
defined preferences
.

Custom Layout Managers


Implement LayoutManager
2

interface


(old LayoutManager interface is obsolete).


Components should be positioned relative to
each other when the toolkit invokes
layoutContainer() on the custom layout
manager.

All Interface Components Must Be
Keyboard Traversable


… because many people can’t use a
pointing device effectively



Pressing tab key should move input focus
from component to component



shift
-
tab should move focus in opposite
direction.


How to implement?


default FocusManager sets focus order : left
-
to
-
right and
top
-
to
-
bottom.


If component shouldn’t receive input focus, create a
subclass and override
isFocusTraversable()

to
return false.


Invoke
setNextFocusableComponent()

on each
JComponent to "hard
-
wire" the focus traversal order.


Messy to do this on some components and have others use the
default ordering. If used, invoke on all JComponents in a
window.


Implement a subclass of
java.awt.FocusManager

and install it with the static method
FocusManager.setCurrentManager().


Use Mnemonics


Mnemonics


underlined characters that appear in menu items and on the buttons in
some dialog boxes.


can only be activated when the item is visible and does not require a
modifier key (e.g., the user does not need to press the Alt key).


If keyboard use is to be practical, then

All menu items must have
mnemonics



menu = new JMenu();


menu.setText(resources.getString("fileMenu.label"));


menu.setMnemonic(
resources.getString("fileMenu.mnemonic").charAt(0));



item = new JMenuItem();





item.setMnemonic(
resources.getString("menuitem.file.new.mnemonic").charAt(0));






Use Accelerators


displayed on menu items or buttons in parentheses after
the item's text [e.g., "Save (Ctrl+S)"].


requires the use of a modifier key


can be activated any time the application's window has
the input focus.





item = new JMenuItem();
item.setAccelerator(KeyStroke.getKeyStroke(
resources.getString("menuitem.file.new.accelerator")));






Custom Components Must
Implement Accessible


All standard JComponent subclasses implement this interface and
do everything necessary to be accessible



All custom components should extend a standard class as far down
the JFC/Swing inheritance hierarchy as possible.


For example, you want round buttons


First try to extend JButton, override all paint methods, add support
for any new properties.


If JButton is too restrictive, then try to extend JButton's superclass,
AbstractButton.


Only if AbstractButton is too restrictive should you extend directly
from JComponent.


JComponent doesn’t implement Accessible, so subclass must do
more work to work w/ assistive technologies.


Some methods do exist in JComponent to help: getAccessibleParent()
and getAccessibleName() will work properly for most JComponent
subclasses, with no additional code (other than 'implements
Accessible').


Custom components, continued


must express its accessible role as specifically as
possible.

See:
http://java.sun.com/j2se/1.4.2/docs/api/javax/accessibility
/AccessibleContext.html



Each JFC/Swing class contains a protected inner class
that actually does the accessibility work, and the root
class is JComponent.AccessibleJComponent


To extend accessibility behavior of subclass, create a protected
inner class that extends the inner class of the superclass


override getAccessibleContext() to create an instance of this
new accessibility class.

Example

public class WarningLight extends JComponent





implements Accessible {


public AccessibleContext getAccessibleContext() {


// variable accessibleContext is protected in superclass



if (accessibleContext == null) {



accessibleContext = new AccessibleWarningLight();



}



return accessibleContext;


}


protected class AccessibleWarningLight extends
AccessibleJComponent {




public AccessibleRole getAccessibleRole() {




return AccessibleRole.ALERT;


}



// Implementation of WarningLight omitted...

}




Test Cases


1. Don't touch your mouse



Bring up each window and popup in your application
and attempt to visit
every

component using only the
Tab key on the keyboard.


Use the application without touching the mouse


Verify that:


Application’s features are all available


Frequently
-
used functionality is directly accessible via an
accelerator


All menu items have mnemonics


Test Cases


2. Change the default font and color


Choose a font of 24 points or larger, and
colors other than the default.


Bring up each window of the application and
verify that screen objects do not overlap and
that the colors are correct.



If overlapping occurs, check the code that
interacts with the LayoutManager in that
window.


Test Cases


Try using a low
-
vision look
-
and
-
feel


Here’s a sample
LowVisionMetalLookAndFeel.java


Compile the file


Add this code to your application:


import LowVisionMetalLookAndFeel; // ... code omitted

try {
UIManager.setLookAndFeel("LowVisionMetalLookAndFeel");

}

catch (Exception ex) {


System.out.println("Failed loading Low Vision Metal




Look and Feel");


ex.printStackTrace(System.out);

}

Test Cases


3. Use a screen reader


Download and install a trial version of a screen reader that works
with Java applications, (more/better links coming soon)


http://cap.ic.gc.ca/english/learning.html


Bring up each window in your application and tab to
every

component, verifying that you hear a reasonable
description of each component as it receives the input
focus.


Turn your display off.


Try to use your application in this mode, accessing both core
functionality and more lightly
-
used features.



Internationalization


Identify Culturally Dependent Data


Isolate Translatable Text in Resource
Bundles


Deal with Compound Messages


Format Dates and Times


Use Unicode Character Properties


Compare Strings Properly


Convert Non
-
Unicode Text

Nuts and Bolts …


Creating and accessing resource bundles



ResourceBundle objects contain locale
-
specific objects.


When you need a locale
-
specific object,
you fetch it from a ResourceBundle, which
returns the object that matches the end
user's Locale.

The ResourceBundle Class


each ResourceBundle is a set of related
subclasses that share the same base name.


Example:

ButtonLabel


// base_name


ButtonLabel_de


// with language code

ButtonLabel_en_GB

// with language and country codes

ButtonLabel_fr_CA_UNIX

// with lang, country, and variant codes





To select a ResourceBundle


invoke the ResourceBundle.getBundle
method.


Example:


Locale currentLocale = new Locale("fr", "CA", "UNIX");
ResourceBundle introLabels =
ResourceBundle.getBundle(“ButtonLabel”, currentLocale);