Package javax.swing

Source Code of javax.swing.JSpinner$ModelChangeListener

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package javax.swing;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleEditableText;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.SpinnerUI;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.DocumentFilter;
import javax.swing.text.NumberFormatter;
import org.apache.harmony.luni.util.NotImplementedException;
import org.apache.harmony.x.swing.StringConstants;
import org.apache.harmony.x.swing.Utilities;

import org.apache.harmony.x.swing.internal.nls.Messages;

/**
* <p>
* <i>JSpinner</i>
* </p>
* <h3>Implementation Notes:</h3>
* <ul>
* <li>The <code>serialVersionUID</code> fields are explicitly declared as a performance
* optimization, not as a guarantee of serialization compatibility.</li>
* </ul>
*/
public class JSpinner extends JComponent implements Accessible {
    private static final long serialVersionUID = 5455034942343575490L;

    protected class AccessibleJSpinner extends JComponent.AccessibleJComponent implements
            AccessibleValue, AccessibleAction, AccessibleText, AccessibleEditableText,
            ChangeListener {
        private static final long serialVersionUID = -8871493856204319541L;

        protected AccessibleJSpinner() {
        }

        public void stateChanged(ChangeEvent e) throws NotImplementedException {
            throw new NotImplementedException();
        }

        @Override
        public AccessibleRole getAccessibleRole() throws NotImplementedException {
            throw new NotImplementedException();
        }

        @Override
        public int getAccessibleChildrenCount() throws NotImplementedException {
            throw new NotImplementedException();
        }

        @Override
        public Accessible getAccessibleChild(int i) throws NotImplementedException {
            throw new NotImplementedException();
        }

        @Override
        public AccessibleAction getAccessibleAction() throws NotImplementedException {
            throw new NotImplementedException();
        }

        @Override
        public AccessibleText getAccessibleText() throws NotImplementedException {
            throw new NotImplementedException();
        }

        @Override
        public AccessibleValue getAccessibleValue() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public Number getCurrentAccessibleValue() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public boolean setCurrentAccessibleValue(Number n) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public Number getMinimumAccessibleValue() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public Number getMaximumAccessibleValue() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public int getAccessibleActionCount() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public String getAccessibleActionDescription(int i) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public boolean doAccessibleAction(int i) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public int getIndexAtPoint(Point p) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public Rectangle getCharacterBounds(int i) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public int getCharCount() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public int getCaretPosition() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public String getAtIndex(int part, int index) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public String getAfterIndex(int part, int index) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public String getBeforeIndex(int part, int index) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public AttributeSet getCharacterAttribute(int i) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public int getSelectionStart() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public int getSelectionEnd() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public String getSelectedText() throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void setTextContents(String s) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void insertTextAtIndex(int index, String s) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public String getTextRange(int startIndex, int endIndex) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void delete(int startIndex, int endIndex) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void cut(int startIndex, int endIndex) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void paste(int startIndex) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void replaceText(int startIndex, int endIndex, String s)
                throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void selectText(int startIndex, int endIndex) throws NotImplementedException {
            throw new NotImplementedException();
        }

        public void setAttributes(int startIndex, int endIndex, AttributeSet as)
                throws NotImplementedException {
            throw new NotImplementedException();
        }
    }

