/** * 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 java.util.logging.Logger; import org.freecolandroid.repackaged.java.awt.Color; import org.freecolandroid.repackaged.java.awt.Dimension; import org.freecolandroid.repackaged.java.awt.Font; import org.freecolandroid.repackaged.java.awt.Graphics; import org.freecolandroid.repackaged.java.awt.Image; import org.freecolandroid.repackaged.javax.swing.ImageIcon; import net.sf.freecol.client.ClientOptions; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.GUI; import net.sf.freecol.client.gui.i18n.Messages; import net.sf.freecol.common.model.AbstractGoods; import net.sf.freecol.common.model.GoodsType; import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.resources.ResourceManager; /** * The ProductionLabel represents Goods that are produced in a * WorkLocation or Settlement. It is similar to the GoodsLabel. */ public final class ProductionLabel extends AbstractGoodsLabel { private static Logger logger = Logger.getLogger(ProductionLabel.class.getName()); /** * The maximum number of goodsIcons to display. */ private int maxIcons = 7; /** * Whether to display positive integers with a "+" sign. */ private boolean drawPlus = false; /** * Whether the ProductionLabel should be centered. */ private boolean centered = true; /** * The compressed width of the ProductionLabel. */ private int compressedWidth = -1; /** * The goodsIcon for this type of production. */ private ImageIcon goodsIcon; /** * The amount of goods that could be produced. */ private int maximumProduction = -1; /** * The smallest number to display above the goodsIcons. */ private int displayNumber; /** * The smallest number to display above the goodsIcons. * used to Show stored items in ReportColonyPanel */ private int stockNumber = -1; /** * Describe toolTipPrefix here. */ private String toolTipPrefix = null; private Image stringImage = null; /** * Creates a new <code>ProductionLabel</code> instance. * * @param goods a <code>AbstractGoods</code> value * @param parent a <code>Canvas</code> value */ public ProductionLabel(FreeColClient freeColClient, GUI gui, AbstractGoods goods) { this(freeColClient, gui, goods, -1); } /** * Creates a new <code>ProductionLabel</code> instance. * * @param goods a <code>AbstractGoods</code> value * @param maximum an <code>AbstractGoods</code> value * @param parent a <code>Canvas</code> value */ public ProductionLabel(FreeColClient freeColClient, GUI gui, AbstractGoods goods, AbstractGoods maximum) { this(freeColClient, gui, goods, maximum.getAmount()); } /** * Creates a new <code>ProductionLabel</code> instance. * * @param goodsType a <code>GoodsType</code> value * @param amount an <code>int</code> value * @param parent a <code>Canvas</code> value */ public ProductionLabel(FreeColClient freeColClient, GUI gui, GoodsType goodsType, int amount) { this(freeColClient, gui, new AbstractGoods(goodsType, amount), -1); } /** * Creates a new <code>ProductionLabel</code> instance. * * @param goods a <code>AbstractGoods</code> value * @param maximum a <code>AbstractGoods</code> value * @param parent a <code>Canvas</code> value */ public ProductionLabel(FreeColClient freeColClient, GUI gui, AbstractGoods goods, int maximum) { super(goods, gui); this.maximumProduction = maximum; ClientOptions options = freeColClient.getClientOptions(); maxIcons = options.getInteger(ClientOptions.MAX_NUMBER_OF_GOODS_IMAGES); displayNumber = options.getInteger(ClientOptions.MIN_NUMBER_FOR_DISPLAYING_GOODS_COUNT); setFont(ResourceManager.getFont("SimpleFont", Font.BOLD, 12f)); if (goods.getAmount() < 0) { setForeground(Color.RED); } else { setForeground(Color.WHITE); } if (goods.getType() != null) { setGoodsIcon(getGUI().getImageLibrary().getGoodsImageIcon(goods.getType())); updateToolTipText(); } } /** * Get the <code>ToolTipPrefix</code> value. * * @return a <code>String</code> value */ public String getToolTipPrefix() { return toolTipPrefix; } /** * Set the <code>ToolTipPrefix</code> value. * * @param newToolTipPrefix The new ToolTipPrefix value. */ public void setToolTipPrefix(final String newToolTipPrefix) { this.toolTipPrefix = newToolTipPrefix; updateToolTipText(); } /** * Get the <code>DisplayNumber</code> value. * * @return an <code>int</code> value */ public int getDisplayNumber() { return displayNumber; } /** * Set the <code>DisplayNumber</code> value. * * @param newDisplayNumber The new DisplayNumber value. */ public void setDisplayNumber(final int newDisplayNumber) { this.displayNumber = newDisplayNumber; } /** * Get the <code>GoodsIcon</code> value. * * @return an <code>ImageIcon</code> value */ public ImageIcon getGoodsIcon() { return goodsIcon; } /** * Set the <code>GoodsIcon</code> value. * * @param newGoodsIcon The new GoodsIcon value. */ public void setGoodsIcon(final ImageIcon newGoodsIcon) { this.goodsIcon = newGoodsIcon; compressedWidth = goodsIcon.getIconWidth()*2; } /** * Set the <code>Production</code> value. * * @param newProduction The new Production value. */ public void setProduction(final int newProduction) { getGoods().setAmount(newProduction); updateToolTipText(); } private void updateToolTipText() { if (getType() == null || getAmount() == 0) { setToolTipText(null); } else { String text = Messages.message(StringTemplate.template("model.goods.goodsAmount") .add("%goods%", getGoods().getNameKey()) .addAmount("%amount%", getAmount())); if (toolTipPrefix != null) { text = toolTipPrefix + " " + text; } setToolTipText(text); } } /** * Get the <code>MaximumProduction</code> value. * * @return an <code>int</code> value */ public int getMaximumProduction() { return maximumProduction; } /** * Set the <code>MaximumProduction</code> value. * * @param newMaximumProduction The new MaximumProduction value. */ public void setMaximumProduction(final int newMaximumProduction) { this.maximumProduction = newMaximumProduction; } /** * Get the <code>MaxGoodsIcons</code> value. * * @return an <code>int</code> value */ public int getMaxGoodsIcons() { return maxIcons; } /** * Set the <code>MaxGoodsIcons</code> value. * * @param newMaxGoodsIcons The new MaxGoodsIcons value. */ public void setMaxGoodsIcons(final int newMaxGoodsIcons) { this.maxIcons = newMaxGoodsIcons; } /** * Get the <code>stockNumber</code> value. * used to Show stored items in ReportColonyPanel * * @return an <code>int</code> value */ public int getStockNumber() { return stockNumber; } /** * Set the <code>stockNumber</code> value. * used to Show stored items in ReportColonyPanel * * @param newStockNumber The new StockNumber value. */ public void setStockNumber(final int newStockNumber) { this.stockNumber = newStockNumber; } /** * Get the <code>DrawPlus</code> value. * * @return a <code>boolean</code> value */ public boolean drawPlus() { return drawPlus; } /** * Set the <code>DrawPlus</code> value. * * @param newDrawPlus The new DrawPlus value. */ public void setDrawPlus(final boolean newDrawPlus) { this.drawPlus = newDrawPlus; } /** * Get the <code>Centered</code> value. * * @return a <code>boolean</code> value */ public boolean isCentered() { return centered; } /** * Set the <code>Centered</code> value. * * @param newCentered The new Centered value. */ public void setCentered(final boolean newCentered) { this.centered = newCentered; } /** * Get the <code>CompressedWidth</code> value. * * @return an <code>int</code> value */ public int getCompressedWidth() { return compressedWidth; } /** * Set the <code>CompressedWidth</code> value. * * @param newCompressedWidth The new CompressedWidth value. */ public void setCompressedWidth(final int newCompressedWidth) { this.compressedWidth = newCompressedWidth; } /** * Overrides the <code>getPreferredSize</code> method. * * @return a <code>Dimension</code> value */ public Dimension getPreferredSize() { if (goodsIcon == null) { return new Dimension(0, 0); } else { return new Dimension(getPreferredWidth(), goodsIcon.getImage().getHeight(null)); } } /** * Returns only the width component of the preferred size. * * @return an <code>int</code> value */ public int getPreferredWidth() { if (goodsIcon == null) { return 0; } int drawImageCount = Math.max(1, Math.min(Math.abs(getAmount()), maxIcons)); int iconWidth = goodsIcon.getIconWidth(); int pixelsPerIcon = iconWidth / 2; if (pixelsPerIcon - iconWidth < 0) { pixelsPerIcon = (compressedWidth - iconWidth) / drawImageCount; } int maxSpacing = iconWidth; /* TODO Tune this: all icons are the same width, but many * do not take up the whole width, eg. bells */ boolean iconsTooFarApart = pixelsPerIcon > maxSpacing; if (iconsTooFarApart) { pixelsPerIcon = maxSpacing; } int width = pixelsPerIcon * (drawImageCount - 1) + iconWidth; if (getStringImage() == null) { return width; } else { return Math.max(getStringImage().getWidth(null), width); } } /** * Paints this ProductionLabel. * * @param g The graphics context in which to do the painting. */ public void paintComponent(Graphics g) { if (goodsIcon == null || (getAmount() == 0 && stockNumber<0) ) { logger.fine("Empty production label: fix this!"); return; } int stringWidth = getStringImage() == null ? 0 : getStringImage().getWidth(null); int drawImageCount = Math.min(Math.abs(getAmount()), maxIcons); if (drawImageCount==0) { drawImageCount=1; } int iconWidth = goodsIcon.getIconWidth(); int pixelsPerIcon = iconWidth / 2; if (pixelsPerIcon - iconWidth < 0) { pixelsPerIcon = (compressedWidth - iconWidth) / drawImageCount; } int maxSpacing = iconWidth; /* TODO Tune this: all icons are the same width, but many * do not take up the whole width, eg. bells */ boolean iconsTooFarApart = pixelsPerIcon > maxSpacing; if (iconsTooFarApart) { pixelsPerIcon = maxSpacing; } int coverage = pixelsPerIcon * (drawImageCount - 1) + iconWidth; int leftOffset = 0; int width = Math.max(getWidth(), Math.max(stringWidth, coverage)); if (centered && coverage < width) { leftOffset = (width - coverage)/2; } int height = Math.max(getHeight(), goodsIcon.getImage().getHeight(null)); setSize(new Dimension(width, height)); // Draw the icons onto the image: for (int i = 0; i < drawImageCount; i++) { goodsIcon.paintIcon(null, g, leftOffset + i*pixelsPerIcon, 0); } if (stringImage != null) { int textOffset = width > stringWidth ? (width - stringWidth)/2 : 0; textOffset = (textOffset >= 0) ? textOffset : 0; g.drawImage(stringImage, textOffset, goodsIcon.getIconHeight()/2 - stringImage.getHeight(null)/2, null); } } private Image getStringImage() { if (stringImage == null) { if (getAmount() >= displayNumber || getAmount() < 0 || maxIcons < getAmount() || stockNumber > 0 || (maximumProduction > getAmount() && getAmount() > 0)) { String number = ""; if (stockNumber >= 0 ) { number = Integer.toString(stockNumber); // Show stored items in ReportColonyPanel drawPlus = true; } if (getAmount() >=0 && drawPlus ) { number = number + "+" + Integer.toString(getAmount()); } else { number = number + Integer.toString(getAmount()); } if (maximumProduction > getAmount() && getAmount() > 0) { number = number + "/" + String.valueOf(maximumProduction); } Font font = ResourceManager.getFont("SimpleFont", Font.BOLD, 12f); stringImage = getGUI().getMapViewer().createStringImage(getGUI().getCanvas().getGraphics(), number, getForeground(), font); } } return stringImage; } }