/**
* Copyright (c) 2001-2017 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*/
package net.sf.robocode.ui.dialog;
import net.sf.robocode.battle.BattleProperties;
import net.sf.robocode.battle.IBattleManager;
import net.sf.robocode.core.Container;
import net.sf.robocode.repository.IRobotSpecItem;
import net.sf.robocode.settings.ISettingsManager;
import net.sf.robocode.ui.IWindowManager;
import static net.sf.robocode.ui.util.ShortcutUtil.MENU_SHORTCUT_KEY_MASK;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.List;
/**
* @author Mathew A. Nelson (original)
* @author Matthew Reeder (contributor)
* @author Flemming N. Larsen (contributor)
* @author Robert D. Maupin (contributor)
*/
@SuppressWarnings("serial")
public class NewBattleDialog extends JDialog implements WizardListener {
private final static int MAX_ROBOTS = 256; // 64;
private final static int MIN_ROBOTS = 1;
private final EventHandler eventHandler = new EventHandler();
private ISettingsManager settingsManager;
private BattleProperties battleProperties;
private WizardTabbedPane tabbedPane;
private NewBattleRulesTab battleFieldTab;
private WizardController wizardController;
private RobotSelectionPanel robotSelectionPanel;
private final IBattleManager battleManager;
public NewBattleDialog(IWindowManager windowManager, IBattleManager battleManager) {
super(windowManager.getRobocodeFrame(), true);
this.battleManager = battleManager;
}
public void setup(ISettingsManager settingsManager, BattleProperties battleProperties) { // XXX
this.settingsManager = settingsManager;
this.battleProperties = battleProperties;
robotSelectionPanel = null;
setTitle("New Battle");
setPreferredSize(new Dimension(850, 650));
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
addCancelByEscapeKey();
add(createNewBattleDialogPanel());
}
public void cancelButtonActionPerformed() {
dispose();
}
public void finishButtonActionPerformed() {
if (robotSelectionPanel.getSelectedRobotsCount() > 24) {
if (JOptionPane.showConfirmDialog(this,
"Warning: The battle you are about to start (" + robotSelectionPanel.getSelectedRobotsCount()
+ " robots) " + " is very large and will consume a lot of CPU and memory. Do you wish to proceed?",
"Large Battle Warning",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE)
== JOptionPane.NO_OPTION) {
return;
}
}
if (robotSelectionPanel.getSelectedRobotsCount() == 1) {
if (JOptionPane.showConfirmDialog(this,
"You have only selected one robot. For normal battles you should select at least 2.\nDo you wish to proceed anyway?",
"Just one robot?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
== JOptionPane.NO_OPTION) {
return;
}
}
// Dispose this dialog before starting the battle due to pause/resume battle state
dispose();
// Start new battle after the dialog has been disposed and hence has called resumeBattle()
battleManager.startNewBattle(battleProperties, false, false);
}
private NewBattleRulesTab getBattleFieldTab() {
if (battleFieldTab == null) {
battleFieldTab = new NewBattleRulesTab();
battleFieldTab.setup(settingsManager, battleProperties);
}
return battleFieldTab;
}
private JPanel createNewBattleDialogPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(getWizardController(), BorderLayout.SOUTH);
panel.add(getTabbedPane(), BorderLayout.CENTER);
panel.registerKeyboardAction(eventHandler, "Refresh",
KeyStroke.getKeyStroke(KeyEvent.VK_R, MENU_SHORTCUT_KEY_MASK), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
return panel;
}
public List<IRobotSpecItem> getSelectedRobots() {
return getRobotSelectionPanel().getSelectedRobots();
}
private void addCancelByEscapeKey() {
String CANCEL_ACTION_KEY = "CANCEL_ACTION_KEY";
int noModifiers = 0;
KeyStroke escapeKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, noModifiers, false);
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
inputMap.put(escapeKey, CANCEL_ACTION_KEY);
AbstractAction cancelAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
cancelButtonActionPerformed();
}
};
getRootPane().getActionMap().put(CANCEL_ACTION_KEY, cancelAction);
}
/**
* Return the wizardController
*
* @return JButton
*/
private WizardController getWizardController() {
if (wizardController == null) {
wizardController = getTabbedPane().getWizardController();
wizardController.setFinishButtonTextAndMnemonic("Start Battle", 'S', 0);
wizardController.setFocusOnEnabled(true);
}
return wizardController;
}
/**
* Return the Page property value.
*
* @return JPanel
*/
private RobotSelectionPanel getRobotSelectionPanel() {
if (robotSelectionPanel == null) {
robotSelectionPanel = Container.createComponent(RobotSelectionPanel.class);
robotSelectionPanel.addAncestorListener(eventHandler);
final boolean ignoreTeamRobots = false; // TODO do we really want to have this !properties.getOptionsTeamShowTeamRobots();
String selectedRobots = (battleProperties == null) ? "" : battleProperties.getSelectedRobots();
robotSelectionPanel.setup(MIN_ROBOTS, MAX_ROBOTS, true, "Select robots for the battle", false, false, false,
false, false, ignoreTeamRobots, selectedRobots);
}
return robotSelectionPanel;
}
/**
* Return the tabbedPane.
*
* @return JTabbedPane
*/
private WizardTabbedPane getTabbedPane() {
if (tabbedPane == null) {
tabbedPane = new WizardTabbedPane(this);
tabbedPane.insertTab("Robots", null, getRobotSelectionPanel(), null, 0);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_R);
tabbedPane.setDisplayedMnemonicIndexAt(0, 0);
tabbedPane.insertTab("Rules", null, getBattleFieldTab(), null, 1);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_U);
tabbedPane.setDisplayedMnemonicIndexAt(1, 1);
}
return tabbedPane;
}
private class EventHandler implements AncestorListener, ActionListener {
@Override
public void ancestorAdded(AncestorEvent event) {}
@Override
public void ancestorRemoved(AncestorEvent event) {
battleProperties.setSelectedRobots(getRobotSelectionPanel().getSelectedRobotsAsString());
}
@Override
public void ancestorMoved(AncestorEvent event) {}
@Override
public void actionPerformed(ActionEvent event) {
if (event.getActionCommand().equals("Refresh")) {
getRobotSelectionPanel().refreshRobotList(true);
}
}
}
}