FileDocCategorySizeDatePackage
BasicSpinnerUI.javaAPI DocJava SE 6 API35796Tue Jun 10 00:26:48 BST 2008javax.swing.plaf.basic

BasicSpinnerUI

public class BasicSpinnerUI extends SpinnerUI
The default Spinner UI delegate.
version
1.28 04/10/06
author
Hans Muller
since
1.4

Fields Summary
protected JSpinner
spinner
The spinner that we're a UI delegate for. Initialized by the installUI method, and reset to null by uninstallUI.
private Handler
handler
private static final ArrowButtonHandler
nextButtonHandler
The mouse/action listeners that are added to the spinner's arrow buttons. These listeners are shared by all spinner arrow buttons.
private static final ArrowButtonHandler
previousButtonHandler
private PropertyChangeListener
propertyChangeListener
private static final Dimension
zeroSize
Used by the default LayoutManager class - SpinnerLayout for missing (null) editor/nextButton/previousButton children.
Constructors Summary
Methods Summary
private java.awt.ComponentcreateArrowButton(int direction)

	JButton b = new BasicArrowButton(direction);
	Border buttonBorder = UIManager.getBorder("Spinner.arrowButtonBorder");
	if (buttonBorder instanceof UIResource) {
	    // Wrap the border to avoid having the UIResource be replaced by
	    // the ButtonUI. This is the opposite of using BorderUIResource.
	    b.setBorder(new CompoundBorder(buttonBorder, null));
	} else {
	    b.setBorder(buttonBorder);
	}
        b.setInheritsPopupMenu(true);
	return b;
    
protected javax.swing.JComponentcreateEditor()
This method is called by installUI to get the editor component of the JSpinner. By default it just returns JSpinner.getEditor(). Subclasses can override createEditor to return a component that contains the spinner's editor or null, if they're going to handle adding the editor to the JSpinner in an installUI override.

Typically this method would be overridden to wrap the editor with a container with a custom border, since one can't assume that the editors border can be set directly.

The replaceEditor method is called when the spinners editor is changed with JSpinner.setEditor. If you've overriden this method, then you'll probably want to override replaceEditor as well.

return
the JSpinners editor JComponent, spinner.getEditor() by default
see
#installUI
see
#replaceEditor
see
JSpinner#getEditor

	JComponent editor = spinner.getEditor();
	maybeRemoveEditorBorder(editor);
	installEditorBorderListener(editor);
        editor.setInheritsPopupMenu(true);
        updateEditorAlignment(editor);
        return editor;
    
protected java.awt.LayoutManagercreateLayout()
Create a LayoutManager that manages the editor, nextButton, and previousButton children of the JSpinner. These three children must be added with a constraint that identifies their role: "Editor", "Next", and "Previous". The default layout manager can handle the absence of any of these children.

return
a LayoutManager for the editor, next button, and previous button.
see
#createNextButton
see
#createPreviousButton
see
#createEditor

        return getHandler();
    
protected java.awt.ComponentcreateNextButton()
Create a component that will replace the spinner models value with the object returned by spinner.getNextValue. By default the nextButton is a JButton who's ActionListener updates it's JSpinner ancestors model. If a nextButton isn't needed (in a subclass) then override this method to return null.

return
a component that will replace the spinners model with the next value in the sequence, or null
see
#installUI
see
#createPreviousButton
see
#installNextButtonListeners

	Component c = createArrowButton(SwingConstants.NORTH);
        c.setName("Spinner.nextButton");
        installNextButtonListeners(c);
        return c;
    
protected java.awt.ComponentcreatePreviousButton()
Create a component that will replace the spinner models value with the object returned by spinner.getPreviousValue. By default the previousButton is a JButton. This method invokes installPreviousButtonListeners to install the necessary listeners to update the JSpinner's model in response to a user gesture. If a previousButton isn't needed (in a subclass) then override this method to return null.

return
a component that will replace the spinners model with the next value in the sequence, or null
see
#installUI
see
#createNextButton
see
#installPreviousButtonListeners

	Component c = createArrowButton(SwingConstants.SOUTH);
        c.setName("Spinner.previousButton");
        installPreviousButtonListeners(c);
        return c;
    
protected java.beans.PropertyChangeListenercreatePropertyChangeListener()
Create a PropertyChangeListener that can be added to the JSpinner itself. Typically, this listener will call replaceEditor when the "editor" property changes, since it's the SpinnerUI's responsibility to add the editor to the JSpinner (and remove the old one). This method is called by installListeners.

return
A PropertyChangeListener for the JSpinner itself
see
#installListeners

        return getHandler();
    
public static javax.swing.plaf.ComponentUIcreateUI(javax.swing.JComponent c)
Returns a new instance of BasicSpinnerUI. SpinnerListUI delegates are allocated one per JSpinner.

param
c the JSpinner (not used)
see
ComponentUI#createUI
return
a new BasicSpinnerUI object



                                        
         
        return new BasicSpinnerUI();
    
public intgetBaseline(javax.swing.JComponent c, int width, int height)
Returns the baseline.

