/* * This file is part of MazeSolver. * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * * Copyright (c) 2014 MazeSolver * Sergio M. Afonso Fumero <theSkatrak@gmail.com> * Kevin I. Robayna Hernández <kevinirobaynahdez@gmail.com> */ /** * @file EnvSelectorDialog.java * @date 2/10/2015 */ package es.ull.mazesolver.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.border.EtchedBorder; import com.alee.extended.layout.VerticalFlowLayout; import es.ull.mazesolver.gui.environment.Environment; import es.ull.mazesolver.gui.environment.EnvironmentSet; import es.ull.mazesolver.maze.Maze; import es.ull.mazesolver.translations.Translations; /** * Interfaz gráfica para crear o modificar entornos. */ public class EnvSelectorDialog extends JDialog { private static final long serialVersionUID = 1L; private static final int MIN_WINDOW_WIDTH = 300; private EnvironmentSet m_envs; private Environment m_result; private JTextField m_name; private JRadioButton m_new_maze, m_open_maze, m_loaded_maze; private JComboBox <String> m_loaded_envs; private JButton m_ok, m_cancel; /** * Crea el diálogo de creación de entornos. * * @param parent Ventana padre del diálogo. * @param envs Conjunto de entornos cargados. */ public EnvSelectorDialog (Window parent, EnvironmentSet envs) { this(parent, envs, null); } /** * Crea el diálogo de modificación de entornos. * * @param parent Ventana padre del diálogo. * @param envs Conjunto de entornos cargados. * @param current Entorno que se quiere modificar. */ public EnvSelectorDialog (Window parent, EnvironmentSet envs, Environment current) { super(parent); m_envs = envs; m_result = current; setupInterface(); } /** * Muestra el diálogo y devuelve el entorno creado utilizando la * configuración elegida por el usuario. * * @return El entorno creado o modificado o {@code null} si el usuario cancela * la creación del entorno. */ public Environment showDialog () { setVisible(true); return m_result; } /** * Crea la interfaz de usuario y configura los controladores. */ private void setupInterface () { buildInterface(); setupListeners(); setResizable(false); setModal(true); } /** * Crea los elementos y layouts de la interfaz gráfica. */ private void buildInterface () { Translations tr = MainWindow.getTranslations(); // Name String name = m_result != null? m_result.getEnvName() : tr.menu().environment() + " " + (Environment.getInstancesCreated() + 1); m_name = new JTextField(name); JPanel name_panel = new JPanel(new BorderLayout(5, 5)); name_panel.setBorder(BorderFactory.createEmptyBorder(10, 7, 0, 7)); name_panel.add(new JLabel(tr.agent().name() + ":"), BorderLayout.WEST); name_panel.add(m_name, BorderLayout.CENTER); // Maze ButtonGroup group = new ButtonGroup(); m_new_maze = new JRadioButton(tr.env().newMaze()); m_open_maze = new JRadioButton(tr.env().openMaze()); m_loaded_maze = new JRadioButton(tr.env().loadedMaze()); group.add(m_new_maze); group.add(m_open_maze); group.add(m_loaded_maze); // This combo box contains the names of the currently loaded environments m_loaded_envs = new JComboBox <String>(); for (Environment env: m_envs.getEnvironmentList()) m_loaded_envs.addItem(env.getEnvName()); JPanel loaded_maze_panel = new JPanel(new BorderLayout()); loaded_maze_panel.add(m_loaded_maze, BorderLayout.WEST); loaded_maze_panel.add(m_loaded_envs, BorderLayout.CENTER); JPanel maze_panel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.CENTER, 0, 3)); maze_panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5), BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), tr.env().maze()))); maze_panel.add(m_new_maze); maze_panel.add(m_open_maze); maze_panel.add(loaded_maze_panel); if (m_envs.getEnvironmentCount() == 0) m_loaded_maze.setEnabled(false); // Buttons m_ok = new JButton(tr.button().ok()); m_cancel = new JButton(tr.button().cancel()); JPanel button_panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); button_panel.add(m_ok); button_panel.add(m_cancel); setTitle(m_result == null? tr.menu().newEnv() : tr.menu().configEnv()); setLayout(new BorderLayout(5, 5)); setMinimumSize(new Dimension(MIN_WINDOW_WIDTH, 0)); add(name_panel, BorderLayout.NORTH); add(maze_panel, BorderLayout.CENTER); add(button_panel, BorderLayout.SOUTH); if (m_result == null) { m_new_maze.setSelected(true); m_loaded_envs.setEnabled(false); } else { m_loaded_maze.setSelected(true); m_loaded_envs.setSelectedItem(m_result.getEnvName()); } pack(); } /** * Configura los controladores de la interfaz gráfica. */ private void setupListeners () { final Translations tr = MainWindow.getTranslations(); ActionListener radio_listener = new ActionListener() { @Override public void actionPerformed (ActionEvent e) { m_loaded_envs.setEnabled(e.getSource() == m_loaded_maze); } }; m_new_maze.addActionListener(radio_listener); m_open_maze.addActionListener(radio_listener); m_loaded_maze.addActionListener(radio_listener); m_ok.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent e) { // Comprobamos que el nombre del entorno no está repetido ni vacío String name = m_name.getText(); boolean valid_name = !name.isEmpty(); if (valid_name) { for (int i = 0; i < m_loaded_envs.getItemCount(); ++i) { if (m_loaded_envs.getItemAt(i).equals(name)) { if (m_envs.getEnvironmentList().get(i) != m_result) valid_name = false; break; } } } if (!valid_name) { JOptionPane.showMessageDialog(null, name.isEmpty()? tr.exception().unnamedEnv() : tr.exception().repeatedEnvName()); return; } // Creamos el entorno resultante de manera distinta dependiendo del // origen del laberinto boolean exit_dialog = true; EnvSelectorDialog that = EnvSelectorDialog.this; m_result = null; // Crear laberinto aleatorio if (m_new_maze.isSelected()) { MazeSelectorDialog dialog = new MazeSelectorDialog(that); dialog.setLocationRelativeTo(that); Maze generated = dialog.showDialog(); if (generated != null) m_result = new Environment(generated, name); else exit_dialog = false; } // Abrir laberinto desde un fichero else if (m_open_maze.isSelected()) { try { Maze maze = FileDialog.loadMaze(); if (maze != null) m_result = new Environment(maze, name); else exit_dialog = false; } catch (IOException exc) { JOptionPane.showMessageDialog(null, exc.getMessage(), tr.message().fileOpenFailed(), JOptionPane.ERROR_MESSAGE); exit_dialog = false; } } // Utilizar laberinto contenido en otro entorno else /* m_loaded_maze.isSelected() */ { String env_name = (String) m_loaded_envs.getSelectedItem(); for (Environment env: m_envs.getEnvironmentList()) { if (env.getEnvName().equals(env_name)) { m_result = new Environment(env.getMaze(), name); break; } } } if (exit_dialog) { setVisible(false); dispose(); } } }); m_cancel.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent e) { setVisible(false); dispose(); } }); } }