changeset 32:02ef906d0341

2010/11/18 added GUIEditor Monotonic-tree GUI editor. modified Editor API bug fix (not done yet , still buggy)
author shoshi
date Thu, 18 Nov 2010 19:05:23 +0900
parents ff4d4704e5d7
children c0a0fa870e6e
files CHANGELOG src/treecms/proto/api/Editor.java src/treecms/proto/gui/GUIEditor.java src/treecms/proto/simple/SimpleEditor.java src/treecms/proto/simple/SimpleNode.java
diffstat 5 files changed, 355 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Wed Nov 17 18:28:21 2010 +0900
+++ b/CHANGELOG	Thu Nov 18 19:05:23 2010 +0900
@@ -1,5 +1,12 @@
 CHANGELOG
 
+2010/11/18
+added GUIEditor
+	Monotonic-tree GUI editor.
+
+modified Editor API
+	bug fix (not done yet , still buggy)
+
 2010/11/17
 modified Node API
 	delete setLinkedNode,getLinkedNode
--- a/src/treecms/proto/api/Editor.java	Wed Nov 17 18:28:21 2010 +0900
+++ b/src/treecms/proto/api/Editor.java	Thu Nov 18 19:05:23 2010 +0900
@@ -9,5 +9,6 @@
 	public boolean commit(boolean _force);
 	public boolean update();
 	public boolean check();
+	public void merge();
 	public Node getUncommited();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treecms/proto/gui/GUIEditor.java	Thu Nov 18 19:05:23 2010 +0900
