FileDocCategorySizeDatePackage
JSlider.javaAPI DocJava SE 5 API38091Fri Aug 26 14:57:56 BST 2005javax.swing

JSlider

public class JSlider extends JComponent implements SwingConstants, Accessible
A component that lets the user graphically select a value by sliding a knob within a bounded interval. The slider can show both major tick marks and minor tick marks between them. The number of values between the tick marks is controlled with setMajorTickSpacing and setMinorTickSpacing.

For further information and examples see How to Use Sliders, a section in The Java Tutorial.

Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeansTM has been added to the java.beans package. Please see {@link java.beans.XMLEncoder}.

beaninfo
attribute: isContainer false description: A component that supports selecting a integer value from a range.
version
1.105 05/12/04
author
David Kloba

Fields Summary
private static final String
uiClassID
private boolean
paintTicks
private boolean
paintTrack
private boolean
paintLabels
private boolean
isInverted
protected BoundedRangeModel
sliderModel
The data model that handles the numeric maximum value, minimum value, and current-position value for the slider.
protected int
majorTickSpacing
The number of values between the major tick marks -- the larger marks that break up the minor tick marks.
protected int
minorTickSpacing
The number of values between the minor tick marks -- the smaller marks that occur between the major tick marks.
protected boolean
snapToTicks
If true, the knob (and the data value it represents) resolve to the closest tick mark next to where the user positioned the knob. The default is false.
boolean
snapToValue
If true, the knob (and the data value it represents) resolve to the closest slider value next to where the user positioned the knob.
protected int
orientation
private Dictionary
labelTable
protected ChangeListener
changeListener
The changeListener (no suffix) is the listener we add to the Sliders model. By default this listener just forwards events to ChangeListeners (if any) added directly to the slider.
protected transient ChangeEvent
changeEvent
Only one ChangeEvent is needed per slider instance since the event's only (read-only) state is the source property. The source of events generated here is always "this". The event is lazily created the first time that an event notification is fired.
Constructors Summary
public JSlider()
Creates a horizontal slider with the range 0 to 100 and an initial value of 50.

        this(HORIZONTAL, 0, 100, 50);
    
public JSlider(int orientation)
Creates a slider using the specified orientation with the range 0 to 100 and an initial value of 50.

        this(orientation, 0, 100, 50);
    
public JSlider(int min, int max)
Creates a horizontal slider using the specified min and max with an initial value equal to the average of the min plus max.

        this(HORIZONTAL, min, max, (min + max) / 2);
    
public JSlider(int min, int max, int value)
Creates a horizontal slider using the specified min, max and value.

        this(HORIZONTAL, min, max, value);
    
public JSlider(int orientation, int min, int max, int value)
Creates a slider with the specified orientation and the specified minimum, maximum, and initial values.

exception
IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL
see
#setOrientation
see
#setMinimum
see
#setMaximum
see
#setValue

        checkOrientation(orientation);
        this.orientation = orientation;
        sliderModel = new DefaultBoundedRangeModel(value, 0, min, max);
        sliderModel.addChangeListener(changeListener);
        updateUI();
    
public JSlider(BoundedRangeModel brm)
Creates a horizontal slider using the specified BoundedRangeModel.

        this.orientation = JSlider.HORIZONTAL;
        setModel(brm);
        sliderModel.addChangeListener(changeListener);
        updateUI();
    
Methods Summary
public voidaddChangeListener(javax.swing.event.ChangeListener l)
Adds a ChangeListener to the slider.

param
l the ChangeListener to add
see
#fireStateChanged
see
#removeChangeListener

        listenerList.add(ChangeListener.class, l);
    
private voidcheckOrientation(int orientation)



        
        switch (orientation) {
        case VERTICAL:
        case HORIZONTAL:
            break;
        default:
            throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
        }
    
protected javax.swing.event.ChangeListenercreateChangeListener()
Subclasses that want to handle model ChangeEvents differently can override this method to return their own ChangeListener implementation. The default ChangeListener just forwards ChangeEvents to the ChangeListeners added directly to the slider.

see
#fireStateChanged

        return new ModelListener();
    
