121
122 /**
123 * If true, the knob (and the data value it represents)
124 * resolve to the closest slider value next to where the user
125 * positioned the knob.
126 */
127 boolean snapToValue = true;
128
129 /**
130 * Whether the slider is horizontal or vertical
131 * The default is horizontal.
132 *
133 * @see #setOrientation
134 */
135 protected int orientation;
136
137
138 /**
139 * {@code Dictionary} of what labels to draw at which values
140 */
141 private Dictionary<Integer, JComponent> labelTable;
142
143
144 /**
145 * The changeListener (no suffix) is the listener we add to the
146 * slider's model. This listener is initialized to the
147 * {@code ChangeListener} returned from {@code createChangeListener},
148 * which by default just forwards events
149 * to {@code ChangeListener}s (if any) added directly to the slider.
150 *
151 * @see #addChangeListener
152 * @see #createChangeListener
153 */
154 protected ChangeListener changeListener = createChangeListener();
155
156
157 /**
158 * Only one <code>ChangeEvent</code> is needed per slider instance since the
159 * event's only (read-only) state is the source property. The source
160 * of events generated here is always "this". The event is lazily
161 * created the first time that an event notification is fired.
756 /**
757 * {@inheritDoc}
758 *
759 * @since 1.6
760 */
761 public void setFont(Font font) {
762 super.setFont(font);
763 updateLabelSizes();
764 }
765
766 /**
767 * {@inheritDoc}
768 * @since 1.7
769 */
770 public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
771 if (!isShowing()) {
772 return false;
773 }
774
775 // Check that there is a label with such image
776 Enumeration<JComponent> elements = labelTable.elements();
777
778 while (elements.hasMoreElements()) {
779 JComponent component = elements.nextElement();
780
781 if (component instanceof JLabel) {
782 JLabel label = (JLabel) component;
783
784 if (SwingUtilities.doesIconReferenceImage(label.getIcon(), img) ||
785 SwingUtilities.doesIconReferenceImage(label.getDisabledIcon(), img)) {
786 return super.imageUpdate(img, infoflags, x, y, w, h);
787 }
788 }
789 }
790
791 return false;
792 }
793
794 /**
795 * Returns the dictionary of what labels to draw at which values.
796 *
797 * @return the <code>Dictionary</code> containing labels and
798 * where to draw them
799 */
800 public Dictionary<Integer, JComponent> getLabelTable() {
801 /*
802 if ( labelTable == null && getMajorTickSpacing() > 0 ) {
803 setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
804 }
805 */
806 return labelTable;
807 }
808
809
810 /**
811 * Used to specify what label will be drawn at any given value.
812 * The key-value pairs are of this format:
813 * <code>{ Integer value, java.swing.JComponent label }</code>.
814 * <p>
815 * An easy way to generate a standard table of value labels is by using the
816 * {@code createStandardLabels} method.
817 * <p>
818 * Once the labels have been set, this method calls {@link #updateLabelUIs}.
819 * Note that the labels are only painted if the {@code paintLabels}
820 * property is {@code true}.
821 *
822 * @param labels new {@code Dictionary} of labels, or {@code null} to
823 * remove all labels
824 * @see #createStandardLabels(int)
825 * @see #getLabelTable
826 * @see #setPaintLabels
827 * @beaninfo
828 * hidden: true
829 * bound: true
830 * attribute: visualUpdate true
831 * description: Specifies what labels will be drawn for any given value.
832 */
833 public void setLabelTable( Dictionary<Integer, JComponent> labels ) {
834 Dictionary<Integer, JComponent> oldTable = labelTable;
835 labelTable = labels;
836 updateLabelUIs();
837 firePropertyChange("labelTable", oldTable, labelTable );
838 if (labels != oldTable) {
839 revalidate();
840 repaint();
841 }
842 }
843
844
845 /**
846 * Updates the UIs for the labels in the label table by calling
847 * {@code updateUI} on each label. The UIs are updated from
848 * the current look and feel. The labels are also set to their
849 * preferred size.
850 *
851 * @see #setLabelTable
852 * @see JComponent#updateUI
853 */
854 protected void updateLabelUIs() {
855 Dictionary<Integer, JComponent> labelTable = getLabelTable();
856
857 if (labelTable == null) {
858 return;
859 }
860 Enumeration<Integer> labels = labelTable.keys();
861 while ( labels.hasMoreElements() ) {
862 JComponent component = labelTable.get(labels.nextElement());
863 component.updateUI();
864 component.setSize(component.getPreferredSize());
865 }
866 }
867
868 private void updateLabelSizes() {
869 Dictionary<Integer, JComponent> labelTable = getLabelTable();
870 if (labelTable != null) {
871 Enumeration<JComponent> labels = labelTable.elements();
872 while (labels.hasMoreElements()) {
873 JComponent component = labels.nextElement();
874 component.setSize(component.getPreferredSize());
875 }
876 }
877 }
878
879
880 /**
881 * Creates a {@code Hashtable} of numerical text labels, starting at the
882 * slider minimum, and using the increment specified.
883 * For example, if you call <code>createStandardLabels( 10 )</code>
884 * and the slider minimum is zero,
885 * then labels will be created for the values 0, 10, 20, 30, and so on.
886 * <p>
887 * For the labels to be drawn on the slider, the returned {@code Hashtable}
888 * must be passed into {@code setLabelTable}, and {@code setPaintLabels}
889 * must be set to {@code true}.
890 * <p>
891 * For further details on the makeup of the returned {@code Hashtable}, see
1000 // Add the saved labels
1001 keys = hashtable.keys();
1002 while ( keys.hasMoreElements() ) {
1003 Integer key = keys.nextElement();
1004 put( key, hashtable.get( key ) );
1005 }
1006
1007 ((JSlider)e.getSource()).setLabelTable( this );
1008 }
1009 }
1010
1011 void createLabels() {
1012 for ( int labelIndex = start; labelIndex <= getMaximum(); labelIndex += increment ) {
1013 put( Integer.valueOf( labelIndex ), new LabelUIResource( ""+labelIndex, JLabel.CENTER ) );
1014 }
1015 }
1016 }
1017
1018 SmartHashtable table = new SmartHashtable( increment, start );
1019
1020 Dictionary<Integer, JComponent> labelTable = getLabelTable();
1021
1022 if (labelTable != null && (labelTable instanceof PropertyChangeListener)) {
1023 removePropertyChangeListener((PropertyChangeListener) labelTable);
1024 }
1025
1026 addPropertyChangeListener( table );
1027
1028 return table;
1029 }
1030
1031
1032 /**
1033 * Returns true if the value-range shown for the slider is reversed,
1034 *
1035 * @return true if the slider values are reversed from their normal order
1036 * @see #setInverted
1037 */
1038 public boolean getInverted() {
1039 return isInverted;
1040 }
|
121
122 /**
123 * If true, the knob (and the data value it represents)
124 * resolve to the closest slider value next to where the user
125 * positioned the knob.
126 */
127 boolean snapToValue = true;
128
129 /**
130 * Whether the slider is horizontal or vertical
131 * The default is horizontal.
132 *
133 * @see #setOrientation
134 */
135 protected int orientation;
136
137
138 /**
139 * {@code Dictionary} of what labels to draw at which values
140 */
141 private Dictionary<Integer, ? extends JComponent> labelTable;
142
143
144 /**
145 * The changeListener (no suffix) is the listener we add to the
146 * slider's model. This listener is initialized to the
147 * {@code ChangeListener} returned from {@code createChangeListener},
148 * which by default just forwards events
149 * to {@code ChangeListener}s (if any) added directly to the slider.
150 *
151 * @see #addChangeListener
152 * @see #createChangeListener
153 */
154 protected ChangeListener changeListener = createChangeListener();
155
156
157 /**
158 * Only one <code>ChangeEvent</code> is needed per slider instance since the
159 * event's only (read-only) state is the source property. The source
160 * of events generated here is always "this". The event is lazily
161 * created the first time that an event notification is fired.
756 /**
757 * {@inheritDoc}
758 *
759 * @since 1.6
760 */
761 public void setFont(Font font) {
762 super.setFont(font);
763 updateLabelSizes();
764 }
765
766 /**
767 * {@inheritDoc}
768 * @since 1.7
769 */
770 public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
771 if (!isShowing()) {
772 return false;
773 }
774
775 // Check that there is a label with such image
776 Enumeration<? extends JComponent> elements = labelTable.elements();
777
778 while (elements.hasMoreElements()) {
779 JComponent component = elements.nextElement();
780
781 if (component instanceof JLabel) {
782 JLabel label = (JLabel) component;
783
784 if (SwingUtilities.doesIconReferenceImage(label.getIcon(), img) ||
785 SwingUtilities.doesIconReferenceImage(label.getDisabledIcon(), img)) {
786 return super.imageUpdate(img, infoflags, x, y, w, h);
787 }
788 }
789 }
790
791 return false;
792 }
793
794 /**
795 * Returns the dictionary of what labels to draw at which values.
796 *
797 * @return the <code>Dictionary</code> containing labels and
798 * where to draw them
799 */
800 public Dictionary<Integer, ? extends JComponent> getLabelTable() {
801 /*
802 if ( labelTable == null && getMajorTickSpacing() > 0 ) {
803 setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
804 }
805 */
806 return labelTable;
807 }
808
809
810 /**
811 * Used to specify what label will be drawn at any given value.
812 * The key-value pairs are of this format:
813 * <code>{ Integer value, java.swing.JComponent label }</code>.
814 * <p>
815 * An easy way to generate a standard table of value labels is by using the
816 * {@code createStandardLabels} method.
817 * <p>
818 * Once the labels have been set, this method calls {@link #updateLabelUIs}.
819 * Note that the labels are only painted if the {@code paintLabels}
820 * property is {@code true}.
821 *
822 * @param labels new {@code Dictionary} of labels, or {@code null} to
823 * remove all labels
824 * @see #createStandardLabels(int)
825 * @see #getLabelTable
826 * @see #setPaintLabels
827 * @beaninfo
828 * hidden: true
829 * bound: true
830 * attribute: visualUpdate true
831 * description: Specifies what labels will be drawn for any given value.
832 */
833 public void setLabelTable( Dictionary<Integer, ? extends JComponent> labels ) {
834 Dictionary<Integer, ? extends JComponent> oldTable = labelTable;
835 labelTable = labels;
836 updateLabelUIs();
837 firePropertyChange("labelTable", oldTable, labelTable );
838 if (labels != oldTable) {
839 revalidate();
840 repaint();
841 }
842 }
843
844
845 /**
846 * Updates the UIs for the labels in the label table by calling
847 * {@code updateUI} on each label. The UIs are updated from
848 * the current look and feel. The labels are also set to their
849 * preferred size.
850 *
851 * @see #setLabelTable
852 * @see JComponent#updateUI
853 */
854 protected void updateLabelUIs() {
855 Dictionary<Integer, ? extends JComponent> labelTable = getLabelTable();
856
857 if (labelTable == null) {
858 return;
859 }
860 Enumeration<Integer> labels = labelTable.keys();
861 while ( labels.hasMoreElements() ) {
862 JComponent component = labelTable.get(labels.nextElement());
863 component.updateUI();
864 component.setSize(component.getPreferredSize());
865 }
866 }
867
868 private void updateLabelSizes() {
869 Dictionary<Integer, ? extends JComponent> labelTable = getLabelTable();
870 if (labelTable != null) {
871 Enumeration<? extends JComponent> labels = labelTable.elements();
872 while (labels.hasMoreElements()) {
873 JComponent component = labels.nextElement();
874 component.setSize(component.getPreferredSize());
875 }
876 }
877 }
878
879
880 /**
881 * Creates a {@code Hashtable} of numerical text labels, starting at the
882 * slider minimum, and using the increment specified.
883 * For example, if you call <code>createStandardLabels( 10 )</code>
884 * and the slider minimum is zero,
885 * then labels will be created for the values 0, 10, 20, 30, and so on.
886 * <p>
887 * For the labels to be drawn on the slider, the returned {@code Hashtable}
888 * must be passed into {@code setLabelTable}, and {@code setPaintLabels}
889 * must be set to {@code true}.
890 * <p>
891 * For further details on the makeup of the returned {@code Hashtable}, see
1000 // Add the saved labels
1001 keys = hashtable.keys();
1002 while ( keys.hasMoreElements() ) {
1003 Integer key = keys.nextElement();
1004 put( key, hashtable.get( key ) );
1005 }
1006
1007 ((JSlider)e.getSource()).setLabelTable( this );
1008 }
1009 }
1010
1011 void createLabels() {
1012 for ( int labelIndex = start; labelIndex <= getMaximum(); labelIndex += increment ) {
1013 put( Integer.valueOf( labelIndex ), new LabelUIResource( ""+labelIndex, JLabel.CENTER ) );
1014 }
1015 }
1016 }
1017
1018 SmartHashtable table = new SmartHashtable( increment, start );
1019
1020 Dictionary<Integer, ? extends JComponent> labelTable = getLabelTable();
1021
1022 if (labelTable != null && (labelTable instanceof PropertyChangeListener)) {
1023 removePropertyChangeListener((PropertyChangeListener) labelTable);
1024 }
1025
1026 addPropertyChangeListener( table );
1027
1028 return table;
1029 }
1030
1031
1032 /**
1033 * Returns true if the value-range shown for the slider is reversed,
1034 *
1035 * @return true if the slider values are reversed from their normal order
1036 * @see #setInverted
1037 */
1038 public boolean getInverted() {
1039 return isInverted;
1040 }
|