1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
package com.explodingpixels.widgets.plaf;
import com.explodingpixels.painter.Painter;
import com.explodingpixels.widgets.WindowUtils;
import java.awt.*;
/**
* An implementation of {@link Painter} that paints a scroll thumb using images.
*/
public class ScrollThumbImagePainter implements Painter<Component> {
private final ScrollBarOrientation fOrientation;
private final ImageSet fDisabledImageSet;
private final ImageSet fInactiveImageSet;
private final ImageSet fActiveImageSet;
private ScrollThumbImagePainter(
ScrollBarOrientation orientation,
Image disabledLowerBound, Image disabledMiddle, Image disabledUpperBound,
Image inactiveLowerBound, Image inactiveMiddle, Image inactiveUpperBound,
Image activeLowerBound, Image activeMiddle, Image activeUpperBound) {
// TODO add null checking.
fOrientation = orientation;
fDisabledImageSet = new ImageSet(disabledLowerBound, disabledMiddle, disabledUpperBound);
fInactiveImageSet = new ImageSet(inactiveLowerBound, inactiveMiddle, inactiveUpperBound);
fActiveImageSet = new ImageSet(activeLowerBound, activeMiddle, activeUpperBound);
}
/**
* Creates an image-based vertical scroll thumb painter using the given images. Lower bound
* refers to the area closest to the minimum value (top or left). Upper bound refers to the area
* closest to the maximum value (bottom or right).
*
* @param disabledLowerBound the lower bound disabled image.
* @param disabledMiddle the middle disabled image.
* @param disabledUpperBound the upper bound disabled image.
* @param inactiveLowerBound the lower bound inactiveimage
* @param inactiveMiddle the middle inactive image
* @param inactiveUpperBound the upper bound inactive image.
* @param activeLowerBound the lower bound active image.
* @param activeMiddle the middle active image.
* @param activeUpperBound the upper bound active image.
* @return a state based (disabled or inactive or active) scroll thumb painter.
*/
public static ScrollThumbImagePainter createVerticalScrollThumbImagePainter(
Image disabledLowerBound, Image disabledMiddle, Image disabledUpperBound,
Image inactiveLowerBound, Image inactiveMiddle, Image inactiveUpperBound,
Image activeLowerBound, Image activeMiddle, Image activeUpperBound) {
return new ScrollThumbImagePainter(ScrollBarOrientation.VERTICAL, disabledLowerBound,
disabledMiddle, disabledUpperBound, inactiveLowerBound, inactiveMiddle,
inactiveUpperBound, activeLowerBound, activeMiddle, activeUpperBound);
}
/**
* Creates an image-based horizontal scroll thumb painter using the given images. Lower bound
* refers to the area closest to the minimum value (top or left). Upper bound refers to the area
* closest to the maximum value (bottom or right).
*
* @param disabledLowerBound the lower bound disabled image.
* @param disabledMiddle the middle disabled image.
* @param disabledUpperBound the upper bound disabled image.
* @param inactiveLowerBound the lower bound inactiveimage
* @param inactiveMiddle the middle inactive image
* @param inactiveUpperBound the upper bound inactive image.
* @param activeLowerBound the lower bound active image.
* @param activeMiddle the middle active image.
* @param activeUpperBound the upper bound active image.
* @return a state based (disabled or inactive or active) scroll thumb painter.
*/
public static ScrollThumbImagePainter createHorizontalScrollThumbImagePainter(
Image disabledLowerBound, Image disabledMiddle, Image disabledUpperBound,
Image inactiveLowerBound, Image inactiveMiddle, Image inactiveUpperBound,
Image activeLowerBound, Image activeMiddle, Image activeUpperBound) {
return new ScrollThumbImagePainter(ScrollBarOrientation.HORIZONTAL, disabledLowerBound,
disabledMiddle, disabledUpperBound, inactiveLowerBound, inactiveMiddle,
inactiveUpperBound, activeLowerBound, activeMiddle, activeUpperBound);
}
private ImageSet getImageSet(Component objectToPaint) {
ImageSet retVal;
if (!objectToPaint.isEnabled()) {
retVal = fDisabledImageSet;
} else if (WindowUtils.isParentWindowFocused(objectToPaint)) {
retVal = fActiveImageSet;
} else {
retVal = fInactiveImageSet;
}
return retVal;
}
public void paint(Graphics2D graphics, Component objectToPaint, int width, int height) {
ImageSet imageSet = getImageSet(objectToPaint);
// grab the size of the scroll bar in dimension agnostic terms.
Dimension scrollerSize = new Dimension(width, height);
int scrollerLength = fOrientation.getLength(scrollerSize);
int scrollerThickness = fOrientation.getThickness(imageSet.getLowerBoundImageSize());
// calculate the starting point of the lower bound image in dimension agnostic terms, such
// that the image is draw centered in the containing component. note that we pass in -1 for
// the length of the resultant bounds rectangle as we don't care about creating a second
// coordinate.
int lowerPosition = 0;
Point lowerPoint = fOrientation.createCenteredBounds(
objectToPaint, lowerPosition, scrollerThickness, -1).getLocation();
graphics.drawImage(imageSet.getLowerBoundImage(), lowerPoint.x, lowerPoint.y, null);
// calculate the starting point of the middle bound image in dimension agnostic terms. start
// by determing the position (the value in the scrolling dimension) and length to draw the
// image. then create bounds from that position and length.
int upperLength = fOrientation.getLength(imageSet.getUpperBoundImageSize());
int middleStartPosition = fOrientation.getLength(imageSet.getLowerBoundImageSize());
int middleEndPosition = scrollerLength - upperLength;
int middleLength = middleEndPosition - middleStartPosition;
Rectangle middleBounds = fOrientation.createCenteredBounds(
objectToPaint, middleStartPosition, scrollerThickness, middleLength);
Image middleImage = imageSet.getMiddleImage();
graphics.drawImage(middleImage, middleBounds.x, middleBounds.y,
middleBounds.x + middleBounds.width, middleBounds.y + middleBounds.height,
0, 0, middleImage.getWidth(null), middleImage.getHeight(null), null);
// calculate the position (the value in the scrolling dimension) of the upper bound image,
// such that the image is draw centered in the containing component. note that we pass in -1
// for the length of the resultant bounds rectangle as we don't care about creating a second
// coordinate.
int upperPosition = scrollerLength - upperLength;
Point upperPoint = fOrientation.createCenteredBounds(
objectToPaint, upperPosition, scrollerThickness, -1).getLocation();
graphics.drawImage(imageSet.getUpperBoundImage(), upperPoint.x, upperPoint.y, null);
}
// ImageSet implementation. ///////////////////////////////////////////////////////////////////
private static class ImageSet {
private final Image fLowerBoundImage;
private final Image fMiddleImage;
private final Image fUpperBoundImage;
private Dimension fLowerBoundImageSize;
private Dimension fMiddleBoundImageSize;
private Dimension fUppoerBoundImageSize;
private ImageSet(Image lowerBoundImage, Image middleImage, Image upperBoundImage) {
fLowerBoundImage = lowerBoundImage;
fMiddleImage = middleImage;
fUpperBoundImage = upperBoundImage;
fLowerBoundImageSize = createImageSize(fLowerBoundImage);
fMiddleBoundImageSize = createImageSize(fMiddleImage);
fUppoerBoundImageSize = createImageSize(fUpperBoundImage);
}
public Image getLowerBoundImage() {
return fLowerBoundImage;
}
public Image getMiddleImage() {
return fMiddleImage;
}
public Image getUpperBoundImage() {
return fUpperBoundImage;
}
public Dimension getLowerBoundImageSize() {
return fLowerBoundImageSize;
}
public Dimension getMiddleBoundImageSize() {
return fMiddleBoundImageSize;
}
public Dimension getUpperBoundImageSize() {
return fUppoerBoundImageSize;
}
private static Dimension createImageSize(Image image) {
return new Dimension(image.getWidth(null), image.getHeight(null));
}
}
}
|