|
|
|
@ -20,13 +20,10 @@
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
|
|
|
* SOFTWARE. |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
package com.github.weisj.darklaf.components.border; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.github.weisj.darklaf.util.ImageUtil; |
|
|
|
|
|
|
|
|
|
import javax.swing.border.Border; |
|
|
|
|
import java.awt.*; |
|
|
|
|
import java.awt.geom.RoundRectangle2D; |
|
|
|
|
import java.awt.image.BufferedImage; |
|
|
|
@ -37,17 +34,24 @@ import java.util.Arrays;
|
|
|
|
|
import java.util.HashMap; |
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
import javax.swing.border.Border; |
|
|
|
|
|
|
|
|
|
import com.github.weisj.darklaf.util.ImageUtil; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Implements a DropShadow for components. In general, the DropShadowBorder will work with any rectangular components |
|
|
|
|
* that do not have a default border installed as part of the look and feel, or otherwise. For example, DropShadowBorder |
|
|
|
|
* works wonderfully with JPanel, but horribly with JComboBox. |
|
|
|
|
* <p> |
|
|
|
|
* Note: {@code DropShadowBorder} should usually be added to non-opaque components, otherwise the background is likely |
|
|
|
|
* to bleed through.</p> |
|
|
|
|
* <p>Note: Since generating drop shadows is relatively expensive operation, |
|
|
|
|
* to bleed through. |
|
|
|
|
* </p> |
|
|
|
|
* <p> |
|
|
|
|
* Note: Since generating drop shadows is relatively expensive operation, |
|
|
|
|
* {@code DropShadowBorder} keeps internal static cache that allows sharing same border for multiple re-rendering and |
|
|
|
|
* between different instances of the class. Since this cache is shared at class level and never reset, it might bleed |
|
|
|
|
* your app memory in case you tend to create many different borders rapidly.</p> |
|
|
|
|
* your app memory in case you tend to create many different borders rapidly. |
|
|
|
|
* </p> |
|
|
|
|
* |
|
|
|
|
* @author rbair Adaptions made by |
|
|
|
|
* @author Jannis Weis |
|
|
|
@ -63,18 +67,15 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
private boolean showBottomShadow; |
|
|
|
|
private boolean showRightShadow; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public DropShadowBorder() { |
|
|
|
|
this(Color.BLACK, 5); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public DropShadowBorder(final Color shadowColor, final int shadowSize) { |
|
|
|
|
this(shadowColor, shadowSize, .5f, 12, false, true, |
|
|
|
|
true, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public DropShadowBorder(final Color shadowColor, final int shadowSize, |
|
|
|
|
final float shadowOpacity, final int cornerSize, final boolean showTopShadow, |
|
|
|
|
final boolean showLeftShadow, final boolean showBottomShadow, |
|
|
|
@ -89,7 +90,6 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
setShowRightShadow(showRightShadow); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void paintBorder(final Component c, final Graphics graphics, |
|
|
|
|
final int x, final int y, final int width, final int height) { |
|
|
|
@ -166,8 +166,7 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
|
|
|
|
|
if (showLeftShadow) { |
|
|
|
|
assert topLeftShadowPoint != null && bottomLeftShadowPoint != null; |
|
|
|
|
Rectangle leftShadowRect = |
|
|
|
|
new Rectangle(x, topLeftShadowPoint.y + shadowSize, shadowSize, |
|
|
|
|
Rectangle leftShadowRect = new Rectangle(x, topLeftShadowPoint.y + shadowSize, shadowSize, |
|
|
|
|
bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize); |
|
|
|
|
g2.drawImage(images[Position.LEFT.ordinal()], |
|
|
|
|
leftShadowRect.x, leftShadowRect.y, |
|
|
|
@ -176,9 +175,10 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
|
|
|
|
|
if (showBottomShadow) { |
|
|
|
|
assert bottomLeftShadowPoint != null && bottomRightShadowPoint != null; |
|
|
|
|
Rectangle bottomShadowRect = |
|
|
|
|
new Rectangle(bottomLeftShadowPoint.x + shadowSize, y + height - shadowSize, |
|
|
|
|
bottomRightShadowPoint.x - bottomLeftShadowPoint.x - shadowSize, |
|
|
|
|
Rectangle bottomShadowRect = new Rectangle(bottomLeftShadowPoint.x + shadowSize, |
|
|
|
|
y + height - shadowSize, |
|
|
|
|
bottomRightShadowPoint.x - bottomLeftShadowPoint.x |
|
|
|
|
- shadowSize, |
|
|
|
|
shadowSize); |
|
|
|
|
g2.drawImage(images[Position.BOTTOM.ordinal()], |
|
|
|
|
bottomShadowRect.x, bottomShadowRect.y, |
|
|
|
@ -187,9 +187,10 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
|
|
|
|
|
if (showRightShadow) { |
|
|
|
|
assert topRightShadowPoint != null && bottomRightShadowPoint != null; |
|
|
|
|
Rectangle rightShadowRect = |
|
|
|
|
new Rectangle(x + width - shadowSize, topRightShadowPoint.y + shadowSize, shadowSize, |
|
|
|
|
bottomRightShadowPoint.y - topRightShadowPoint.y - shadowSize); |
|
|
|
|
Rectangle rightShadowRect = new Rectangle(x + width - shadowSize, topRightShadowPoint.y + shadowSize, |
|
|
|
|
shadowSize, |
|
|
|
|
bottomRightShadowPoint.y - topRightShadowPoint.y |
|
|
|
|
- shadowSize); |
|
|
|
|
g2.drawImage(images[Position.RIGHT.ordinal()], |
|
|
|
|
rightShadowRect.x, rightShadowRect.y, |
|
|
|
|
rightShadowRect.width, rightShadowRect.height, null); |
|
|
|
@ -197,9 +198,9 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
|
|
|
|
|
if (showTopShadow) { |
|
|
|
|
assert topLeftShadowPoint != null && topRightShadowPoint != null; |
|
|
|
|
Rectangle topShadowRect = |
|
|
|
|
new Rectangle(topLeftShadowPoint.x + shadowSize, y, |
|
|
|
|
topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, shadowSize); |
|
|
|
|
Rectangle topShadowRect = new Rectangle(topLeftShadowPoint.x + shadowSize, y, |
|
|
|
|
topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, |
|
|
|
|
shadowSize); |
|
|
|
|
g2.drawImage(images[Position.TOP.ordinal()], |
|
|
|
|
topShadowRect.x, topShadowRect.y, |
|
|
|
|
topShadowRect.width, topShadowRect.height, null); |
|
|
|
@ -331,7 +332,6 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
* Returns a new BufferedImage that represents a subregion of the given BufferedImage. (Note that this method does |
|
|
|
|
* not use BufferedImage.getSubimage(), which will defeat image acceleration strategies on later JDKs.) |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
private BufferedImage getSubImage(final BufferedImage img, final int x, final int y, final int w, final int h) { |
|
|
|
|
BufferedImage ret = ImageUtil.createCompatibleTranslucentImage(w, h); |
|
|
|
|
Graphics2D g2 = ret.createGraphics(); |
|
|
|
@ -437,12 +437,17 @@ public class DropShadowBorder implements Border, Serializable {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private enum Position { |
|
|
|
|
TOP, TOP_LEFT, LEFT, BOTTOM_LEFT, |
|
|
|
|
BOTTOM, BOTTOM_RIGHT, RIGHT, TOP_RIGHT; |
|
|
|
|
TOP, |
|
|
|
|
TOP_LEFT, |
|
|
|
|
LEFT, |
|
|
|
|
BOTTOM_LEFT, |
|
|
|
|
BOTTOM, |
|
|
|
|
BOTTOM_RIGHT, |
|
|
|
|
RIGHT, |
|
|
|
|
TOP_RIGHT; |
|
|
|
|
|
|
|
|
|
static int count() { |
|
|
|
|
return 8; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|