package disparity.game.editor;
import java.awt.Canvas;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Stack;
import javax.swing.AbstractAction;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SpringLayout;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import disparity.rpg.being.Being;
import disparity.rpg.being.Character;
import disparity.rpg.races.Race;
public class RPGDevMainWindow {
private JFrame frmJustAnotherRpg;
private JList<?> list = new JList<Object>();
@SuppressWarnings("rawtypes")
private DefaultListModel listModel = new DefaultListModel();
private HashMap<JTextField,GhostText> textBoxes = new HashMap<JTextField,GhostText>();
private Stack<JLabel> labels = new Stack<JLabel>();
private HashMap<String,Character> characters = new HashMap<String,Character>();
/**
* Launch the application.
*/
public static void run(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
RPGDevMainWindow window = new RPGDevMainWindow();
window.frmJustAnotherRpg.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public RPGDevMainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
@SuppressWarnings("unchecked")
private void initialize() {
//Set look and feel
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}
frmJustAnotherRpg = new JFrame();
frmJustAnotherRpg.setTitle("Just Another RPG Editor");
frmJustAnotherRpg.setBounds(100, 100, 525, 565);
frmJustAnotherRpg.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
SpringLayout springLayout = new SpringLayout();
frmJustAnotherRpg.getContentPane().setLayout(springLayout);
list.addListSelectionListener(new ListSelectionListener() { //Change when character is selected
@Override
public void valueChanged(ListSelectionEvent arg0) {
if(list.getSelectedValue() == null) { //Prevent an exception by not doing anything if we somehow un-selected an item
for(Entry<JTextField,GhostText> textBox : textBoxes.entrySet()) {
textBox.getValue().focusGained(new FocusEvent(new Canvas(), 0));
textBox.getKey().setText("");
textBox.getValue().focusLost(new FocusEvent(new Canvas(), 1));
}
} else
for(Entry<JTextField,GhostText> textBox : textBoxes.entrySet()) {
try {
textBox.getValue().focusGained(new FocusEvent(new Canvas(), 0)); //We have to fake a FocusEvent in order for this to work.
textBox.getKey().setText( characters.get( list.getSelectedValue().toString() ).getStat( getKeyFromValue(textBox.getValue().ghostText) ).toString() ); //Get the values of each stat
textBox.getValue().focusLost(new FocusEvent(new Canvas(), 1));
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
list.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0), "delete" );
list.getActionMap().put("delete", new AbstractAction() {
private static final long serialVersionUID = 1L; //required
@Override
public void actionPerformed(ActionEvent e) {
removeCharacter((Character)list.getSelectedValue());
}
});
springLayout.putConstraint(SpringLayout.NORTH, list, 10, SpringLayout.NORTH, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, list, 10, SpringLayout.WEST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, list, -10, SpringLayout.EAST, frmJustAnotherRpg.getContentPane());
list.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Character select", TitledBorder.LEFT, TitledBorder.BOTTOM, null, null));
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
list.setModel(listModel);
frmJustAnotherRpg.getContentPane().add(list);
JButton btnNewCharacter = new JButton("New character");
springLayout.putConstraint(SpringLayout.NORTH, btnNewCharacter, -33, SpringLayout.SOUTH, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, btnNewCharacter, 10, SpringLayout.WEST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, btnNewCharacter, -10, SpringLayout.SOUTH, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnNewCharacter, -10, SpringLayout.EAST, frmJustAnotherRpg.getContentPane());
btnNewCharacter.addActionListener(new ActionListener() { //Character creation menu
@Override
public void actionPerformed(ActionEvent arg0) {
String name;
name = (String)JOptionPane.showInputDialog(null, "Character name:","New character",JOptionPane.PLAIN_MESSAGE,null,null,"Player");
while(characters.containsKey(name)) {
name = (String)JOptionPane.showInputDialog(null, "That name is already used.\nCharacter name:","New character",JOptionPane.ERROR_MESSAGE,null,null,"Player");
}
if(name == null || name.length() == 0) return;
Object[] races = Race.getAllRaces().toArray();
String race = (String)JOptionPane.showInputDialog(null, "Race:", "Select race",JOptionPane.PLAIN_MESSAGE,null,races,"HUMAN");
addCharacter(new Character(name, race));
}
});
frmJustAnotherRpg.getContentPane().add(btnNewCharacter);
JButton btnUpdateCharacter = new JButton("Update character");
springLayout.putConstraint(SpringLayout.NORTH, btnUpdateCharacter, -29, SpringLayout.NORTH, btnNewCharacter);
springLayout.putConstraint(SpringLayout.WEST, btnUpdateCharacter, 10, SpringLayout.WEST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, btnUpdateCharacter, -6, SpringLayout.NORTH, btnNewCharacter);
springLayout.putConstraint(SpringLayout.EAST, btnUpdateCharacter, -10, SpringLayout.EAST, frmJustAnotherRpg.getContentPane());
btnUpdateCharacter.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) { //Update our character stats
if(list.isSelectionEmpty())return;
Character c = (Character)list.getSelectedValue(); //Apparently we have to cast our Object into a Character first
String oldName = c.name;
try {
for(Entry<JTextField,GhostText> textBox : textBoxes.entrySet()) {
c.setStat( getKeyFromValue(textBox.getValue().ghostText), textBox.getKey().getText() );
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "An error occured while updating the character; see console for details.","Update Character",JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
String newName = c.name; //We're assuming that this changed after the loop.
listModel.setElementAt(c, list.getSelectedIndex());
characters.put(newName, characters.remove(oldName) );
}
});
frmJustAnotherRpg.getContentPane().add(btnUpdateCharacter);
JPanel statsPanel = new JPanel();
springLayout.putConstraint(SpringLayout.NORTH, statsPanel, 208, SpringLayout.NORTH, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, list, -6, SpringLayout.NORTH, statsPanel);
springLayout.putConstraint(SpringLayout.WEST, statsPanel, 10, SpringLayout.WEST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, statsPanel, -10, SpringLayout.EAST, frmJustAnotherRpg.getContentPane());
frmJustAnotherRpg.getContentPane().add(statsPanel);
statsPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
JButton btnShowStats = new JButton("Show me the stats");
springLayout.putConstraint(SpringLayout.WEST, btnShowStats, 10, SpringLayout.WEST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnShowStats, -10, SpringLayout.EAST, frmJustAnotherRpg.getContentPane());
btnShowStats.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) { //When "Show me the stats" button is pressed
if(list.getSelectedValue() == null || !characters.containsKey( list.getSelectedValue().toString() ))JOptionPane.showMessageDialog(null, "No character was selected.","Character Stats",JOptionPane.ERROR_MESSAGE);
else JOptionPane.showMessageDialog(null, characters.get(list.getSelectedValue().toString()).printStats(), "Character Stats", JOptionPane.INFORMATION_MESSAGE);
}
});
springLayout.putConstraint(SpringLayout.SOUTH, btnShowStats, -8, SpringLayout.NORTH, btnUpdateCharacter);
frmJustAnotherRpg.getContentPane().add(btnShowStats);
JButton btnDeleteCharacter = new JButton("Delete character");
springLayout.putConstraint(SpringLayout.WEST, btnDeleteCharacter, 10, SpringLayout.WEST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnDeleteCharacter, -10, SpringLayout.EAST, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, statsPanel, -6, SpringLayout.NORTH, btnDeleteCharacter);
springLayout.putConstraint(SpringLayout.NORTH, btnShowStats, 6, SpringLayout.SOUTH, btnDeleteCharacter);
springLayout.putConstraint(SpringLayout.NORTH, btnDeleteCharacter, -124, SpringLayout.SOUTH, frmJustAnotherRpg.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, btnDeleteCharacter, -99, SpringLayout.SOUTH, frmJustAnotherRpg.getContentPane());
btnDeleteCharacter.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeCharacter((Character)list.getSelectedValue());
}
});
frmJustAnotherRpg.getContentPane().add(btnDeleteCharacter);
//Let's add some text boxes, shall we?
//For each stat field, make a text box for it
JTextField tempTextBox;
JLabel tempLabel;
for(Entry<String,String> field : Being.getStatFields().entrySet()) {
tempLabel = new JLabel(field.getValue());
labels.push(tempLabel);
tempTextBox = new JTextField();
tempTextBox.setColumns(15);
tempTextBox.setToolTipText(String.valueOf(field.getValue().toCharArray()[0]).toUpperCase() + field.getValue().substring(1)); //Make first letter uppercase
textBoxes.put( tempTextBox, new GhostText(tempTextBox,field.getValue()) );
statsPanel.add(tempLabel);
statsPanel.add(tempTextBox);
}
}
@SuppressWarnings("unchecked")
public void addCharacter(Character c) {
listModel.addElement(c);
characters.put(c.name,c);
list.setSelectedValue(characters.get(c.name), true); //Select our new character
}
public void removeCharacter(Character c) {
if(list.isSelectionEmpty())return;
if(JOptionPane.showConfirmDialog(null, "Are you sure you want to delete \""+c.name+"\"?","Character Stats",JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
listModel.removeElement(c);
characters.remove(c.name);
}
}
public String getKeyFromValue(String val) {
for(Entry<String, String> keyval : Being.getStatFields().entrySet()) {
if(val.equals(keyval.getValue()))return keyval.getKey();
}
return null;
}
}