public java.util.HashtablecreateStandardLabels(int increment)
Creates a hashtable that will draw text labels starting at the slider minimum using the increment specified. If you call createStandardLabels( 10 ) and the slider minimum is zero, then it will make labels for the values 0, 10, 20, 30, and so on.

see
#setLabelTable

        return createStandardLabels( increment, getMinimum() );
    
public java.util.HashtablecreateStandardLabels(int increment, int start)
Creates a hashtable that will draw text labels starting at the start point specified using the increment specified. If you call createStandardLabels( 10, 2 ), then it will make labels for the values 2, 12, 22, 32, and so on.

see
#setLabelTable
exception
IllegalArgumentException if slider label start point out of range or if label increment is less than or equal to zero

        if ( start > getMaximum() || start < getMinimum() ) {
            throw new IllegalArgumentException( "Slider label start point out of range." );
        }

        if ( increment <= 0 ) {
            throw new IllegalArgumentException( "Label incremement must be > 0" );
        }

        class SmartHashtable extends Hashtable implements PropertyChangeListener {
            int increment = 0;
            int start = 0;
            boolean startAtMin = false;

            class LabelUIResource extends JLabel implements UIResource {
                public LabelUIResource( String text, int alignment ) {
                    super( text, alignment );
                    setName("Slider.label");
                }
            }

            public SmartHashtable( int increment, int start ) {
                super();
                this.increment = increment;
                this.start = start;
                startAtMin = start == getMinimum();
                createLabels();
            }

            public void propertyChange( PropertyChangeEvent e ) {
                if ( e.getPropertyName().equals( "minimum" ) && startAtMin ) {
                    start = getMinimum();
                }

                if ( e.getPropertyName().equals( "minimum" ) ||
                     e.getPropertyName().equals( "maximum" ) ) {

                    Enumeration keys = getLabelTable().keys();
                    Object key = null;
                    Hashtable hashtable = new Hashtable();

                    // Save the labels that were added by the developer
                    while ( keys.hasMoreElements() ) {
                        key = keys.nextElement();
                        Object value = getLabelTable().get( key );
                        if ( !(value instanceof LabelUIResource) ) {
                            hashtable.put( key, value );
                        }
                    }

                    clear();
                    createLabels();

                    // Add the saved labels
                    keys = hashtable.keys();
                    while ( keys.hasMoreElements() ) {
                        key = keys.nextElement();
                        put( key, hashtable.get( key ) );
                    }

                    ((JSlider)e.getSource()).setLabelTable( this );
                }
            }

            void createLabels() {
                for ( int labelIndex = start; labelIndex <= getMaximum(); labelIndex += increment ) {
                    put( new Integer( labelIndex ), new LabelUIResource( ""+labelIndex, JLabel.CENTER ) );
                }
            }
        }

        SmartHashtable table = new SmartHashtable( increment, start );

        if ( getLabelTable() != null && (getLabelTable() instanceof PropertyChangeListener) ) {
            removePropertyChangeListener( (PropertyChangeListener)getLabelTable() );
        }

        addPropertyChangeListener( table );

        return table;
    
protected voidfireStateChanged()
Send a ChangeEvent, whose source is this Slider, to each listener. This method method is called each time a ChangeEvent is received from the model.

see
#addChangeListener
see
EventListenerList

        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i]==ChangeListener.class) {
                if (changeEvent == null) {
                    changeEvent = new ChangeEvent(this);
                }
                ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
            }
        }
    
public javax.accessibility.AccessibleContextgetAccessibleContext()
Gets the AccessibleContext associated with this JSlider. For sliders, the AccessibleContext takes the form of an AccessibleJSlider. A new AccessibleJSlider instance is created if necessary.

return
an AccessibleJSlider that serves as the AccessibleContext of this JSlider

        if (accessibleContext == null) {
            accessibleContext = new AccessibleJSlider();
        }
        return accessibleContext;
    
public javax.swing.event.ChangeListener[]getChangeListeners()
Returns an array of all the ChangeListeners added to this JSlider with addChangeListener().

return
all of the ChangeListeners added or an empty array if no listeners have been added
since
1.4

        return (ChangeListener[])listenerList.getListeners(
                ChangeListener.class);
    
