package com.clearlyspam23.GLE.basic.layers.tile.gui.tileset; import java.awt.Component; import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.DropMode; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import com.clearlyspam23.GLE.GUI.util.TreeTransferHandler; import com.clearlyspam23.GLE.basic.layers.tile.TilesetGroupNode; import com.clearlyspam23.GLE.basic.layers.tile.TilesetTileNode; import com.clearlyspam23.GLE.basic.layers.tile.TilesetTreeNode; import com.clearlyspam23.GLE.basic.layers.tile.TilesetTreeNode.Type; import com.clearlyspam23.GLE.basic.layers.tile.resources.BasicTilesetHandle; public class TilesetTreeViewPanel extends JPanel { /** * */ private static final long serialVersionUID = 1L; private JTree tilesetTree; private DefaultMutableTreeNode top = new DefaultMutableTreeNode(); private DefaultTreeModel model; //private TwoWayMap<TilesetTreeNode, DefaultMutableTreeNode> nodeMap = new TwoWayMap<TilesetTreeNode, DefaultMutableTreeNode>(); private TilesetViewListener listener; private TilesetTreeCellEditor editor; private static final TilesetViewListener DEFAULT_LISTENER = new TilesetViewListener(){ @Override public void onTilesetDoubleClick(TilesetTreeViewPanel panel, TilesetTileNode tileNode, MouseEvent e) {} @Override public void onGroupDoubleClick(TilesetTreeViewPanel panel, TilesetGroupNode tileNode, MouseEvent e) {} @Override public void onTilesetRightClick(TilesetTreeViewPanel panel, TilesetTileNode tileNode, MouseEvent e) {} @Override public void onGroupRightClick(TilesetTreeViewPanel panel, TilesetGroupNode tileNode, MouseEvent e) {} @Override public void onTilesetRenamed(TilesetTreeViewPanel panel, TilesetTileNode node) {} @Override public void onGroupRenamed(TilesetTreeViewPanel panel, TilesetGroupNode node) {} }; private static void printTree(TilesetTreeNode node, int indentLevel){ for(int i = 0; i < indentLevel; i++){ System.out.print(" "); } System.out.println(node.getName()); if(node.getType()==Type.GROUP){ for(TilesetTreeNode n : node.getAsGroup().getChildren()) printTree(n, indentLevel+1); } } private static void printTree(DefaultMutableTreeNode node, int indentLevel){ for(int i = 0; i < indentLevel; i++){ System.out.print(" "); } System.out.println(((TilesetTreeNode)node.getUserObject()).getName()); for(int i = 0; i < node.getChildCount(); i++) printTree((DefaultMutableTreeNode)node.getChildAt(i), indentLevel+1); } public static void main(String[] args){ try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e1) { //honestly, if this doesnt work, whatever we'll use default. should fail silently. } final TilesetTreeViewPanel panel = new TilesetTreeViewPanel(); final TilesetGroupNode root = new TilesetGroupNode("tilesets"); final TilesetGroupNode group = new TilesetGroupNode("group"); final TilesetTileNode node1 = new TilesetTileNode(new BasicTilesetHandle("tileset1")); final TilesetTileNode node2 = new TilesetTileNode(new BasicTilesetHandle("tileset2")); final TilesetTileNode node3 = new TilesetTileNode(new BasicTilesetHandle("tileset3")); final JPopupMenu rightPopUp = new JPopupMenu(); JMenuItem button = new JMenuItem("New Tileset"); button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { System.out.println("I was Clicked!"); panel.insertNode(new TilesetTileNode(new BasicTilesetHandle("New Tileset"))); } }); rightPopUp.add(button); button = new JMenuItem("New Group"); button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { panel.insertNode(new TilesetGroupNode("New Group")); } }); rightPopUp.add(button); button = new JMenuItem("Run Analysis"); button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { printTree(root, 0); printTree(panel.top, 0); } }); rightPopUp.add(button); group.addNode(node1); group.addNode(node2); root.addNode(node3); root.addNode(group); panel.setToTilesets(root, new TilesetViewListener(){ @Override public void onTilesetDoubleClick(TilesetTreeViewPanel panel, TilesetTileNode tileNode, MouseEvent e) { System.out.println("Double Click on Tileset - " + tileNode.getName()); } @Override public void onGroupDoubleClick(TilesetTreeViewPanel panel, TilesetGroupNode tileNode, MouseEvent e) { System.out.println("Double Click on Group - " + tileNode.getName()); } @Override public void onTilesetRightClick(TilesetTreeViewPanel panel, TilesetTileNode tileNode, MouseEvent e) { System.out.println("Right Click on Tileset - " + tileNode.getName()); } @Override public void onGroupRightClick(TilesetTreeViewPanel panel, TilesetGroupNode tileNode, MouseEvent e) { System.out.println("Right Click on Group - " + tileNode.getName()); rightPopUp.show(e.getComponent(), e.getX(), e.getY()); } @Override public void onTilesetRenamed(TilesetTreeViewPanel panel, TilesetTileNode node) { System.out.println("Renamed Tile node!"); } @Override public void onGroupRenamed(TilesetTreeViewPanel panel, TilesetGroupNode node) { System.out.println("Renamed Group node!"); } }); EventQueue.invokeLater(new Runnable() { public void run() { try { JFrame frame = new JFrame(); frame.getContentPane().setLayout(new GridLayout(1, 1, 0, 0)); JScrollPane scroll = new JScrollPane(panel); frame.add(scroll); frame.setSize(150, 400); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the panel. */ public TilesetTreeViewPanel() { setLayout(new GridLayout(1, 1, 0, 0)); // JScrollPane scrollPane = new JScrollPane(); // add(scrollPane); model = new DefaultTreeModel(top); model.addTreeModelListener(new TreeModelListener(){ @Override public void treeNodesChanged(TreeModelEvent e) { TilesetTreeNode out = (TilesetTreeNode)((DefaultMutableTreeNode)e.getChildren()[e.getChildren().length-1]).getUserObject(); if(out.getType()==Type.GROUP) listener.onGroupRenamed(TilesetTreeViewPanel.this, out.getAsGroup()); else listener.onTilesetRenamed(TilesetTreeViewPanel.this, out.getAsTiles()); } @Override public void treeNodesInserted(TreeModelEvent e) { TilesetGroupNode group = (TilesetGroupNode) ((DefaultMutableTreeNode)e.getTreePath().getLastPathComponent()).getUserObject(); TilesetTreeNode out = (TilesetTreeNode)((DefaultMutableTreeNode)e.getChildren()[e.getChildren().length-1]).getUserObject(); out.setParent(group); } @Override public void treeNodesRemoved(TreeModelEvent e) { } @Override public void treeStructureChanged(TreeModelEvent e) { } }); tilesetTree = new JTree(model); tilesetTree.setDragEnabled(true); tilesetTree.setDropMode(DropMode.ON_OR_INSERT); tilesetTree.setTransferHandler(new TreeTransferHandler()); tilesetTree.addMouseListener(new MouseListener(){ @Override public void mouseClicked(MouseEvent e) { TreePath selPath = tilesetTree.getPathForLocation(e.getX(), e.getY()); if(selPath==null) return; int row = tilesetTree.getClosestRowForLocation(e.getX(), e.getY()); tilesetTree.setSelectionRow(row); TilesetTreeNode node = (TilesetTreeNode) ((DefaultMutableTreeNode)selPath.getLastPathComponent()).getUserObject(); if (SwingUtilities.isRightMouseButton(e)) { if(node.getType()==Type.GROUP){ listener.onGroupRightClick(TilesetTreeViewPanel.this, node.getAsGroup(), e); } else{ listener.onTilesetRightClick(TilesetTreeViewPanel.this, node.getAsTiles(), e); } } else if(SwingUtilities.isLeftMouseButton(e)&&e.getClickCount()==2){ if(node.getType()==Type.GROUP){ listener.onGroupDoubleClick(TilesetTreeViewPanel.this, node.getAsGroup(), e); } else{ listener.onTilesetDoubleClick(TilesetTreeViewPanel.this, node.getAsTiles(), e); } } } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { } @Override public void mouseReleased(MouseEvent arg0) { } }); add(tilesetTree); try { Image image = ImageIO.read(new File("images/TilesetIconSmall.png")); tilesetTree.setCellRenderer(new TilesetTreeCellRenderer(new ImageIcon(image))); editor = new TilesetTreeCellEditor(tilesetTree, (DefaultTreeCellRenderer) tilesetTree.getCellRenderer()); tilesetTree.setCellEditor(editor); tilesetTree.setEditable(true); } catch (IOException e) { throw new RuntimeException(e); } } private void loadTilesets(TilesetTreeNode node, DefaultMutableTreeNode parent){ DefaultMutableTreeNode current = new DefaultMutableTreeNode(node); current.setAllowsChildren(node.getType()==Type.GROUP); //nodeMap.put(node, current); model.insertNodeInto(current, parent, parent.getChildCount()); if(node.getType()==Type.GROUP){ for(TilesetTreeNode n : node.getAsGroup().getChildren()) loadTilesets(n, current); } } private static class TilesetTreeCellRenderer extends DefaultTreeCellRenderer{ /** * */ private static final long serialVersionUID = 1L; private TilesetTreeCellRenderer(Icon tilesetIcon){ setLeafIcon(tilesetIcon); } @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); if(value==null) return this; TilesetTreeNode node = (TilesetTreeNode) ((DefaultMutableTreeNode)value).getUserObject(); if(node==null) return this; this.setText(node.getName()); if(node.getType()==Type.GROUP){ if(expanded) this.setIcon(this.openIcon); else this.setIcon(this.closedIcon); } else{ setIcon(this.leafIcon); } return this; } } public void setToTilesets(TilesetGroupNode root){ setToTilesets(root, DEFAULT_LISTENER); } public void setToTilesets(TilesetGroupNode root, TilesetViewListener listener){ this.listener = listener; top.removeAllChildren(); model.reload(); top.setUserObject(root); editor.setTilesetRoot(root); for(TilesetTreeNode n : root.getChildren()) loadTilesets(n, top); tilesetTree.expandRow(0); } public void insertNode(TilesetTreeNode node){ insertNode(node, (DefaultMutableTreeNode) tilesetTree.getLastSelectedPathComponent(), false); } public void insertNode(TilesetTreeNode node, boolean select){ insertNode(node, (DefaultMutableTreeNode) tilesetTree.getLastSelectedPathComponent(), select); } public void insertNode(TilesetTreeNode node, DefaultMutableTreeNode treeNode, boolean select){ TilesetTreeNode tileNode = (TilesetTreeNode) treeNode.getUserObject(); int index = treeNode.getChildCount(); if(tileNode.getType()!=Type.GROUP){ index = treeNode.getParent().getIndex(treeNode)+1; treeNode = (DefaultMutableTreeNode) treeNode.getParent(); } DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(node, node.getType()==Type.GROUP); model.insertNodeInto(newNode, treeNode, index); if(select){ tilesetTree.setSelectionPath(new TreePath(newNode.getPath())); } } public void removeNode(){ removeNode((DefaultMutableTreeNode) tilesetTree.getLastSelectedPathComponent()); } public void removeNode(DefaultMutableTreeNode node){ if(node!=top) model.removeNodeFromParent(node); } public TilesetTreeNode getSelectedNode(){ DefaultMutableTreeNode node = (DefaultMutableTreeNode) tilesetTree.getLastSelectedPathComponent(); if(node!=null) return (TilesetTreeNode) node.getUserObject(); return null; } }