package games.strategy.triplea.ui; import java.awt.event.ActionEvent; import java.util.Collection; import java.util.Iterator; import java.util.Optional; import java.util.Set; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import games.strategy.engine.data.GameData; import games.strategy.engine.data.PlayerID; import games.strategy.engine.data.Territory; import games.strategy.engine.data.Unit; import games.strategy.triplea.attachments.TerritoryAttachment; import games.strategy.triplea.oddsCalculator.ta.OddsCalculatorDialog; import games.strategy.triplea.util.UnitCategory; import games.strategy.triplea.util.UnitSeperator; import games.strategy.ui.OverlayIcon; public class TerritoryDetailPanel extends AbstractStatPanel { private static final long serialVersionUID = 1377022163587438988L; private final IUIContext m_uiContext; private final JButton m_showOdds = new JButton("Battle Calculator (Ctrl-B)"); private Territory m_currentTerritory; private final TripleAFrame m_frame; public static String getHoverText() { return "Hover over or drag and drop from a territory to list those units in this panel"; } public TerritoryDetailPanel(final MapPanel mapPanel, final GameData data, final IUIContext uiContext, final TripleAFrame frame) { super(data); m_frame = frame; m_uiContext = uiContext; mapPanel.addMapSelectionListener(new DefaultMapSelectionListener() { @Override public void mouseEntered(final Territory territory) { territoryChanged(territory); } }); initLayout(); } @Override protected void initLayout() { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setBorder(new EmptyBorder(5, 5, 0, 0)); final String show_battle_calc = "show_battle_calc"; final Action showBattleCalc = new AbstractAction(show_battle_calc) { private static final long serialVersionUID = -1863748437390486994L; @Override public void actionPerformed(final ActionEvent e) { OddsCalculatorDialog.show(m_frame, m_currentTerritory); } }; m_showOdds.addActionListener(e -> showBattleCalc.actionPerformed(e)); final JComponent contentPane = (JComponent) m_frame.getContentPane(); contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke('B', java.awt.event.InputEvent.META_MASK), show_battle_calc); contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke('B', java.awt.event.InputEvent.CTRL_MASK), show_battle_calc); contentPane.getActionMap().put(show_battle_calc, showBattleCalc); } @Override public void setGameData(final GameData data) { m_data = data; territoryChanged(null); } private void territoryChanged(final Territory territory) { m_currentTerritory = territory; removeAll(); refresh(); if (territory == null) { return; } add(m_showOdds); final TerritoryAttachment ta = TerritoryAttachment.get(territory); String labelText; if (ta == null) { labelText = "<html>" + territory.getName() + "<br>Water Territory" + "<br><br></html>"; } else { labelText = "<html>" + ta.toStringForInfo(true, true) + "<br></html>"; } add(new JLabel(labelText)); Collection<Unit> unitsInTerritory; m_data.acquireReadLock(); try { unitsInTerritory = territory.getUnits().getUnits(); } finally { m_data.releaseReadLock(); } add(new JLabel("Units: " + unitsInTerritory.size())); final JScrollPane scroll = new JScrollPane(unitsInTerritoryPanel(unitsInTerritory, m_uiContext, m_data)); scroll.setBorder(BorderFactory.createEmptyBorder()); add(scroll); refresh(); } private static JPanel unitsInTerritoryPanel(final Collection<Unit> unitsInTerritory, final IUIContext uiContext, final GameData data) { final JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(2, 20, 2, 2)); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); final Set<UnitCategory> units = UnitSeperator.categorize(unitsInTerritory); final Iterator<UnitCategory> iter = units.iterator(); PlayerID currentPlayer = null; while (iter.hasNext()) { // seperate players with a seperator final UnitCategory item = iter.next(); if (item.getOwner() != currentPlayer) { currentPlayer = item.getOwner(); panel.add(Box.createVerticalStrut(15)); } // TODO Kev determine if we need to identify if the unit is hit/disabled final Optional<ImageIcon> unitIcon = uiContext.getUnitImageFactory().getIcon(item.getType(), item.getOwner(), data, item.hasDamageOrBombingUnitDamage(), item.getDisabled()); if (unitIcon.isPresent()) { // overlay flag onto upper-right of icon final ImageIcon flagIcon = new ImageIcon(uiContext.getFlagImageFactory().getSmallFlag(item.getOwner())); final Icon flaggedUnitIcon = new OverlayIcon(unitIcon.get(), flagIcon, unitIcon.get().getIconWidth() - (flagIcon.getIconWidth() / 2), 0); final JLabel label = new JLabel("x" + item.getUnits().size(), flaggedUnitIcon, SwingConstants.LEFT); final String toolTipText = "<html>" + item.getType().getName() + ": " + item.getType().getTooltip(currentPlayer) + "</html>"; label.setToolTipText(toolTipText); panel.add(label); } } return panel; } private void refresh() { validate(); repaint(); } }