public intgetExtent()
Returns the "extent" -- the range of values "covered" by the knob.

return
an int representing the extent
see
#setExtent
see
BoundedRangeModel#getExtent

 
        return getModel().getExtent(); 
    
public booleangetInverted()
Returns true if the value-range shown for the slider is reversed,

return
true if the slider values are reversed from their normal order
see
#setInverted

 
        return isInverted; 
    
public java.util.DictionarygetLabelTable()
Returns the dictionary of what labels to draw at which values.

return
the Dictionary containing labels and where to draw them

/*
        if ( labelTable == null && getMajorTickSpacing() > 0 ) {
            setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
        }
*/
        return labelTable;
    
public intgetMajorTickSpacing()
This method returns the major tick spacing. The number that is returned represents the distance, measured in values, between each major tick mark. If you have a slider with a range from 0 to 50 and the major tick spacing is set to 10, you will get major ticks next to the following values: 0, 10, 20, 30, 40, 50.

return
the number of values between major ticks
see
#setMajorTickSpacing

 
        return majorTickSpacing; 
    
public intgetMaximum()
Returns the maximum value supported by the slider.

return
the value of the models maximum property
see
#setMaximum

 
        return getModel().getMaximum(); 
    
public intgetMinimum()
Returns the minimum value supported by the slider.

return
the value of the models minimum property
see
#setMinimum

 
        return getModel().getMinimum(); 
    
public intgetMinorTickSpacing()
This method returns the minor tick spacing. The number that is returned represents the distance, measured in values, between each minor tick mark. If you have a slider with a range from 0 to 50 and the minor tick spacing is set to 10, you will get minor ticks next to the following values: 0, 10, 20, 30, 40, 50.

return
the number of values between minor ticks
see
#getMinorTickSpacing

 
        return minorTickSpacing; 
    
public javax.swing.BoundedRangeModelgetModel()
Returns data model that handles the sliders three fundamental properties: minimum, maximum, value.

see
#setModel

        return sliderModel;
    
public intgetOrientation()
Return this slider's vertical or horizontal orientation.

return
VERTICAL or HORIZONTAL
see
#setOrientation

 
        return orientation; 
    
public booleangetPaintLabels()
Tells if labels are to be painted.

return
true if labels are painted, else false
see
#setPaintLabels

 
        return paintLabels; 
    
public booleangetPaintTicks()
Tells if tick marks are to be painted.

return
true if tick marks are painted, else false
see
#setPaintTicks

 
        return paintTicks; 
    
public booleangetPaintTrack()
Tells if the track (area the slider slides in) is to be painted.

return
true if track is painted, else false
see
#setPaintTrack

 
        return paintTrack; 
    
public booleangetSnapToTicks()
Returns true if the knob (and the data value it represents) resolve to the closest tick mark next to where the user positioned the knob.

return
true if the value snaps to the nearest tick mark, else false
see
#setSnapToTicks

 
        return snapToTicks; 
    
booleangetSnapToValue()
Returns true if the knob (and the data value it represents) resolve to the closest slider value next to where the user positioned the knob.

return
true if the value snaps to the nearest slider value, else false

 
        return snapToValue; 
    
public javax.swing.plaf.SliderUIgetUI()
Gets the UI object which implements the L&F for this component.

return
the SliderUI object that implements the Slider L&F

        return(SliderUI)ui;
    
public java.lang.StringgetUIClassID()
Returns the name of the L&F class that renders this component.

return
"SliderUI"
see
JComponent#getUIClassID
see
UIDefaults#getUI

        return uiClassID;
    
public intgetValue()
Returns the sliders value.

return
the models value property
see
#setValue

 
        return getModel().getValue(); 
    
public booleangetValueIsAdjusting()
True if the slider knob is being dragged.

return
the value of the models valueIsAdjusting property
see
#setValueIsAdjusting

 
        return getModel().getValueIsAdjusting(); 
    
protected java.lang.StringparamString()
Returns a string representation of this JSlider. This method is intended to be used only for debugging purposes, and the content and format of the returned string may vary between implementations. The returned string may be empty but may not be null.

