/* * AtBScenarioViewPanel.java * * Copyright (C) 2014-2016 MegaMek team * Copyright (c) 2014 Carl Spain. All rights reserved. * * This file is part of MekHQ. * * MekHQ 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 3 of the License, or * (at your option) any later version. * * MekHQ 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 MekHQ. If not, see <http://www.gnu.org/licenses/>. */ package mekhq.gui.view; import java.awt.Color; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.ResourceBundle; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.event.MouseInputAdapter; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import megamek.client.ui.swing.UnitEditorDialog; import megamek.common.Crew; import megamek.common.IStartingPositions; import megamek.common.PlanetaryConditions; import megamek.common.util.EncodeControl; import mekhq.IconPackage; import mekhq.campaign.Campaign; import mekhq.campaign.force.Force; import mekhq.campaign.force.ForceStub; import mekhq.campaign.force.UnitStub; import mekhq.campaign.mission.AtBScenario; import mekhq.campaign.mission.AtBScenario.BotForceStub; import mekhq.campaign.mission.Loot; import mekhq.gui.dialog.PrincessBehaviorDialog; /** * @author Neoancient * */ public class AtBScenarioViewPanel extends JPanel { private static final long serialVersionUID = -3104784717190158181L; private AtBScenario scenario; private Campaign campaign; private ForceStub playerForces; private ArrayList<String> attachedAllyStub; private ArrayList<BotForceStub> botStubs; private IconPackage icons; private JFrame frame; private JPanel panStats; private JLabel lblStatus = new JLabel(); private JLabel lblStatusDesc = new JLabel(); private JLabel lblType = new JLabel(); private JLabel lblTypeDesc = new JLabel(); private JLabel lblForce = new JLabel(); private JLabel lblForceDesc = new JLabel(); private JLabel lblTerrain = new JLabel(); private JLabel lblTerrainDesc = new JLabel(); private JLabel lblMap = new JLabel(); private JLabel lblMapDesc = new JLabel(); private JLabel lblMapSize = new JLabel(); private JLabel lblMapSizeDesc = new JLabel(); private JLabel lblLight = new JLabel(); private JLabel lblLightDesc = new JLabel(); private JLabel lblWeather = new JLabel(); private JLabel lblWeatherDesc = new JLabel(); private JLabel lblWind = new JLabel(); private JLabel lblWindDesc = new JLabel(); private JLabel lblFog = new JLabel(); private JLabel lblFogDesc = new JLabel(); private JLabel lblAtmosphere = new JLabel(); private JLabel lblAtmosphereDesc = new JLabel(); private JLabel lblGravity = new JLabel(); private JLabel lblGravityDesc = new JLabel(); private JLabel lblPlayerStart = new JLabel(); private JLabel lblPlayerStartPos = new JLabel(); private JTextArea txtDetails = new JTextArea(); private final static int REROLL_TERRAIN = 0; private final static int REROLL_MAP = 1; private final static int REROLL_MAPSIZE = 2; private final static int REROLL_LIGHT = 3; private final static int REROLL_WEATHER = 4; private final static int REROLL_NUM = 5; private JCheckBox[] chkReroll = new JCheckBox[REROLL_NUM]; JButton btnReroll; private JTree playerForceTree; private JTextArea txtDesc; private JTextArea txtReport; private StubTreeModel playerForceModel; private static final String[] battleResourceKeys = { "baseAttack", "extraction", "chase", "holdTheLine", "breakthrough", "hideAndSeek", "standup", "reconRaid", "probe", "officerDuel", "aceDuel", "ambush", "civilianHelp", "alliedTraitors", "prisonBreak", "starLeagueCache1", "starLeagueCache2", "allyRescue", "civilianRiot", "convoyRescue", "convoyAttack", "pirateFreeForAll" }; public AtBScenarioViewPanel(AtBScenario s, Campaign c, IconPackage ip, JFrame frame) { this.frame = frame; this.scenario = s; this.campaign = c; this.icons = ip; botStubs = new ArrayList<BotForceStub>(); if(s.isCurrent()) { s.refresh(c); this.playerForces = new ForceStub(s.getForces(campaign), campaign); attachedAllyStub = s.generateEntityStub(s.getAlliesPlayer()); for (int i = 0; i < s.getNumBots(); i++) { botStubs.add(s.generateBotStub(s.getBotForce(i))); } } else { this.playerForces = s.getForceStub(); attachedAllyStub = s.getAlliesPlayerStub(); botStubs = s.getBotForceStubs(); } playerForceModel = new StubTreeModel(playerForces); initComponents(); } private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; panStats = new JPanel(); txtDesc = new JTextArea(); txtReport = new JTextArea(); playerForceTree = new JTree(); setLayout(new GridBagLayout()); setBackground(Color.WHITE); int y = 0; panStats.setName("pnlStats"); panStats.setBorder(BorderFactory.createTitledBorder(scenario.getName())); panStats.setBackground(Color.WHITE); fillStats(); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridheight = 1; gridBagConstraints.weightx = 0.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 20); gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; add(panStats, gridBagConstraints); txtReport.setName("txtReport"); txtReport.setText(scenario.getReport()); txtReport.setEditable(false); txtReport.setLineWrap(true); txtReport.setWrapStyleWord(true); txtReport.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("After-Action Report"), BorderFactory.createEmptyBorder(5,5,5,5))); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; add(txtReport, gridBagConstraints); } private void fillStats() { ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.AtBScenarioViewPanel", new EncodeControl()); //$NON-NLS-1$ lblStatus = new javax.swing.JLabel(); GridBagConstraints gridBagConstraints = new GridBagConstraints(); panStats.setLayout(new java.awt.GridBagLayout()); int y = 0; lblStatus.setName("lblStatus"); // NOI18N lblStatus.setText(resourceMap.getString("lblStatus.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 0.0; gridBagConstraints.fill = GridBagConstraints.NONE; gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; panStats.add(lblStatus, gridBagConstraints); lblStatusDesc.setName("lblOwner"); // NOI18N lblStatusDesc.setText(scenario.getStatusName()); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblStatusDesc, gridBagConstraints); playerForceTree.setModel(playerForceModel); playerForceTree.setCellRenderer(new ForceStubRenderer()); playerForceTree.setRowHeight(50); playerForceTree.setRootVisible(false); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 3; gridBagConstraints.gridheight = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 20); gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(playerForceTree, gridBagConstraints); if (attachedAllyStub.size() > 0) { DefaultMutableTreeNode top = new DefaultMutableTreeNode("Attached Allies"); for (String en : attachedAllyStub) { top.add(new DefaultMutableTreeNode(en)); } JTree tree = new JTree(top); tree.collapsePath(new TreePath(top)); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 3; gridBagConstraints.gridheight = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 20); gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(tree, gridBagConstraints); } for (int i = 0; i < botStubs.size(); i++) { if (null == botStubs.get(i)) { continue; } DefaultMutableTreeNode top = new DefaultMutableTreeNode(botStubs.get(i).getName()); for (String en : botStubs.get(i).getEntityList()) { top.add(new DefaultMutableTreeNode(en)); } JTree tree = new JTree(top); tree.collapsePath(new TreePath(top)); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 3; gridBagConstraints.gridheight = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 20); gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(tree, gridBagConstraints); if (scenario.isCurrent()) { tree.addMouseListener(new TreeMouseAdapter(tree, i)); } } gridBagConstraints = new GridBagConstraints(); lblType.setText(resourceMap.getString("lblType.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.fill = GridBagConstraints.NONE; gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; panStats.add(lblType, gridBagConstraints); lblTypeDesc.setText(scenario.getDesc()); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblTypeDesc, gridBagConstraints); if (scenario.isCurrent()) { lblForce.setText(resourceMap.getString("lblForce.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblForce, gridBagConstraints); if (null != scenario.getLance(campaign)) { lblForceDesc.setText(campaign.getForce(scenario.getLanceForceId()).getFullName()); } gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 1; panStats.add(lblForceDesc, gridBagConstraints); } chkReroll[REROLL_TERRAIN] = new JCheckBox(); lblTerrain.setText(resourceMap.getString("lblTerrain.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblTerrain, gridBagConstraints); if (scenario.isCurrent()) { gridBagConstraints.gridx = 1; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(chkReroll[REROLL_TERRAIN], gridBagConstraints); chkReroll[REROLL_TERRAIN].setVisible(scenario.getRerollsRemaining() > 0 && scenario.canRerollTerrain()); chkReroll[REROLL_TERRAIN].addItemListener(checkBoxListener); } lblTerrainDesc.setText(AtBScenario.terrainTypes[scenario.getTerrainType()]); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblTerrainDesc, gridBagConstraints); lblMap.setText(resourceMap.getString("lblMap.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblMap, gridBagConstraints); chkReroll[REROLL_MAP] = new JCheckBox(); if (scenario.isCurrent()) { gridBagConstraints.gridx = 1; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(chkReroll[REROLL_MAP], gridBagConstraints); chkReroll[REROLL_MAP].setVisible(scenario.getRerollsRemaining() > 0 && scenario.canRerollMap()); chkReroll[REROLL_MAP].addItemListener(checkBoxListener); } lblMapDesc.setText(scenario.getMap()); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblMapDesc, gridBagConstraints); lblMapSize.setText(resourceMap.getString("lblMapSize.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblMapSize, gridBagConstraints); chkReroll[REROLL_MAPSIZE] = new JCheckBox(); if (scenario.isCurrent()) { gridBagConstraints.gridx = 1; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(chkReroll[REROLL_MAPSIZE], gridBagConstraints); chkReroll[REROLL_MAPSIZE].setVisible(scenario.getRerollsRemaining() > 0 && scenario.canRerollMapSize()); chkReroll[REROLL_MAPSIZE].addItemListener(checkBoxListener); } lblMapSizeDesc.setText(scenario.getMapX() + "x" + scenario.getMapY()); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblMapSizeDesc, gridBagConstraints); lblLight.setText(resourceMap.getString("lblLight.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblLight, gridBagConstraints); chkReroll[REROLL_LIGHT] = new JCheckBox(); if (scenario.isCurrent() && campaign.getCampaignOptions().getUseLightConditions()) { gridBagConstraints.gridx = 1; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(chkReroll[REROLL_LIGHT], gridBagConstraints); chkReroll[REROLL_LIGHT].setVisible(scenario.getRerollsRemaining() > 0 && scenario.canRerollLight()); chkReroll[REROLL_LIGHT].addItemListener(checkBoxListener); } lblLightDesc.setText(PlanetaryConditions.getLightDisplayableName(scenario.getLight())); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblLightDesc, gridBagConstraints); lblLight.setVisible(campaign.getCampaignOptions().getUseLightConditions()); lblLightDesc.setVisible(campaign.getCampaignOptions().getUseLightConditions()); lblWeather.setText(resourceMap.getString("lblWeather.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblWeather, gridBagConstraints); chkReroll[REROLL_WEATHER] = new JCheckBox(); if (scenario.isCurrent() && campaign.getCampaignOptions().getUseWeatherConditions()) { gridBagConstraints.gridx = 1; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(chkReroll[REROLL_WEATHER], gridBagConstraints); chkReroll[REROLL_WEATHER].setVisible(scenario.getRerollsRemaining() > 0 && scenario.canRerollWeather()); chkReroll[REROLL_WEATHER].addItemListener(checkBoxListener); } lblWeatherDesc.setText(PlanetaryConditions.getWeatherDisplayableName(scenario.getWeather())); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblWeatherDesc, gridBagConstraints); lblWeather.setVisible(campaign.getCampaignOptions().getUseWeatherConditions()); lblWeatherDesc.setVisible(campaign.getCampaignOptions().getUseWeatherConditions()); lblWind.setText(resourceMap.getString("lblWind.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblWind, gridBagConstraints); lblWindDesc.setText(PlanetaryConditions.getWindDisplayableName(scenario.getWind())); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblWindDesc, gridBagConstraints); lblWind.setVisible(campaign.getCampaignOptions().getUseWeatherConditions()); lblWindDesc.setVisible(campaign.getCampaignOptions().getUseWeatherConditions()); lblFog.setText(resourceMap.getString("lblFog.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblFog, gridBagConstraints); lblFogDesc.setText(PlanetaryConditions.getFogDisplayableName(scenario.getFog())); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblFogDesc, gridBagConstraints); lblFog.setVisible(campaign.getCampaignOptions().getUseWeatherConditions()); lblFogDesc.setVisible(campaign.getCampaignOptions().getUseWeatherConditions()); lblGravity.setText(resourceMap.getString("lblGravity.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblGravity, gridBagConstraints); lblGravityDesc.setText((new DecimalFormat()).format(scenario.getGravity())); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblGravityDesc, gridBagConstraints); lblGravity.setVisible(scenario.getGravity() != 1.0); lblGravityDesc.setVisible(scenario.getGravity() != 1.0); lblAtmosphere.setText(resourceMap.getString("lblAtmosphere.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblAtmosphere, gridBagConstraints); lblAtmosphereDesc.setText(PlanetaryConditions.getAtmosphereDisplayableName(scenario.getAtmosphere())); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblAtmosphereDesc, gridBagConstraints); lblAtmosphere.setVisible(scenario.getAtmosphere() != PlanetaryConditions.ATMO_STANDARD); lblAtmosphereDesc.setVisible(scenario.getAtmosphere() != PlanetaryConditions.ATMO_STANDARD); lblPlayerStart.setText(resourceMap.getString("lblPlayerStart.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y; gridBagConstraints.gridwidth = 1; panStats.add(lblPlayerStart, gridBagConstraints); lblPlayerStartPos.setText(IStartingPositions.START_LOCATION_NAMES[scenario.getStart()]); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = y++; panStats.add(lblPlayerStartPos, gridBagConstraints); if (scenario.isCurrent()) { btnReroll = new JButton(scenario.getRerollsRemaining() + " Reroll" + ((scenario.getRerollsRemaining() == 1)?"":"s") + " Remaining"); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 1; panStats.add(btnReroll, gridBagConstraints); btnReroll.setEnabled(scenario.getRerollsRemaining() > 0); btnReroll.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { rerollBattleConditions(); } }); } txtDetails.setLineWrap(true); txtDetails.setWrapStyleWord(true); txtDetails.setEditable(false); if (scenario.getBattleType() < AtBScenario.SPECIALMISSIONS) { txtDetails.setText("Victory Conditions:\n" + resourceMap.getString("battleDetails." + battleResourceKeys[scenario.getBattleType()] + (scenario.isAttacker()? ".attacker.victory": ".defender.victory")) + "\n\n" + "Observations:\n" + resourceMap.getString("battleDetails." + battleResourceKeys[scenario.getBattleType()] + (scenario.isAttacker()? ".attacker.observations": ".defender.observations"))); } else if (scenario.getBattleType() < AtBScenario.BIGBATTLES) { txtDetails.setText("Details:\n" + resourceMap.getString("battleDetails." + battleResourceKeys[scenario.getBattleType()] + ".description")); } else { txtDetails.setText("Special Conditions:\n" + resourceMap.getString("battleDetails." + battleResourceKeys[scenario.getBattleType()] + ".specialConditions") + "\n\n" + "Victory Conditions:\n" + resourceMap.getString("battleDetails." + battleResourceKeys[scenario.getBattleType()] + ".victory") + "\n\n" + "Observations:\n" + resourceMap.getString("battleDetails." + battleResourceKeys[scenario.getBattleType()] + ".observations")); } gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 3; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 20); gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(txtDetails, gridBagConstraints); txtDesc.setName("txtDesc"); txtDesc.setText(scenario.getDescription()); txtDesc.setEditable(false); txtDesc.setLineWrap(true); txtDesc.setWrapStyleWord(true); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 20); gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(txtDesc, gridBagConstraints); if(scenario.getLoot().size() > 0) { gridBagConstraints.gridx = 0; gridBagConstraints.gridy = y++; gridBagConstraints.gridwidth = 2; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 0.0; gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); gridBagConstraints.fill = java.awt.GridBagConstraints.NONE; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(new JLabel("<html><b>Potential Rewards:</b></html>"), gridBagConstraints); for(Loot loot : scenario.getLoot()) { gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; gridBagConstraints.gridwidth = 2; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 0.0; gridBagConstraints.insets = new java.awt.Insets(0, 10, 5, 0); gridBagConstraints.fill = java.awt.GridBagConstraints.NONE; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; panStats.add(new JLabel(loot.getShortDescription()), gridBagConstraints); } } } private ItemListener checkBoxListener = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { countRerollBoxes(); } }; private void countRerollBoxes() { int checkedBoxes = 0; for (int i = 0; i < REROLL_NUM; i++) { if (chkReroll[i].isSelected()) checkedBoxes++; } /* Once the number of checked boxes hits the number of rerolls * remaining, any boxes that aren't checked need to be disabled. * If the number falls below that, all are re-enabled. */ for (int i = 0; i < REROLL_NUM; i++) { chkReroll[i].setEnabled(checkedBoxes < scenario.getRerollsRemaining() || chkReroll[i].isSelected()); } } private void rerollBattleConditions() { if (chkReroll[REROLL_TERRAIN].isSelected()) { scenario.setTerrain(); scenario.setMapFile(); scenario.useReroll(); chkReroll[REROLL_TERRAIN].setSelected(false); lblTerrainDesc.setText(AtBScenario.terrainTypes[scenario.getTerrainType()]); lblMapDesc.setText(scenario.getMap()); } if (chkReroll[REROLL_MAP].isSelected()) { scenario.setMapFile(); scenario.useReroll(); chkReroll[REROLL_MAP].setSelected(false); lblMapDesc.setText(scenario.getMap()); } if (chkReroll[REROLL_MAPSIZE].isSelected()) { scenario.setMapSize(); scenario.useReroll(); chkReroll[REROLL_MAPSIZE].setSelected(false); lblMapSizeDesc.setText(scenario.getMapX() + "x" + scenario.getMapY()); } if (chkReroll[REROLL_LIGHT].isSelected()) { scenario.setLightConditions(); scenario.useReroll(); chkReroll[REROLL_LIGHT].setSelected(false); lblLightDesc.setText(PlanetaryConditions.getLightDisplayableName(scenario.getLight())); } if (chkReroll[REROLL_WEATHER].isSelected()) { scenario.setWeather(); scenario.useReroll(); chkReroll[REROLL_WEATHER].setSelected(false); lblWeatherDesc.setText(PlanetaryConditions.getWeatherDisplayableName(scenario.getWeather())); lblWindDesc.setText(PlanetaryConditions.getWindDisplayableName(scenario.getWind())); lblFogDesc.setText(PlanetaryConditions.getFogDisplayableName(scenario.getFog())); } btnReroll.setText(scenario.getRerollsRemaining() + " Reroll" + ((scenario.getRerollsRemaining() == 1)?"":"s") + " Remaining"); btnReroll.setEnabled(scenario.getRerollsRemaining() > 0); countRerollBoxes(); } protected class StubTreeModel implements TreeModel { private ForceStub rootForce; private Vector<TreeModelListener> listeners = new Vector<TreeModelListener>(); public StubTreeModel(ForceStub root) { rootForce = root; } @Override public Object getChild(Object parent, int index) { if(parent instanceof ForceStub) { return ((ForceStub)parent).getAllChildren().get(index); } return null; } @Override public int getChildCount(Object parent) { if(parent instanceof ForceStub) { return ((ForceStub)parent).getAllChildren().size(); } return 0; } @Override public int getIndexOfChild(Object parent, Object child) { if(parent instanceof ForceStub) { return ((ForceStub)parent).getAllChildren().indexOf(child); } return 0; } @Override public Object getRoot() { return rootForce; } @Override public boolean isLeaf(Object node) { return node instanceof UnitStub || (node instanceof ForceStub && ((ForceStub)node).getAllChildren().size() == 0); } @Override public void valueForPathChanged(TreePath arg0, Object arg1) { // Auto-generated method stub } @Override public void addTreeModelListener( TreeModelListener listener ) { if ( listener != null && !listeners.contains( listener ) ) { listeners.addElement( listener ); } } @Override public void removeTreeModelListener( TreeModelListener listener ) { if ( listener != null ) { listeners.removeElement( listener ); } } } protected class ForceStubRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = 4076620029822185784L; public ForceStubRenderer() { } @Override public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasFocus); //setOpaque(true); setIcon(getIcon(value)); return this; } protected Icon getIcon(Object node) { if(node instanceof UnitStub) { return getIconFrom((UnitStub)node); } else if(node instanceof ForceStub) { return getIconFrom((ForceStub)node); } else { return null; } } protected Icon getIconFrom(UnitStub unit) { String category = unit.getPortraitCategory(); String filename = unit.getPortraitFileName(); if(Crew.ROOT_PORTRAIT.equals(category)) { category = ""; } // Return a null if the player has selected no portrait file. if ((null == category) || (null == filename) || Crew.PORTRAIT_NONE.equals(filename)) { filename = "default.gif"; } // Try to get the player's portrait file. Image portrait = null; try { portrait = (Image) icons.getPortraits().getItem(category, filename); if(null != portrait) { portrait = portrait.getScaledInstance(50, -1, Image.SCALE_DEFAULT); } else { portrait = (Image) icons.getPortraits().getItem("", "default.gif"); if(null != portrait) { portrait = portrait.getScaledInstance(50, -1, Image.SCALE_DEFAULT); } } return new ImageIcon(portrait); } catch (Exception err) { err.printStackTrace(); return null; } } protected Icon getIconFrom(ForceStub force) { String category = force.getIconCategory(); String filename = force.getIconFileName(); LinkedHashMap<String, Vector<String>> iconMap = force.getIconMap(); if(Crew.ROOT_PORTRAIT.equals(category)) { category = ""; } // Return a null if the player has selected no portrait file. if ((null == category) || (null == filename) || (Crew.PORTRAIT_NONE.equals(filename) && !Force.ROOT_LAYERED.equals(category))) { filename = "empty.png"; } // Try to get the player's portrait file. Image portrait = null; try { portrait = IconPackage.buildForceIcon(category, filename, icons.getForceIcons(), iconMap); if(null != portrait) { portrait = portrait.getScaledInstance(58, -1, Image.SCALE_SMOOTH); } else { portrait = (Image) icons.getForceIcons().getItem("", "empty.png"); if(null != portrait) { portrait = portrait.getScaledInstance(58, -1, Image.SCALE_SMOOTH); } } return new ImageIcon(portrait); } catch (Exception err) { err.printStackTrace(); return null; } } } protected class EntityListModel implements TreeModel { private ArrayList<String> root; private Vector<TreeModelListener> listeners = new Vector<TreeModelListener>(); private String name; public EntityListModel(ArrayList<String> root, String name) { this.root = root; this.name = name; } public String getName() { return name; } @Override public Object getChild(Object parent, int index) { if(parent instanceof ArrayList<?>) { return ((ArrayList<?>)parent).get(index); } return null; } @Override public int getChildCount(Object parent) { if(parent instanceof ArrayList<?>) { return ((ArrayList<?>)parent).size(); } return 0; } @Override public int getIndexOfChild(Object parent, Object child) { if(parent instanceof ArrayList<?>) { return ((ArrayList<?>)parent).indexOf(child); } return 0; } @Override public Object getRoot() { return root; } @Override public boolean isLeaf(Object node) { return node instanceof String; } @Override public void valueForPathChanged(TreePath arg0, Object arg1) { // Auto-generated method stub } @Override public void addTreeModelListener( TreeModelListener listener ) { if ( listener != null && !listeners.contains( listener ) ) { listeners.addElement( listener ); } } @Override public void removeTreeModelListener( TreeModelListener listener ) { if ( listener != null ) { listeners.removeElement( listener ); } } } private class TreeMouseAdapter extends MouseInputAdapter implements ActionListener { private JTree tree; int index; public TreeMouseAdapter(JTree tree, int index) { this.tree = tree; this.index = index; } @Override public void actionPerformed(ActionEvent action) { String command = action.getActionCommand(); if (command.equalsIgnoreCase("CONFIG_BOT")) { PrincessBehaviorDialog pbd = new PrincessBehaviorDialog(frame, scenario.getBotForce(index).getBehaviorSettings(), scenario.getBotForce(index).getName()); pbd.setVisible(true); if (!pbd.dialogAborted) { scenario.getBotForce(index).setBehaviorSettings(pbd.getBehaviorSettings()); scenario.getBotForce(index).setName(pbd.getBotName()); } } else if (command.equalsIgnoreCase("EDIT_UNIT")) { if (tree.getSelectionCount() > 0) { // row 0 is root node int i = tree.getSelectionRows()[0] - 1; UnitEditorDialog med = new UnitEditorDialog(frame, scenario.getBotForce(index).getEntityList().get(i)); med.setVisible(true); } } } @Override public void mousePressed(MouseEvent e) { maybeShowPopup(e); } @Override public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { JPopupMenu popup = new JPopupMenu(); if (e.isPopupTrigger()) { TreePath path = tree.getPathForLocation(e.getX(), e.getY()); JMenuItem menuItem = null; if (path.getPathCount() > 1) { menuItem = new JMenuItem("Edit Unit..."); menuItem.setActionCommand("EDIT_UNIT"); menuItem.addActionListener(this); popup.add(menuItem); } menuItem = new JMenuItem("Configure Bot..."); menuItem.setActionCommand("CONFIG_BOT"); menuItem.addActionListener(this); popup.add(menuItem); popup.show(e.getComponent(), e.getX(), e.getY()); } } }; }