/**
* Copyright (C) 2002-2012 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.client.gui.panel;
import org.freecolandroid.repackaged.java.awt.Component;
import org.freecolandroid.repackaged.java.awt.Graphics;
import org.freecolandroid.repackaged.java.awt.Graphics2D;
import org.freecolandroid.repackaged.java.awt.Image;
import org.freecolandroid.repackaged.java.awt.Insets;
import org.freecolandroid.repackaged.java.awt.Rectangle;
import org.freecolandroid.repackaged.java.awt.TexturePaint;
import org.freecolandroid.repackaged.java.awt.image.BufferedImage;
import org.freecolandroid.repackaged.javax.swing.border.AbstractBorder;
import net.sf.freecol.common.resources.ResourceManager;
/**
* A border created from a set of images.
*/
public class FreeColImageBorder extends AbstractBorder {
// The buffered image objects
private BufferedImage topImage;
private BufferedImage leftImage;
private BufferedImage bottomImage;
private BufferedImage rightImage;
private BufferedImage topLeftCornerImage;
private BufferedImage topRightCornerImage;
private BufferedImage bottomLeftCornerImage;
private BufferedImage bottomRightCornerImage;
public static final FreeColImageBorder imageBorder =
new FreeColImageBorder(ResourceManager.getImage("menuborder.n.image"),
ResourceManager.getImage("menuborder.w.image"),
ResourceManager.getImage("menuborder.s.image"),
ResourceManager.getImage("menuborder.e.image"),
ResourceManager.getImage("menuborder.nw.image"),
ResourceManager.getImage("menuborder.ne.image"),
ResourceManager.getImage("menuborder.sw.image"),
ResourceManager.getImage("menuborder.se.image"));
/**
* Creates a border with the given set of images.<br />
* Converts the <code>Image</code> objects to <code>BufferedImage</code>, because the images will
* be used as Textures for the border.
*/
public FreeColImageBorder(Image topImage, Image leftImage, Image bottomImage, Image rightImage,
Image topLeftCornerImage, Image topRightCornerImage, Image bottomLeftCornerImage,
Image bottomRightCornerImage) {
// Convert images to buffered images
this.topImage = createBufferedImage(topImage);
this.leftImage = createBufferedImage(leftImage);
this.bottomImage = createBufferedImage(bottomImage);
this.rightImage = createBufferedImage(rightImage);
this.topLeftCornerImage = createBufferedImage(topLeftCornerImage);
this.topRightCornerImage = createBufferedImage(topRightCornerImage);
this.bottomLeftCornerImage = createBufferedImage(bottomLeftCornerImage);
this.bottomRightCornerImage = createBufferedImage(bottomRightCornerImage);
}
/**
* Creates a buffered image out of a given <code>Image</code> object.
*
* @param img The <code>Image</code> object.
* @return The created <code>BufferedImage</code> object.
*/
private BufferedImage createBufferedImage(Image img) {
if(img != null) {
BufferedImage buff = new BufferedImage(getWidth(img), getHeight(img), BufferedImage.TYPE_INT_ARGB);
Graphics gfx = buff.createGraphics();
gfx.drawImage(img, 0, 0, null);
gfx.dispose();
return buff;
} else {
return null;
}
}
/**
* Gets the insets of this border around the given component.
*
* @param c The <code>Component</code> having the border.
* @return The <code>Insets</code>.
*/
public Insets getBorderInsets(Component c) {
return getBorderInsets(c, null);
}
/**
* Gets the insets of this border around the given component.
*
* @param c The <code>Component</code> having the border.
* @param insets An instance of <code>Insets</code> to be updated.
* @return The given instance of <code>Insets</code> if not
* <code>null</code>, or a new instance otherwise.
*/
public Insets getBorderInsets(Component c, Insets insets) {
int top = Math.max(Math.max(getHeight(topImage), getHeight(topLeftCornerImage)), getHeight(topRightCornerImage));
int left = Math.max(Math.max(getWidth(leftImage), getWidth(topLeftCornerImage)), getWidth(bottomLeftCornerImage));
int bottom = Math.max(Math.max(getHeight(bottomImage), getHeight(bottomLeftCornerImage)), getHeight(bottomRightCornerImage));
int right = Math.max(Math.max(getWidth(rightImage), getWidth(topRightCornerImage)), getWidth(bottomRightCornerImage));
if (leftImage == null) {
left = 0;
}
if (rightImage == null) {
right = 0;
}
if (topImage == null) {
top = 0;
}
if (bottomImage == null) {
bottom = 0;
}
if (insets == null) {
return new Insets(top, left, bottom, right);
} else {
insets.top = top;
insets.left = left;
insets.bottom = bottom;
insets.right = right;
return insets;
}
}
/**
* Get the height of an image. If image is null, return 0.
* @param im The image.
* @return The height of the image.
*/
private int getHeight(Image im) {
return (im != null) ? im.getHeight(null) : 0;
}
/**
* Get the width of an image. If image is null, return 0.
* @param im The image.
* @return The width of the image.
*/
private int getWidth(Image im) {
return (im != null) ? im.getWidth(null) : 0;
}
/**
* Paints the border on the given component.
*
* @param c The <code>Component</code> to draw the border on.
* @param g The <code>Graphics</code> used for painting the border.
* @param x The x-component of the offset.
* @param y The y-component of the offset.
* @param width The width of the border.
* @param height The height of the border.
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Insets insets = getBorderInsets(c);
Graphics2D g2 = (Graphics2D) g;
// Get width and height of the images
int topHeight = getHeight(topImage);
int leftWidth = getWidth(leftImage);
int bottomHeight = getHeight(bottomImage);
int rightWidth = getWidth(rightImage);
int topLeftCornerWidth = getWidth(topLeftCornerImage);
int topLeftCornerHeight = getHeight(topLeftCornerImage);
int topRightCornerWidth = getWidth(topRightCornerImage);
int topRightCornerHeight = getHeight(topRightCornerImage);
int bottomLeftCornerWidth = getWidth(bottomLeftCornerImage);
int bottomLeftCornerHeight = getHeight(bottomLeftCornerImage);
int bottomRightCornerWidth = getWidth(bottomRightCornerImage);
int bottomRightCornerHeight = getHeight(bottomRightCornerImage);
// Add the image border
if(topImage != null) {
fillTexture(g2, topImage, x + topLeftCornerWidth, y + insets.top - topHeight, width - topLeftCornerWidth - topRightCornerWidth, topHeight);
}
if(leftImage != null) {
fillTexture(g2, leftImage, x + insets.left - leftWidth, y + topLeftCornerHeight, leftWidth, height - topLeftCornerHeight - bottomLeftCornerHeight);
}
if(bottomImage != null) {
fillTexture(g2, bottomImage, x + bottomLeftCornerWidth, y + height - insets.bottom, width - bottomLeftCornerWidth - bottomRightCornerWidth, bottomHeight);
}
if(rightImage != null) {
fillTexture(g2, rightImage, x + width - insets.right, y + topRightCornerHeight, rightWidth, height - topRightCornerHeight - bottomRightCornerHeight);
}
if(topLeftCornerImage != null) {
fillTexture(g2, topLeftCornerImage, x + Math.max(insets.left, topLeftCornerWidth) - topLeftCornerWidth, y + Math.max(insets.top, topLeftCornerHeight) - topLeftCornerHeight, topLeftCornerWidth, topLeftCornerHeight);
}
if(topRightCornerImage != null) {
fillTexture(g2, topRightCornerImage, x + width - Math.max(insets.right, topRightCornerWidth), y + Math.max(insets.top, topRightCornerHeight) - topRightCornerHeight, topRightCornerWidth, topRightCornerHeight);
}
if(bottomLeftCornerImage != null) {
fillTexture(g2, bottomLeftCornerImage, x + Math.max(insets.left, bottomLeftCornerWidth) - bottomLeftCornerWidth, y + height - Math.max(insets.bottom, bottomLeftCornerHeight), bottomLeftCornerWidth, bottomLeftCornerHeight);
}
if(bottomRightCornerImage != null) {
fillTexture(g2, bottomRightCornerImage, x + width - Math.max(insets.right, bottomRightCornerWidth), y + height - Math.max(insets.bottom, bottomRightCornerHeight), bottomRightCornerWidth, bottomRightCornerHeight);
}
}
/**
* Fills a certain rectangle with the image texture.
*
* @param g2 The <code>Graphics</code> used for painting the border.
* @param img The <code>BufferedImage</code> to fill the texture.
* @param x The x-component of the offset.
* @param y The y-component of the offset.
* @param width The width of the rectangle.
* @param height The height of the rectangle.
*/
public void fillTexture(Graphics2D g2, BufferedImage img, int x, int y, int width, int height) {
Rectangle anchor = new Rectangle(x, y, getWidth(img), getHeight(img));
TexturePaint paint = new TexturePaint(img, anchor);
g2.setPaint(paint);
g2.fillRect(x, y, width, height);
}
}