return
a string representation of this JSlider.

        String paintTicksString = (paintTicks ?
                                   "true" : "false");
        String paintTrackString = (paintTrack ?
                                   "true" : "false");
        String paintLabelsString = (paintLabels ?
                                    "true" : "false");
        String isInvertedString = (isInverted ?
                                   "true" : "false");
        String snapToTicksString = (snapToTicks ?
                                    "true" : "false");
        String snapToValueString = (snapToValue ?
                                    "true" : "false");
        String orientationString = (orientation == HORIZONTAL ?
                                    "HORIZONTAL" : "VERTICAL");

        return super.paramString() +
        ",isInverted=" + isInvertedString +
        ",majorTickSpacing=" + majorTickSpacing +
        ",minorTickSpacing=" + minorTickSpacing +
        ",orientation=" + orientationString +
        ",paintLabels=" + paintLabelsString +
        ",paintTicks=" + paintTicksString +
        ",paintTrack=" + paintTrackString +
        ",snapToTicks=" + snapToTicksString +
        ",snapToValue=" + snapToValueString;
    
public voidremoveChangeListener(javax.swing.event.ChangeListener l)
Removes a ChangeListener from the slider.

param
l the ChangeListener to remove
see
#fireStateChanged
see
#addChangeListener

        listenerList.remove(ChangeListener.class, l);
    
public voidsetExtent(int extent)
Sets the size of the range "covered" by the knob. Most look and feel implementations will change the value by this amount if the user clicks on either side of the knob.

see
#getExtent
see
BoundedRangeModel#setExtent
beaninfo
expert: true description: Size of the range covered by the knob.

 
        getModel().setExtent(extent); 
    
public voidsetInverted(boolean b)
Specify true to reverse the value-range shown for the slider and false to put the value range in the normal order. The order depends on the slider's ComponentOrientation property. Normal (non-inverted) horizontal sliders with a ComponentOrientation value of LEFT_TO_RIGHT have their maximum on the right. Normal horizontal sliders with a ComponentOrientation value of RIGHT_TO_LEFT have their maximum on the left. Normal vertical sliders have their maximum on the top. These labels are reversed when the slider is inverted.

param
b true to reverse the slider values from their normal order
beaninfo
bound: true attribute: visualUpdate true description: If true reverses the slider values from their normal order

 
        boolean oldValue = isInverted;
        isInverted = b; 
        firePropertyChange("inverted", oldValue, isInverted);
        if (b != oldValue) {
            repaint();
        }
    
public voidsetLabelTable(java.util.Dictionary labels)
Used to specify what label will be drawn at any given value. The key-value pairs are of this format: { Integer value, java.swing.JComponent label }.

see
#createStandardLabels
see
#getLabelTable
beaninfo
hidden: true bound: true attribute: visualUpdate true description: Specifies what labels will be drawn for any given value.

        Dictionary oldTable = labelTable;
        labelTable = labels;
        updateLabelUIs();
        firePropertyChange("labelTable", oldTable, labelTable );
        if (labels != oldTable) {
            revalidate();
            repaint();
        }
    
public voidsetMajorTickSpacing(int n)
This method sets the major tick spacing. The number that is passed-in represents the distance, measured in values, between each major tick mark. If you have a slider with a range from 0 to 50 and the major tick spacing is set to 10, you will get major ticks next to the following values: 0, 10, 20, 30, 40, 50.

see
#getMajorTickSpacing
beaninfo
bound: true attribute: visualUpdate true description: Sets the number of values between major tick marks.

        int oldValue = majorTickSpacing;
        majorTickSpacing = n;
        if ( labelTable == null && getMajorTickSpacing() > 0 && getPaintLabels() ) {
            setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
        }
        firePropertyChange("majorTickSpacing", oldValue, majorTickSpacing);
        if (majorTickSpacing != oldValue && getPaintTicks()) {
            repaint();
        }
    
public voidsetMaximum(int maximum)
Sets the models maximum property.