@@ -0,0 +1,321 @@
+package treecms.proto.gui;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.JTree;
+import javax.swing.border.BevelBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+
+import treecms.proto.api.Editor;
+import treecms.proto.api.Node;
+import treecms.proto.simple.SimpleEditor;
+import treecms.proto.simple.SimpleNode;
+
+public class GUIEditor extends JFrame
+{
+	private static final long serialVersionUID = 1095393471116557554L;
+
+	public static void main(String _args[])
+	{
+		Node root = new SimpleNode();
+		root.setTitle("root");
+		Node c1 = root.addChild(new SimpleNode());
+		c1.setTitle("c1");
+		Node c2 = root.addChild(new SimpleNode());
+		c2.setTitle("c2");
+		
+		
+		Node c11 = c1.addChild(new SimpleNode());
+		c11.setTitle("c11");
+		Node c12 = c1.addChild(new SimpleNode());
+		c12.setTitle("c12");
+		
+		Node c121 = c12.addChild(new SimpleNode());
+		c121.setTitle("c121");
+		
+		AtomicReference<Node> repo = new AtomicReference<Node>(root);
+		
+		new GUIEditor(new SimpleEditor(repo));
+		new GUIEditor(new SimpleEditor(repo));
+	}
+	
+	private static final String WINDOW_TITLE = "Monotonic-Tree Editor";
+	
+	//menu bar
+	private JButton m_commit,m_update,m_check,m_merge;
+	
+	//buttons
+	private JButton m_saveButton,m_clearButton;
+	
+	//contents view
+	private JTree m_tree;
+	
+	//properties view
+	private JTable m_table;
+	
+	//editor
+	private Editor m_editor;
+	
+	public GUIEditor(Editor _editor)
+	{
+		super(WINDOW_TITLE);
+		
+		m_editor = _editor;
+		
+		getContentPane().setLayout(new BorderLayout());
+		
+		JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,buildTreeViewer(),buildNodeEditor());
+		split.setDividerLocation(400);
+		
+		getContentPane().add(buildMenuBar(),BorderLayout.NORTH);
+		getContentPane().add(split,BorderLayout.CENTER);
+		
+		setSize(500,600);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setVisible(true);
+	}
+	
+	public JComponent buildMenuBar()
+	{
+		JPanel panel = new JPanel(new GridLayout(1,4));
+		m_commit = new JButton("commit");
+		m_update = new JButton("update");
+		m_check = new JButton("check");
+		m_merge = new JButton("merge");
+		
+		EditorMenuActionListener listener = new EditorMenuActionListener();
+		m_commit.addActionListener(listener);
+		m_update.addActionListener(listener);
+		m_check.addActionListener(listener);
+		m_merge.addActionListener(listener);
+		
+		panel.add(m_commit);
+		panel.add(m_update);
+		panel.add(m_check);
+		panel.add(m_merge);
+		
+		return panel;
+	}
+	
+	public JComponent buildNodeEditor()
+	{
+		m_table = new JTable(new NodeEditorTableModel());
+		m_saveButton = new JButton("save");
+		m_clearButton = new JButton("clear");
+		
+		EditorButtonActionListener listener = new EditorButtonActionListener();
+		m_saveButton.addActionListener(listener);
+		m_clearButton.addActionListener(listener);
+		
+		JPanel panel = new JPanel(new BorderLayout());
+		panel.setBorder(new TitledBorder("Node Editor"));
+		
+		JPanel btnPanel = new JPanel(new GridLayout(1,2));
+		btnPanel.add(m_saveButton);
+		btnPanel.add(m_clearButton);
+		
+		panel.add(new JScrollPane(m_table),BorderLayout.CENTER);
+		panel.add(btnPanel,BorderLayout.SOUTH);
+		
+		return panel;
+	}
+	
+	private class NodeEditorTableModel extends DefaultTableModel
+	{
+		private static final long serialVersionUID = -7158401828787373107L;
+		
+		private Node m_node;
+		
+		public NodeEditorTableModel()
+		{
+			m_node = null;
+			setColumnIdentifiers(new String[]{"Key","Value"});
+		}
+		
+		public NodeEditorTableModel(Node _node)
+		{
+			this();
+			m_node = _node;
+			printNode();
+		}
+		
+		@Override
+		public boolean isCellEditable(int _row,int _col)
+		{
+			if(_col == 0 || _row == 0){
+				return false; //disable editing id and parameter names
+			}
+			return true;
+		}
+		
+		public void setNode(Node _node)
+		{
+			m_node = _node;
+			printNode();
+		}
+		
+		public void clear()
+		{
+			printNode();
+		}
+		
+		private void printNode()
+		{
+			setRowCount(0);
+			addRow(new String[]{"id",m_node.getID().toString()});
+			addRow(new String[]{"title",m_node.getTitle()});
+			addRow(new String[]{"class",m_node.getClassName()});
+		}
+		
+		public String getTitle()
+		{
+			return (String)getValueAt(1,1);
+		}
+		
+		public String getClassName()
+		{
+			return (String)getValueAt(2,1);
+		}
+		
+		public Node getNode()
+		{
+			return m_node;
+		}
+	}
+	
+	public JComponent buildTreeViewer()
+	{
+		m_tree = new JTree(new ContentsViewerTreeModel(m_editor.useContents()));
+		m_tree.addTreeSelectionListener(new TreeSelectionListener(){
+			@Override
+			public void valueChanged(TreeSelectionEvent _e)
+			{
+				DefaultMutableTreeNode selected = (DefaultMutableTreeNode)m_tree.getLastSelectedPathComponent();
+				if(selected == null){
+					return;
+				}
+				Node node = (Node)selected.getUserObject(); //get node
+				
+				//
+				NodeEditorTableModel model = (NodeEditorTableModel)m_table.getModel();
+				model.setNode(node);
+			}
+		});
+		
+		return new JScrollPane(m_tree);
+	}
+	
+	private class ContentsViewerTreeModel extends DefaultTreeModel
+	{
+		private static final long serialVersionUID = -4710796110922619395L;
+		
+		public ContentsViewerTreeModel(Node _contents)
+		{
+			super(new DefaultMutableTreeNode());
+			setRootNode(_contents,false);
+		}
+
+		public void setRootNode(Node _contents,boolean _reload)
+		{
+			DefaultMutableTreeNode root = (DefaultMutableTreeNode)getRoot();
+			root.removeAllChildren();
+			root.setUserObject(_contents);
+			
+			for(Node child : _contents.getChildren()){
+				treewalk(child,root);
+			}
+			
+			if(_reload){
+				reload();
+			}
+		}
+		
+		private void treewalk(Node _node,DefaultMutableTreeNode _treeNode)
+		{
+			DefaultMutableTreeNode treeChild = new DefaultMutableTreeNode();
+			treeChild.setUserObject(_node);
+			_treeNode.add(treeChild);
+			
+			for(Node child : _node.getChildren()){
+				treewalk(child,treeChild);
+			}
+		}
+	}
+	
+	private class EditorMenuActionListener implements ActionListener
+	{
+		@Override
+		public void actionPerformed(ActionEvent _e)
+		{
+			JButton source = (JButton)_e.getSource();
+			if(source.equals(m_commit)){
+				//commit
+				m_editor.commit(true);
+			}
+			if(source.equals(m_update)){
+				//update
+				m_editor.update();
+				ContentsViewerTreeModel model = (ContentsViewerTreeModel)m_tree.getModel();
+				model.setRootNode(m_editor.useContents(),true);
+			}
+			if(source.equals(m_check)){
+				//check
+				if(m_editor.check()){
+					JOptionPane.showMessageDialog(GUIEditor.this,"updates aviable!","update check",JOptionPane.OK_OPTION);
+				}else{
+					JOptionPane.showMessageDialog(GUIEditor.this,"updates not aviable!","update check",JOptionPane.OK_OPTION);
+				}
+			}
+			if(source.equals(m_merge)){
+				//merge
+				m_editor.merge();
+				ContentsViewerTreeModel model = (ContentsViewerTreeModel)m_tree.getModel();
+				model.setRootNode(m_editor.useContents(),true);
+			}
+		}
+	}
+	
+	private class EditorButtonActionListener implements ActionListener
+	{
+		@Override
+		public void actionPerformed(ActionEvent _e)
+		{
+			JButton source = (JButton)_e.getSource();
+			
+			if(source.equals(m_saveButton)){
+				NodeEditorTableModel tableModel = (NodeEditorTableModel)m_table.getModel();
+				Node target = tableModel.getNode();
+				Node newNode = m_editor.edit(target);
+				newNode.setTitle(tableModel.getTitle());
+				newNode.setClassName(tableModel.getClassName());
+				
+				ContentsViewerTreeModel treeModel = (ContentsViewerTreeModel)m_tree.getModel();
+				treeModel.setRootNode(m_editor.getUncommited(),true);
+			}
+			
+			if(source.equals(m_clearButton)){
+				NodeEditorTableModel tableModel = (NodeEditorTableModel)m_table.getModel();
+				tableModel.clear();
+			}
+		}
+		
+	}
+}
--- a/src/treecms/proto/simple/SimpleEditor.java	Wed Nov 17 18:28:21 2010 +0900
+++ b/src/treecms/proto/simple/SimpleEditor.java	Thu Nov 18 19:05:23 2010 +0900
@@ -8,72 +8,69 @@
 
 public class SimpleEditor implements Editor
 {
-	private AtomicReference<Node> m_contents;
-	private Node m_tip,m_modified;
+	private AtomicReference<Node> m_repository;
+	private Node m_tip,m_latest;
 	
 	private LinkedList<Node> m_log;
 	
 	public SimpleEditor(AtomicReference<Node> _contents)
 	{
-		m_contents = _contents;
-		m_tip = m_contents.get();
-		m_modified = null;
+		m_repository = _contents;
+		m_tip = m_repository.get();
+		m_latest = m_tip;
 		m_log = new LinkedList<Node>();
 	}
 	
 	public boolean checkUpdate()
 	{
-		return m_contents.equals(m_modified);
+		return !m_repository.compareAndSet(m_latest,m_latest);
 	}
 	
 	public boolean commit(boolean _force)
 	{
 		if(_force){
-			m_contents.set(m_tip);
+			m_repository.set(m_tip);
 			update();
 			return true;
 		}
-		return m_contents.compareAndSet(m_modified,m_tip);
+		return m_repository.compareAndSet(m_latest,m_tip);
 	}
 	
 	public void merge()
 	{
 		LinkedList<Node> log = new LinkedList<Node>(m_log);
-		update();
+		
+		update(); //update first.
 		for(Node node : log){
-			edit(node);
+			edit(node); //edit again;
 		}
 	}
 	
 	public void discard()
 	{
-		m_modified = null;
+		m_tip = m_latest;
 		m_log.clear();
 	}
 
 	@Override
 	public Node useContents()
 	{
-		// TODO Auto-generated method stub
-		return m_contents.get();
+		return m_latest;
 	}
 
 	@Override
 	public void login(String user, String pass)
 	{
-		// TODO Auto-generated method stub
 	}
 
 	@Override
 	public void logout()
 	{
-		// TODO Auto-generated method stub
 	}
 
 	@Override
 	public Node edit(Node _target)
 	{
-		// TODO Auto-generated method stub
 		LinkedList<Node> path = findPath(m_tip,_target);
 		if(path.isEmpty()){
 			return null;
@@ -84,11 +81,9 @@
 		change.add(root);
 		cloneTree(path,root,change);
 		
-		if(m_modified == null){
-			m_modified = m_tip;
-		}
 		m_tip = root;
-		m_log.add(change.peekLast());
+		m_log.add(change.peekLast()); //add to change log.
+		
 		return change.peekLast();
 	}
 	
@@ -107,8 +102,7 @@
 				_change.add(clone);
 				
 				//remove old node from clonedTree
-				_parent.addChild(clone);
-				_parent.removeChild(_child);
+				_parent.replace(_child,clone);
 				
 				cloneTree(_path,clone,_change);
 				break;
@@ -142,23 +136,21 @@
 	@Override
 	public Node getUncommited()
 	{
-		// TODO Auto-generated method stub
-		return this.m_tip;
+		return m_tip;
 	}
 
 	@Override
 	public boolean update()
 	{
-		// TODO Auto-generated method stub
 		discard();
-		m_modified = m_contents.get();
-		return false;
+		m_latest = m_repository.get();
+		m_tip = m_latest;
+		return true;
 	}
 
 	@Override
 	public boolean check()
 	{
-		// TODO Auto-generated method stub
-		return m_contents.equals(m_modified);
+		return checkUpdate();
 	}
 }
--- a/src/treecms/proto/simple/SimpleNode.java	Wed Nov 17 18:28:21 2010 +0900
+++ b/src/treecms/proto/simple/SimpleNode.java	Thu Nov 18 19:05:23 2010 +0900
@@ -165,4 +165,9 @@
 		
 		m_children = new CopyOnWriteArrayList<Node>(children);
 	}
+	
+	public String toString()
+	{
+		return getTitle()+"["+getID().toString()+"]";
+	}
 }