|
|
@ -37,6 +37,7 @@ import java.util.Map; |
|
|
|
import javax.swing.border.Border; |
|
|
|
import javax.swing.border.Border; |
|
|
|
|
|
|
|
|
|
|
|
import com.github.weisj.darklaf.graphics.ImageUtil; |
|
|
|
import com.github.weisj.darklaf.graphics.ImageUtil; |
|
|
|
|
|
|
|
import com.github.weisj.darklaf.util.Disposable; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Implements a DropShadow for components. In general, the DropShadowBorder will work with any rectangular components |
|
|
|
* Implements a DropShadow for components. In general, the DropShadowBorder will work with any rectangular components |
|
|
@ -93,15 +94,10 @@ public class DropShadowBorder implements Border, Serializable { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void paintBorder(final Component c, final Graphics graphics, |
|
|
|
public void paintBorder(final Component c, final Graphics graphics, |
|
|
|
final int x, final int y, final int width, final int height) { |
|
|
|
final int x, final int y, final int width, final int height) { |
|
|
|
/* |
|
|
|
final BufferedImage[] images = getImages(); |
|
|
|
* 1) Get images for this border |
|
|
|
final Graphics2D g2 = (Graphics2D) graphics.create(); |
|
|
|
* 2) Paint the images for each side of the border that should be painted |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
BufferedImage[] images = getImages((Graphics2D) graphics); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Graphics2D g2 = (Graphics2D) graphics.create(); |
|
|
|
try (Disposable d = g2::dispose) { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
// The location and size of the shadows depends on which shadows are being
|
|
|
|
// The location and size of the shadows depends on which shadows are being
|
|
|
|
// drawn. For instance, if the left & bottom shadows are being drawn, then
|
|
|
|
// drawn. For instance, if the left & bottom shadows are being drawn, then
|
|
|
|
// the left shadow extends all the way down to the corner, a corner is drawn,
|
|
|
|
// the left shadow extends all the way down to the corner, a corner is drawn,
|
|
|
@ -160,78 +156,72 @@ public class DropShadowBorder implements Border, Serializable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, |
|
|
|
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, |
|
|
|
RenderingHints.VALUE_INTERPOLATION_BICUBIC); |
|
|
|
RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
|
|
|
g2.setRenderingHint(RenderingHints.KEY_RENDERING, |
|
|
|
g2.setRenderingHint(RenderingHints.KEY_RENDERING, |
|
|
|
RenderingHints.VALUE_RENDER_SPEED); |
|
|
|
RenderingHints.VALUE_RENDER_SPEED); |
|
|
|
|
|
|
|
|
|
|
|
if (showLeftShadow) { |
|
|
|
if (showLeftShadow) { |
|
|
|
assert topLeftShadowPoint != null && bottomLeftShadowPoint != null; |
|
|
|
assert topLeftShadowPoint != null && bottomLeftShadowPoint != null; |
|
|
|
Rectangle leftShadowRect = new Rectangle(x, topLeftShadowPoint.y + shadowSize, shadowSize, |
|
|
|
drawImage(g2, images[Position.LEFT.ordinal()], |
|
|
|
bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize); |
|
|
|
x, |
|
|
|
g2.drawImage(images[Position.LEFT.ordinal()], |
|
|
|
topLeftShadowPoint.y + shadowSize, |
|
|
|
leftShadowRect.x, leftShadowRect.y, |
|
|
|
shadowSize, |
|
|
|
leftShadowRect.width, leftShadowRect.height, null); |
|
|
|
bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (showBottomShadow) { |
|
|
|
if (showBottomShadow) { |
|
|
|
assert bottomLeftShadowPoint != null && bottomRightShadowPoint != null; |
|
|
|
assert bottomLeftShadowPoint != null && bottomRightShadowPoint != null; |
|
|
|
Rectangle bottomShadowRect = new Rectangle(bottomLeftShadowPoint.x + shadowSize, |
|
|
|
drawImage(g2, images[Position.BOTTOM.ordinal()], |
|
|
|
y + height - shadowSize, |
|
|
|
bottomLeftShadowPoint.x + shadowSize, |
|
|
|
bottomRightShadowPoint.x - bottomLeftShadowPoint.x |
|
|
|
y + height - shadowSize, |
|
|
|
- shadowSize, |
|
|
|
bottomRightShadowPoint.x - bottomLeftShadowPoint.x - shadowSize, |
|
|
|
shadowSize); |
|
|
|
shadowSize); |
|
|
|
g2.drawImage(images[Position.BOTTOM.ordinal()], |
|
|
|
|
|
|
|
bottomShadowRect.x, bottomShadowRect.y, |
|
|
|
|
|
|
|
bottomShadowRect.width, bottomShadowRect.height, null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (showRightShadow) { |
|
|
|
if (showRightShadow) { |
|
|
|
assert topRightShadowPoint != null && bottomRightShadowPoint != null; |
|
|
|
assert topRightShadowPoint != null && bottomRightShadowPoint != null; |
|
|
|
Rectangle rightShadowRect = new Rectangle(x + width - shadowSize, topRightShadowPoint.y + shadowSize, |
|
|
|
drawImage(g2, images[Position.RIGHT.ordinal()], |
|
|
|
shadowSize, |
|
|
|
x + width - shadowSize, |
|
|
|
bottomRightShadowPoint.y - topRightShadowPoint.y |
|
|
|
topRightShadowPoint.y + shadowSize, |
|
|
|
- shadowSize); |
|
|
|
shadowSize, |
|
|
|
g2.drawImage(images[Position.RIGHT.ordinal()], |
|
|
|
bottomRightShadowPoint.y - topRightShadowPoint.y - shadowSize); |
|
|
|
rightShadowRect.x, rightShadowRect.y, |
|
|
|
|
|
|
|
rightShadowRect.width, rightShadowRect.height, null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (showTopShadow) { |
|
|
|
if (showTopShadow) { |
|
|
|
assert topLeftShadowPoint != null && topRightShadowPoint != null; |
|
|
|
assert topLeftShadowPoint != null && topRightShadowPoint != null; |
|
|
|
Rectangle topShadowRect = new Rectangle(topLeftShadowPoint.x + shadowSize, y, |
|
|
|
drawImage(g2, images[Position.TOP.ordinal()], |
|
|
|
topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, |
|
|
|
topLeftShadowPoint.x + shadowSize, |
|
|
|
shadowSize); |
|
|
|
y, |
|
|
|
g2.drawImage(images[Position.TOP.ordinal()], |
|
|
|
topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, |
|
|
|
topShadowRect.x, topShadowRect.y, |
|
|
|
shadowSize); |
|
|
|
topShadowRect.width, topShadowRect.height, null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (showLeftShadow || showTopShadow) { |
|
|
|
if (showLeftShadow || showTopShadow) { |
|
|
|
assert topLeftShadowPoint != null; |
|
|
|
drawImage(g2, images[Position.TOP_LEFT.ordinal()], topLeftShadowPoint); |
|
|
|
g2.drawImage(images[Position.TOP_LEFT.ordinal()], topLeftShadowPoint.x, topLeftShadowPoint.y, null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (showLeftShadow || showBottomShadow) { |
|
|
|
if (showLeftShadow || showBottomShadow) { |
|
|
|
assert bottomLeftShadowPoint != null; |
|
|
|
drawImage(g2, images[Position.BOTTOM_LEFT.ordinal()], bottomLeftShadowPoint); |
|
|
|
g2.drawImage(images[Position.BOTTOM_LEFT.ordinal()], bottomLeftShadowPoint.x, bottomLeftShadowPoint.y, |
|
|
|
|
|
|
|
null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (showRightShadow || showBottomShadow) { |
|
|
|
if (showRightShadow || showBottomShadow) { |
|
|
|
assert bottomRightShadowPoint != null; |
|
|
|
drawImage(g2, images[Position.BOTTOM_RIGHT.ordinal()], bottomRightShadowPoint); |
|
|
|
g2.drawImage(images[Position.BOTTOM_RIGHT.ordinal()], bottomRightShadowPoint.x, |
|
|
|
|
|
|
|
bottomRightShadowPoint.y, null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (showRightShadow || showTopShadow) { |
|
|
|
if (showRightShadow || showTopShadow) { |
|
|
|
assert topRightShadowPoint != null; |
|
|
|
drawImage(g2, images[Position.TOP_RIGHT.ordinal()], topRightShadowPoint); |
|
|
|
g2.drawImage(images[Position.TOP_RIGHT.ordinal()], topRightShadowPoint.x, topRightShadowPoint.y, null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} finally { |
|
|
|
|
|
|
|
g2.dispose(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("SuspiciousNameCombination") |
|
|
|
protected void drawImage(final Graphics g, final Image image, final Point p) { |
|
|
|
|
|
|
|
if (p == null) return; |
|
|
|
|
|
|
|
g.drawImage(image, p.x, p.y, null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private BufferedImage[] getImages(final Graphics2D g2) { |
|
|
|
protected void drawImage(final Graphics g, final Image image, final int x, final int y, final int w, final int h) { |
|
|
|
|
|
|
|
g.drawImage(image, x, y, w, h, null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("SuspiciousNameCombination") |
|
|
|
|
|
|
|
private BufferedImage[] getImages() { |
|
|
|
// first, check to see if an image for this size has already been rendered
|
|
|
|
// first, check to see if an image for this size has already been rendered
|
|
|
|
// if so, use the cache. Else, draw and save
|
|
|
|
// if so, use the cache. Else, draw and save
|
|
|
|
BufferedImage[] images = CACHE.get(getBorderHash(shadowSize, shadowOpacity, shadowColor)); |
|
|
|
BufferedImage[] images = CACHE.get(getBorderHash(shadowSize, shadowOpacity, shadowColor)); |
|
|
@ -258,13 +248,11 @@ public class DropShadowBorder implements Border, Serializable { |
|
|
|
BufferedImage image = ImageUtil.createCompatibleTranslucentImage(imageWidth, imageWidth); |
|
|
|
BufferedImage image = ImageUtil.createCompatibleTranslucentImage(imageWidth, imageWidth); |
|
|
|
Graphics2D buffer = (Graphics2D) image.getGraphics(); |
|
|
|
Graphics2D buffer = (Graphics2D) image.getGraphics(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try (Disposable d = buffer::dispose) { |
|
|
|
buffer.setPaint(new Color(shadowColor.getRed(), shadowColor.getGreen(), |
|
|
|
buffer.setPaint(new Color(shadowColor.getRed(), shadowColor.getGreen(), |
|
|
|
shadowColor.getBlue(), (int) (shadowOpacity * 255))); |
|
|
|
shadowColor.getBlue(), (int) (shadowOpacity * 255))); |
|
|
|
buffer.translate(shadowSize, shadowSize); |
|
|
|
buffer.translate(shadowSize, shadowSize); |
|
|
|
buffer.fill(rect); |
|
|
|
buffer.fill(rect); |
|
|
|
} finally { |
|
|
|
|
|
|
|
buffer.dispose(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float blurry = 1.0f / (float) (shadowSize * shadowSize); |
|
|
|
float blurry = 1.0f / (float) (shadowSize * shadowSize); |
|
|
@ -336,10 +324,8 @@ public class DropShadowBorder implements Border, Serializable { |
|
|
|
BufferedImage ret = ImageUtil.createCompatibleTranslucentImage(w, h); |
|
|
|
BufferedImage ret = ImageUtil.createCompatibleTranslucentImage(w, h); |
|
|
|
Graphics2D g2 = ret.createGraphics(); |
|
|
|
Graphics2D g2 = ret.createGraphics(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try (Disposable d = g2::dispose) { |
|
|
|
g2.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); |
|
|
|
g2.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); |
|
|
|
} finally { |
|
|
|
|
|
|
|
g2.dispose(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|