see
#getMaximum
see
BoundedRangeModel#setMaximum
beaninfo
bound: true preferred: true description: The sliders maximum value.

 
        int oldMax = getModel().getMaximum();
        getModel().setMaximum(maximum); 
        firePropertyChange( "maximum", new Integer( oldMax ), new Integer( maximum ) );
    
public voidsetMinimum(int minimum)
Sets the models minimum property.

see
#getMinimum
see
BoundedRangeModel#setMinimum
beaninfo
bound: true preferred: true description: The sliders minimum value.

 
        int oldMin = getModel().getMinimum();
        getModel().setMinimum(minimum); 
        firePropertyChange( "minimum", new Integer( oldMin ), new Integer( minimum ) );
    
public voidsetMinorTickSpacing(int n)
This method sets the minor tick spacing. The number that is passed-in represents the distance, measured in values, between each minor tick mark. If you have a slider with a range from 0 to 50 and the minor tick spacing is set to 10, you will get minor ticks next to the following values: 0, 10, 20, 30, 40, 50.

see
#getMinorTickSpacing
beaninfo
bound: true attribute: visualUpdate true description: Sets the number of values between minor tick marks.

 
        int oldValue = minorTickSpacing;
        minorTickSpacing = n; 
        firePropertyChange("minorTickSpacing", oldValue, minorTickSpacing);
        if (minorTickSpacing != oldValue && getPaintTicks()) {
            repaint();
        }
    
public voidsetModel(javax.swing.BoundedRangeModel newModel)
Sets the model that handles the sliders three fundamental properties: minimum, maximum, value.

see
#getModel
beaninfo
bound: true description: The sliders BoundedRangeModel.

        BoundedRangeModel oldModel = getModel();

        if (oldModel != null) {
            oldModel.removeChangeListener(changeListener);
        }

        sliderModel = newModel;

        if (newModel != null) {
            newModel.addChangeListener(changeListener);

            if (accessibleContext != null) {
                accessibleContext.firePropertyChange(
                                                    AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
                                                    (oldModel == null 
                                                     ? null : new Integer(oldModel.getValue())),
                                                    (newModel == null 
                                                     ? null : new Integer(newModel.getValue())));
            }
        }

        firePropertyChange("model", oldModel, sliderModel);
    
public voidsetOrientation(int orientation)
Set the scrollbars orientation to either VERTICAL or HORIZONTAL.

exception
IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL
see
#getOrientation
beaninfo
preferred: true bound: true attribute: visualUpdate true description: Set the scrollbars orientation to either VERTICAL or HORIZONTAL. enum: VERTICAL JSlider.VERTICAL HORIZONTAL JSlider.HORIZONTAL

 
        checkOrientation(orientation);
        int oldValue = this.orientation;
        this.orientation = orientation;
        firePropertyChange("orientation", oldValue, orientation);

        if ((oldValue != orientation) && (accessibleContext != null)) {
            accessibleContext.firePropertyChange(
                                                AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                                                ((oldValue == VERTICAL) 
                                                 ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL),
                                                ((orientation == VERTICAL) 
                                                 ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL));
        }
        if (orientation != oldValue) {
            revalidate();
        }
    
public voidsetPaintLabels(boolean b)
Determines whether labels are painted on the slider.

see
#getPaintLabels
beaninfo
bound: true attribute: visualUpdate true description: If true labels are painted on the slider.

        boolean oldValue = paintLabels;
        paintLabels = b;
        if ( labelTable == null && getMajorTickSpacing() > 0 ) {
            setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
        }
        firePropertyChange("paintLabels", oldValue, paintLabels);
        if (paintLabels != oldValue) {
            revalidate();
            repaint();
        }
    
public voidsetPaintTicks(boolean b)
Determines whether tick marks are painted on the slider.

see
#getPaintTicks
beaninfo
bound: true attribute: visualUpdate true description: If true tick marks are painted on the slider.

 
        boolean oldValue = paintTicks;
        paintTicks = b;
        firePropertyChange("paintTicks", oldValue, paintTicks);
        if (paintTicks != oldValue) {
            revalidate();
            repaint();
        }
    
public voidsetPaintTrack(boolean b)
Determines whether the track is painted on the slider.

