/** * 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.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Iterator; import java.util.logging.Logger; import org.freecolandroid.repackaged.java.awt.Component; import org.freecolandroid.repackaged.java.awt.Container; import org.freecolandroid.repackaged.java.awt.event.MouseListener; import org.freecolandroid.repackaged.javax.swing.BorderFactory; import org.freecolandroid.repackaged.javax.swing.JPanel; import org.freecolandroid.repackaged.javax.swing.border.TitledBorder; 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.Goods; import net.sf.freecol.common.model.Player; import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.model.Unit; /** * A panel that holds units and goods that represent Units and cargo * that are on board the currently selected ship. */ public class CargoPanel extends FreeColPanel implements PropertyChangeListener { private static Logger logger = Logger.getLogger(CargoPanel.class.getName()); /** * The carrier that contains cargo. */ private Unit carrier; private final DefaultTransferHandler defaultTransferHandler; private final MouseListener pressListener; private final TitledBorder border; private JPanel parentPanel; /** * Creates this CargoPanel. * * @param parent The parent Canvas that holds this CargoPanel * @param withTitle boolean */ public CargoPanel(FreeColClient freeColClient, GUI gui, boolean withTitle) { super(freeColClient, gui); carrier = null; defaultTransferHandler = new DefaultTransferHandler(freeColClient, gui, this); pressListener = new DragListener(getFreeColClient(), gui, this); if (withTitle) { border = BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), Messages.message("cargoOnCarrier")); } else { border = null; } setBorder(border); initialize(); } /** * Get the <code>ParentPanel</code> value. * * @return a <code>JPanel</code> value */ public final JPanel getParentPanel() { return parentPanel; } /** * Set the <code>ParentPanel</code> value. * * @param newParentPanel The new ParentPanel value. */ public final void setParentPanel(final JPanel newParentPanel) { this.parentPanel = newParentPanel; } /** * Whether this panel is active. * * @return boolean <b>true</b> == active */ public boolean isActive() { return carrier != null; } /** * Get the <code>Carrier</code> value. * * @return an <code>Unit</code> value */ public Unit getCarrier() { return carrier; } /** * Set the <code>Carrier</code> value. * * @param newCarrier The new Carrier value. */ public void setCarrier(final Unit newCarrier) { removePropertyChangeListeners(); this.carrier = newCarrier; addPropertyChangeListeners(); update(); } /** * Initialize this CargoPanel. */ public void initialize() { update(); } /** * Clean up this CargoPanel. */ public void cleanup() { removePropertyChangeListeners(); } /** * Update this CargoPanel. */ public void update() { removeAll(); if (carrier != null) { Iterator<Unit> unitIterator = carrier.getUnitIterator(); while (unitIterator.hasNext()) { Unit unit = unitIterator.next(); UnitLabel label = new UnitLabel(getFreeColClient(), unit, getGUI()); if (isEditable()) { label.setTransferHandler(defaultTransferHandler); label.addMouseListener(pressListener); } add(label); } Iterator<Goods> goodsIterator = carrier.getGoodsIterator(); while (goodsIterator.hasNext()) { Goods g = goodsIterator.next(); GoodsLabel label = new GoodsLabel(g, getGUI()); if (isEditable()) { label.setTransferHandler(defaultTransferHandler); label.addMouseListener(pressListener); } add(label); } } updateTitle(); revalidate(); repaint(); } /** * Update the title of this CargoPanel. */ private void updateTitle() { // sanitation if (border == null) { return; } if (carrier == null) { border.setTitle(Messages.message("cargoOnCarrier")); } else { int spaceLeft = carrier.getSpaceLeft(); StringTemplate t = StringTemplate.template("cargoOnCarrierLong") .addStringTemplate("%name%", Messages.getLabel(carrier)) .addAmount("%space%", spaceLeft); border.setTitle(Messages.message(t)); } } /** * Adds a component to this CargoPanel and makes sure that the unit or * good that the component represents gets modified so that it is on * board the currently selected ship. * * @param comp The component to add to this CargoPanel. * @param editState Must be set to 'true' if the state of the component * that is added (which should be a dropped component * representing a Unit or good) should be changed so that the * underlying unit or goods are on board the currently * selected ship. * @return The component argument. */ public Component add(Component comp, boolean editState) { if (carrier == null) { return null; } if (editState) { if (comp instanceof UnitLabel) { Unit unit = ((UnitLabel) comp).getUnit(); if (carrier.canAdd(unit)) { Container oldParent = comp.getParent(); if (getController().boardShip(unit, carrier)) { ((UnitLabel) comp).setSmall(false); if (oldParent != null) oldParent.remove(comp); update(); return comp; } } } else if (comp instanceof GoodsLabel) { Goods goods = ((GoodsLabel) comp).getGoods(); int loadableAmount = carrier.getLoadableAmount(goods.getType()); if (loadableAmount == 0) { return null; } else if (loadableAmount > goods.getAmount()) { loadableAmount = goods.getAmount(); } Goods goodsToAdd = new Goods(goods.getGame(), goods.getLocation(), goods.getType(), loadableAmount); goods.setAmount(goods.getAmount() - loadableAmount); getController().loadCargo(goodsToAdd, carrier); update(); return comp; } else if (comp instanceof MarketLabel) { MarketLabel label = (MarketLabel) comp; Player player = carrier.getOwner(); if (player.canTrade(label.getType())) { getController().buyGoods(label.getType(), label.getAmount(), carrier); getController().nextModelMessage(); update(); return comp; } else { getController().payArrears(label.getType()); return null; } } else { return null; } } else { super.add(comp); } return null; } @Override public void remove(Component comp) { if (comp instanceof UnitLabel) { Unit unit = ((UnitLabel) comp).getUnit(); getController().leaveShip(unit); update(); } else if (comp instanceof GoodsLabel) { Goods g = ((GoodsLabel) comp).getGoods(); getController().unloadCargo(g, false); update(); } } public void addPropertyChangeListeners() { if (carrier != null) { carrier.addPropertyChangeListener(Unit.CARGO_CHANGE, this); carrier.getGoodsContainer().addPropertyChangeListener(this); } } public void removePropertyChangeListeners() { if (carrier != null) { carrier.removePropertyChangeListener(Unit.CARGO_CHANGE, this); carrier.getGoodsContainer().removePropertyChangeListener(this); } } public void propertyChange(PropertyChangeEvent event) { logger.finest("CargoPanel change " + event.getPropertyName() + ": " + event.getOldValue() + " -> " + event.getNewValue()); update(); } @Override public String getUIClassID() { return "CargoPanelUI"; } }