/**
* 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.List;
import java.util.logging.Logger;
import org.freecolandroid.repackaged.java.awt.Component;
import org.freecolandroid.repackaged.java.awt.GridLayout;
import org.freecolandroid.repackaged.java.awt.event.ActionEvent;
import org.freecolandroid.repackaged.java.awt.event.ActionListener;
import org.freecolandroid.repackaged.java.awt.event.KeyEvent;
import org.freecolandroid.repackaged.java.awt.event.MouseAdapter;
import org.freecolandroid.repackaged.java.awt.event.MouseListener;
import org.freecolandroid.repackaged.javax.swing.BorderFactory;
import org.freecolandroid.repackaged.javax.swing.ComponentInputMap;
import org.freecolandroid.repackaged.javax.swing.InputMap;
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.JPanel;
import org.freecolandroid.repackaged.javax.swing.JScrollPane;
import org.freecolandroid.repackaged.javax.swing.JTextPane;
import org.freecolandroid.repackaged.javax.swing.KeyStroke;
import org.freecolandroid.repackaged.javax.swing.ScrollPaneConstants;
import org.freecolandroid.repackaged.javax.swing.SwingUtilities;
import org.freecolandroid.repackaged.javax.swing.border.TitledBorder;
import org.freecolandroid.repackaged.javax.swing.text.SimpleAttributeSet;
import org.freecolandroid.repackaged.javax.swing.text.StyleConstants;
import org.freecolandroid.repackaged.javax.swing.text.StyledDocument;
import net.miginfocom.swing.MigLayout;
import net.sf.freecol.client.ClientOptions;
import net.sf.freecol.client.FreeColClient;
import net.sf.freecol.client.gui.Canvas;
import net.sf.freecol.client.gui.GUI;
import net.sf.freecol.client.gui.i18n.Messages;
import net.sf.freecol.common.model.Europe;
import net.sf.freecol.common.model.FreeColGameObject;
import net.sf.freecol.common.model.Game;
import net.sf.freecol.common.model.Goods;
import net.sf.freecol.common.model.GoodsType;
import net.sf.freecol.common.model.HighSeas;
import net.sf.freecol.common.model.Location;
import net.sf.freecol.common.model.Map;
import net.sf.freecol.common.model.Market;
import net.sf.freecol.common.model.StringTemplate;
import net.sf.freecol.common.model.TransactionListener;
import net.sf.freecol.common.model.Unit;
/**
* This is a panel for the Europe display. It shows the ships in Europe and
* allows the user to send them back.
*/
public final class EuropePanel extends FreeColPanel {
private static Logger logger = Logger.getLogger(EuropePanel.class.getName());
public static enum EuropeAction {
EXIT,
RECRUIT,
PURCHASE,
TRAIN,
UNLOAD,
SAIL
}
private final DestinationPanel toAmericaPanel;
private final DestinationPanel toEuropePanel;
private final InPortPanel inPortPanel;
private final DocksPanel docksPanel;
private final EuropeCargoPanel cargoPanel;
private final MarketPanel marketPanel;
private final TransactionLog log;
private final DefaultTransferHandler defaultTransferHandler;
private final MouseListener pressListener;
private Europe europe;
private UnitLabel selectedUnitLabel;
private JButton exitButton;
private JLabel header = getDefaultHeader("");
/**
* The constructor for a EuropePanel.
* @param freeColClient
*
* @param parent The parent of this panel
*/
public EuropePanel(FreeColClient freeColClient, GUI gui, Canvas canvas) {
super(freeColClient, gui);
setFocusCycleRoot(true);
// Use ESCAPE for closing the ColonyPanel:
exitButton = new EuropeButton(Messages.message("close"),
KeyEvent.VK_ESCAPE, EuropeAction.EXIT.toString(), this);
EuropeButton trainButton = new EuropeButton(Messages.message("train"),
KeyEvent.VK_T, EuropeAction.TRAIN.toString(), this);
EuropeButton purchaseButton = new EuropeButton(Messages.message("purchase"),
KeyEvent.VK_P, EuropeAction.PURCHASE.toString(), this);
EuropeButton recruitButton = new EuropeButton(Messages.message("recruit"),
KeyEvent.VK_R, EuropeAction.RECRUIT.toString(), this);
EuropeButton unloadButton = new EuropeButton(Messages.message("unload"),
KeyEvent.VK_U, EuropeAction.UNLOAD.toString(), this);
EuropeButton sailButton = new EuropeButton(Messages.message("sail"),
KeyEvent.VK_S, EuropeAction.SAIL.toString(), this);
toAmericaPanel = new DestinationPanel();
toEuropePanel = new DestinationPanel();
inPortPanel = new InPortPanel();
cargoPanel = new EuropeCargoPanel(freeColClient, getGUI());
cargoPanel.setParentPanel(this);
docksPanel = new DocksPanel();
marketPanel = new MarketPanel(this);
log = new TransactionLog();
SimpleAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setAlignment(attributes, StyleConstants.ALIGN_RIGHT);
//StyleConstants.setForeground(attributes, Color.WHITE);
StyleConstants.setBold(attributes, true);
log.setParagraphAttributes(attributes, true);
defaultTransferHandler = new DefaultTransferHandler(freeColClient, getGUI(), this);
toAmericaPanel.setTransferHandler(defaultTransferHandler);
toEuropePanel.setTransferHandler(defaultTransferHandler);
inPortPanel.setTransferHandler(defaultTransferHandler);
cargoPanel.setTransferHandler(defaultTransferHandler);
docksPanel.setTransferHandler(defaultTransferHandler);
marketPanel.setTransferHandler(defaultTransferHandler);
pressListener = new DragListener(freeColClient, gui, this);
MouseListener releaseListener = new DropListener();
toAmericaPanel.addMouseListener(releaseListener);
toEuropePanel.addMouseListener(releaseListener);
inPortPanel.addMouseListener(releaseListener);
cargoPanel.addMouseListener(releaseListener);
docksPanel.addMouseListener(releaseListener);
marketPanel.addMouseListener(releaseListener);
toAmericaPanel.setLayout(new GridLayout(1, 0));
toEuropePanel.setLayout(new GridLayout(1, 0));
inPortPanel.setLayout(new GridLayout(1, 0));
cargoPanel.setLayout(new GridLayout(1, 0));
docksPanel.setLayout(new GridLayout(0, 5));
JScrollPane toAmericaScroll = new JScrollPane(toAmericaPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
toAmericaScroll.getVerticalScrollBar().setUnitIncrement(16);
JScrollPane toEuropeScroll = new JScrollPane(toEuropePanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
toEuropeScroll.getVerticalScrollBar().setUnitIncrement(16);
JScrollPane inPortScroll = new JScrollPane(inPortPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
inPortScroll.getVerticalScrollBar().setUnitIncrement(16);
JScrollPane cargoScroll = new JScrollPane(cargoPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
cargoScroll.getVerticalScrollBar().setUnitIncrement(16);
JScrollPane docksScroll = new JScrollPane(docksPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
docksScroll.getVerticalScrollBar().setUnitIncrement(16);
JScrollPane marketScroll = new JScrollPane(marketPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane logScroll = new JScrollPane(log, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
logScroll.getVerticalScrollBar().setUnitIncrement(16);
toAmericaPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), Messages
.message("goingToAmerica")));
toEuropePanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), Messages
.message("goingToEurope")));
docksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), Messages
.message("docks")));
inPortPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), Messages
.message("inPort")));
marketPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
log.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
Messages.message("sales")));
toAmericaScroll.getViewport().setOpaque(false);
toAmericaPanel.setOpaque(false);
toEuropeScroll.getViewport().setOpaque(false);
toEuropePanel.setOpaque(false);
inPortScroll.getViewport().setOpaque(false);
inPortPanel.setOpaque(false);
cargoScroll.getViewport().setOpaque(false);
cargoPanel.setOpaque(false);
docksScroll.getViewport().setOpaque(false);
docksPanel.setOpaque(false);
marketScroll.getViewport().setOpaque(false);
marketPanel.setOpaque(false);
logScroll.getViewport().setOpaque(false);
log.setOpaque(false);
setLayout(new MigLayout("wrap 3, insets 20, fill",
"[380:][380:][150:200:]"));
if (canvas.getHeight() > 750) {
add(header, "span, center");
}
add(toAmericaScroll, "sg, height 124:, grow");
add(toEuropeScroll, "sg, height 124:, grow");
add(logScroll, "spany 3, grow");
add(inPortScroll, "sg, height 124:, grow");
add(docksScroll, "spany 2, grow");
add(cargoScroll, "height 100:, grow");
add(marketScroll, "span, grow");
add(recruitButton, "span, split 6");
add(purchaseButton);
add(trainButton);
add(unloadButton);
add(sailButton);
add(exitButton, "tag ok");
selectedUnitLabel = null;
// See the message of Ulf Onnen for more information about the presence
// of this fake mouse listener.
addMouseListener(new MouseAdapter() {});
restoreSavedSize(1000, canvas.getHeight() > 750 ? 700 : 600);
}
/**
* What to do when requesting focus.
*/
public void requestFocus() {
exitButton.requestFocus();
}
/**
* Refreshes this panel.
*/
public void refresh() {
repaint(0, 0, getWidth(), getHeight());
}
/**
* Gets the cargo panel.
*
* @return The cargo panel.
*/
public final CargoPanel getCargoPanel() {
return cargoPanel;
}
/**
* Returns the currently select unit.
*
* @return The currently select unit.
*/
public Unit getSelectedUnit() {
return (selectedUnitLabel == null) ? null
: selectedUnitLabel.getUnit();
}
/**
* Selects a unit that is potentially located somewhere in port.
*
* @param unit The <code>Unit</code> to select.
*/
public void setSelectedUnit(Unit unit) {
UnitLabel unitLabel = null;
if (unit != null) {
Component[] components = inPortPanel.getComponents();
for (int i = 0; i < components.length; i++) {
if (components[i] instanceof UnitLabel
&& ((UnitLabel) components[i]).getUnit() == unit) {
unitLabel = (UnitLabel) components[i];
break;
}
}
}
setSelectedUnitLabel(unitLabel);
}
/**
* Returns the currently select unit label.
*
* @return The currently select unit label.
*/
public UnitLabel getSelectedUnitLabel() {
return selectedUnitLabel;
}
/**
* Selects a unit that is located somewhere on this panel.
*
* @param unitLabel The <code>UnitLabel</code> for the unit that
* is being selected.
*/
public void setSelectedUnitLabel(UnitLabel unitLabel) {
if (selectedUnitLabel != unitLabel) {
if (selectedUnitLabel != null) {
selectedUnitLabel.setSelected(false);
}
selectedUnitLabel = unitLabel;
if (unitLabel == null) {
cargoPanel.setCarrier(null);
} else {
cargoPanel.setCarrier(unitLabel.getUnit());
unitLabel.setSelected(true);
}
}
inPortPanel.revalidate();
inPortPanel.repaint();
}
/**
* Initialize this EuropePanel.
*
* @param europe The <code>Europe</code> this panel should display.
* @param game The <code>Game</code> the <code>Europe</code> is in.
*/
public void initialize(Europe europe, Game game) {
this.europe = europe;
header.setText(Messages.message(europe.getNameKey()));
// Initialize the subpanels.
toAmericaPanel.initialize(getGame().getMap());
toEuropePanel.initialize(getMyPlayer().getEurope());
// Initialize cargoPanel before inPortPanel calls setSelectedUnit().
cargoPanel.initialize();
inPortPanel.initialize();
marketPanel.initialize();
docksPanel.initialize();
log.initialize();
}
/**
* Cleans up this EuropePanel.
*/
public void cleanup() {
log.cleanup();
docksPanel.cleanup();
marketPanel.cleanup();
inPortPanel.cleanup();
cargoPanel.cleanup();
toEuropePanel.cleanup();
toAmericaPanel.cleanup();
}
/**
* Exits this EuropePanel.
*/
private void exitAction() {
cleanup();
getGUI().removeFromCanvas(this);
getController().nextModelMessage();
}
/**
* Unload the contents of the currently selected carrier.
*/
private void unloadAction() {
Unit unit = getSelectedUnit();
if (unit != null && unit.isCarrier()) {
Iterator<Goods> goodsIterator = unit.getGoodsIterator();
while (goodsIterator.hasNext()) {
Goods goods = goodsIterator.next();
if (getMyPlayer().canTrade(goods)) {
getController().sellGoods(goods);
} else {
getController().payArrears(goods.getType());
}
}
Iterator<Unit> unitIterator = unit.getUnitIterator();
while (unitIterator.hasNext()) {
Unit newUnit = unitIterator.next();
getController().leaveShip(newUnit);
}
cargoPanel.update();
docksPanel.update();
}
requestFocus();
}
/**
* A unit sets sail for the new world.
*/
private void sailAction() {
Unit unit = getSelectedUnit();
if (unit != null && unit.isNaval()) {
UnitLabel unitLabel = getSelectedUnitLabel();
toAmericaPanel.add(unitLabel, true);
}
requestFocus();
}
/**
* Analyzes an event and calls the right external methods to take care of
* the user's request.
*
* @param event The incoming action event
*/
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
// Close any open Europe Dialog, and show new one if required
EuropeAction act = EuropeAction.valueOf(command);
getGUI().showEuropeDialog(act);
switch (act) {
case EXIT:
exitAction();
break;
case RECRUIT: case PURCHASE: case TRAIN:
requestFocus(); // handled by docks panel
break;
case UNLOAD:
unloadAction();
break;
case SAIL:
sailAction();
break;
default:
logger.warning("Invalid action command: " + command);
}
}
/**
* Trivial wrapper for CargoPanel.
* TODO: check if still needed?
*/
public final class EuropeCargoPanel extends CargoPanel {
public EuropeCargoPanel(FreeColClient freeColClient, GUI gui) {
super(freeColClient, gui, true);
}
}
/**
* A panel that holds UnitsLabels that represent Units that are going to
* America or Europe.
*/
public final class DestinationPanel extends JPanel {
private Location destination;
/**
* Initialize this DestinationPanel.
*/
public void initialize(Location destination) {
this.destination = destination;
update();
}
/**
* Cleans up this DestinationPanel.
*/
public void cleanup() {}
/**
* Update this DestinationPanel.
*/
public void update() {
removeAll();
HighSeas highSeas = getMyPlayer().getHighSeas();
if (highSeas != null) {
for (Unit unit : highSeas.getUnitList()) {
boolean belongs;
if (destination instanceof Europe) {
belongs = unit.getDestination() == destination;
} else if (destination instanceof Map) {
belongs = unit.getDestination() == destination
|| (unit.getDestination() != null
&& unit.getDestination().getTile() != null
&& unit.getDestination().getTile().getMap()
== destination);
} else {
logger.warning("Bogus DestinationPanel location: "
+ ((FreeColGameObject) destination)
+ " for unit: " + unit);
belongs = false;
}
if (belongs) {
UnitLabel unitLabel = new UnitLabel(getFreeColClient(), unit, getGUI());
unitLabel.setTransferHandler(defaultTransferHandler);
unitLabel.addMouseListener(pressListener);
add(unitLabel);
}
}
}
StringTemplate t = StringTemplate.template("sailingTo")
.addStringTemplate("%location%",
destination.getLocationNameFor(getMyPlayer()));
((TitledBorder) getBorder()).setTitle(Messages.message(t));
revalidate();
}
/**
* Adds a component to this DestinationPanel and makes sure that
* the unit that the component represents gets modified so
* that it will sail to America.
*
* @param comp The component to add.
* @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) should be changed so that the
* underlying unit is now sailing to America.
* @return The component argument.
*/
public Component add(Component comp, boolean editState) {
if (editState) {
if (!(comp instanceof UnitLabel)) {
logger.warning("Invalid component dropped on this DestinationPanel.");
return null;
}
final Unit unit = ((UnitLabel) comp).getUnit();
Location dest = destination;
if (unit.isInEurope()) {
dest = getGUI().showSelectDestinationDialog(unit);
if (dest == null) return null; // user aborted
}
final ClientOptions co = getClientOptions();
if (!co.getBoolean(ClientOptions.AUTOLOAD_EMIGRANTS)
&& unit.isInEurope()
&& !(destination instanceof Europe)
&& docksPanel.getComponentCount() > 0
&& unit.getSpaceLeft() > 0) {
boolean leave = getGUI().showConfirmDialog(null,
StringTemplate.template("europe.leaveColonists")
.addStringTemplate("%newWorld%",
destination.getLocationNameFor(unit.getOwner())),
"yes", "no");
if (!leave) return null; // Colonists remain in Europe.
}
comp.getParent().remove(comp);
getController().moveTo(unit, dest);
inPortPanel.update();
docksPanel.update();
}
Component c = add(comp);
revalidate();
EuropePanel.this.refresh();
return c;
}
}
/**
* A panel that holds UnitLabels that represent naval units that are
* waiting in Europe.
*/
public final class InPortPanel extends JPanel
implements PropertyChangeListener {
/**
* Initialize this InPortPanel.
*/
public void initialize() {
addPropertyChangeListeners();
update();
}
/**
* Cleans up this InPortPanel.
*/
public void cleanup() {
removePropertyChangeListeners();
}
/**
* Update this InPortPanel.
*/
public void update() {
removeAll();
UnitLabel lastCarrier = null;
UnitLabel prevCarrier = null;
for (Unit unit : europe.getUnitList()) {
if (unit.isNaval()
&& (unit.getState() == Unit.UnitState.ACTIVE
|| unit.getState() == Unit.UnitState.SENTRY)) {
UnitLabel unitLabel = new UnitLabel(getFreeColClient(), unit, getGUI());
unitLabel.setTransferHandler(defaultTransferHandler);
unitLabel.addMouseListener(pressListener);
add(unitLabel);
lastCarrier = unitLabel;
if (getSelectedUnit() == unit) prevCarrier = unitLabel;
}
}
// Keep the previous selected unit if possible, otherwise default
// on the last carrier.
setSelectedUnitLabel((prevCarrier != null) ? prevCarrier
: (lastCarrier != null) ? lastCarrier
: null);
// No revalidate+repaint as this is done in setSelectedUnitLabel
}
public void addPropertyChangeListeners() {
europe.addPropertyChangeListener(this);
}
public void removePropertyChangeListeners() {
europe.removePropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent event) {
logger.finest("Europe-port change " + event.getPropertyName()
+ ": " + event.getOldValue()
+ " -> " + event.getNewValue());
update();
}
}
/**
* A panel that holds UnitsLabels that represent Units that are
* waiting on the docks in Europe.
*/
public final class DocksPanel extends JPanel
implements PropertyChangeListener {
/**
* Initializes this DocksPanel.
*/
public void initialize() {
setLayout(new MigLayout("wrap 6"));
addPropertyChangeListeners();
update();
}
/**
* Cleans up this DocksPanel.
*/
public void cleanup() {
removePropertyChangeListeners();
}
/**
* Update this DocksPanel.
*/
public void update() {
removeAll();
List<Unit> units = europe.getUnitList();
for (Unit unit : units) {
if (!unit.isNaval()) {
UnitLabel unitLabel = new UnitLabel(getFreeColClient(), unit, getGUI());
unitLabel.setTransferHandler(defaultTransferHandler);
unitLabel.addMouseListener(pressListener);
add(unitLabel);
}
}
revalidate();
repaint();
}
public Component add(Component comp, boolean editState) {
Component c = add(comp);
update();
return c;
}
@Override
public void remove(Component comp) {
update();
}
public void addPropertyChangeListeners() {
europe.addPropertyChangeListener(this);
}
public void removePropertyChangeListeners() {
europe.removePropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent event) {
logger.finest("Europe-docks change " + event.getPropertyName()
+ ": " + event.getOldValue()
+ " -> " + event.getNewValue());
update();
}
}
/**
* A panel that shows goods available for purchase in Europe.
*/
public final class MarketPanel extends JPanel {
private final EuropePanel europePanel;
/**
* Creates this MarketPanel.
*
* @param europePanel The panel that holds this CargoPanel.
*/
public MarketPanel(EuropePanel europePanel) {
this.europePanel = europePanel;
setLayout(new GridLayout(2, 8));
}
/**
* Initialize this MarketPanel.
*/
public void initialize() {
removeAll();
List<GoodsType> goodsTypes = getSpecification().getGoodsTypeList();
Market market = getMyPlayer().getMarket();
for (GoodsType goodsType : goodsTypes) {
if (goodsType.isStorable()) {
MarketLabel marketLabel
= new MarketLabel(goodsType, market, getGUI());
marketLabel.setTransferHandler(defaultTransferHandler);
marketLabel.addMouseListener(pressListener);
add(marketLabel);
}
}
}
/**
* Cleans up this MarketPanel.
*/
public void cleanup() {}
/**
* If a GoodsLabel is dropped here, sell the goods.
*
* @param comp The component to add to this MarketPanel.
* @param editState Must be set to 'true' if the state of the component
* that is added (which should be a dropped component
* representing goods) should be sold.
* @return The component argument.
*/
public Component add(Component comp, boolean editState) {
if (editState) {
if (!(comp instanceof GoodsLabel)) {
logger.warning("Invalid component dropped on this MarketPanel.");
return null;
}
Goods goods = ((GoodsLabel) comp).getGoods();
if (getMyPlayer().canTrade(goods)) {
getController().sellGoods(goods);
} else {
switch (getGUI().showBoycottedGoodsDialog(goods, europe)) {
case PAY_ARREARS:
getController().payArrears(goods.getType());
break;
case DUMP_CARGO:
getController().unloadCargo(goods, true);
break;
case CANCEL:
default:
break;
}
}
cargoPanel.revalidate();
revalidate();
getController().nextModelMessage();
}
europePanel.refresh();
return comp;
}
public void remove(Component comp) {
// Don't remove market labels.
}
}
/**
* To log transactions made in Europe
*/
public class TransactionLog extends JTextPane
implements TransactionListener {
public TransactionLog() {
setEditable(false);
}
/**
* Initializes this TransactionLog.
*/
public void initialize() {
getMyPlayer().getMarket().addTransactionListener(this);
setText("");
}
/**
* Cleans up this TransactionLog.
*/
public void cleanup() {
getMyPlayer().getMarket().removeTransactionListener(this);
}
public void logPurchase(GoodsType goodsType, int amount, int price) {
int total = amount * price;
String text = Messages.message(StringTemplate.template("transaction.purchase")
.add("%goods%", goodsType.getNameKey())
.addAmount("%amount%", amount)
.addAmount("%gold%", price))
+ "\n" + Messages.message(StringTemplate.template("transaction.price")
.addAmount("%gold%", total));
add(text);
}
public void logSale(GoodsType goodsType, int amount, int price, int tax) {
int totalBeforeTax = amount * price;
int totalTax = totalBeforeTax * tax / 100;
int totalAfterTax = totalBeforeTax - totalTax;
String text = Messages.message(StringTemplate.template("transaction.sale")
.add("%goods%", goodsType.getNameKey())
.addAmount("%amount%", amount)
.addAmount("%gold%", price))
+ "\n" + Messages.message(StringTemplate.template("transaction.price")
.addAmount("%gold%", totalBeforeTax))
+ "\n" + Messages.message(StringTemplate.template("transaction.tax")
.addAmount("%tax%", tax)
.addAmount("%gold%", totalTax))
+ "\n" + Messages.message(StringTemplate.template("transaction.net")
.addAmount("%gold%", totalAfterTax));
add(text);
}
private void add(String text) {
StyledDocument doc = getStyledDocument();
try {
if (doc.getLength() > 0) {
text = "\n\n" + text;
}
doc.insertString(doc.getLength(), text, null);
} catch(Exception e) {
logger.warning("Failed to update transaction log: " + e.toString());
}
}
}
public class EuropeButton extends JButton {
public EuropeButton(String text, int keyEvent, String command,
ActionListener listener) {
setOpaque(true);
setText(text);
setActionCommand(command);
addActionListener(listener);
InputMap closeInputMap = new ComponentInputMap(this);
closeInputMap.put(KeyStroke.getKeyStroke(keyEvent, 0, false),
"pressed");
closeInputMap.put(KeyStroke.getKeyStroke(keyEvent, 0, true),
"released");
SwingUtilities.replaceUIInputMap(this, JComponent.WHEN_IN_FOCUSED_WINDOW, closeInputMap);
enterPressesWhenFocused(this);
}
}
}