mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
Draw CardPanel to a buffered image and cache it across instances
Speeds up GUI performance.
This commit is contained in:
parent
892cfdce45
commit
b8e5f5f942
1 changed files with 133 additions and 7 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
package org.mage.card.arcane;
|
package org.mage.card.arcane;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.MapMaker;
|
||||||
import java.awt.AlphaComposite;
|
import java.awt.AlphaComposite;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
|
@ -23,6 +25,7 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
|
|
@ -38,6 +41,7 @@ import mage.cards.action.TransferData;
|
||||||
import mage.client.dialog.PreferencesDialog;
|
import mage.client.dialog.PreferencesDialog;
|
||||||
import mage.client.plugins.adapters.MageActionCallback;
|
import mage.client.plugins.adapters.MageActionCallback;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
|
import mage.client.util.ImageCaches;
|
||||||
import mage.client.util.ImageHelper;
|
import mage.client.util.ImageHelper;
|
||||||
import mage.client.util.audio.AudioManager;
|
import mage.client.util.audio.AudioManager;
|
||||||
import mage.components.ImagePanel;
|
import mage.components.ImagePanel;
|
||||||
|
|
@ -52,6 +56,7 @@ import mage.view.PermanentView;
|
||||||
import mage.view.StackAbilityView;
|
import mage.view.StackAbilityView;
|
||||||
import net.java.truevfs.access.TFile;
|
import net.java.truevfs.access.TFile;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||||
import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL;
|
import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL;
|
||||||
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
|
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
|
||||||
import org.mage.plugins.card.images.ImageCache;
|
import org.mage.plugins.card.images.ImageCache;
|
||||||
|
|
@ -158,6 +163,111 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
// if this is set, it's opened if the user right clicks on the card panel
|
// if this is set, it's opened if the user right clicks on the card panel
|
||||||
private JPopupMenu popupMenu;
|
private JPopupMenu popupMenu;
|
||||||
|
|
||||||
|
private static Map<Key, BufferedImage> IMAGE_CACHE;
|
||||||
|
|
||||||
|
private final static class Key
|
||||||
|
{
|
||||||
|
final int width;
|
||||||
|
final int height;
|
||||||
|
final int cardWidth;
|
||||||
|
final int cardHeight;
|
||||||
|
final int cardXOffset;
|
||||||
|
final int cardYOffset;
|
||||||
|
final boolean hasImage;
|
||||||
|
final boolean isSelected;
|
||||||
|
final boolean isChoosable;
|
||||||
|
final boolean isPlayable;
|
||||||
|
final boolean canAttack;
|
||||||
|
|
||||||
|
public Key(int width, int height, int cardWidth, int cardHeight, int cardXOffset, int cardYOffset, boolean hasImage, boolean isSelected, boolean isChoosable, boolean isPlayable, boolean canAttack) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.cardWidth = cardWidth;
|
||||||
|
this.cardHeight = cardHeight;
|
||||||
|
this.cardXOffset = cardXOffset;
|
||||||
|
this.cardYOffset = cardYOffset;
|
||||||
|
this.hasImage = hasImage;
|
||||||
|
this.isSelected = isSelected;
|
||||||
|
this.isChoosable = isChoosable;
|
||||||
|
this.isPlayable = isPlayable;
|
||||||
|
this.canAttack = canAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 3;
|
||||||
|
hash = 19 * hash + this.width;
|
||||||
|
hash = 19 * hash + this.height;
|
||||||
|
hash = 19 * hash + this.cardWidth;
|
||||||
|
hash = 19 * hash + this.cardHeight;
|
||||||
|
hash = 19 * hash + this.cardXOffset;
|
||||||
|
hash = 19 * hash + this.cardYOffset;
|
||||||
|
hash = 19 * hash + (this.hasImage ? 1 : 0);
|
||||||
|
hash = 19 * hash + (this.isSelected ? 1 : 0);
|
||||||
|
hash = 19 * hash + (this.isChoosable ? 1 : 0);
|
||||||
|
hash = 19 * hash + (this.isPlayable ? 1 : 0);
|
||||||
|
hash = 19 * hash + (this.canAttack ? 1 : 0);
|
||||||
|
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.cardWidth != other.cardWidth) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.cardHeight != other.cardHeight) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.cardXOffset != other.cardXOffset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.cardYOffset != other.cardYOffset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.hasImage != other.hasImage) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isSelected != other.isSelected) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isChoosable != other.isChoosable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isPlayable != other.isPlayable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.canAttack != other.canAttack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<Key, BufferedImage>() {
|
||||||
|
@Override
|
||||||
|
public BufferedImage apply(Key key) {
|
||||||
|
return createImage(key);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
public CardPanel(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) {
|
public CardPanel(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) {
|
||||||
this.gameCard = newGameCard;
|
this.gameCard = newGameCard;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
|
@ -475,15 +585,28 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
Graphics2D g2d = (Graphics2D)(g.create());
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
|
|
||||||
if (alpha != 1.0f) {
|
if (alpha != 1.0f) {
|
||||||
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
|
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
|
||||||
g2d.setComposite(composite);
|
g2d.setComposite(composite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasImage) {
|
g2d.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), cardWidth, cardHeight, cardXOffset, cardYOffset, hasImage, isSelected, isChoosable, isPlayable, canAttack)), 0, 0, null);
|
||||||
|
g2d.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BufferedImage createImage(Key key) {
|
||||||
|
int cardWidth = key.cardWidth;
|
||||||
|
int cardHeight = key.cardHeight;
|
||||||
|
int cardXOffset = key.cardXOffset;
|
||||||
|
int cardYOffset = key.cardYOffset;
|
||||||
|
|
||||||
|
BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height);
|
||||||
|
Graphics2D g2d = image.createGraphics();
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
if (!key.hasImage) {
|
||||||
g2d.setColor(new Color(30, 200, 200, 120));
|
g2d.setColor(new Color(30, 200, 200, 120));
|
||||||
} else {
|
} else {
|
||||||
g2d.setColor(new Color(0, 0, 0, 0));
|
g2d.setColor(new Color(0, 0, 0, 0));
|
||||||
|
|
@ -492,19 +615,19 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
int cornerSize = Math.max(4, Math.round(cardWidth * ROUNDED_CORNER_SIZE));
|
int cornerSize = Math.max(4, Math.round(cardWidth * ROUNDED_CORNER_SIZE));
|
||||||
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
|
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
|
||||||
|
|
||||||
if (isSelected) {
|
if (key.isSelected) {
|
||||||
g2d.setColor(Color.green);
|
g2d.setColor(Color.green);
|
||||||
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
||||||
} else if (isChoosable) {
|
} else if (key.isChoosable) {
|
||||||
g2d.setColor(new Color(250, 250, 0, 230));
|
g2d.setColor(new Color(250, 250, 0, 230));
|
||||||
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
||||||
} else if (isPlayable) {
|
} else if (key.isPlayable) {
|
||||||
g2d.setColor(new Color(153, 102, 204, 200));
|
g2d.setColor(new Color(153, 102, 204, 200));
|
||||||
//g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
//g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
||||||
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
|
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canAttack) {
|
if (key.canAttack) {
|
||||||
g2d.setColor(new Color(0, 0, 255, 230));
|
g2d.setColor(new Color(0, 0, 255, 230));
|
||||||
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
||||||
}
|
}
|
||||||
|
|
@ -515,6 +638,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
|
||||||
g2d.setColor(new Color(200,10,10,200));
|
g2d.setColor(new Color(200,10,10,200));
|
||||||
g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize);
|
g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize);
|
||||||
}*/
|
}*/
|
||||||
|
g2d.dispose();
|
||||||
|
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue