synthspinnerui.java

来自「java jdk 1.4的源码」· Java 代码 · 共 818 行 · 第 1/2 页

JAVA
818
字号
/* * @(#)SynthSpinnerUI.java	1.8 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.java.swing.plaf.gtk;import java.awt.*;import java.awt.event.*;import java.text.ParseException;import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*;import javax.swing.text.*;import java.beans.*;import java.text.*;import java.util.*;/** * The default Spinner UI delegate. * * @version 1.8, 01/23/03 (based on BasicSpinnerUI v 1.12) * @author Hans Muller */class SynthSpinnerUI extends SpinnerUI implements SynthUI {    private SynthStyle style;    /**     * The spinner that we're a UI delegate for.  Initialized by      * the <code>installUI</code> method, and reset to null     * by <code>uninstallUI</code>.     *      * @see #installUI     * @see #uninstallUI     */    protected JSpinner spinner;      /**     * The <code>PropertyChangeListener</code> that's added to the      * <code>JSpinner</code> itself. This listener is created by the     * <code>createPropertyChangeListener</code> method, added by the     * <code>installListeners</code> method, and removed by the     * <code>uninstallListeners</code> method.     * <p>     * One instance of this listener is shared by all JSpinners.     *      * @see #createPropertyChangeListener     * @see #installListeners     * @see #uninstallListeners     */    private static final PropertyChangeListener propertyChangeListener = new PropertyChangeHandler();    /**     * The mouse/action listeners that are added to the spinner's      * arrow buttons.  These listeners are shared by all      * spinner arrow buttons.     *      * @see #createNextButton     * @see #createPreviousButton     */    private static final ArrowButtonHandler nextButtonHandler = new ArrowButtonHandler("increment", true);    private static final ArrowButtonHandler previousButtonHandler = new ArrowButtonHandler("decrement", false);    /**     * Returns a new instance of SynthSpinnerUI.       *      * @param c the JSpinner (not used)     * @see ComponentUI#createUI     * @return a new SynthSpinnerUI object     */    public static ComponentUI createUI(JComponent c) {        return new SynthSpinnerUI();    }    public static void loadActionMap(ActionMap map) {        // NOTE: this needs to remain static. If you have a need to        // have Actions that reference the UI in the ActionMap,        // then you'll also need to change the registeration of the        // ActionMap.        map.put("increment", nextButtonHandler);        map.put("decrement", previousButtonHandler);    }    /**     * Calls <code>installDefaults</code>, <code>installListeners</code>,     * and then adds the components returned by <code>createNextButton</code>,     * <code>createPreviousButton</code>, and <code>createEditor</code>.     *      * @param c the JSpinner     * @see #installDefaults     * @see #installListeners     * @see #createNextButton     * @see #createPreviousButton     * @see #createEditor     */    public void installUI(JComponent c) {	this.spinner = (JSpinner)c;	installDefaults();	installListeners();        Component next = createNextButton();        if (next != null) {            next.setName("Spinner.nextButton");            if (next instanceof JComponent) {                ((JComponent)next).updateUI();            }            spinner.add(next, "Next");        }        Component previous = createPreviousButton();        if (previous != null) {            previous.setName("Spinner.previousButton");            if (previous instanceof JComponent) {                ((JComponent)previous).updateUI();            }            spinner.add(previous, "Previous");        }        Component editor = createEditor();        if (editor != null) {            editor.setName("Spinner.editor");            if (editor instanceof JComponent) {                ((JComponent)editor).updateUI();            }            spinner.add(editor, "Editor");        }        updateEnabledState();        installKeyboardActions();    }    /**     * Calls <code>uninstallDefaults</code>, <code>uninstallListeners</code>,     * and then removes all of the spinners children.     *      * @param c the JSpinner (not used)     */    public void uninstallUI(JComponent c) {	uninstallDefaults();	uninstallListeners();	this.spinner = null;	c.removeAll();    }        /**     * Initializes <code>propertyChangeListener</code> with      * a shared object that delegates interesting PropertyChangeEvents     * to protected methods.     * <p>     * This method is called by <code>installUI</code>.     *      * @see #replaceEditor     * @see #uninstallListeners     */    protected void installListeners() {	spinner.addPropertyChangeListener(propertyChangeListener);    }    /**     * Removes the <code>propertyChangeListener</code> added     * by installListeners.     * <p>     * This method is called by <code>uninstallUI</code>.     *      * @see #installListeners     */    protected void uninstallListeners() {	spinner.removePropertyChangeListener(propertyChangeListener);    }    /**     * Initialize the <code>JSpinner</code> <code>border</code>,      * <code>foreground</code>, and <code>background</code>, properties      * based on the corresponding "Spinner.*" properties from defaults table.       * The <code>JSpinners</code> layout is set to the value returned by     * <code>createLayout</code>.  This method is called by <code>installUI</code>.     *     * @see #uninstallDefaults     * @see #installUI     * @see #createLayout     * @see LookAndFeel#installBorder     * @see LookAndFeel#installColors     */    protected void installDefaults() {        LayoutManager layout = spinner.getLayout();        if (layout == null || layout instanceof UIResource) {            spinner.setLayout(createLayout());        }        // Dig the formatted text field out of the editor and set its name.        JComponent editor = spinner.getEditor();        if (editor instanceof JSpinner.DefaultEditor) {            JFormattedTextField ftf =                ((JSpinner.DefaultEditor)editor).getTextField();            ftf.setName("Spinner.formattedTextField");        }        fetchStyle(spinner);    }    private void fetchStyle(JSpinner c) {        SynthContext context = getContext(c, ENABLED);        style = SynthLookAndFeel.updateStyle(context, this);        context.dispose();    }    /**     * Sets the <code>JSpinner's</code> layout manager to null.  This     * method is called by <code>uninstallUI</code>.     *      * @see #installDefaults     * @see #uninstallUI     */    protected void uninstallDefaults() {        if (spinner.getLayout() instanceof UIResource) {            spinner.setLayout(null);        }        SynthContext context = getContext(spinner, ENABLED);        style.uninstallDefaults(context);        context.dispose();        style = null;    }    /**     * Create a <code>LayoutManager</code> that manages the <code>editor</code>,      * <code>nextButton</code>, and <code>previousButton</code>      * 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     */    protected LayoutManager createLayout() {	return new SpinnerLayout();    }    /**     * Create a <code>PropertyChangeListener</code> that can be     * added to the JSpinner itself.  Typically, this listener     * will call replaceEditor when the "editor" property changes,      * since it's the <code>SpinnerUI's</code> responsibility to      * add the editor to the JSpinner (and remove the old one).     * This method is called by <code>installListeners</code>.     *      * @return A PropertyChangeListener for the JSpinner itself     * @see #installListeners     */    protected PropertyChangeListener createPropertyChangeListener() {	return propertyChangeListener;    }    /**     * Create a component that will replace the spinner models value     * with the object returned by <code>spinner.getPreviousValue</code>.     * By default the <code>previousButton</code> is a JButton     * who's <code>ActionListener</code> updates it's <code>JSpinner</code>     * ancestors model.  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     */    protected Component createPreviousButton() {	JButton b = new SynthArrowButton(SwingConstants.SOUTH);	b.addActionListener(previousButtonHandler);	b.addMouseListener(previousButtonHandler);	return b;    }    /**     * Create a component that will replace the spinner models value     * with the object returned by <code>spinner.getNextValue</code>.     * By default the <code>nextButton</code> is a JButton     * who's <code>ActionListener</code> updates it's <code>JSpinner</code>     * 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     */    protected Component createNextButton() {	JButton b = new SynthArrowButton(SwingConstants.NORTH);	b.addActionListener(nextButtonHandler);	b.addMouseListener(nextButtonHandler);	return b;    }    /**     * This method is called by installUI to get the editor component     * of the <code>JSpinner</code>.  By default it just returns      * <code>JSpinner.getEditor()</code>.  Subclasses can override     * <code>createEditor</code> to return a component that contains      * the spinner's editor or null, if they're going to handle adding      * the editor to the <code>JSpinner</code> in an      * <code>installUI</code> override.     * <p>     * 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.       * <p>     * The <code>replaceEditor</code> method is called when the spinners     * editor is changed with <code>JSpinner.setEditor</code>.  If you've     * overriden this method, then you'll probably want to override     * <code>replaceEditor</code> as well.     *      * @return the JSpinners editor JComponent, spinner.getEditor() by default     * @see #installUI     * @see #replaceEditor     * @see JSpinner#getEditor     */    protected JComponent createEditor() {	return spinner.getEditor();    }    /**     * Called by the <code>PropertyChangeListener</code> when the      * <code>JSpinner</code> 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:     * <pre>     * spinner.remove(oldEditor);     * spinner.add(newEditor, "Editor");     * </pre>     * The implementation of <code>replaceEditor</code> should be coordinated     * with the <code>createEditor</code> method.     *      * @see #createEditor     * @see #createPropertyChangeListener     */    protected void replaceEditor(JComponent oldEditor, JComponent newEditor) {	spinner.remove(oldEditor);	spinner.add(newEditor, "Editor");        // Dig the formatted text field out of the editor and set its name.        JComponent editor = spinner.getEditor();        if (editor instanceof JSpinner.DefaultEditor) {            JFormattedTextField ftf =                ((JSpinner.DefaultEditor)editor).getTextField();            ftf.setName("Spinner.formattedTextField");        }    }    /**     * Updates the enabled state of the children Components based on the     * enabled state of the <code>JSpinner</code>.     */    private void updateEnabledState() {        updateEnabledState(spinner, spinner.isEnabled());    }    /**     * Recursively updates the enabled state of the child     * <code>Component</code>s of <code>c</code>.     */    private void updateEnabledState(Container c, boolean enabled) {        for (int counter = c.getComponentCount() - 1; counter >= 0;counter--) {            Component child = c.getComponent(counter);            child.setEnabled(enabled);            if (child instanceof Container) {                updateEnabledState((Container)child, enabled);            }        }    }    /**     * Installs the KeyboardActions onto the JSpinner.     */    private void installKeyboardActions() {        InputMap iMap = getInputMap(JComponent.                                   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);	SwingUtilities.replaceUIInputMap(spinner, JComponent.					 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,					 iMap);        LazyActionMap.installLazyActionMap(spinner, SynthSpinnerUI.class,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?