    public static class DefaultEditor extends JPanel implements ChangeListener,
            PropertyChangeListener, LayoutManager {
        private static final long serialVersionUID = 6977154593437159148L;

        private JFormattedTextField text;

        private JSpinner spinner;

        public DefaultEditor(JSpinner spinner) {
            this.spinner = spinner;
            setLayout(this);
            spinner.addChangeListener(this);
            text = new JFormattedTextField();
            text.setEditable(false);
            text.setValue(spinner.getModel().getValue());
            text.addPropertyChangeListener(this);
            text.getActionMap().put("increment", disabledAction);
            text.getActionMap().put("decrement", disabledAction);
            add(text);
        }

        public JSpinner getSpinner() {
            return spinner;
        }

        public JFormattedTextField getTextField() {
            return text;
        }

        public void stateChanged(ChangeEvent e) {
            if (this != spinner.getEditor()) {
                return;
            }
            text.setValue(spinner.getValue());
        }

        public void propertyChange(PropertyChangeEvent e) {
            if (e.getSource() != text || this != spinner.getEditor()) {
                return;
            }
            if (StringConstants.VALUE_PROPERTY_NAME.equals(e.getPropertyName())) {
                try {
                    spinner.setValue(e.getNewValue());
                } catch (IllegalArgumentException ex) {
                    text.setValue(e.getOldValue());
                }
            }
        }

        public void addLayoutComponent(String name, Component child) {
        }

        public void removeLayoutComponent(Component child) {
        }

        public Dimension preferredLayoutSize(Container parent) {
            return Utilities.addInsets(text.getPreferredSize(), parent.getInsets());
        }

        public Dimension minimumLayoutSize(Container parent) {
            return Utilities.addInsets(text.getMinimumSize(), parent.getInsets());
        }

        public void layoutContainer(Container parent) {
            text.setBounds(0, 0, parent.getWidth(), parent.getHeight());
        }

        public void commitEdit() throws ParseException {
            text.commitEdit();
        }

        public void dismiss(JSpinner spinner) {
            spinner.removeChangeListener(this);
        }
    }

    @SuppressWarnings("unchecked")
    private static class SpinnerDateFormatter extends DateFormatter {
        private static final long serialVersionUID = 1L;

        private SpinnerDateModel model;

        public SpinnerDateFormatter(final SimpleDateFormat format, final SpinnerDateModel model) {
            super(format);
            this.model = model;
        }

        @Override
        public void setMaximum(Comparable max) {
            super.setMaximum(max);
            model.setEnd(max);
        }

        @Override
        public void setMinimum(Comparable min) {
            super.setMinimum(min);
            model.setStart(min);
        }

        @Override
        public Comparable getMaximum() {
            Comparable max = model.getEnd();
            super.setMaximum(max);
            return max;
        }

        @Override
        public Comparable getMinimum() {
            Comparable min = model.getStart();
            super.setMinimum(min);
            return min;
        }
    }

    public static class DateEditor extends DefaultEditor {
        private static final long serialVersionUID = 1L;

        private SimpleDateFormat format;

        public DateEditor(JSpinner spinner) {
            super(spinner);
            if (!(spinner.getModel() instanceof SpinnerDateModel)) {
                throw new IllegalArgumentException(Messages.getString("swing.2C","SpinnerDateModel")); //$NON-NLS-1$ //$NON-NLS-2$
            }
            format = new SimpleDateFormat();
            initTextField();
        }

        public DateEditor(JSpinner spinner, String dateFormatPattern) {
            super(spinner);
            if (!(spinner.getModel() instanceof SpinnerDateModel)) {
                throw new IllegalArgumentException(Messages.getString("swing.2C","SpinnerDateModel")); //$NON-NLS-1$ //$NON-NLS-2$
            }
            format = new SimpleDateFormat(dateFormatPattern);
            initTextField();
        }

        public SimpleDateFormat getFormat() {
            return format;
        }

        public SpinnerDateModel getModel() {
            return (SpinnerDateModel) this.getSpinner().getModel();
        }

        private void initTextField() {
            SpinnerDateFormatter formatter = new SpinnerDateFormatter(format, getModel());
            JFormattedTextField textField = getTextField();
            textField.setFormatterFactory(new DefaultFormatterFactory(formatter));
            textField.setEditable(true);
        }
    }

    private static class SpinnerListFormatter extends AbstractFormatter {
        private static final long serialVersionUID = 1L;

        private class ListFilter extends DocumentFilter {
            private JFormattedTextField textField;

            public ListFilter(JFormattedTextField textField) {
                this.textField = textField;
            }

            @Override
            public void insertString(FilterBypass fb, int offset, String text,
                    AttributeSet attrs) throws BadLocationException {
                super.insertString(fb, offset, text, attrs);
            }

            @Override
            public void replace(FilterBypass fb, int offset, int length, String text,
                    AttributeSet attrs) throws BadLocationException {
                String str = textField.getText().substring(0, offset) + text;
                String replace = findElementText(str);
                if (!"".equals(replace)) {
                    fb.replace(0, textField.getText().length(), replace, attrs);
                    textField.setCaretPosition(offset + text.length());
                    textField.moveCaretPosition(textField.getText().length());
                } else {
                    super.replace(fb, offset, length, text, attrs);
                }
            }

