/** * 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.ArrayList; import java.util.List; import java.util.Map.Entry; import org.freecolandroid.repackaged.java.awt.Image; import org.freecolandroid.repackaged.java.awt.image.BufferedImage; import org.freecolandroid.repackaged.javax.swing.ImageIcon; import org.freecolandroid.repackaged.javax.swing.JButton; import org.freecolandroid.repackaged.javax.swing.JComponent; import org.freecolandroid.repackaged.javax.swing.JLabel; import org.freecolandroid.repackaged.javax.swing.text.BadLocationException; import org.freecolandroid.repackaged.javax.swing.text.StyleConstants; import org.freecolandroid.repackaged.javax.swing.text.StyledDocument; import org.freecolandroid.repackaged.javax.swing.tree.DefaultMutableTreeNode; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.GUI; import net.sf.freecol.client.gui.action.ColopediaAction.PanelType; import net.sf.freecol.client.gui.i18n.Messages; import net.sf.freecol.common.model.Ability; import net.sf.freecol.common.model.AbstractUnit; import net.sf.freecol.common.model.BuildableType; import net.sf.freecol.common.model.Feature; import net.sf.freecol.common.model.FreeColGameObjectType; import net.sf.freecol.common.model.GoodsType; import net.sf.freecol.common.model.Modifier; import net.sf.freecol.common.model.ResourceType; import net.sf.freecol.common.model.Scope; import net.sf.freecol.common.model.Unit.Role; import net.sf.freecol.common.model.UnitType; /** * This panel displays the Colopedia. */ public abstract class ColopediaGameObjectTypePanel<T extends FreeColGameObjectType> extends FreeColPanel implements ColopediaDetailPanel<T> { private String id; private double scale = 1; private ColopediaPanel colopediaPanel; public ColopediaGameObjectTypePanel(FreeColClient freeColClient, GUI gui, ColopediaPanel colopediaPanel, String id, double scale) { super(freeColClient, gui); this.colopediaPanel = colopediaPanel; this.id = "colopediaAction." + id; this.scale = scale; } /** * Returns the name of this ColopediaDetailPanel, which is * generally used to label the root node of its sub-tree. * * @return a String value */ public String getName() { return Messages.message(id + ".name"); } protected String getId() { return id; } /** * Returns the scale to use for icons. * * @return a double value */ protected double getScale() { return scale; } /** * Builds a subtree including all the given objects. * * @param root a <code>DefaultMutableTreeNode</code> * @param types a List of FreeColGameObjectTypes */ public void addSubTrees(DefaultMutableTreeNode root, List<T> types) { addSubTrees(root, id, types); } /** * Builds a subtree including all the given objects. * * @param root a <code>DefaultMutableTreeNode</code> * @param id the ID of the new branch node * @param types a List of FreeColGameObjectTypes */ public void addSubTrees(DefaultMutableTreeNode root, String id, List<T> types) { String name = Messages.message(id + ".name"); DefaultMutableTreeNode node = new DefaultMutableTreeNode(new ColopediaTreeItem(this, id, name, null)); int width = 0; int height = 0; for (FreeColGameObjectType type : types) { Image image = getLibrary().getImage(type, scale); width = Math.max(image.getWidth(null), width); height = Math.max(image.getHeight(null), height); } for (FreeColGameObjectType type : types) { BufferedImage centeredImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Image image = getLibrary().getImage(type, scale); int x = (width - image.getWidth(null)) / 2; int y = (height - image.getHeight(null)) / 2; centeredImage.getGraphics().drawImage(image, x, y, null); node.add(buildItem(type, new ImageIcon(centeredImage))); } root.add(node); } protected DefaultMutableTreeNode buildItem(FreeColGameObjectType type, ImageIcon icon) { String name = Messages.getName(type); DefaultMutableTreeNode item = new DefaultMutableTreeNode(new ColopediaTreeItem(this, type.getId(), name, icon)); return item; } protected JButton getButton(FreeColGameObjectType type, String text, ImageIcon icon) { JButton button = getLinkButton(text == null ? Messages.getName(type) : text, icon, type.getId()); button.addActionListener(colopediaPanel); return button; } protected JButton getButton(PanelType panelType, String text, ImageIcon icon) { JButton button = getLinkButton(text, icon, "colopediaAction." + panelType); button.addActionListener(colopediaPanel); return button; } protected JButton getButton(FreeColGameObjectType type) { return getButton(type, null, null); } protected JButton getResourceButton(final ResourceType resourceType) { return getButton(resourceType, null, getLibrary().getBonusImageIcon(resourceType)); } protected JButton getGoodsButton(final GoodsType goodsType) { return getGoodsButton(goodsType, null); } protected JButton getGoodsButton(final GoodsType goodsType, int amount) { return getGoodsButton(goodsType, Integer.toString(amount)); } protected JButton getGoodsButton(final GoodsType goodsType, String text) { JButton result = getButton(goodsType, text, getLibrary().getGoodsImageIcon(goodsType)); result.setToolTipText(Messages.getName(goodsType)); return result; } protected JButton getUnitButton(AbstractUnit unit) { return getUnitButton(unit.getUnitType(getSpecification()), unit.getRole()); } protected JButton getUnitButton(final UnitType unitType, Role role) { ImageIcon unitIcon = getLibrary().getUnitImageIcon(unitType, role, 0.66); JButton unitButton = getButton(unitType, null, unitIcon); unitButton.setHorizontalAlignment(JButton.LEFT); return unitButton; } protected JButton getUnitButton(final UnitType unitType) { return getUnitButton(unitType, Role.DEFAULT); } private String getFeatureName(Feature feature) { return Messages.message(feature.getNameKey()); } private String getFeatureAsString(Feature feature) { String label = Messages.message(getFeatureName(feature)) + ":"; if (feature.hasScope()) { for (Scope scope : feature.getScopes()) { String key = null; if (scope.getType() != null) { key = scope.getType(); } else if (scope.getAbilityID() != null) { key = scope.getAbilityID(); } else if (scope.getMethodName() != null) { key = "model.scope." + scope.getMethodName(); } if (key != null) { label += (scope.isMatchNegated() ? " !" : " ") + Messages.message(key + ".name") + ","; } } } return label.substring(0, label.length() - 1); } public String getModifierAsString(Modifier modifier) { String bonus = modifierFormat.format(modifier.getValue()); switch(modifier.getType()) { case ADDITIVE: if (modifier.getValue() > 0) { bonus = "+" + bonus; } break; case PERCENTAGE: if (modifier.getValue() > 0) { bonus = "+" + bonus; } bonus = bonus + "%"; break; case MULTIPLICATIVE: bonus = "\u00D7" + bonus; break; default: } return bonus; } public JComponent getModifierComponent(Modifier modifier) { try { GoodsType goodsType = getSpecification() .getGoodsType(modifier.getId()); String bonus = getModifierAsString(modifier); return getGoodsButton(goodsType, bonus); } catch(Exception e) { // not a production bonus JLabel label = new JLabel(getFeatureAsString(modifier) + ": " + getModifierAsString(modifier)); label.setToolTipText(Messages.message(modifier.getId() + ".shortDescription")); return label; } } public JLabel getAbilityComponent(Ability ability) { if (ability.getValue()) { JLabel label = new JLabel(getFeatureAsString(ability)); label.setToolTipText(Messages.message(ability.getId() + ".shortDescription")); return label; } else { return null; } } public void appendRequiredAbilities(StyledDocument doc, BuildableType buildableType) throws BadLocationException { for (Entry<String, Boolean> entry : buildableType.getAbilitiesRequired().entrySet()) { doc.insertString(doc.getLength(), Messages.message(entry.getKey() + ".name"), doc.getStyle("regular")); List<JButton> requiredTypes = new ArrayList<JButton>(); for (FreeColGameObjectType type : getSpecification() .getTypesProviding(entry.getKey(), entry.getValue())) { JButton typeButton = getButton(type); typeButton.addActionListener(this); requiredTypes.add(typeButton); } if (!requiredTypes.isEmpty()) { doc.insertString(doc.getLength(), " (", doc.getStyle("regular")); StyleConstants.setComponent(doc.getStyle("button"), requiredTypes.get(0)); doc.insertString(doc.getLength(), " ", doc.getStyle("button")); for (int index = 1; index < requiredTypes.size(); index++) { JButton button = requiredTypes.get(index); doc.insertString(doc.getLength(), " / ", doc.getStyle("regular")); StyleConstants.setComponent(doc.getStyle("button"), button); doc.insertString(doc.getLength(), " ", doc.getStyle("button")); } doc.insertString(doc.getLength(), ")", doc.getStyle("regular")); } doc.insertString(doc.getLength(), "\n", doc.getStyle("regular")); } } }