com.senacor.wbs.web.project.EditableTreeTablePanel.java Source code

Java tutorial

Introduction

Here is the source code for com.senacor.wbs.web.project.EditableTreeTablePanel.java

Source

/**
 * Copyright 2009 Roland Foerther, Carl-Eric-Menzel, Olaf Siefart
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.senacor.wbs.web.project;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.markup.html.tree.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.tree.table.ColumnLocation;
import org.apache.wicket.extensions.markup.html.tree.table.IColumn;
import org.apache.wicket.extensions.markup.html.tree.table.IRenderable;
import org.apache.wicket.extensions.markup.html.tree.table.PropertyTreeColumn;
import org.apache.wicket.extensions.markup.html.tree.table.TreeTable;
import org.apache.wicket.extensions.markup.html.tree.table.ColumnLocation.Alignment;
import org.apache.wicket.extensions.markup.html.tree.table.ColumnLocation.Unit;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.html.tree.AbstractTree;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import com.senacor.domain.project.Project;
import com.senacor.domain.project.Task;
import com.senacor.domain.project.TaskManager;
import com.senacor.domain.project.TaskStatus;

public class EditableTreeTablePanel extends Panel {
    private static final ResourceReference ADD = new ResourceReference(EditableTreeTablePanel.class, "res/add.png");
    private static final ResourceReference GO_BUTTOM = new ResourceReference(EditableTreeTablePanel.class,
            "res/go-bottom.png");
    private static final ResourceReference GO_DOWN = new ResourceReference(EditableTreeTablePanel.class,
            "res/go-down.png");
    private static final ResourceReference GO_TOP = new ResourceReference(EditableTreeTablePanel.class,
            "res/go-top.png");
    private static final ResourceReference GO_UP = new ResourceReference(EditableTreeTablePanel.class,
            "res/go-up.png");
    private static final ResourceReference REMOVE = new ResourceReference(EditableTreeTablePanel.class,
            "res/remove.png");
    @SpringBean()
    private TaskManager taskManager;
    private TreeTable tree;
    private DefaultTreeModel defaultTreeModel;
    private final Project project;

    public EditableTreeTablePanel(String id, Project project) {
        super(id);
        this.project = project;
        List<Task> tasks = taskManager.findTasks(project);
        IColumn columns[] = new IColumn[] {
                new PropertyTreeColumn(new ColumnLocation(Alignment.LEFT, 10, Unit.EM), "Tree Column",
                        "userObject.id"),
                new EditableTextFieldColumn(new ColumnLocation(Alignment.LEFT, 6, Unit.EM), "Name",
                        "userObject.name"),
                new EditableTextFieldColumn(new ColumnLocation(Alignment.MIDDLE, 30, Unit.PROPORTIONAL),
                        "Beschreibung", "userObject.beschreibung"),
                new EditableDropDownChoiceColumn(new ColumnLocation(Alignment.RIGHT, 10, Unit.EM), "Status",
                        "userObject.status", Arrays.asList(TaskStatus.values())),
                new AbstractColumn(new ColumnLocation(Alignment.RIGHT, 30, Unit.PX), "") {
                    public IRenderable newCell(TreeNode node, int level) {
                        return null;
                    }

                    public Component newCell(MarkupContainer parent, String id, final TreeNode node, int level) {
                        return new LinkPanel(id, REMOVE, node) {
                            @Override
                            protected void handle(TreeNode treeNode, AjaxRequestTarget target) {
                                // Node
                                DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeNode;
                                Task nodeTask = (Task) node.getUserObject();
                                // Parent
                                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
                                Task parentTask = (Task) parent.getUserObject();
                                // Entferne den Task aus den Subtaks
                                // parentTask.getSubtasks().remove(
                                // defaultTreeModel
                                // .getIndexOfChild(parent, node));
                                // Entfernung des Knotens und neu rendern
                                defaultTreeModel.removeNodeFromParent(node);
                                tree.modelChanged();
                                tree.updateTree(target);
                            }

                            @Override
                            protected boolean show() {
                                if (node.getParent() == null) {
                                    return false;
                                }
                                return true;
                            }
                        };
                    }
                }, new AbstractColumn(new ColumnLocation(Alignment.RIGHT, 30, Unit.PX), "") {
                    public IRenderable newCell(TreeNode node, int level) {
                        return null;
                    }

                    public Component newCell(MarkupContainer parent, String id, final TreeNode node, int level) {
                        return new LinkPanel(id, ADD, node) {
                            @Override
                            protected void handle(TreeNode treeNode, AjaxRequestTarget target) {
                                // Node
                                DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeNode;
                                Task nodeTask = (Task) node.getUserObject();
                                // Fge den Task zu den Subtasks hinzu
                                Task newTask = new Task();
                                nodeTask.getSubtasks().add(newTask);
                                defaultTreeModel.insertNodeInto(new DefaultMutableTreeNode(newTask), node, 0);
                                tree.getTreeState().expandNode(node);
                                tree.getTreeState().selectNode(node, true);
                                tree.invalidateAll();
                                tree.modelChanged();
                                tree.updateTree(target);
                            }

                            @Override
                            protected boolean show() {
                                return true;
                            }
                        };
                    }
                }, new AbstractColumn(new ColumnLocation(Alignment.RIGHT, 30, Unit.PX), "") {
                    public IRenderable newCell(TreeNode node, int level) {
                        return null;
                    }

                    public Component newCell(MarkupContainer parent, String id, final TreeNode node, int level) {
                        return new LinkPanel(id, GO_UP, node) {
                            @Override
                            protected void handle(TreeNode node, AjaxRequestTarget target) {
                                DefaultMutableTreeNode node1 = (DefaultMutableTreeNode) node;
                                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node1.getParent();
                                int index = defaultTreeModel.getIndexOfChild(parent, node1);
                                defaultTreeModel.removeNodeFromParent(node1);
                                defaultTreeModel.insertNodeInto(node1, parent, index - 1);
                                tree.getTreeState().expandNode(parent);
                                tree.invalidateAll();
                                tree.modelChanged();
                                tree.updateTree(target);
                            }

                            @Override
                            protected boolean show() {
                                if (node.getParent() == null
                                        || defaultTreeModel.getIndexOfChild(node.getParent(), node) == 0) {
                                    return false;
                                }
                                return true;
                            }
                        };
                    }
                }, new AbstractColumn(new ColumnLocation(Alignment.RIGHT, 30, Unit.PX), "") {
                    public IRenderable newCell(TreeNode node, int level) {
                        return null;
                    }

                    public Component newCell(MarkupContainer parent, String id, final TreeNode node, int level) {
                        return new LinkPanel(id, GO_DOWN, node) {
                            @Override
                            protected void handle(TreeNode node, AjaxRequestTarget target) {
                                DefaultMutableTreeNode node1 = (DefaultMutableTreeNode) node;
                                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node1.getParent();
                                int index = defaultTreeModel.getIndexOfChild(parent, node1);
                                defaultTreeModel.removeNodeFromParent(node1);
                                defaultTreeModel.insertNodeInto(node1, parent, index + 1);
                                tree.getTreeState().expandNode(parent);
                                tree.invalidateAll();
                                tree.modelChanged();
                                tree.updateTree(target);
                            }

                            @Override
                            protected boolean show() {
                                if (node.getParent() == null || defaultTreeModel.getIndexOfChild(node.getParent(),
                                        node) == defaultTreeModel.getChildCount(node.getParent()) - 1) {
                                    return false;
                                }
                                return true;
                            }
                        };
                    }
                } };
        Form form = new Form("form");
        form.setOutputMarkupId(true);
        add(form);
        //
        defaultTreeModel = createTreeModel(tasks);
        tree = new TreeTable("treeTable", defaultTreeModel, columns);
        tree.setOutputMarkupId(true);
        tree.getTreeState().collapseAll();
        form.add(tree);
        form.add(new AjaxButton("submit") {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form form1) {
                Task rootTask = getTaskStructure((DefaultMutableTreeNode) defaultTreeModel.getRoot());
                taskManager.saveTasks(EditableTreeTablePanel.this.project, rootTask.getSubtasks());
            }
        });
    }

    private Task getTaskStructure(DefaultMutableTreeNode treeNode) {
        // Zugehrigen Task ermittel
        Task task = (Task) ((DefaultMutableTreeNode) treeNode).getUserObject();
        // Die Kinder erst lschen
        task.getSubtasks().clear();
        // und dann neu aufbauen
        if (!treeNode.isLeaf()) {
            Enumeration<DefaultMutableTreeNode> children = treeNode.children();
            while (children.hasMoreElements()) {
                task.getSubtasks().add(getTaskStructure(children.nextElement()));
            }
        }
        return task;
    }

    /**
     * @see BaseTreePage#getTree()
     */
    protected AbstractTree getTree() {
        return tree;
    }

    /**
     * Creates the model that feeds the tree.
     * 
     * @return New instance of tree model.
     */
    protected DefaultTreeModel createTreeModel(List<Task> tasks) {
        return convertToTreeModel(tasks);
    }

    private DefaultTreeModel convertToTreeModel(List<Task> tasks) {
        DefaultTreeModel model = null;
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(new Task());
        add(rootNode, tasks);
        model = new DefaultTreeModel(rootNode);
        return model;
    }

    private void add(DefaultMutableTreeNode parent, List<Task> tasks) {
        for (Task task : tasks) {
            if (!task.getSubtasks().isEmpty()) {
                DefaultMutableTreeNode child = new DefaultMutableTreeNode(task);
                parent.add(child);
                add(child, task.getSubtasks());
            } else {
                DefaultMutableTreeNode child = new DefaultMutableTreeNode(task);
                parent.add(child);
            }
        }
    }

    public static class EditableTextFieldColumn extends PropertyEditableColumn {
        public EditableTextFieldColumn(ColumnLocation location, String header, String propertyExpression) {
            super(location, header, propertyExpression);
        }

        @Override
        public Component newCell(MarkupContainer parent, String id, TreeNode node, int level) {
            return new EditablePanel(id, new PropertyModel(node, getPropertyExpression()));
        }
    }

    public static class EditableDropDownChoiceColumn extends PropertyEditableColumn {
        private final List values;

        public EditableDropDownChoiceColumn(ColumnLocation location, String header, String propertyExpression,
                List values) {
            super(location, header, propertyExpression);
            this.values = values;
        }

        @Override
        public Component newCell(MarkupContainer parent, String id, TreeNode node, int level) {
            return new DropDownBoxPanel(id, new PropertyModel(node, getPropertyExpression()), values);
        }
    }
}