            private String findElementText(String text) {
                Object findElement = findElement(text);
                if (findElement == null) {
                    return "";
                }
                String result = findElement.toString();
                return (result.indexOf(text) == 0) ? result : "";
            }
        }

        private SpinnerListModel model;

        private ListFilter filter;

        public SpinnerListFormatter(SpinnerListModel model, JFormattedTextField textField) {
            this.model = model;
            filter = new ListFilter(textField);
        }

        @Override
        public Object stringToValue(String text) throws ParseException {
            return ("".equals(text)) ? null : findElement(text);
        }

        @Override
        public String valueToString(Object value) throws ParseException {
            return (value == null ? "" : value.toString());
        }

        @Override
        protected DocumentFilter getDocumentFilter() {
            return filter;
        }

        private Object findElement(String text) {
            List<?> modelList = model.getList();
            for (int i = 0; i < modelList.size(); i++) {
                Object obj = modelList.get(i);
                if (obj != null && obj.toString().indexOf(text) == 0) {
                    return obj;
                }
            }
            return modelList.get(0);
        }
    }

    public static class ListEditor extends DefaultEditor {
        private static final long serialVersionUID = 1L;

        public ListEditor(JSpinner spinner) {
            super(spinner);
            if (!(spinner.getModel() instanceof SpinnerListModel)) {
                throw new IllegalArgumentException(Messages.getString("swing.2C","SpinnerListModel")); //$NON-NLS-1$ //$NON-NLS-2$
            }
            SpinnerListFormatter formatter = new SpinnerListFormatter(this.getModel(), this
                    .getTextField());
            JFormattedTextField textField = this.getTextField();
            textField.setFormatterFactory(new DefaultFormatterFactory(formatter));
            textField.setEditable(true);
        }

        public SpinnerListModel getModel() {
            return (SpinnerListModel) this.getSpinner().getModel();
        }
    }

    @SuppressWarnings("unchecked")
    private static class SpinnerNumberFormatter extends NumberFormatter {
        private static final long serialVersionUID = 1L;

        private SpinnerNumberModel model;

        public SpinnerNumberFormatter(DecimalFormat format, SpinnerNumberModel model) {
            super(format);
            this.model = model;
            setValueClass(model.getValue().getClass());
        }

        @Override
        public void setMaximum(Comparable max) {
            super.setMaximum(max);
            model.setMaximum(max);
        }

        @Override
        public void setMinimum(Comparable min) {
            super.setMinimum(min);
            model.setMinimum(min);
        }

        @Override
        public Comparable getMaximum() {
            Comparable max = model.getMaximum();
            super.setMaximum(max);
            return max;
        }

        @Override
        public Comparable getMinimum() {
            Comparable min = model.getMinimum();
            super.setMinimum(min);
            return min;
        }
    }

    public static class NumberEditor extends DefaultEditor {
        private static final long serialVersionUID = 1L;

        private DecimalFormat format;

        public NumberEditor(JSpinner spinner) {
            super(spinner);
            if (!(spinner.getModel() instanceof SpinnerNumberModel)) {
                throw new IllegalArgumentException(Messages.getString("swing.2C","SpinnerNumberModel")); //$NON-NLS-1$ //$NON-NLS-2$
            }
            format = new DecimalFormat();
            initTextField();
        }

        public NumberEditor(JSpinner spinner, String decimalFormatPattern) {
            super(spinner);
            if (!(spinner.getModel() instanceof SpinnerNumberModel)) {
                throw new IllegalArgumentException(Messages.getString("swing.2C","SpinnerNumberModel")); //$NON-NLS-1$ //$NON-NLS-2$
            }
            format = new DecimalFormat(decimalFormatPattern);
            initTextField();
        }

        public DecimalFormat getFormat() {
            return format;
        }

        public SpinnerNumberModel getModel() {
            return (SpinnerNumberModel) this.getSpinner().getModel();
        }

        private void initTextField() {
            SpinnerNumberFormatter numberFormatter = new SpinnerNumberFormatter(format, this
                    .getModel());
            JFormattedTextField textField = this.getTextField();
            textField.setFormatterFactory(new DefaultFormatterFactory(numberFormatter));
            textField.setHorizontalAlignment(SwingConstants.RIGHT);
            textField.setEditable(true);
        }
    }