see
#getPaintTrack
beaninfo
bound: true attribute: visualUpdate true description: If true, the track is painted on the slider.

 
        boolean oldValue = paintTrack;
        paintTrack = b;
        firePropertyChange("paintTrack", oldValue, paintTrack);
        if (paintTrack != oldValue) {
            repaint();
        }
    
public voidsetSnapToTicks(boolean b)
Specifying true makes the knob (and the data value it represents) resolve to the closest tick mark next to where the user positioned the knob.

param
b true to snap the knob to the nearest tick mark
see
#getSnapToTicks
beaninfo
bound: true description: If true snap the knob to the nearest tick mark.

 
        boolean oldValue = snapToTicks;
        snapToTicks = b; 
        firePropertyChange("snapToTicks", oldValue, snapToTicks);
    
voidsetSnapToValue(boolean b)
Specifying true makes the knob (and the data value it represents) resolve to the closest slider value next to where the user positioned the knob. If the snapToTicks property has been set to true, the snap-to-ticks behavior will prevail.

param
b true to snap the knob to the nearest slider value
see
#getSnapToValue
see
#setSnapToTicks
beaninfo
bound: true description: If true snap the knob to the nearest slider value.

 
        boolean oldValue = snapToValue;
        snapToValue = b; 
        firePropertyChange("snapToValue", oldValue, snapToValue);
    
public voidsetUI(javax.swing.plaf.SliderUI ui)
Sets the UI object which implements the L&F for this component.

param
ui the SliderUI L&F object
see
UIDefaults#getUI
beaninfo
bound: true hidden: true attribute: visualUpdate true description: The UI object that implements the slider's LookAndFeel.

        super.setUI(ui);
    
public voidsetValue(int n)
Sets the sliders current value. This method just forwards the value to the model.

see
#getValue
beaninfo
preferred: true description: The sliders current value.

 
        BoundedRangeModel m = getModel();
        int oldValue = m.getValue();
        if (oldValue == n) {
            return;
        }
        m.setValue(n);

        if (accessibleContext != null) {
            accessibleContext.firePropertyChange(
                                                AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
                                                new Integer(oldValue),
                                                new Integer(m.getValue()));
        }
    
public voidsetValueIsAdjusting(boolean b)
Sets the models valueIsAdjusting property. Slider look and feel implementations should set this property to true when a knob drag begins, and to false when the drag ends. The slider model will not generate ChangeEvents while valueIsAdjusting is true.

see
#getValueIsAdjusting
see
BoundedRangeModel#setValueIsAdjusting
beaninfo
expert: true description: True if the slider knob is being dragged.

 
        BoundedRangeModel m = getModel();   
        boolean oldValue = m.getValueIsAdjusting();
        m.setValueIsAdjusting(b);

        if ((oldValue != b) && (accessibleContext != null)) {
            accessibleContext.firePropertyChange(
                                                AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                                                ((oldValue) ? AccessibleState.BUSY : null),
                                                ((b) ? AccessibleState.BUSY : null));
        }
    
protected voidupdateLabelUIs()
Resets the UI property to a value from the current look and feel.

see
JComponent#updateUI

        if ( getLabelTable() == null ) {
            return;
        }
        Enumeration labels = getLabelTable().keys();
        while ( labels.hasMoreElements() ) {
            Object value = getLabelTable().get( labels.nextElement() );
            if ( value instanceof JComponent ) {
                JComponent component = (JComponent)value;
                component.updateUI();
                component.setSize( component.getPreferredSize()  );
            }
        }
    
public voidupdateUI()
Resets the UI property to a value from the current look and feel.

see
JComponent#updateUI

        updateLabelUIs();
        setUI((SliderUI)UIManager.getUI(this));
    
private voidwriteObject(java.io.ObjectOutputStream s)
See readObject() and writeObject() in JComponent for more information about serialization in Swing.

        s.defaultWriteObject();
        if (getUIClassID().equals(uiClassID)) {
            byte count = JComponent.getWriteObjCounter(this);
            JComponent.setWriteObjCounter(this, --count);
            if (count == 0 && ui != null) {
                ui.installUI(this);
            }
        }