throws
NullPointerException {@inheritDoc}
throws
IllegalArgumentException {@inheritDoc}
see
javax.swing.JComponent#getBaseline(int, int)
since
1.6

        super.getBaseline(c, width, height);
        JComponent editor = spinner.getEditor();
        Insets insets = spinner.getInsets();
        width = width - insets.left - insets.right;
        height = height - insets.top - insets.bottom;
        if (width >= 0 && height >= 0) {
            int baseline = editor.getBaseline(width, height);
            if (baseline >= 0) {
                return insets.top + baseline;
            }
        }
        return -1;
    
public java.awt.Component$BaselineResizeBehaviorgetBaselineResizeBehavior(javax.swing.JComponent c)
Returns an enum indicating how the baseline of the component changes as the size changes.

throws
NullPointerException {@inheritDoc}
see
javax.swing.JComponent#getBaseline(int, int)
since
1.6

        super.getBaselineResizeBehavior(c);
        return spinner.getEditor().getBaselineResizeBehavior();
    
private javax.swing.plaf.basic.BasicSpinnerUI$HandlergetHandler()

        if (handler == null) {
            handler = new Handler();
        }
        return handler;
    
private javax.swing.InputMapgetInputMap(int condition)
Returns the InputMap to install for condition.

        if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
	    return (InputMap)DefaultLookup.get(spinner, this,
                    "Spinner.ancestorInputMap");
        }
        return null;
    
private voidinstallButtonListeners(java.awt.Component c, javax.swing.plaf.basic.BasicSpinnerUI$ArrowButtonHandler handler)

        if (c instanceof JButton) {
            ((JButton)c).addActionListener(handler);
        }
        c.addMouseListener(handler);
    
protected voidinstallDefaults()
Initialize the JSpinner border, foreground, and background, properties based on the corresponding "Spinner.*" properties from defaults table. The JSpinners layout is set to the value returned by createLayout. This method is called by installUI.

see
#uninstallDefaults
see
#installUI
see
#createLayout
see
LookAndFeel#installBorder
see
LookAndFeel#installColors

	spinner.setLayout(createLayout());
        LookAndFeel.installBorder(spinner, "Spinner.border");
        LookAndFeel.installColorsAndFont(spinner, "Spinner.background", "Spinner.foreground", "Spinner.font");
        LookAndFeel.installProperty(spinner, "opaque", Boolean.TRUE);
    
private voidinstallEditorBorderListener(javax.swing.JComponent editor)
Remove the border around the inner editor component for LaFs that install an outside border around the spinner,

        if (!UIManager.getBoolean("Spinner.editorBorderPainted")) {
	    if (editor instanceof JPanel &&
		editor.getBorder() == null &&
		editor.getComponentCount() > 0) {

		editor = (JComponent)editor.getComponent(0);
	    }
	    if (editor != null &&
		(editor.getBorder() == null ||
		 editor.getBorder() instanceof UIResource)) {
		editor.addPropertyChangeListener(getHandler());
	    }
	}
    
protected voidinstallKeyboardActions()
Installs the keyboard Actions onto the JSpinner.

