rita.ui.component.DialogSelectEnemies.java Source code

Java tutorial

Introduction

Here is the source code for rita.ui.component.DialogSelectEnemies.java

Source

/*
 * Copyright 2013 Vanessa Aybar Rosales
 * This file is part of RITA.
 * RITA 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.
 * RITA 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 
 * RITA. If not, see http://www.gnu.org/licenses/.
 */

package rita.ui.component;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

import org.apache.commons.io.FileUtils;

import rita.battle.Batalla;
import rita.settings.HelperEditor;
import rita.settings.Language;
import rita.settings.Settings;
import rita.ui.component.exception.NoEnemiesException;
import rita.widget.SourceCode;

/**
 * Esta clase representa la ventana de dilogo que permite seleccionar
 * mediante checkbox los robots que se enfrentarn en el campo de batalla.
 * 
 * @author Vanessa Aybar Rosales
 * */
public class DialogSelectEnemies extends CloseableJDialog {
    private static final long serialVersionUID = -3463604350524085848L;

    private static final String pattern = Pattern.quote(System.getProperty("file.separator"));
    private JCheckBox randomMode;
    private RobotNameClickedEvent robotNameClicked;
    private JPanel panelSelectRobots;
    private JButton btnOK;

    private JSpinner roundsNumberSpinner;
    // posicion de mi robot
    private JButton buttonPos;
    private ImageIcon icon;
    private static Map<String, RobotWithPositionTemp> mapRobotsTemp = new HashMap<String, RobotWithPositionTemp>();

    private static DialogSelectEnemies dialogSelectEnemies = null;

    private static boolean canSelectPosition = false;

    private static List<Component> positionComponents = new ArrayList<Component>();

    public static void clean() {
        dialogSelectEnemies = null;
        mapRobotsTemp = new HashMap<String, DialogSelectEnemies.RobotWithPositionTemp>();
        canSelectPosition = false;
        positionComponents = new ArrayList<Component>();
    }

    private class RobotNameClickedEvent implements ActionListener {
        JButton okButton;

        public RobotNameClickedEvent(JButton disableEnableBtn) {
            okButton = disableEnableBtn;
        }

        int selectionCount = 0;

        @Override
        public void actionPerformed(ActionEvent evt) {
            JCheckBox check = (JCheckBox) evt.getSource();
            if (check.isSelected()) {
                ++selectionCount;
                if (!okButton.isEnabled()) {
                    okButton.setEnabled(true);
                }
                if (canSelectPosition)
                    ((JButton) ((JPanel) check.getParent()).getComponent(1)).setEnabled(true);
            } else {
                --selectionCount;
                if (selectionCount == 0) {
                    okButton.setEnabled(false);
                }
                ((JButton) ((JPanel) check.getParent()).getComponent(1)).setEnabled(false);
            }
        }

    }

    /**
     * Create the application.
     */
    private DialogSelectEnemies() throws NoEnemiesException {
        initialize();
    }

    public static DialogSelectEnemies getInstance() throws NoEnemiesException {
        if (dialogSelectEnemies == null)
            dialogSelectEnemies = new DialogSelectEnemies();
        else
            dialogSelectEnemies.setVisible(true);
        return dialogSelectEnemies;
    }

