58 |
import java.beans.PropertyChangeListener; |
import java.beans.PropertyChangeListener; |
59 |
import java.util.Dictionary; |
import java.util.Dictionary; |
60 |
import java.util.Enumeration; |
import java.util.Enumeration; |
|
|
|
61 |
import javax.swing.BoundedRangeModel; |
import javax.swing.BoundedRangeModel; |
62 |
import javax.swing.JComponent; |
import javax.swing.JComponent; |
63 |
import javax.swing.JLabel; |
import javax.swing.JLabel; |
151 |
{ |
{ |
152 |
// Maximum, minimum, and extent values will be taken |
// Maximum, minimum, and extent values will be taken |
153 |
// care of automatically when the slider is repainted. |
// care of automatically when the slider is repainted. |
|
|
|
154 |
// Only thing that needs recalculation is the thumb. |
// Only thing that needs recalculation is the thumb. |
155 |
calculateThumbLocation(); |
calculateThumbLocation(); |
156 |
slider.repaint(); |
slider.repaint(); |
230 |
slider.getModel().addChangeListener(changeListener); |
slider.getModel().addChangeListener(changeListener); |
231 |
calculateThumbLocation(); |
calculateThumbLocation(); |
232 |
} |
} |
233 |
|
|
234 |
// elif the componentOrientation changes (this is a bound property, |
// elif the componentOrientation changes (this is a bound property, |
235 |
// just undocumented) we change leftToRightCache. In Sun's |
// just undocumented) we change leftToRightCache. In Sun's |
236 |
// implementation, the LTR cache changes on a repaint. This is strange |
// implementation, the LTR cache changes on a repaint. This is strange |
237 |
// since there is no need to do so. We could events here and |
// since there is no need to do so. We could events here and |
238 |
// update the cache. |
// update the cache. |
|
|
|
239 |
// elif the border/insets change, we recalculateInsets. |
// elif the border/insets change, we recalculateInsets. |
240 |
slider.repaint(); |
slider.repaint(); |
241 |
} |
} |
328 |
/** The current Y position of the mouse. */ |
/** The current Y position of the mouse. */ |
329 |
protected int currentMouseY; |
protected int currentMouseY; |
330 |
|
|
331 |
/** The offset between the current slider value |
/** |
332 |
and the cursor's position. */ |
* The offset between the current slider value and the cursor's position. |
333 |
|
*/ |
334 |
protected int offset; |
protected int offset; |
335 |
|
|
336 |
/** |
/** |
389 |
if (slider.getSnapToTicks()) |
if (slider.getSnapToTicks()) |
390 |
value = findClosestTick(value); |
value = findClosestTick(value); |
391 |
|
|
|
if (value == slider.getValue()) |
|
|
return; |
|
|
|
|
392 |
// If the thumb is hit, then we don't need to set the timers to move it. |
// If the thumb is hit, then we don't need to set the timers to move it. |
393 |
if (!thumbRect.contains(e.getPoint())) |
if (!thumbRect.contains(e.getPoint())) |
394 |
{ |
{ |
853 |
*/ |
*/ |
854 |
|
|
855 |
/** |
/** |
856 |
* This method returns the preferred size when the slider is |
* This method returns the preferred size when the slider is horizontally |
857 |
* horizontally oriented. |
* oriented. |
858 |
* |
* |
859 |
* @return The dimensions of the preferred horizontal size. |
* @return The dimensions of the preferred horizontal size. |
860 |
*/ |
*/ |
864 |
|
|
865 |
// The width should cover all the labels (which are usually the |
// The width should cover all the labels (which are usually the |
866 |
// deciding factor of the width) |
// deciding factor of the width) |
867 |
int width = getWidthOfWidestLabel() * (slider.getLabelTable() == null ? |
int width = getWidthOfWidestLabel() * (slider.getLabelTable() == null ? 0 |
868 |
0 : slider.getLabelTable().size()); |
: slider.getLabelTable() |
869 |
|
.size()); |
870 |
|
|
871 |
// If there are not enough labels. |
// If there are not enough labels. |
872 |
// This number is pretty much arbitrary, but it looks nice. |
// This number is pretty much arbitrary, but it looks nice. |
875 |
|
|
876 |
// We can only draw inside of the focusRectangle, so we have to |
// We can only draw inside of the focusRectangle, so we have to |
877 |
// pad it with insets. |
// pad it with insets. |
878 |
width += insets.left + insets.right + focusInsets.left + |
width += insets.left + insets.right + focusInsets.left + focusInsets.right; |
|
focusInsets.right; |
|
879 |
|
|
880 |
// Height is determined by the thumb, the ticks and the labels. |
// Height is determined by the thumb, the ticks and the labels. |
881 |
int height = thumbHeight; |
int height = thumbHeight; |
882 |
|
|
883 |
if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0 || |
if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0 |
884 |
slider.getMinorTickSpacing() > 0) |
|| slider.getMinorTickSpacing() > 0) |
885 |
height += tickHeight; |
height += tickHeight; |
886 |
|
|
887 |
if (slider.getPaintLabels()) |
if (slider.getPaintLabels()) |
888 |
height += getHeightOfTallestLabel(); |
height += getHeightOfTallestLabel(); |
889 |
|
|
890 |
height += insets.top + insets.bottom + focusInsets.top + |
height += insets.top + insets.bottom + focusInsets.top |
891 |
focusInsets.bottom; |
+ focusInsets.bottom; |
892 |
|
|
893 |
return new Dimension(width, height); |
return new Dimension(width, height); |
894 |
} |
} |
895 |
|
|
896 |
/** |
/** |
897 |
* This method returns the preferred size when the slider is |
* This method returns the preferred size when the slider is vertically |
898 |
* vertically oriented. |
* oriented. |
899 |
* |
* |
900 |
* @return The dimensions of the preferred vertical size. |
* @return The dimensions of the preferred vertical size. |
901 |
*/ |
*/ |
903 |
{ |
{ |
904 |
Insets insets = slider.getInsets(); |
Insets insets = slider.getInsets(); |
905 |
|
|
906 |
int height = getHeightOfTallestLabel() * (slider.getLabelTable() == null ? |
int height = getHeightOfTallestLabel() * (slider.getLabelTable() == null |
907 |
0 : slider.getLabelTable().size()); |
? 0 : slider.getLabelTable() |
908 |
|
.size()); |
909 |
|
|
910 |
if (height < 200) |
if (height < 200) |
911 |
height = 200; |
height = 200; |
912 |
|
|
913 |
height += insets.top + insets.bottom + focusInsets.top + |
height += insets.top + insets.bottom + focusInsets.top |
914 |
focusInsets.bottom; |
+ focusInsets.bottom; |
915 |
|
|
916 |
int width = thumbHeight; |
int width = thumbHeight; |
917 |
|
|
918 |
if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0 || |
if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0 |
919 |
slider.getMinorTickSpacing() > 0) |
|| slider.getMinorTickSpacing() > 0) |
920 |
width += tickHeight; |
width += tickHeight; |
921 |
|
|
922 |
if (slider.getPaintLabels()) |
if (slider.getPaintLabels()) |
923 |
width += getWidthOfWidestLabel(); |
width += getWidthOfWidestLabel(); |
924 |
|
|
925 |
width += insets.left + insets.right + focusInsets.left + |
width += insets.left + insets.right + focusInsets.left + focusInsets.right; |
|
focusInsets.right; |
|
926 |
|
|
927 |
return new Dimension(width, height); |
return new Dimension(width, height); |
928 |
} |
} |
929 |
|
|
930 |
/** |
/** |
931 |
* This method returns the minimum size when the slider is |
* This method returns the minimum size when the slider is horizontally |
932 |
* horizontally oriented. |
* oriented. |
933 |
* |
* |
934 |
* @return The dimensions of the minimum horizontal size. |
* @return The dimensions of the minimum horizontal size. |
935 |
*/ |
*/ |
939 |
} |
} |
940 |
|
|
941 |
/** |
/** |
942 |
* This method returns the minimum size of the slider when it |
* This method returns the minimum size of the slider when it is vertically |
943 |
* is vertically oriented. |
* oriented. |
944 |
* |
* |
945 |
* @return The dimensions of the minimum vertical size. |
* @return The dimensions of the minimum vertical size. |
946 |
*/ |
*/ |
1001 |
} |
} |
1002 |
|
|
1003 |
/** |
/** |
1004 |
* This method calculates all the sizes of the rectangles by delegating |
* This method calculates all the sizes of the rectangles by delegating to |
1005 |
* to the helper methods calculateXXXRect. |
* the helper methods calculateXXXRect. |
1006 |
*/ |
*/ |
1007 |
protected void calculateGeometry() |
protected void calculateGeometry() |
1008 |
{ |
{ |
1535 |
c.translate((trackRect.width / 2) + (width / 2), trackRect.height); |
c.translate((trackRect.width / 2) + (width / 2), trackRect.height); |
1536 |
d.translate((trackRect.width / 2) + (width / 2), 0); |
d.translate((trackRect.width / 2) + (width / 2), 0); |
1537 |
} |
} |
1538 |
high = new Polygon(new int[] { b.x, c.x, d.x }, |
g.setColor(Color.GRAY); |
1539 |
new int[] { b.y, c.y, d.y }, 3); |
g.fillRect(a.x, a.y, width, height); |
|
shadow = new Polygon(new int[] { b.x, a.x, d.x }, |
|
|
new int[] { b.y, a.y, d.y }, 3); |
|
1540 |
|
|
1541 |
g.setColor(getHighlightColor()); |
g.setColor(getHighlightColor()); |
1542 |
g.drawPolygon(high); |
g.drawLine(b.x, b.y, c.x, c.y); |
1543 |
|
g.drawLine(c.x, c.y, d.x, d.y); |
1544 |
|
|
1545 |
g.setColor(getShadowColor()); |
g.setColor(getShadowColor()); |
1546 |
g.drawPolygon(shadow); |
g.drawLine(b.x, b.y, a.x, a.y); |
1547 |
|
g.drawLine(a.x, a.y, d.x, d.y); |
1548 |
|
|
|
g.setColor(Color.GRAY); |
|
|
g.fillRect(a.x + 1, a.y + 1, width - 2, height - 2); |
|
1549 |
g.setColor(saved_color); |
g.setColor(saved_color); |
1550 |
} |
} |
1551 |
|
|
1657 |
Rectangle tickBounds, int x) |
Rectangle tickBounds, int x) |
1658 |
{ |
{ |
1659 |
int y = tickRect.y + tickRect.height / 4; |
int y = tickRect.y + tickRect.height / 4; |
1660 |
|
Color saved = g.getColor(); |
1661 |
|
g.setColor(Color.BLACK); |
1662 |
|
|
1663 |
g.drawLine(x, y, x, y + tickRect.height / 4); |
g.drawLine(x, y, x, y + tickRect.height / 4); |
1664 |
|
g.setColor(saved); |
1665 |
} |
} |
1666 |
|
|
1667 |
/** |
/** |
1676 |
Rectangle tickBounds, int x) |
Rectangle tickBounds, int x) |
1677 |
{ |
{ |
1678 |
int y = tickRect.y + tickRect.height / 4; |
int y = tickRect.y + tickRect.height / 4; |
1679 |
|
Color saved = g.getColor(); |
1680 |
|
g.setColor(Color.BLACK); |
1681 |
|
|
1682 |
g.drawLine(x, y, x, y + tickRect.height / 2); |
g.drawLine(x, y, x, y + tickRect.height / 2); |
1683 |
|
g.setColor(saved); |
1684 |
} |
} |
1685 |
|
|
1686 |
/** |
/** |
1695 |
int y) |
int y) |
1696 |
{ |
{ |
1697 |
int x = tickRect.x + tickRect.width / 4; |
int x = tickRect.x + tickRect.width / 4; |
1698 |
|
Color saved = g.getColor(); |
1699 |
|
g.setColor(Color.BLACK); |
1700 |
|
|
1701 |
g.drawLine(x, y, x + tickRect.width / 4, y); |
g.drawLine(x, y, x + tickRect.width / 4, y); |
1702 |
|
g.setColor(saved); |
1703 |
} |
} |
1704 |
|
|
1705 |
/** |
/** |
1714 |
int y) |
int y) |
1715 |
{ |
{ |
1716 |
int x = tickRect.x + tickRect.width / 4; |
int x = tickRect.x + tickRect.width / 4; |
1717 |
|
Color saved = g.getColor(); |
1718 |
|
g.setColor(Color.BLACK); |
1719 |
|
|
1720 |
g.drawLine(x, y, x + tickRect.width / 2, y); |
g.drawLine(x, y, x + tickRect.width / 2, y); |
1721 |
|
g.setColor(saved); |
1722 |
} |
} |
1723 |
|
|
1724 |
/** |
/** |
1793 |
// the labels may not fit inside the slider's bounds. Rather than mucking |
// the labels may not fit inside the slider's bounds. Rather than mucking |
1794 |
// with font sizes and possible icon sizes, we'll set the bounds for |
// with font sizes and possible icon sizes, we'll set the bounds for |
1795 |
// the label and let it get clipped. |
// the label and let it get clipped. |
|
|
|
1796 |
Dimension dim = label.getPreferredSize(); |
Dimension dim = label.getPreferredSize(); |
1797 |
int w = (int) dim.getWidth(); |
int w = (int) dim.getWidth(); |
1798 |
int h = (int) dim.getHeight(); |
int h = (int) dim.getHeight(); |
1810 |
// | | |
// | | |
1811 |
// | | |
// | | |
1812 |
// The label must move w/2 to the right to fit directly under the value. |
// The label must move w/2 to the right to fit directly under the value. |
|
|
|
|
|
|
1813 |
int xpos = xPositionForValue(value) - w / 2; |
int xpos = xPositionForValue(value) - w / 2; |
1814 |
int ypos = labelRect.y; |
int ypos = labelRect.y; |
1815 |
|
|