since
1.5

        InputMap iMap = getInputMap(JComponent.
                                   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

	SwingUtilities.replaceUIInputMap(spinner, JComponent.
					 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
					 iMap);

        LazyActionMap.installLazyActionMap(spinner, BasicSpinnerUI.class,
                "Spinner.actionMap");
    
protected voidinstallListeners()
Initializes PropertyChangeListener with a shared object that delegates interesting PropertyChangeEvents to protected methods.

This method is called by installUI.

see
#replaceEditor
see
#uninstallListeners

        propertyChangeListener = createPropertyChangeListener();
        spinner.addPropertyChangeListener(propertyChangeListener);
	if (DefaultLookup.getBoolean(spinner, this,
	    "Spinner.disableOnBoundaryValues", false)) {
	    spinner.addChangeListener(getHandler());
	}
	JComponent editor = spinner.getEditor();
	if (editor != null && editor instanceof JSpinner.DefaultEditor) {
	    JTextField tf = ((JSpinner.DefaultEditor)editor).getTextField();
	    if (tf != null) {
		tf.addFocusListener(nextButtonHandler);
		tf.addFocusListener(previousButtonHandler);
	    }
	}
    
protected voidinstallNextButtonListeners(java.awt.Component c)
Installs the necessary listeners on the next button, c, to update the JSpinner in response to a user gesture.

param
c Component to install the listeners on
throws
NullPointerException if c is null.
see
#createNextButton
since
1.5

        installButtonListeners(c, nextButtonHandler);
    
protected voidinstallPreviousButtonListeners(java.awt.Component c)
Installs the necessary listeners on the previous button, c, to update the JSpinner in response to a user gesture.

param
c Component to install the listeners on.
throws
NullPointerException if c is null.
see
#createPreviousButton
since
1.5

        installButtonListeners(c, previousButtonHandler);
    
public voidinstallUI(javax.swing.JComponent c)
Calls installDefaults, installListeners, and then adds the components returned by createNextButton, createPreviousButton, and createEditor.

param
c the JSpinner
see
#installDefaults
see
#installListeners
see
#createNextButton
see
#createPreviousButton
see
#createEditor

	this.spinner = (JSpinner)c;
	installDefaults();
	installListeners();
	maybeAdd(createNextButton(), "Next");
	maybeAdd(createPreviousButton(), "Previous");
	maybeAdd(createEditor(), "Editor");
        updateEnabledState();
        installKeyboardActions();
    
static voidloadActionMap(javax.swing.plaf.basic.LazyActionMap map)

        map.put("increment", nextButtonHandler);
        map.put("decrement", previousButtonHandler);
    
private voidmaybeAdd(java.awt.Component c, java.lang.String s)

	if (c != null) {
	    spinner.add(c, s);
	}
    
private voidmaybeRemoveEditorBorder(javax.swing.JComponent editor)
Remove the border around the inner editor component for LaFs that install an outside border around the spinner,

        if (!UIManager.getBoolean("Spinner.editorBorderPainted")) {
	    if (editor instanceof JPanel &&
		editor.getBorder() == null &&
		editor.getComponentCount() > 0) {

		editor = (JComponent)editor.getComponent(0);
	    }

	    if (editor != null && editor.getBorder() instanceof UIResource) {
		editor.setBorder(null);
	    }
	}
    
private voidremoveEditorBorderListener(javax.swing.JComponent editor)

        if (!UIManager.getBoolean("Spinner.editorBorderPainted")) {
	    if (editor instanceof JPanel &&
		editor.getComponentCount() > 0) {

		editor = (JComponent)editor.getComponent(0);
	    }
	    if (editor != null) {
		editor.removePropertyChangeListener(getHandler());
	    }
	}
    
protected voidreplaceEditor(javax.swing.JComponent oldEditor, javax.swing.JComponent newEditor)
Called by the PropertyChangeListener when the JSpinner editor property changes. It's the responsibility of this method to remove the old editor and add the new one. By default this operation is just:
spinner.remove(oldEditor);
spinner.add(newEditor, "Editor");
The implementation of replaceEditor should be coordinated with the createEditor method.

see
#createEditor
see
#createPropertyChangeListener

	spinner.remove(oldEditor);
	maybeRemoveEditorBorder(newEditor);
	installEditorBorderListener(newEditor);
        newEditor.setInheritsPopupMenu(true);
        updateEditorAlignment(newEditor);
	spinner.add(newEditor, "Editor");
    
protected voiduninstallDefaults()
Sets the JSpinner's layout manager to null. This method is called by uninstallUI.

see
#installDefaults
see
#uninstallUI

	spinner.setLayout(null);
    
protected voiduninstallListeners()
Removes the PropertyChangeListener added by installListeners.

This method is called by uninstallUI.

see
#installListeners

	spinner.removePropertyChangeListener(propertyChangeListener);
	spinner.removeChangeListener(handler);
	JComponent editor = spinner.getEditor();
	removeEditorBorderListener(editor);
	if (editor instanceof JSpinner.DefaultEditor) {
	    JTextField tf = ((JSpinner.DefaultEditor)editor).getTextField();
	    if (tf != null) {
		tf.removeFocusListener(nextButtonHandler);
		tf.removeFocusListener(previousButtonHandler);
	    }
	}
        propertyChangeListener = null;
        handler = null;
    
public voiduninstallUI(javax.swing.JComponent c)
Calls uninstallDefaults, uninstallListeners, and then removes all of the spinners children.

param
c the JSpinner (not used)

	uninstallDefaults();
	uninstallListeners();
	this.spinner = null;
	c.removeAll();
    
private voidupdateEditorAlignment(javax.swing.JComponent editor)

        if (editor instanceof JSpinner.DefaultEditor) {
            // if editor alignment isn't set in LAF, we get 0 (CENTER) here
            int alignment = UIManager.getInt("Spinner.editorAlignment");
            JTextField text = ((JSpinner.DefaultEditor)editor).getTextField();
            text.setHorizontalAlignment(alignment);
        }
    
private voidupdateEnabledState()
Updates the enabled state of the children Components based on the enabled state of the JSpinner.

        updateEnabledState(spinner, spinner.isEnabled());
    
private voidupdateEnabledState(java.awt.Container c, boolean enabled)
Recursively updates the enabled state of the child Components of c.

        for (int counter = c.getComponentCount() - 1; counter >= 0;counter--) {
            Component child = c.getComponent(counter);

	    if (DefaultLookup.getBoolean(spinner, this,
		"Spinner.disableOnBoundaryValues", false)) {
 		SpinnerModel model = spinner.getModel();
 		if (child.getName() == "Spinner.nextButton" &&
		    model.getNextValue() == null) {
 		    child.setEnabled(false);
 		}
 		else if (child.getName() == "Spinner.previousButton" &&
			 model.getPreviousValue() == null) {
 		    child.setEnabled(false);
 		}
 		else {
 		    child.setEnabled(enabled);
 		}
 	    }
	    else {
		child.setEnabled(enabled);
	    }
            if (child instanceof Container) {
                updateEnabledState((Container)child, enabled);
            }
        }