    /**
     * Initialize the contents of the frame.
     * 
     * @throws NoEnemiesException
     */
    private void initialize() throws NoEnemiesException {
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.getContentPane().setLayout(new BorderLayout(6, 6));
        this.setTitle(Language.get("selectEnemies"));
        randomMode = new JCheckBox(Language.get("robotsBattleMode.random"));
        randomMode.setSelected(true);
        randomMode.addActionListener(new SelectUnselectPositionAction());

        icon = new ImageIcon(DialogSelectEnemies.class.getResource("/images/icons/target.jpg"));

        JPanel panelRobots = new JPanel();
        panelRobots.setBorder(new EmptyBorder(0, 12, 12, 0));
        panelRobots.setLayout(new BorderLayout(0, 0));

        JPanel panelSelectAllNone = new JPanel();
        panelSelectAllNone.setBorder(new EmptyBorder(0, 12, 0, 12));
        panelRobots.add(panelSelectAllNone, BorderLayout.EAST);
        this.getContentPane().add(panelRobots, BorderLayout.CENTER);

        GridBagLayout gbl_panelSelectAllNone = new GridBagLayout();
        gbl_panelSelectAllNone.columnWidths = new int[] { 0, 0 };
        gbl_panelSelectAllNone.rowHeights = new int[] { 0, 0, 8 };
        gbl_panelSelectAllNone.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
        gbl_panelSelectAllNone.rowWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
        panelSelectAllNone.setLayout(gbl_panelSelectAllNone);

        JButton btnSelectAll = new JButton(Language.get("selectAllEnemies"));
        GridBagConstraints gbc_btnSelectAll = new GridBagConstraints();
        gbc_btnSelectAll.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnSelectAll.insets = new Insets(0, 0, 5, 0);
        gbc_btnSelectAll.gridx = 0;
        gbc_btnSelectAll.gridy = 0;
        panelSelectAllNone.add(btnSelectAll, gbc_btnSelectAll);

        JButton btnSelectNone = new JButton(Language.get("selectNoEnemies"));
        GridBagConstraints gbc_btnSelectNone = new GridBagConstraints();
        gbc_btnSelectNone.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnSelectNone.gridx = 0;
        gbc_btnSelectNone.gridy = 1;
        panelSelectAllNone.add(btnSelectNone, gbc_btnSelectNone);

        /*
         * btnInitialPositionsConfig = new
         * JButton(Language.get("selectRobotsInitialPositions"));
         * GridBagConstraints gbc_btnInitialPositionsConfig = new
         * GridBagConstraints(); gbc_btnSelectNone.fill =
         * GridBagConstraints.HORIZONTAL; gbc_btnSelectNone.gridx = 0;
         * gbc_btnSelectNone.gridy = 1;
         * panelSelectAllNone.add(btnInitialPositionsConfig,
         * gbc_btnInitialPositionsConfig);
         * btnInitialPositionsConfig.addActionListener(new ActionListener() {
         * public void actionPerformed(ActionEvent evt) {
         * selectRobotsInitialPositions(); } });
         */

        JLabel label = new JLabel(String.format(Language.get("youtRobotAgainst"), HelperEditor.currentRobotName));
        label.setBorder(new EmptyBorder(12, 12, 0, 12));
        label.setIcon(new ImageIcon(DialogSelectEnemies.class.getResource("/images/icons/compite2.png")));
        label.setVerticalAlignment(SwingConstants.TOP);
        label.setFont(label.getFont().deriveFont(Font.BOLD, 14));

        panelSelectRobots = new JPanel();
        panelSelectRobots.setLayout(new GridLayout(0, 2));
        panelSelectRobots.setAutoscrolls(true);

        panelRobots.add(label, BorderLayout.NORTH);
        panelRobots.add(panelSelectRobots, BorderLayout.CENTER);

        // posicion de mi robot
        JPanel panelSetMyRobotPosition = new JPanel();
        // panelRobots.add(panelSetMyRobotPosition, BorderLayout.PAGE_END);
        panelSetMyRobotPosition.setLayout(new FlowLayout());
        JLabel ownPosition = new JLabel(Language.get("myRobotPosition") + " " + HelperEditor.currentRobotName);
        ownPosition.setFont(new Font("sansserif", Font.BOLD, 12));
        panelSetMyRobotPosition.add(ownPosition);
        // Posicion de mi robot
        buttonPos = new JButton(icon);
        buttonPos.addActionListener(new PosicionRobotAction(HelperEditor.currentRobotName)); // el nombre aqui es solo a
        // modo informativo
        buttonPos.setPreferredSize(new Dimension(30, 30));
        panelSetMyRobotPosition.add(buttonPos);
        positionComponents.add(buttonPos);

        // Matas
        JPanel panelSelectRoundsNumber = new JPanel();
        // panelRobots.add(panelSelectRoundsNumber, BorderLayout.SOUTH);
        panelSelectRoundsNumber.setLayout(new FlowLayout());
        panelSelectRoundsNumber.add(new JLabel(Language.get("selectRoundsNumber")));
        //      this.roundsNumberTextField = new JTextField(
        //            Integer.toString(Batalla.NUMBER_OF_ROUNDS), 5);
        this.roundsNumberSpinner = new JSpinner(new SpinnerNumberModel(Batalla.NUMBER_OF_ROUNDS,
                Batalla.MIN_NUMBER_OF_ROUNDS, Batalla.MAX_NUMBER_OF_ROUNDS, 1));

        panelSelectRoundsNumber.add(this.roundsNumberSpinner);

        JPanel panelSouth = new JPanel();
        panelSouth.setLayout(new GridLayout(4, 1));

        panelSouth.add(panelSetMyRobotPosition);
        //this.getContentPane().add(randomMode, BorderLayout.SOUTH);
        panelSouth.add(randomMode);
        panelSouth.add(new JSeparator());
        panelSouth.add(panelSelectRoundsNumber);
        panelRobots.add(panelSouth, BorderLayout.SOUTH);

        JPanel panelOkCancel = new JPanel();
        this.getContentPane().add(panelOkCancel, BorderLayout.SOUTH);
        panelOkCancel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 12));

        btnOK = new JButton(Language.get("selectStartBattle"));
        btnOK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                startBattle(panelSelectRobots);
            }
        });
        // comienza deshabilitado hasta que se seleccione 1 enemigo
        // btnOK.setEnabled(false);
        panelOkCancel.add(btnOK);

        JButton btnCancel = new JButton(Language.get("cancel"));
        btnCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                closeDialog();
            }
        });
        panelOkCancel.add(btnCancel);

        btnSelectAll.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                selectChecks(panelSelectRobots, true);
                // btnOK.setEnabled(true);
            }
        });

        btnSelectNone.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                selectChecks(panelSelectRobots, false);
                // btnOK.setEnabled(false);
            }
        });

        // TODO Agregar funcionalidad de elegir las posiciones iniciales de los
        // robots.
        // TODO Averiguar como pasar las posiciones para que se elijan de manera
        // random, probar (0,0,0)

        try {
            robotNameClicked = new RobotNameClickedEvent(btnOK);
            addRobotsToPanel(panelSelectRobots);

            this.setResizable(false);
            this.pack();
            PositionCalc.centerDialog(this);
            enablePositionOptions(false);
            this.setVisible(true);
        } catch (FileNotFoundException e) {
            throw new NoEnemiesException(e.getMessage());
        }

    }

    /**
     * Recorre el directorio robots y agrega al panel a todos los robots
     * (.class) instalados
     * 
     * @throws FileNotFoundException
     *             si no hay .class en el dir File(Settings.getInstallPath(),
     *             "robots")
     */
    private void addRobotsToPanel(JPanel panel) throws FileNotFoundException {
        if (Settings.getInstallPath() == null) {
            throw new FileNotFoundException(
                    "La carpeta de robots no pudo ser encontrara porque InstallPath no esta definido");
        }
        File robotDir = new File(Settings.getInstallPath(), "robots");
        if (!robotDir.isDirectory() || !robotDir.canRead()) {
            //otra carpeta posible MVN
            robotDir = new File(Settings.getInstallPath() + Settings.getMvnResourcesPath(), "robots");
            if (!robotDir.isDirectory() || !robotDir.canRead())
                throw new FileNotFoundException(
                        "La carpeta de robots " + robotDir + " no existe o no tiene permisos de lectura");
        }
        boolean robotFound = false;
        // recorrer directorio robots y traer todos los robots instalados
        JCheckBox cb;
        JButton buttonPos;

        /*
         * buscar recursivametne a todos los .class en InstallPath() + "robots",
         * excluyendo a las inner clases, porque asumimos que son clases de
         * implementacion. Las reconocemos porque tienen '$' en el nombre de la
         * clase.
         */

        for (File f : FileUtils.listFiles(robotDir, new String[] { "class" }, true)) {
            if (f.getName().endsWith(".class") && f.getName().indexOf('$') == -1) {
                String[] splitPath = f.getParent().split(pattern);
                /*
                 * si el path del robot tiene directorio/nombrerobot.class => el
                 * nombre del robot es "directorio.nombrerobot", sino es solo
                 * "nombrerobot"
                 */
                if (splitPath.length > 0) {
                    cb = new JCheckBox(splitPath[splitPath.length - 1] + "."
                            + f.getName().substring(0, f.getName().lastIndexOf('.')), false);
                } else {
                    cb = new JCheckBox(f.getName().substring(0, f.getName().lastIndexOf('.')), false);
                }

                JPanel panelCheckButton = new JPanel();
                buttonPos = new JButton(icon);
                buttonPos.addActionListener(new PosicionRobotAction(cb.getText()));
                buttonPos.setPreferredSize(new Dimension(30, 30));
                positionComponents.add(buttonPos);

                cb.addActionListener(robotNameClicked);
                cb.setPreferredSize(new Dimension(160, 30));
                panelCheckButton.add(cb);

                panelCheckButton.add(buttonPos);
                panel.add(panelCheckButton);
                robotFound = true;
            }
        }
        if (!robotFound) {
            throw new FileNotFoundException("La carpeta de robots no contiene robots");
        }
    }

    protected class RobotWithPositionTemp {
        private String robotName;
        private int x;
        private int y;
        private int orientation;

        public RobotWithPositionTemp(String robotName, int x, int y, int orient) {
            this.robotName = robotName;
            this.x = x;
            this.y = y;
            this.orientation = orient;
        }

        public String getRobotName() {
            return robotName;
        }

        public void setRobotName(String robotName) {
            this.robotName = robotName;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }

        public void setOrientation(Orientation orientationParam) {
            this.orientation = orientationParam.getValue();

        }

        public int getOrientation() {
            return orientation;
        }

    }

    private class PosicionRobotAction implements ActionListener {

        RobotWithPositionTemp robotTemp;

        public PosicionRobotAction(String robotName) {
            if (mapRobotsTemp.get(robotName) == null) {
                robotTemp = new RobotWithPositionTemp(robotName, -1, -1, -1);
                mapRobotsTemp.put(robotName, robotTemp);
            }
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            new DialogPositionRobot(robotTemp);
        }

    }

    /** seleccionar o deseleccionar a todos los checkboxes adentro de un panel */
    private void selectChecks(JPanel panelChecks, boolean b) {
        for (Component comp : panelChecks.getComponents()) {
            if (comp instanceof JPanel) {
                for (Component compInt : ((JPanel) comp).getComponents()) {
                    if (compInt instanceof JCheckBox)
                        ((JCheckBox) compInt).setSelected(b);
                }
            }
        }

    }

    /**
     * el usuario selecciono los robots para competir, encontrar cuales
     * selecciono y comenzar la batalla
     */
    private void startBattle(JPanel checks) {
        Integer roundsNumber;
        try {
            roundsNumber = (Integer) this.roundsNumberSpinner.getValue();
        } catch (NumberFormatException e) {
            roundsNumber = Batalla.NUMBER_OF_ROUNDS;
        }
        StringBuilder selectedRobots = new StringBuilder();
        // el robot del usuario siempre participa en la batalla
        selectedRobots.append(HelperEditor.currentRobotPackage + "." + HelperEditor.currentRobotName);
        selectedRobots.append("*,");
        String robotName;
        // recorrer los checkboxes de los enemigos seleccionados
        StringBuilder initialPositions = new StringBuilder("");
        // posicion de mi robot
        RobotWithPositionTemp miRobotPos = mapRobotsTemp.get(HelperEditor.currentRobotName);
        positionAsStringBuilder(initialPositions, miRobotPos);

        RobotWithPositionTemp rt = null;
        for (Component compPanel : checks.getComponents()) {
            for (Component comp : ((JPanel) compPanel).getComponents()) {
                if (comp instanceof JCheckBox && ((JCheckBox) comp).isSelected()) {
                    robotName = ((JCheckBox) comp).getText();
                    /*
                     * "sample" es el paquete de los que vienen con Robocode; si
                     * el robot no es de ese paquete, entonces el nombre debe
                     * estar seguido por un asterisco
                     */
                    selectedRobots.append(robotName);
                    if (robotName.contains("sample.")) {
                        selectedRobots.append(',');
                    } else {
                        selectedRobots.append("*,");
                    }
                    rt = mapRobotsTemp.get(robotName);
                    positionAsStringBuilder(initialPositions, rt);
                }
            }
        }
        if (initialPositions.length() > 1) {
            initialPositions.deleteCharAt(initialPositions.length() - 1); // borra
            // la
            // ultima
            // coma

        }

        HelperEditor.setEnemies(selectedRobots.toString());
        closeDialog();
        SourceCode.callBatalla(Integer.valueOf(roundsNumber), initialPositions.toString());
    }

    private void positionAsStringBuilder(StringBuilder initialPositions, RobotWithPositionTemp rt) {
        if (canSelectPosition) {
            if (rt.getX() >= 0)
                initialPositions.append("(" + rt.getX() + ",");
            else
                initialPositions.append("(?,");
            if (rt.getY() >= 0)
                initialPositions.append(rt.getY() + ",");
            else
                initialPositions.append("?,");
            if (rt.getOrientation() >= 0)
                initialPositions.append(rt.getOrientation() + "),");
            else
                initialPositions.append("?),");
        } else
            initialPositions.append("(?,?,?),");

    }

    private final class SelectUnselectPositionAction implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            JCheckBox check = (JCheckBox) e.getSource();
            if (check.isSelected()) {
                enablePositionOptions(false);
            } else {
                enablePositionOptions(true);
            }

        }

    }

    private void enablePositionOptions(boolean enable) {
        if (!enable) {
            canSelectPosition = false;
            for (Component comp : positionComponents) {
                comp.setEnabled(false);
            }
        } else {
            canSelectPosition = true;
            buttonPos.setEnabled(true);
            for (Component compPanel : panelSelectRobots.getComponents()) {
                JPanel parent = (JPanel) compPanel;
                // para cada panel la primer componente es el check y el segundo
                // es el boton
                JCheckBox check = (JCheckBox) parent.getComponent(0);
                if (check.isSelected()) {
                    JButton button = (JButton) parent.getComponent(1);
                    button.setEnabled(true);
                }
            }
        }
    }

    public enum Orientation {

        NORTH(0), SOUTH(180), EAST(270), WEST(90);

        int value;

        Orientation(int i) {
            value = i;
        }

        public int getValue() {
            return value;
        }

    }

}