Draw MageRoundPane and its shadow to a buffered image and cache it across instances

Speeds up GUI performance.
This commit is contained in:
draxdyn 2016-06-01 17:00:42 +02:00
parent ffb65d48fe
commit 892cfdce45

View file

@ -1,12 +1,18 @@
package mage.client.components; package mage.client.components;
import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.Objects;
import javax.swing.JPanel; import javax.swing.JPanel;
import mage.client.util.ImageCaches;
import org.jdesktop.swingx.graphics.GraphicsUtilities; import org.jdesktop.swingx.graphics.GraphicsUtilities;
import org.jdesktop.swingx.graphics.ShadowRenderer; import org.jdesktop.swingx.graphics.ShadowRenderer;
@ -21,23 +27,145 @@ public class MageRoundPane extends JPanel {
private int X_OFFSET = 30; private int X_OFFSET = 30;
private int Y_OFFSET = 30; private int Y_OFFSET = 30;
private BufferedImage shadow = null;
private final Color defaultBackgroundColor = new Color(255, 255, 255, 200); private final Color defaultBackgroundColor = new Color(255, 255, 255, 200);
private Color backgroundColor = defaultBackgroundColor; private Color backgroundColor = defaultBackgroundColor;
private final int alpha = 0; private final int alpha = 0;
private static Map<ShadowKey, BufferedImage> SHADOW_IMAGE_CACHE;
private static Map<Key, BufferedImage> IMAGE_CACHE;
static {
SHADOW_IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<ShadowKey, BufferedImage>() {
@Override
public BufferedImage apply(ShadowKey key) {
return createShadowImage(key);
}
}));
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<Key, BufferedImage>() {
@Override
public BufferedImage apply(Key key) {
return createImage(key);
}
}));
}
private final static class ShadowKey
{
final int width;
final int height;
public ShadowKey(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + this.width;
hash = 97 * hash + this.height;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ShadowKey other = (ShadowKey) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
return true;
}
}
private final static class Key
{
final int width;
final int height;
final int xOffset;
final int yOffset;
final Color backgroundColor;
public Key(int width, int height, int xOffset, int yOffset, Color backgroundColor) {
this.width = width;
this.height = height;
this.xOffset = xOffset;
this.yOffset = yOffset;
this.backgroundColor = backgroundColor;
}
@Override
public int hashCode() {
int hash = 5;
hash = 59 * hash + this.width;
hash = 59 * hash + this.height;
hash = 59 * hash + this.xOffset;
hash = 59 * hash + this.yOffset;
hash = 59 * hash + Objects.hashCode(this.backgroundColor);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Key other = (Key) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
if (this.xOffset != other.xOffset) {
return false;
}
if (this.yOffset != other.yOffset) {
return false;
}
if (!Objects.equals(this.backgroundColor, other.backgroundColor)) {
return false;
}
return true;
}
}
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
int x = X_OFFSET; g.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), X_OFFSET, Y_OFFSET, backgroundColor)), 0, 0, null);
int y = Y_OFFSET; }
int w = getWidth() - 2 * X_OFFSET;
int h = getHeight() - 2 * Y_OFFSET; private static BufferedImage createImage(Key key) {
int x = key.xOffset;
int y = key.yOffset;
int w = key.width - 2 * key.xOffset;
int h = key.height - 2 * key.yOffset;
int arc = 10; int arc = 10;
Graphics2D g2 = (Graphics2D) g.create(); BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (shadow != null) { BufferedImage shadow = SHADOW_IMAGE_CACHE.get(new ShadowKey(w, h));
{
int xOffset = (shadow.getWidth() - w) / 2; int xOffset = (shadow.getWidth() - w) / 2;
int yOffset = (shadow.getHeight() - h) / 2; int yOffset = (shadow.getHeight() - h) / 2;
g2.drawImage(shadow, x - xOffset, y - yOffset, null); g2.drawImage(shadow, x - xOffset, y - yOffset, null);
@ -54,7 +182,7 @@ public class MageRoundPane extends JPanel {
g2.fillRoundRect(x, y, w, h, arc, arc); g2.fillRoundRect(x, y, w, h, arc, arc);
}*/ }*/
g2.setColor(backgroundColor); g2.setColor(key.backgroundColor);
g2.fillRoundRect(x, y, w, h, arc, arc); g2.fillRoundRect(x, y, w, h, arc, arc);
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -66,6 +194,7 @@ public class MageRoundPane extends JPanel {
// //////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////
g2.dispose(); g2.dispose();
return image;
} }
public void setXOffset(int x_offset) { public void setXOffset(int x_offset) {
@ -76,24 +205,21 @@ public class MageRoundPane extends JPanel {
Y_OFFSET = y_offset; Y_OFFSET = y_offset;
} }
@Override private static BufferedImage createShadowImage(ShadowKey key) {
public void setBounds(int x, int y, int width, int height) { int w = key.width;
super.setBounds(x, y, width, height); int h = key.height;
int w = getWidth() - 2 * X_OFFSET;
int h = getHeight() - 2 * Y_OFFSET;
int arc = 10; int arc = 10;
int shadowSize = 50; int shadowSize = 50;
shadow = GraphicsUtilities.createCompatibleTranslucentImage(w, h); BufferedImage base = GraphicsUtilities.createCompatibleTranslucentImage(w, h);
Graphics2D g2 = shadow.createGraphics(); Graphics2D g2 = base.createGraphics();
g2.setColor(Color.WHITE); g2.setColor(Color.WHITE);
g2.fillRoundRect(0, 0, w, h, arc, arc); g2.fillRoundRect(0, 0, w, h, arc, arc);
g2.dispose(); g2.dispose();
ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f, ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f,
Color.GRAY); Color.GRAY);
shadow = renderer.createShadow(shadow); return renderer.createShadow(base);
} }
public void showDialog(boolean bShow) { public void showDialog(boolean bShow) {