package de.tobiyas.racesandclasses.standalonegui.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collections; import java.util.LinkedList; import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTree; import javax.swing.SwingConstants; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; import de.tobiyas.racesandclasses.standalonegui.data.GuiClass; import de.tobiyas.racesandclasses.standalonegui.data.GuiLoader; import de.tobiyas.racesandclasses.standalonegui.data.GuiRace; import de.tobiyas.racesandclasses.standalonegui.data.GuiTrait; import de.tobiyas.racesandclasses.standalonegui.data.option.AbstractTraitConfigOption; import de.tobiyas.racesandclasses.standalonegui.data.option.TraitConfigOption; public class MainFrame extends JFrame { private static final long serialVersionUID = 1L; /** * The Tree to use. */ private static JTree raceTree; /** * The Tree to use. */ private static JTree classTree; /** * The Tree to use. */ private JPanel rightSide; public MainFrame() { this.setPreferredSize(new Dimension(500,500)); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); buildUI(); rebuildTree(); this.pack(); this.setVisible(true); } /** * Builds the UI. */ private void buildUI() { getContentPane().setLayout(new BorderLayout(0, 0)); ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if(command == null || command.isEmpty()) return; if(command.equals("LOAD")){ GuiLoader.openBaseFileSelection(); rebuildTree(); return; } if(command.equals("SAVE")){ GuiLoader.save(); JOptionPane.showMessageDialog(null, "Save done!"); return; } if(command.equals("REMOVERACE")){ if(raceTree == null || raceTree.getSelectionModel() == null) return; TreePath selectedPath = raceTree.getSelectionModel().getSelectionPath(); if(selectedPath == null) return; Object selectedNode = selectedPath.getLastPathComponent(); if(selectedNode == null) return; if(selectedNode instanceof DefaultMutableTreeNode){ Object userInfo = ((DefaultMutableTreeNode) selectedNode).getUserObject(); if(userInfo instanceof TraitConfigOption){ ((TraitConfigOption)userInfo).reset(); rebuildSelection(); treeUpdated(); } return; } if(selectedNode instanceof DefaultMutableTreeNode){ Object userInfo = ((DefaultMutableTreeNode) selectedNode).getUserObject(); if(userInfo instanceof GuiTrait){ ((GuiTrait)userInfo).removeFromParent(); rebuildSelection(); treeUpdated(); } return; } if(selectedNode instanceof DefaultMutableTreeNode){ Object userInfo = ((DefaultMutableTreeNode) selectedNode).getUserObject(); if(userInfo instanceof GuiRace){ ((DefaultMutableTreeNode)selectedNode).removeFromParent(); GuiLoader.removeRace((GuiRace) userInfo); rebuildTree(); } return; } } if(command.equals("REMOVECLASS")){ if(classTree == null || classTree.getSelectionModel() == null) return; TreePath selectedPath = classTree.getSelectionModel().getSelectionPath(); if(selectedPath == null) return; Object selectedNode = selectedPath.getLastPathComponent(); if(selectedNode == null) return; if(selectedNode instanceof DefaultMutableTreeNode){ Object userInfo = ((DefaultMutableTreeNode) selectedNode).getUserObject(); if(userInfo instanceof TraitConfigOption){ ((TraitConfigOption)userInfo).reset(); rebuildSelection(); treeUpdated(); } return; } if(selectedNode instanceof DefaultMutableTreeNode){ Object userInfo = ((DefaultMutableTreeNode) selectedNode).getUserObject(); if(userInfo instanceof GuiClass){ ((DefaultMutableTreeNode)selectedNode).removeFromParent(); GuiLoader.removeClass((GuiClass) userInfo); rebuildTree(); } return; } } } }; JLabel titleLabel = new JLabel("Races And Classes Builder"); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); getContentPane().add(titleLabel, BorderLayout.NORTH); JSplitPane splitPane = new JSplitPane(); splitPane.setContinuousLayout(true); splitPane.setResizeWeight(0.5); getContentPane().add(splitPane, BorderLayout.CENTER); raceTree = new JTree(); raceTree.setRootVisible(false); raceTree.addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { if(e == null || e.getNewLeadSelectionPath() == null) return; Object last = e.getNewLeadSelectionPath().getLastPathComponent(); if(last == null) return; if(last instanceof DefaultMutableTreeNode){ DefaultMutableTreeNode node = (DefaultMutableTreeNode) last; Object obj = node.getUserObject(); if(obj != null && obj instanceof AbstractTraitConfigOption){ //we have a new Selection! AbstractTraitConfigOption option = (AbstractTraitConfigOption) obj; userSelectedSomething(node,option); }else{ userUnSelected(); } } } }); JLabel raceHeader = new JLabel("Races"); JPanel racePanel = new JPanel(); racePanel.setLayout(new BorderLayout()); racePanel.add(raceHeader, BorderLayout.NORTH); racePanel.add(new JScrollPane(raceTree), BorderLayout.CENTER); JPanel raceControl = new JPanel(); raceControl.setLayout(new BorderLayout()); JButton removeButton = new JButton("Remove"); removeButton.setActionCommand("REMOVERACE"); removeButton.addActionListener(listener); raceControl.add(removeButton, BorderLayout.EAST); JButton addButton = new JButton("Add"); addButton.setActionCommand("ADDRACE"); addButton.addActionListener(listener); raceControl.add(addButton, BorderLayout.WEST); racePanel.add(raceControl, BorderLayout.SOUTH); classTree = new JTree(); classTree.setRootVisible(false); classTree.addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { Object last = e.getNewLeadSelectionPath().getLastPathComponent(); if(last instanceof DefaultMutableTreeNode){ DefaultMutableTreeNode node = (DefaultMutableTreeNode) last; Object obj = node.getUserObject(); if(obj != null && obj instanceof AbstractTraitConfigOption){ //we have a new Selection! AbstractTraitConfigOption option = (AbstractTraitConfigOption) obj; userSelectedSomething(node,option); }else{ userUnSelected(); } } } }); //class Panel JLabel classHeader = new JLabel("Classes"); JPanel classPanel = new JPanel(); classPanel.setLayout(new BorderLayout()); classPanel.add(classHeader, BorderLayout.NORTH); classPanel.add(new JScrollPane(classTree), BorderLayout.CENTER); JPanel classControl = new JPanel(); classControl.setLayout(new BorderLayout()); removeButton = new JButton("Remove"); removeButton.setActionCommand("REMOVECLASS"); removeButton.addActionListener(listener); classControl.add(removeButton, BorderLayout.EAST); addButton = new JButton("Add"); addButton.setActionCommand("ADDCLASS"); addButton.addActionListener(listener); classControl.add(addButton, BorderLayout.WEST); classPanel.add(classControl, BorderLayout.SOUTH); //splits definition. JSplitPane rcSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT); rcSplit.setTopComponent(racePanel); rcSplit.setBottomComponent(classPanel); rcSplit.setResizeWeight(0.5); splitPane.setLeftComponent(rcSplit); rightSide = new JPanel(); rightSide.setLayout(new BorderLayout(0, 0)); splitPane.setRightComponent(rightSide); JPanel panel = new JPanel(); getContentPane().add(panel, BorderLayout.SOUTH); panel.setLayout(new BorderLayout(0, 0)); JButton saveButton = new JButton("Save"); panel.add(saveButton, BorderLayout.WEST); JButton loadButton = new JButton("Load"); panel.add(loadButton, BorderLayout.EAST); JLabel lblNewLabel = new JLabel("by tobiyas"); lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER); panel.add(lblNewLabel, BorderLayout.CENTER); loadButton.setActionCommand("LOAD"); loadButton.addActionListener(listener); saveButton.setActionCommand("SAVE"); saveButton.addActionListener(listener); } /** * The Selected node. */ private DefaultMutableTreeNode selectedNode = null; /** * The selected Option. */ private AbstractTraitConfigOption selectedOption = null; /** * The User selected a node. * * @param node that was selected * @param obj that was selected. */ protected void userSelectedSomething(DefaultMutableTreeNode node, AbstractTraitConfigOption obj) { this.selectedNode = node; this.selectedOption = obj; rebuildSelection(); } /** * The User selected a node. * * @param node that was selected * @param obj that was selected. */ protected void userUnSelected() { if(this.selectedNode == null || this.selectedOption == null) return; this.selectedNode = null; this.selectedOption = null; rebuildSelection(); } /** * Rebuilds the Selection Interface. */ private void rebuildSelection() { rightSide.removeAll(); boolean empty = this.selectedNode == null || this.selectedOption == null; if(empty) rightSide.add(new JPanel()); else selectedOption.addWithConfigOption(rightSide); rightSide.revalidate(); } /** * Update the Tree on data change. */ public static void treeUpdated(){ if(raceTree != null) raceTree.revalidate(); if(classTree != null) classTree.revalidate(); } /** * Rebuilds the Tree. */ public static void rebuildTree(){ DefaultMutableTreeNode racesNode = new DefaultMutableTreeNode("Races"); DefaultMutableTreeNode classesNode = new DefaultMutableTreeNode("Classes"); DefaultTreeModel raceModel = (DefaultTreeModel)raceTree.getModel(); DefaultTreeModel classModel = (DefaultTreeModel)classTree.getModel(); //add the Races / Classes. for(GuiRace race : GuiLoader.getLoadedRaces()){ DefaultMutableTreeNode raceNode = new DefaultMutableTreeNode(race); raceNode.setUserObject(race); raceNode.add(getForConfig(race)); raceNode.add(getForTraits(new LinkedList<GuiTrait>(race.getTraits()))); racesNode.add(raceNode); } for(GuiClass clazz : GuiLoader.getLoadedClasses()){ DefaultMutableTreeNode classNode = new DefaultMutableTreeNode(clazz.getClassName()); classNode.setUserObject(clazz); classNode.add(getForConfig(clazz)); classNode.add(getForTraits(new LinkedList<GuiTrait>(clazz.getTraits()))); classesNode.add(classNode); } //at last reload. raceModel.setRoot(racesNode); classModel.setRoot(classesNode); raceModel.reload(); classModel.reload(); } private static MutableTreeNode getForConfig(GuiClass clazz) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("Configuration"); for(TraitConfigOption option : clazz.getConfig()){ DefaultMutableTreeNode node = new DefaultMutableTreeNode(option); root.add(node); } return root; } /** * Generates a Config Node. * * @param race to generate for. * @return a tree representation of the Config. */ private static MutableTreeNode getForConfig(GuiRace race) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("Configuration"); for(TraitConfigOption option : race.getConfig()){ DefaultMutableTreeNode node = new DefaultMutableTreeNode(option); root.add(node); } return root; } private static DefaultMutableTreeNode getForTraits(List<GuiTrait> traits){ DefaultMutableTreeNode traitsNode = new DefaultMutableTreeNode("Traits"); Collections.sort(traits); for(GuiTrait trait : traits){ DefaultMutableTreeNode node = new DefaultMutableTreeNode(trait.getTraitType()); DefaultMutableTreeNode needed = new DefaultMutableTreeNode("Needed Options"); DefaultMutableTreeNode optional = new DefaultMutableTreeNode("Optional Options"); node.add(needed); node.add(optional); for(TraitConfigOption option : trait.getTraitConfigurationNeeded()){ DefaultMutableTreeNode traitNode = new DefaultMutableTreeNode(option.toString()); traitNode.setUserObject(option); needed.add(traitNode); } for(TraitConfigOption option : trait.getTraitConfigurationOptional()){ DefaultMutableTreeNode traitNode = new DefaultMutableTreeNode(option.toString()); traitNode.setUserObject(option); optional.add(traitNode); } traitsNode.add(node); } return traitsNode; } }