package games.strategy.triplea.ui; import java.awt.CardLayout; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import games.strategy.engine.data.GameData; import games.strategy.engine.data.PlayerID; import games.strategy.engine.data.ProductionRule; import games.strategy.engine.data.RepairRule; import games.strategy.engine.data.Territory; import games.strategy.engine.data.Unit; import games.strategy.engine.gamePlayer.IPlayerBridge; import games.strategy.triplea.attachments.PoliticalActionAttachment; import games.strategy.triplea.attachments.UserActionAttachment; import games.strategy.triplea.delegate.AbstractMoveDelegate.MoveType; import games.strategy.triplea.delegate.IBattle.BattleType; import games.strategy.triplea.delegate.dataObjects.FightBattleDetails; import games.strategy.triplea.delegate.dataObjects.MoveDescription; import games.strategy.triplea.delegate.dataObjects.TechRoll; import games.strategy.triplea.delegate.remote.IPoliticsDelegate; import games.strategy.triplea.delegate.remote.IUserActionDelegate; import games.strategy.util.IntegerMap; import games.strategy.util.Tuple; /** * Root panel for all action buttons in a triplea game. <br> */ public class ActionButtons extends JPanel { private static final long serialVersionUID = 2175685892863042399L; private final CardLayout m_layout = new CardLayout(); private BattlePanel m_battlePanel; private MovePanel m_movePanel; private PurchasePanel m_purchasePanel; private RepairPanel m_repairPanel; private PlacePanel m_placePanel; private TechPanel m_techPanel; private EndTurnPanel m_endTurnPanel; private MoveForumPosterPanel m_moveForumPosterPanel; private ActionPanel m_current; private PoliticsPanel m_politicsPanel; private UserActionPanel m_userActionPanel; private PickTerritoryAndUnitsPanel m_pickTerritoryAndUnitsPanel; /** Creates new ActionButtons. */ public ActionButtons(final GameData data, final MapPanel map, final MovePanel movePanel, final TripleAFrame parent) { m_battlePanel = new BattlePanel(data, map); m_movePanel = movePanel; m_purchasePanel = new PurchasePanel(data, map); m_repairPanel = new RepairPanel(data, map); m_placePanel = new PlacePanel(data, map, parent); m_techPanel = new TechPanel(data, map); m_endTurnPanel = new EndTurnPanel(data, map); m_moveForumPosterPanel = new MoveForumPosterPanel(data, map); m_politicsPanel = new PoliticsPanel(data, map, parent); m_userActionPanel = new UserActionPanel(data, map, parent); m_pickTerritoryAndUnitsPanel = new PickTerritoryAndUnitsPanel(data, map, parent); m_current = m_techPanel; setLayout(m_layout); add(new JLabel(""), ""); add(m_battlePanel, m_battlePanel.toString()); add(m_movePanel, m_movePanel.toString()); add(m_repairPanel, m_repairPanel.toString()); add(m_purchasePanel, m_purchasePanel.toString()); add(m_placePanel, m_placePanel.toString()); add(m_techPanel, m_techPanel.toString()); add(m_endTurnPanel, m_endTurnPanel.toString()); add(m_moveForumPosterPanel, m_moveForumPosterPanel.toString()); add(m_politicsPanel, m_politicsPanel.toString()); add(m_userActionPanel, m_userActionPanel.toString()); add(m_pickTerritoryAndUnitsPanel, m_pickTerritoryAndUnitsPanel.toString()); // this should not be necceessary // but it makes tracking down garbage leaks easier // in the profiler // since it removes a lot of links // between objects // and if there is a memory leak // this will minimize the damage map.getUIContext().addActive(() -> { removeAll(); m_current = null; m_battlePanel.removeAll(); m_movePanel.removeAll(); m_repairPanel.removeAll(); m_purchasePanel.removeAll(); m_placePanel.removeAll(); m_techPanel.removeAll(); m_endTurnPanel.removeAll(); m_moveForumPosterPanel.removeAll(); m_politicsPanel.removeAll(); m_userActionPanel.removeAll(); m_pickTerritoryAndUnitsPanel.removeAll(); m_battlePanel = null; m_movePanel = null; m_repairPanel = null; m_purchasePanel = null; m_placePanel = null; m_techPanel = null; m_endTurnPanel = null; m_moveForumPosterPanel = null; m_politicsPanel = null; m_userActionPanel = null; m_pickTerritoryAndUnitsPanel = null; }); } public void changeToMove(final PlayerID id, final boolean nonCombat, final String stepName) { m_movePanel.setNonCombat(nonCombat); final boolean airBorne = stepName.endsWith("AirborneCombatMove"); final String displayText = (airBorne ? " Airborne" : (nonCombat ? " Non" : "")); m_movePanel.setDisplayText(displayText + " Combat Move"); m_movePanel.setMoveType(airBorne ? MoveType.SPECIAL : MoveType.DEFAULT); changeTo(id, m_movePanel); } public void changeToRepair(final PlayerID id) { changeTo(id, m_repairPanel); } public void changeToProduce(final PlayerID id) { changeTo(id, m_purchasePanel); } public void changeToPlace(final PlayerID id) { changeTo(id, m_placePanel); } public void changeToBattle(final PlayerID id, final Map<BattleType, Collection<Territory>> battles) { m_battlePanel.setBattlesAndBombing(battles); changeTo(id, m_battlePanel); } public void changeToPolitics(final PlayerID id) { changeTo(id, m_politicsPanel); } public void changeToUserActions(final PlayerID id) { changeTo(id, m_userActionPanel); } public void changeToTech(final PlayerID id) { changeTo(id, m_techPanel); } public void changeToEndTurn(final PlayerID id) { changeTo(id, m_endTurnPanel); } public void changeToMoveForumPosterPanel(final PlayerID id) { changeTo(id, m_moveForumPosterPanel); } private void changeTo(final PlayerID id, final ActionPanel newCurrent) { m_current.setActive(false); m_current = newCurrent; // newCurrent might be null if we are shutting down if (m_current == null) { return; } m_current.display(id); final String currentName = m_current.toString(); SwingUtilities.invokeLater(() -> { if (m_layout != null) { m_layout.show(ActionButtons.this, currentName); } }); } public void changeToPickTerritoryAndUnits(final PlayerID id) { changeTo(id, m_pickTerritoryAndUnitsPanel); } /** * Blocks until the user selects their purchase. * * @return null if no move was made. */ public IntegerMap<ProductionRule> waitForPurchase(final boolean bid) { return m_purchasePanel.waitForPurchase(bid); } /** * Blocks until the user selects their purchase. * * @return null if no move was made. */ public HashMap<Unit, IntegerMap<RepairRule>> waitForRepair(final boolean bid, final Collection<PlayerID> allowedPlayersToRepair) { return m_repairPanel.waitForRepair(bid, allowedPlayersToRepair); } /** * Blocks until the user moves units. * * @return null if no move was made. */ public MoveDescription waitForMove(final IPlayerBridge bridge) { return m_movePanel.waitForMove(bridge); } /** * Blocks until the user selects the number of tech rolls. * * @return null if no tech roll was made. */ public TechRoll waitForTech() { return m_techPanel.waitForTech(); } /** * Blocks until the user selects a political action to attempt * * @return null if no action was picked. */ public PoliticalActionAttachment waitForPoliticalAction(final boolean firstRun, final IPoliticsDelegate iPoliticsDelegate) { return m_politicsPanel.waitForPoliticalAction(firstRun, iPoliticsDelegate); } /** * Blocks until the user selects a user action to attempt * * @return null if no action was picked. */ public UserActionAttachment waitForUserActionAction(final boolean firstRun, final IUserActionDelegate iUserActionDelegate) { return m_userActionPanel.waitForUserActionAction(firstRun, iUserActionDelegate); } /** * Blocks until the user selects units to place. * * @return null if no placement was made. */ public PlaceData waitForPlace(final boolean bid, final IPlayerBridge bridge) { return m_placePanel.waitForPlace(bid, bridge); } /** * Blocks until the user selects an end-of-turn action. */ public void waitForEndTurn(final TripleAFrame frame, final IPlayerBridge bridge) { m_endTurnPanel.waitForEndTurn(frame, bridge); } public void waitForMoveForumPosterPanel(final TripleAFrame frame, final IPlayerBridge bridge) { m_moveForumPosterPanel.waitForDone(frame, bridge); } /** * Blocks until the user selects a battle to fight. */ public FightBattleDetails waitForBattleSelection() { return m_battlePanel.waitForBattleSelection(); } public Tuple<Territory, Set<Unit>> waitForPickTerritoryAndUnits(final List<Territory> territoryChoices, final List<Unit> unitChoices, final int unitsPerPick) { return m_pickTerritoryAndUnitsPanel.waitForPickTerritoryAndUnits(territoryChoices, unitChoices, unitsPerPick); } public ActionPanel getCurrent() { return m_current; } public BattlePanel getBattlePanel() { return m_battlePanel; } public AbstractMovePanel getMovePanel() { return m_movePanel; } public PlacePanel getPlacePanel() { return m_placePanel; } public PurchasePanel getPurchasePanel() { return m_purchasePanel; } public TechPanel getTechPanel() { return m_techPanel; } public EndTurnPanel getEndTurnPanel() { return m_endTurnPanel; } public MoveForumPosterPanel getMoveForumPosterPanel() { return m_moveForumPosterPanel; } }