/** * 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); } }