    private class ModelChangeListener implements ChangeListener, Serializable {
        private static final long serialVersionUID = 1L;

        public void stateChanged(ChangeEvent e) {
            fireStateChanged();
        }
    }

    private static Action disabledAction = new AbstractAction() {
        private static final long serialVersionUID = 1L;

        public void actionPerformed(ActionEvent e) {
        }

        @Override
        public boolean isEnabled() {
            return false;
        }
    };

    private static final String UI_CLASS_ID = "SpinnerUI";

    private SpinnerModel model;

    private boolean editorSet;

    private JComponent editor;

    private ChangeListener changeListener = new ModelChangeListener();

    private ChangeEvent changeEvent;

    public JSpinner(SpinnerModel model) {
        this.model = model;
        model.addChangeListener(changeListener);
        editor = createEditor(model);
        updateUI();
    }

    public JSpinner() {
        this(new SpinnerNumberModel());
    }

    public SpinnerUI getUI() {
        return (SpinnerUI) ui;
    }

    public void setUI(SpinnerUI ui) {
        super.setUI(ui);
    }

    @Override
    public String getUIClassID() {
        return UI_CLASS_ID;
    }

    @Override
    public void updateUI() {
        setUI((SpinnerUI) UIManager.getUI(this));
    }

    protected JComponent createEditor(SpinnerModel model) {
        if (model instanceof SpinnerNumberModel) {
            return new NumberEditor(this);
        }
        if (model instanceof SpinnerDateModel) {
            return new DateEditor(this);
        }
        if (model instanceof SpinnerListModel) {
            return new ListEditor(this);
        }
        return new DefaultEditor(this);
    }

    public void setModel(SpinnerModel model) {
        if (model == null) {
            throw new IllegalArgumentException(Messages.getString("swing.2F")); //$NON-NLS-1$
        }
        SpinnerModel oldModel = this.model;
        oldModel.removeChangeListener(changeListener);
        this.model = model;
        model.addChangeListener(changeListener);
        firePropertyChange(StringConstants.MODEL_PROPERTY_CHANGED, oldModel, model);
        if (!editorSet) {
            setEditor(createEditor(model));
            editorSet = false;
        }
    }

    public SpinnerModel getModel() {
        return model;
    }

    public Object getValue() {
        return model.getValue();
    }

    public void setValue(Object value) {
        model.setValue(value);
    }

    public Object getNextValue() {
        return model.getNextValue();
    }

    public Object getPreviousValue() {
        return model.getPreviousValue();
    }

    public void addChangeListener(ChangeListener listener) {
        listenerList.add(ChangeListener.class, listener);
    }

    public void removeChangeListener(ChangeListener listener) {
        listenerList.remove(ChangeListener.class, listener);
    }

    public ChangeListener[] getChangeListeners() {
        return getListeners(ChangeListener.class);
    }

    protected void fireStateChanged() {
        if (changeEvent == null) {
            changeEvent = new ChangeEvent(this);
        }
        ChangeListener[] listeners = getChangeListeners();
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].stateChanged(changeEvent);
        }
    }

    public void setEditor(JComponent editor) {
        if (editor == null) {
            throw new IllegalArgumentException(Messages.getString("swing.30")); //$NON-NLS-1$
        }
        JComponent oldEditor = this.editor;
        if (oldEditor == editor) {
            return;
        }
        if (oldEditor instanceof DefaultEditor) {
            DefaultEditor def = (DefaultEditor) oldEditor;
            def.dismiss(this);
        }
        this.editor = editor;
        editorSet = true;
        firePropertyChange(StringConstants.EDITOR_PROPERTY_CHANGED, oldEditor, editor);
    }

    public JComponent getEditor() {
        return editor;
    }

    public void commitEdit() throws ParseException {
        if (editor instanceof DefaultEditor) {
            ((DefaultEditor) editor).commitEdit();
        }
    }

    @Override
    public AccessibleContext getAccessibleContext() {
        if (accessibleContext == null) {
            accessibleContext = new AccessibleJSpinner();
        }
        return accessibleContext;
    }
}
TOP

Related Classes of javax.swing.JSpinner$ModelChangeListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.