mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
Draw MageRoundPane and its shadow to a buffered image and cache it across instances
Speeds up GUI performance.
This commit is contained in:
parent
ffb65d48fe
commit
892cfdce45
1 changed files with 143 additions and 17 deletions
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue