GanttTree2.java

Index Score
net.sourceforge.ganttproject
GanttProject

View: Reasons, Metrics, Source Code

These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.

MetricDescription
/*************************************************************************** * GanttTree.java - description * ------------------- * begin : dec 2002 * copyright : (C) 2002 by Thomas Alexandre * email : alexthomas(at)ganttproject.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ package net.sourceforge.ganttproject; import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.GradientPaint; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.SystemColor; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.Autoscroll; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.ToolTipManager; import javax.swing.border.EtchedBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode; import org.jdesktop.swingx.treetable.MutableTreeTableNode; import net.sourceforge.ganttproject.action.GPAction; import net.sourceforge.ganttproject.delay.Delay; import net.sourceforge.ganttproject.delay.DelayObserver; import net.sourceforge.ganttproject.font.Fonts; import net.sourceforge.ganttproject.gui.TableHeaderUIFacade; import net.sourceforge.ganttproject.gui.TaskTreeUIFacade; import net.sourceforge.ganttproject.gui.UIFacade; import net.sourceforge.ganttproject.language.GanttLanguage; import net.sourceforge.ganttproject.task.BlankLineNode; import net.sourceforge.ganttproject.task.ResourceAssignment; import net.sourceforge.ganttproject.task.Task; import net.sourceforge.ganttproject.task.TaskContainmentHierarchyFacade; import net.sourceforge.ganttproject.task.TaskManager; import net.sourceforge.ganttproject.task.TaskManagerImpl; import net.sourceforge.ganttproject.task.TaskNode; import net.sourceforge.ganttproject.task.TaskSelectionManager; import net.sourceforge.ganttproject.task.TaskSelectionManager.Listener; import net.sourceforge.ganttproject.task.algorithm.AdjustTaskBoundsAlgorithm; import net.sourceforge.ganttproject.task.algorithm.RecalculateTaskScheduleAlgorithm; import net.sourceforge.ganttproject.task.dependency.TaskDependency; import net.sourceforge.ganttproject.task.dependency.TaskDependencyConstraint; import net.sourceforge.ganttproject.task.dependency.TaskDependencyException; import net.sourceforge.ganttproject.undo.GPUndoManager; //import org.jdesktop.swing.treetable.DefaultTreeTableModel; /** * Class that generate the JTree */ public class GanttTree2 extends JPanel implements DragSourceListener, DragGestureListener, ProjectEventListener, TaskTreeUIFacade { /** The root node of the Tree */ private TaskNode rootNode; /** The model for the JTableTree */ private GanttTreeTableModel treeModel; private UIFacade myUIFacade; /** The GanttTreeTable. */ private GanttTreeTable treetable; /** Pointer on graphic area */ private GanttGraphicArea area = null; /** Pointer on application */ private GanttProject appli; /** The vertical scrollbar on the JTree */ private JScrollBar vbar; /** The horizontal scrollbar on the JTree */ private JScrollBar hbar; /** The language use */ private GanttLanguage language = GanttLanguage.getInstance(); /** Number of tasks on the tree. */ private int nbTasks = 0; private TreePath dragPath = null; private BufferedImage ghostImage = null; // The 'drag image' private Point offsetPoint = new Point(); // Where, in the drag image, the // mouse was clicked private final TaskManager myTaskManager; private final TaskSelectionManager mySelectionManager; private final GPAction myExpandAllAction = new GPAction() { protected String getIconFilePrefix() { return "expandall_"; } public void actionPerformed(ActionEvent e) { treetable.expandAll(); } protected String getLocalizedName() { return getI18n("expandAll"); } }; private final GPAction myCollapseAllAction = new GPAction() { protected String getIconFilePrefix() { return "collapseall_"; } public void actionPerformed(ActionEvent e) { treetable.collapseAll(); } protected String getLocalizedName() { return getI18n("collapseAll"); } }; private final GPAction myExpandAction = new ExpandAction(); private final GPAction myExpandSubtasksAction = new ExpandSubtasksAction(); private final GPAction myCollapseSubtasksAction = new CollapseSubtasksAction(); private final GPAction myIndentAction = new GPAction() { protected String getIconFilePrefix() { return "indent_"; } public void actionPerformed(ActionEvent e) { indentCurrentNodes(); } protected String getLocalizedName() { return getI18n("indentTask"); } }; private final GPAction myDedentAction = new GPAction() { protected String getIconFilePrefix() { return "unindent_"; } public void actionPerformed(ActionEvent e) { dedentCurrentNodes(); } protected String getLocalizedName() { return getI18n("dedentTask"); } }; private final GPAction myMoveUpAction = new GPAction() { protected String getIconFilePrefix() { return "up_"; } public void actionPerformed(ActionEvent e) { upCurrentNodes(); } protected String getLocalizedName() { return getI18n("upTask"); } }; private final GPAction myMoveDownAction = new GPAction() { protected String getIconFilePrefix() { return "down_"; } public void actionPerformed(ActionEvent e) { downCurrentNodes(); } protected String getLocalizedName() { return getI18n("downTask"); } }; private Action myLinkTasksAction; private Action myUnlinkTasksAction; private class ExpandAction extends GPAction { public ExpandAction() { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)); } protected String getIconFilePrefix() { return "plus_"; } public void actionPerformed(ActionEvent e) { final DefaultMutableTreeTableNode[] cdmtn = getSelectedTaskNodes(); if (cdmtn == null) { myUIFacade.setStatusText(language.getText("msg21")); return; } for (int i=0; i<cdmtn.length; i++) { for (int j=0; j<cdmtn[i].getChildCount(); j++) { DefaultMutableTreeTableNode child = (DefaultMutableTreeTableNode)cdmtn[i].getChildAt(j); getTreeTable().getTree().collapsePath(new TreePath(child.getPath())); } } } protected String getLocalizedName() { return getI18n("expand"); } } private class ExpandSubtasksAction extends GPAction { public ExpandSubtasksAction() { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); } protected String getIconFilePrefix() { return "expandall_"; } public void actionPerformed(ActionEvent e) { final DefaultMutableTreeTableNode[] cdmtn = getSelectedTaskNodes(); if (cdmtn == null) { myUIFacade.setStatusText(language.getText("msg21")); return; } for (int i=0; i<cdmtn.length; i++) { DefaultMutableTreeTableNode node = (DefaultMutableTreeTableNode)cdmtn[i].getLastLeaf().getParent(); getTreeTable().getTree().expandPath(new TreePath(node.getPath())); } } protected String getLocalizedName() { return getI18n("expandSubtasks"); } } private class CollapseSubtasksAction extends GPAction { public CollapseSubtasksAction() { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)); } protected String getIconFilePrefix() { return "collapseall_"; } public void actionPerformed(ActionEvent e) { final DefaultMutableTreeTableNode[] cdmtn = getSelectedTaskNodes(); if (cdmtn == null) { myUIFacade.setStatusText(language.getText("msg21")); return; } for (int i=0; i<cdmtn.length; i++) { getTreeTable().getTree().collapsePath(new TreePath(cdmtn[i].getPath())); } } protected String getLocalizedName() { return getI18n("collapseSubtasks"); } } /** * Constructor. * @param selectionManager TODO * @param facade */ public GanttTree2(final GanttProject app, TaskManager taskManager, TaskSelectionManager selectionManager, UIFacade uiFacade) { super(); app.getProject().addProjectEventListener(this); myUIFacade = uiFacade; myTaskManager = taskManager; mySelectionManager = selectionManager; this.appli = app; // Create the root node initRootNode(); treeModel = new GanttTreeTableModel(rootNode, taskManager); treeModel.addTreeModelListener(new GanttTreeModelListener()); // Create the JTree treetable = new GanttTreeTable(app.getProject(), uiFacade, treeModel, app.getTaskCustomColumnManager()); treetable.getActionMap().put(myExpandAction.getValue(Action.NAME), myExpandAction); treetable.getActionMap().put(myExpandSubtasksAction.getValue(Action.NAME), myExpandSubtasksAction); treetable.getActionMap().put(myCollapseSubtasksAction.getValue(Action.NAME), myCollapseSubtasksAction); treetable.getActionMap().put(myIndentAction.getValue(Action.NAME), myIndentAction); treetable.getActionMap().put(myDedentAction.getValue(Action.NAME), myDedentAction); treetable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), myExpandAction.getValue(Action.NAME)); treetable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), myExpandSubtasksAction.getValue(Action.NAME)); treetable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), myCollapseSubtasksAction.getValue(Action.NAME)); treetable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), myIndentAction.getValue(Action.NAME)); treetable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK), myDedentAction.getValue(Action.NAME)); treetable.getActionMap().put("newTask", appli.getNewToplevelTaskAction()); treetable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(GPAction.getKeyStroke("newArtifact.shortcut"), "newTask"); treetable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.ALT_DOWN_MASK), "cutTask"); treetable.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if (false==treetable.getTable().isEditing()) { app.keyPressed(e); } } }); // callback for keyboard pressed treetable.getTree().addTreeSelectionListener( new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { mySelectionManager.clear(); TaskNode tn[] = (TaskNode[]) getSelectedTaskNodes(); if (tn != null) { for (TaskNode node : tn) { mySelectionManager.addTask((Task)node.getUserObject()); } } } }); treetable.setBackground(new Color(1.0f, 1.0f, 1.0f)); treetable.getTree().addTreeExpansionListener( new GanttTreeExpansionListener()); ToolTipManager.sharedInstance().registerComponent(treetable); // Add The tree on a Scrollpane JScrollPane scrollpane = new JScrollPane(); setLayout(new BorderLayout()); add(scrollpane, BorderLayout.CENTER); scrollpane.getViewport().add(treetable); scrollpane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); vbar = scrollpane.getVerticalScrollBar(); final JPanel jp = new JPanel(new BorderLayout()); jp.add(vbar, BorderLayout.CENTER); jp.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); jp.setVisible(false); vbar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { if (treetable.getSize().getHeight() - 20 < e.getAdjustable() .getMaximum()) jp.setVisible(true); else jp.setVisible(false); repaint(); } }); this.add(jp, BorderLayout.WEST); hbar = scrollpane.getHorizontalScrollBar(); vbar.addAdjustmentListener(new GanttAdjustmentListener()); /* Select (highlight) task chosen in filter tree in task tree */ mySelectionManager.addSelectionListener(new Listener() { public void selectionChanged(List currentSelection) { Iterator it = currentSelection.iterator(); if (it.hasNext()) { Task task = (Task) it.next(); DefaultMutableTreeTableNode taskNode = null; for (Enumeration nodes = rootNode.preorderEnumeration(); nodes.hasMoreElements();) { DefaultMutableTreeTableNode nextNode = (DefaultMutableTreeTableNode) nodes.nextElement(); if (!(nextNode instanceof TaskNode)) continue; if (nextNode.getUserObject().equals(task)) { taskNode = nextNode; break; } } if (taskNode != null) { TreePath taskPath = new TreePath(taskNode.getPath()); treetable.getTree().getSelectionModel().setSelectionPath(taskPath); treetable.scrollPathToVisible(taskPath); } } if (treetable.getTable().isEditing()) { /* Stop editing cell */ treetable.getTable().editingStopped(new ChangeEvent(treetable.getTreeTable())); } } public void userInputConsumerChanged(Object newConsumer) { if (treetable.getTable().isEditing()) { treetable.getTable().editingStopped(new ChangeEvent(treetable.getTreeTable())); } } }); treetable.getTree().addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { super.focusGained(e); mySelectionManager.setUserInputConsumer(this); } }); // A listener on mouse click (menu) MouseListener ml = new MouseAdapter() { public void mouseReleased(MouseEvent e) { handlePopupTrigger(e); } public void mousePressed(MouseEvent e) { handlePopupTrigger(e); } public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub if (e.getClickCount()==2 && e.getButton() == MouseEvent.BUTTON1) { TreePath selPath = treetable.getTreeTable().getPathForLocation(e.getX(), e.getY()); if (selPath!=null) { e.consume(); appli.propertiesTask(); } } else { handlePopupTrigger(e); } } private void handlePopupTrigger(MouseEvent e) { if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3) { TreePath selPath = treetable.getTreeTable().getPathForLocation(e.getX(), e.getY()); if (selPath!=null) { TreePath[] currentSelection = treetable.getTree() .getSelectionPaths(); if (currentSelection == null || currentSelection.length == 0) treetable.getTree().setSelectionPath(selPath); else { boolean contains = false; for (int i = 0; i < currentSelection.length && !contains; i++) if (currentSelection[i] == selPath) contains = true; if (!contains) treetable.getTree().setSelectionPath( selPath); } createPopupMenu(e.getX(), e.getY(), true); } else { treetable.getTree().setSelectionPath(null); createPopupMenu(e.getX(), e.getY(), false); } e.consume(); } } }; if (!app.isOnlyViewer) treetable.addMouseListener(ml); DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(treetable, DnDConstants.ACTION_COPY_OR_MOVE, this); dragSource.addDragSourceListener(this); DropTarget dropTarget = new DropTarget(treetable, new GanttTreeDropListener()); dropTarget.setDefaultActions(DnDConstants.ACTION_COPY_OR_MOVE); getTreeTable().setToolTipText("aze"); getTreeTable().getTreeTable().setToolTipText("rty"); } public void setActions() { treetable.setAction(appli.getCopyAction()); treetable.setAction(appli.getPasteAction()); treetable.setAction(appli.getCutAction()); treetable.addAction(myIndentAction, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); treetable.addAction(myDedentAction, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)); } /** * Edits the <code>t</code> task name in the treetable. */ public void setEditingTask(Task t) { selectTask(t, false); //TreePath tp = new TreePath(getSelectedTaskNode().getPath()); // int c = getTable().convertColumnIndexToView( // getTable().getColumn(GanttTreeTableModel.strColName) // .getModelIndex()); treetable.getTreeTable().editingStopped( new ChangeEvent(treetable.getTreeTable())); treetable.editNewTask(t); // treetable.getTreeTable().editCellAt( // treetable.getTree().getRowForPath(tp), c); // treetable.requestFocus(); //treetable.centerViewOnSelectedCell(); } public void stopEditing() { treetable.getTable().editingCanceled( new ChangeEvent(treetable.getTreeTable())); treetable.getTreeTable().editingCanceled( new ChangeEvent(treetable.getTreeTable())); } public void changeLanguage(GanttLanguage ganttLanguage) { this.language = ganttLanguage; //this.treetable.changeLanguage(language); } private void initRootNode() { getTaskManager().getRootTask().setName("root"); rootNode = new TaskNode(getTaskManager().getRootTask()); } public Action[] getPopupMenuActions() { List<Action> actions = new ArrayList<Action>(); actions.add(appli.getNewSubtaskAction()); if (!mySelectionManager.getSelectedTasks().isEmpty()) { actions.add(getTaskPropertiesAction()); // } actions.add(createMenuAction(GanttProject.correctLabel(language .getText("deleteTask")), "/icons/delete_16.gif")); actions.add(null); actions.add(myExpandAction); actions.add(myExpandSubtasksAction); actions.add(myCollapseSubtasksAction); actions.add(null); actions.add(myIndentAction); actions.add(myDedentAction); actions.add(getMoveUpAction()); actions.add(getMoveDownAction()); actions.add(null); actions.add(getUnlinkTasksAction()); actions.add(getLinkTasksAction()); actions.add(null); actions.add(appli.getCutAction()); actions.add(appli.getCopyAction()); actions.add(appli.getPasteAction()); /* actions.add(null); actions.add(createMenuAction(language.getText("hideTask"), "/icons/hide_16.gif")); actions.add(createMenuAction(language.getText("displayHiddenTasks"), "/icons/show_16.gif")); */ } return (Action[]) actions.toArray(new Action[0]); } private Action createMenuAction(String label, String iconPath) { AbstractAction result = new AbstractAction(label, new ImageIcon( getClass().getResource(iconPath))) { public void actionPerformed(ActionEvent e) { appli.actionPerformed(e); } }; return result; } /** Create a popup menu when mous click */ private void createPopupMenu(int x, int y, boolean all) { JPopupMenu menu = new JPopupMenu(); Action[] popupMenuActions = getPopupMenuActions(); myUIFacade.showPopupMenu(this, popupMenuActions, x - hbar.getValue() + (vbar.isVisible() ? vbar.getWidth() : 0), y - vbar.getValue() + 20); } /** Change grpahic part */ public void setGraphicArea(GanttGraphicArea area) { this.area = area; } /** add an object with the expand information */ public DefaultMutableTreeTableNode addObjectWithExpand(Object child, DefaultMutableTreeTableNode parent, int position) { DefaultMutableTreeTableNode childNode = new TaskNode((Task) child); if (parent == null) parent = rootNode; treeModel.insertNodeInto(childNode, parent, position<0 ? parent.getChildCount() : position); //forwardScheduling(); Task task = (Task) (childNode.getUserObject()); boolean res = true; if (parent == null) res = false; // test for expantion while (parent != null) { Task taskFather = (Task) (parent.getUserObject()); if (!taskFather.getExpand()) { res = false; break; } parent = (DefaultMutableTreeTableNode) (parent.getParent()); } treetable.getTree().scrollPathToVisible( new TreePath(childNode.getPath())); if (!res && parent!=null) { treetable.getTree().collapsePath(new TreePath(parent.getPath())); } // else // task.setExpand(false); nbTasks++; appli.refreshProjectInfos(); return childNode; } /** Add a sub task. */ public TaskNode addObject(Object child, MutableTreeTableNode parent, int index) { TaskNode childNode = new TaskNode((Task) child); if (parent == null) parent = rootNode; // GanttTask tmpTask = (GanttTask)(childNode.getUserObject()); // tmpTask.indentID((String)(((GanttTask)(parent.getUserObject())).getID())); treeModel.insertNodeInto(childNode, parent, index == -1 ? parent .getChildCount() : index); forwardScheduling(); treetable.getTree().scrollPathToVisible( new TreePath(childNode.getPath())); nbTasks++; appli.refreshProjectInfos(); return childNode; } /** Return the selected node */ private DefaultMutableTreeTableNode getSelectedTaskNode() { TreePath currentSelection = treetable.getTree().getSelectionPath(); if (currentSelection == null || !(currentSelection.getLastPathComponent() instanceof TaskNode)) { return null; } DefaultMutableTreeTableNode dmtnselected = (DefaultMutableTreeTableNode) currentSelection .getLastPathComponent(); return dmtnselected; } public TaskNode[] getSelectedTaskNodes() { TreePath[] currentSelection = treetable.getTree().getSelectionPaths(); if (currentSelection == null || currentSelection.length == 0) return null; DefaultMutableTreeTableNode[] dmtnselected = new DefaultMutableTreeTableNode[currentSelection.length]; for (int i = 0; i < currentSelection.length; i++) dmtnselected[i] = (DefaultMutableTreeTableNode) currentSelection[i] .getLastPathComponent(); TaskNode[] res = getOnlyTaskNodes(dmtnselected); return res; } /** @return the list of the selected nodes. */ public DefaultMutableTreeTableNode[] getSelectedNodes() { TreePath[] currentSelection = treetable.getTree().getSelectionPaths(); if (currentSelection == null || currentSelection.length == 0) // no // elements // are // selectionned return null; DefaultMutableTreeTableNode[] dmtnselected = new DefaultMutableTreeTableNode[currentSelection.length]; for (int i = 0; i < currentSelection.length; i++) dmtnselected[i] = (DefaultMutableTreeTableNode) currentSelection[i] .getLastPathComponent(); DefaultMutableTreeTableNode[] res = dmtnselected; return res; } private TaskNode[] getOnlyTaskNodes(DefaultMutableTreeTableNode[] array) { List resAsList = new ArrayList(); for (int i = 0; i < array.length; i++) { DefaultMutableTreeTableNode next = array[i]; if (next instanceof TaskNode) resAsList.add(next); } return (TaskNode[]) resAsList.toArray(new TaskNode[0]); } /** Return the DefaultMutableTreeTableNode with the name name. */ public DefaultMutableTreeTableNode getNode(int id /* String name */) { DefaultMutableTreeTableNode res, base; base = (DefaultMutableTreeTableNode) treetable.getTreeTableModel().getRoot(); Enumeration e = base.preorderEnumeration(); while (e.hasMoreElements()) { res = ((DefaultMutableTreeTableNode) e.nextElement()); if (res instanceof TaskNode) if (((Task) (res.getUserObject())).getTaskID() == id) { return res; } } return null; } public static List convertNodesListToItemList(List nodesList) { List res = new ArrayList(nodesList.size()); Iterator itNodes = nodesList.iterator(); while (itNodes.hasNext()) { res.add(((DefaultMutableTreeTableNode) itNodes.next()).getUserObject()); } return res; } /** Returnan ArrayList with all tasks. */ public ArrayList getAllTasks() { ArrayList res = new ArrayList(); Enumeration enumeration = rootNode.preorderEnumeration(); while (enumeration.hasMoreElements()) { Object o = enumeration.nextElement(); if (o instanceof TaskNode) { res.add(o); } } return res; // return Collections.list(rootNode.preorderEnumeration()); } public List getAllVisibleNodes() { List res = new ArrayList(); Enumeration enumeration = rootNode.preorderEnumeration(); while (enumeration.hasMoreElements()) { DefaultMutableTreeTableNode o = (DefaultMutableTreeTableNode) enumeration .nextElement(); if (getTreeTable().getTree().isVisible(new TreePath(o.getPath()))) res.add(o); } return res; } /** Return all sub task for the tree node base */ public ArrayList getAllChildTask(DefaultMutableTreeTableNode base) { ArrayList res = new ArrayList(); if (base == null || !(base instanceof TaskNode)) return res; Enumeration e = base.children(); while (e.hasMoreElements()) { Object next = e.nextElement(); if (next instanceof TaskNode) res.add(next); } return res; } /** Remove the current node. * @param current */ void removeCurrentNode(DefaultMutableTreeTableNode currentNode) { DefaultMutableTreeTableNode parent = (DefaultMutableTreeTableNode) (currentNode .getParent()); getTaskManager().deleteTask((Task) currentNode.getUserObject()); if (parent != null) { ((GanttTreeTableModel) treeModel) .removeNodeFromParent(currentNode); forwardScheduling(); nbTasks--; appli.refreshProjectInfos(); return; } } /** Clear the JTree. */ public void clearTree() { // expand.clear(); rootNode.removeAllChildren(); initRootNode(); treeModel.setRoot(rootNode); nbTasks = 0; hiddenTask.clear(); } /** Select the row of the tree */ public void selectTreeRow(int row) { treetable.getTree().setSelectionRow(row); } public void selectTasks(List tasksList) { boolean multi = false; Iterator it = tasksList.iterator(); if (it.hasNext()) selectTask((Task) it.next(), false); while (it.hasNext()) selectTask((Task) it.next(), true); } public void selectTask(Task task, boolean multipleSelection) { DefaultMutableTreeTableNode taskNode = null; for (Enumeration nodes = rootNode.preorderEnumeration(); nodes .hasMoreElements();) { DefaultMutableTreeTableNode nextNode = (DefaultMutableTreeTableNode) nodes .nextElement(); if (!(nextNode instanceof TaskNode)) continue; if (nextNode.getUserObject().equals(task)) { taskNode = nextNode; break; } } if (taskNode != null) { TreePath taskPath = new TreePath(taskNode.getPath()); if (multipleSelection) if (treetable.getTree().getSelectionModel().isPathSelected( taskPath)) treetable.getTree().getSelectionModel() .removeSelectionPath(taskPath); else treetable.getTree().getSelectionModel().addSelectionPath( taskPath); else treetable.getTree().getSelectionModel().setSelectionPath( taskPath); } TreePath paths[] = treetable.getTree().getSelectionModel() .getSelectionPaths(); mySelectionManager.clear(); if (paths != null) for (int i = 0; i < paths.length; i++) { TaskNode tn = (TaskNode) paths[i].getLastPathComponent(); if (!tn.isRoot()) mySelectionManager.addTask( (Task) tn.getUserObject()); } } /** Returne the mother task. */ public DefaultMutableTreeTableNode getFatherNode(Task node) { if (node == null) { return null; } DefaultMutableTreeTableNode tmp = (DefaultMutableTreeTableNode) getNode(node .getTaskID()); if (tmp == null) { return null; } return (DefaultMutableTreeTableNode) tmp.getParent(); } /** Returne the mother task. */ public DefaultMutableTreeTableNode getFatherNode(DefaultMutableTreeTableNode node) { if (node == null) { return null; } return (DefaultMutableTreeTableNode) node.getParent(); } /** Return the JTree. */ public JTree getJTree() { return treetable.getTree(); } public JTable getTable() { return treetable.getTable(); } public GanttTreeTable getTreeTable() { return treetable; } class HiddenTask implements Comparable { private DefaultMutableTreeTableNode node = null; private DefaultMutableTreeTableNode parent = null; private int index = -1; public HiddenTask(DefaultMutableTreeTableNode node, DefaultMutableTreeTableNode parent, int index) { this.node = node; this.parent = parent; this.index = index; // this.node.setParent(this.parent); } public DefaultMutableTreeTableNode getNode() { return node; } public DefaultMutableTreeTableNode getParent() { return parent; } public int getIndex() { return index; } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object o) { if (o == null) return 0; if (o instanceof HiddenTask) { HiddenTask ht = (HiddenTask) o; return this.index - ht.index; } return 0; } } private List hiddenTask = new ArrayList(); public Set/*<Task>*/ getHiddenTasks() { HashSet result = new HashSet(); for (int i=0; i<hiddenTask.size(); i++) { HiddenTask next = (HiddenTask) hiddenTask.get(i); result.add(next.getNode().getUserObject()); } return result; } /** * Hides the selected tasks. */ public void hideSelectedNodes() { DefaultMutableTreeTableNode[] t = getSelectedNodes(); for (int i = 0; i < t.length; i++) { DefaultMutableTreeTableNode parent = (DefaultMutableTreeTableNode) t[i] .getParent(); hiddenTask.add(new HiddenTask(t[i], parent, parent.getIndex(t[i]))); } for (int i = 0; i < hiddenTask.size(); i++) { HiddenTask ht = (HiddenTask) hiddenTask.get(i); TreeNode parent = ht.node.getParent(); if (parent != null) ((GanttTreeTableModel) getTreeTable().getTreeTableModel()) .removeNodeFromParent(((HiddenTask) hiddenTask.get(i)) .getNode()); } } /** * Displays the hidden tasks. */ public void displayHiddenTasks() { for (int i = 0; i < hiddenTask.size(); i++) { HiddenTask ht = (HiddenTask) hiddenTask.get(i); DefaultMutableTreeTableNode node = ht.getNode(); DefaultMutableTreeTableNode parent = ht.getParent(); node.setParent(parent); } Collections.sort(hiddenTask); for (int i = 0; i < hiddenTask.size(); i++) { HiddenTask ht = (HiddenTask) hiddenTask.get(i); DefaultMutableTreeTableNode node = ht.getNode(); DefaultMutableTreeTableNode parent = ht.getParent(); int index = ht.getIndex(); node.setParent(null); ((GanttTreeTableModel) getTreeTable().getTreeTableModel()) .insertNodeInto(node, parent, index); if (node instanceof TaskNode) restoreExpand((TaskNode) node); } hiddenTask.clear(); } /** * Retores the expand state of the node and its children. * * @param node */ private void restoreExpand(TaskNode node) { Task task = (Task) node.getUserObject(); boolean expand = task.getExpand(); Enumeration enumeration = node.children(); while (enumeration.hasMoreElements()) restoreExpand((TaskNode) enumeration.nextElement()); if (expand) getTreeTable().getTree().expandPath(new TreePath(node.getPath())); else getTreeTable().getTree().collapsePath(new TreePath(node.getPath())); task.setExpand(expand); } /** Return the root node */ public DefaultMutableTreeTableNode getRoot() { return rootNode; } /** Function to put up the selected tasks */ public void upCurrentNodes() { List<Task> selection = getTaskSelectionManager().getSelectedTasks(); final TaskContainmentHierarchyFacade hierarchy = getTaskManager().getTaskHierarchy(); for (Task nextSelected : selection) { int position = hierarchy.getPositionInParent(nextSelected); if (position>0) { hierarchy.move(nextSelected, hierarchy.getContainer(nextSelected), position-1); } } } /** Function to put down the selected tasks */ public void downCurrentNodes() { List<Task> selection = getTaskSelectionManager().getSelectedTasks(); final TaskContainmentHierarchyFacade hierarchy = getTaskManager().getTaskHierarchy(); for (Task nextSelected : selection) { Task parent = hierarchy.getContainer(nextSelected); int childCount = hierarchy.getNestedTasks(parent).length; int position = hierarchy.getPositionInParent(nextSelected); if (position < childCount-1) { hierarchy.move(nextSelected, hierarchy.getContainer(nextSelected), position+1); } } } /** * Indent several nodes that are selected. Based on the IndentCurrentNode * method. */ private void indentCurrentNodes() { final DefaultMutableTreeTableNode[] cdmtn = getSelectedTaskNodes(); if (cdmtn == null) { myUIFacade.setStatusText(language.getText("msg21")); return; } final GanttTree2 gt2 = this; getUndoManager().undoableEdit("Indent", new Runnable() { public void run() { TreePath[] selectedPaths = new TreePath[cdmtn.length]; for (int i = 0; i < cdmtn.length; i++) { DefaultMutableTreeTableNode father = gt2.getFatherNode(cdmtn[i]); // Where is my nearest sibling in ascending order ? MutableTreeTableNode newFather = cdmtn[i].getPreviousSibling(); // If there is no more indentation possible we must stop if (newFather == null || !(newFather instanceof TaskNode)) { continue; } if (cdmtn[i] instanceof TaskNode && newFather instanceof TaskNode) { Task nextTask = (Task) cdmtn[i].getUserObject(); Task container = (Task) newFather.getUserObject(); getTaskManager().getTaskHierarchy().move(nextTask, container); } } area.repaint(); appli.repaint2(); } }); } /** * Function to dedent selected task this will change the parent child * relationship. This Code is based on the UP/DOWN Coder I found in here * barmeier */ /** Unindent the selected nodes. */ public void dedentCurrentNodes() { final DefaultMutableTreeTableNode[] cdmtn = getSelectedTaskNodes(); if (cdmtn == null) { myUIFacade.setStatusText(language.getText("msg21")); return; } final GanttTree2 gt2 = this; getUndoManager().undoableEdit("Dedent", new Runnable() { public void run() { TreePath[] selectedPaths = new TreePath[cdmtn.length]; // Information about previous node is needed to determine if current node had sibling that was moved. DefaultMutableTreeTableNode previousFather = new DefaultMutableTreeTableNode(); DefaultMutableTreeTableNode father = new DefaultMutableTreeTableNode(); for (int i = 0; i < cdmtn.length; i++) { // We use information about previous father to determine new index of the node in the tree. if (i > 0){ previousFather = father; } father = gt2.getFatherNode(cdmtn[i]); // Getting the fathers father !? The grandpa I think :) DefaultMutableTreeTableNode newFather = gt2.getFatherNode(father); // If no grandpa is available we must stop. if (newFather == null) { return; } int oldIndex = father.getIndex((TreeNode) cdmtn[i]); treeModel.removeNodeFromParent(cdmtn[i]); // If node and previous node were siblings add current node after its previous sibling int newIndex; if (i > 0 && father.equals(previousFather) ) { newIndex = newFather.getIndex((TreeNode) cdmtn[i-1]) + 1; } else { newIndex = newFather.getIndex((TreeNode) father) + 1; } ((GanttTreeTableModel) treeModel).insertNodeInto( (MutableTreeTableNode) cdmtn[i], (MutableTreeTableNode) newFather, newIndex); // Select tagain this node TreeNode[] treepath = cdmtn[i].getPath(); TreePath path = new TreePath(treepath); // tree.setSelectionPath(path); selectedPaths[i] = path; // refresh the father date // Task current = (Task)(cdmtn[i].getUserObject()); // refreshAllFather(current.toString()); expandRefresh(cdmtn[i]); forwardScheduling(); if (father.getChildCount() == 0) ((Task) father.getUserObject()).setProjectTask(false); } treetable.getTree().setSelectionPaths(selectedPaths); area.repaint(); // appli.setQuickSave (true); // appli.quickSave ("Dedent"); } }); } // update 21/03/2003 /** Refresh the expantion (recursive function) */ public void expandRefresh(DefaultMutableTreeTableNode moved) { if (moved instanceof TaskNode) { Task movedTask = (Task) moved.getUserObject(); // if (expand.contains(new Integer(movedTask.getTaskID()))) { if (movedTask.getExpand()) treetable.getTree().expandPath(new TreePath(moved.getPath())); Enumeration children = moved.children(); while (children.hasMoreElements()) { expandRefresh((DefaultMutableTreeTableNode) children.nextElement()); } } } /** * In elder version, this function refresh all the related tasks to the * taskToMove. In the new version, this function is same as * forwardScheduling(). It will refresh all the tasks. * * @param taskToMove */ public void refreshAllChild(String taskToMove) { forwardScheduling(); } // //////////////////////////////////////////////////////////////////////////////////////// /** * Listener when scrollbar move */ public class GanttAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { if (area != null) { int v = e.getValue(); area.setScrollBar(v); area.repaint(); } } } // //////////////////////////////////////////////////////////////////////////////////////// /** * Class for expansion and collapse of node */ public class GanttTreeExpansionListener implements TreeExpansionListener { /** Expansion */ public void treeExpanded(TreeExpansionEvent e) { if (area != null) { area.repaint(); } DefaultMutableTreeTableNode node = (DefaultMutableTreeTableNode) (e.getPath() .getLastPathComponent()); Task task = (Task) node.getUserObject(); /* * if(!expand.contains(new Integer(task.getTaskID()))) { * expand.add(new Integer(task.getTaskID())); * appli.setAskForSave(true); } */ task.setExpand(true); appli.setAskForSave(true); } /** Collapse */ public void treeCollapsed(TreeExpansionEvent e) { if (area != null) { area.repaint(); } DefaultMutableTreeTableNode node = (DefaultMutableTreeTableNode) (e.getPath() .getLastPathComponent()); Task task = (Task) node.getUserObject(); /* * int index = expand.indexOf(new Integer(task.getTaskID())); if * (index >= 0) { expand.remove(index); appli.setAskForSave(true); } */ task.setExpand(false); appli.setAskForSave(true); } } // //////////////////////////////////////////////////////////////////////////////////////// /** * Listener to generate modification on the model */ public class GanttTreeModelListener implements TreeModelListener { /** modify a node */ public void treeNodesChanged(TreeModelEvent e) { if (area != null) { area.repaint(); } } /** Insert a new node. */ public void treeNodesInserted(TreeModelEvent e) { DefaultMutableTreeTableNode node = (DefaultMutableTreeTableNode) (e .getTreePath().getLastPathComponent()); Task task = (Task) node.getUserObject(); /* * if (!expand.contains(new Integer(task.getTaskID()))) { * expand.add(new Integer(task.getTaskID())); } */ // task.setExpand(true); if (area != null) area.repaint(); } /** Delete a node. */ public void treeNodesRemoved(TreeModelEvent e) { if (area != null) { area.repaint(); } } /** Structur change. */ public void treeStructureChanged(TreeModelEvent e) { if (area != null) { area.repaint(); } } } private class GanttTreeDropListener implements DropTargetListener { private TreePath lastPath = null; private Rectangle2D cueLineRect = new Rectangle2D.Float(); private Rectangle2D ghostImageRect = new Rectangle2D.Float(); private Color cueLineColor; private Point lastEventPoint = new Point(); private Timer hoverTimer; public GanttTreeDropListener() { cueLineColor = new Color(SystemColor.controlShadow.getRed(), SystemColor.controlShadow.getGreen(), SystemColor.controlShadow.getBlue(), 64); // Set up a hover timer, so that a node will be automatically // expanded or collapsed // if the user lingers on it for more than a short time hoverTimer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { if (!treetable.getTree().isExpanded(lastPath)) { treetable.getTree().expandPath(lastPath); } } }); // Set timer to one-shot mode - it will be restartet when the // cursor is over a new node hoverTimer.setRepeats(false); } public void dragEnter(DropTargetDragEvent dtde) { if (ghostImage == null) { // In case if you drag a file from out and it's not an // acceptable, and it can crash if the image is null ghostImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE); } if (!isDragAcceptable(dtde)) dtde.rejectDrag(); else dtde.acceptDrag(dtde.getDropAction()); } public void dragOver(DropTargetDragEvent dtde) { if (!isDragAcceptable(dtde)) dtde.rejectDrag(); else dtde.acceptDrag(dtde.getDropAction()); // Even if the mouse is not moving, this method is still invoked // 10 times per second Point pt = dtde.getLocation(); if (pt.equals(lastEventPoint)) return; lastEventPoint = pt; Graphics2D g2 = (Graphics2D) treetable.getGraphics(); // If a drag image is not supported by the platform, then draw our // own drag image if (!DragSource.isDragImageSupported()) { // Rub out the last ghost image and cue line treetable.paintImmediately(ghostImageRect.getBounds()); // And remember where we are about to draw the new ghost image ghostImageRect.setRect(pt.x - offsetPoint.x, pt.y - offsetPoint.y, ghostImage.getWidth(), ghostImage .getHeight()); g2.drawImage(ghostImage, AffineTransform.getTranslateInstance( ghostImageRect.getX(), ghostImageRect.getY()), null); } else { // Just rub out the last cue line treetable.paintImmediately(cueLineRect.getBounds()); } TreePath path = treetable.getTree().getClosestPathForLocation(pt.x, pt.y); if (!(path == lastPath)) { lastPath = path; hoverTimer.restart(); } // In any case draw (over the ghost image if necessary) a cue line // indicating where a drop will occur Rectangle raPath = treetable.getTree().getPathBounds(path); if (raPath == null) raPath = new Rectangle(1, 1); cueLineRect.setRect(0, raPath.y + (int) raPath.getHeight(), getWidth(), 2); g2.setColor(cueLineColor); g2.fill(cueLineRect); // And include the cue line in the area to be rubbed out next time ghostImageRect = ghostImageRect.createUnion(cueLineRect); } public void dropActionChanged(DropTargetDragEvent dtde) { if (!isDragAcceptable(dtde)) dtde.rejectDrag(); else dtde.acceptDrag(dtde.getDropAction()); } public void drop(DropTargetDropEvent dtde) { if (!isDropAcceptable(dtde)) { dtde.rejectDrop(); return; } // Prevent hover timer from doing an unwanted expandPath or // collapsePath hoverTimer.stop(); dtde.acceptDrop(dtde.getDropAction()); Transferable transferable = dtde.getTransferable(); DataFlavor[] flavors = transferable.getTransferDataFlavors(); for (int i = 0; i < flavors.length; i++) { DataFlavor flavor = flavors[i]; if (flavor .isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType)) { try { Point pt = dtde.getLocation(); DefaultMutableTreeTableNode target = (DefaultMutableTreeTableNode) treetable .getTree() .getClosestPathForLocation(pt.x, pt.y) .getLastPathComponent(); TreePath pathSource = (TreePath) transferable .getTransferData(flavor); DefaultMutableTreeTableNode source = (DefaultMutableTreeTableNode) pathSource .getLastPathComponent(); TreePath pathNewChild = null; TreeNode sourceFather = source.getParent(); int index = sourceFather.getIndex(source); source.removeFromParent(); treeModel.removeNodeFromParent(source); ((GanttTreeTableModel) treeModel).insertNodeInto( source, target, 0); pathNewChild = new TreePath( ((DefaultMutableTreeTableNode) pathSource .getLastPathComponent()).getPath()); if (pathNewChild != null) { treetable.getTree().setSelectionPath(pathNewChild); // Mark // this // as // the // selected // path // in // the // tree } // refreshAllFather(source.getUserObject().toString()); expandRefresh(source); forwardScheduling(); area.repaint(); appli.setAskForSave(true); break; // No need to check remaining flavors } catch (UnsupportedFlavorException ufe) { System.out.println(ufe); dtde.dropComplete(false); return; } catch (IOException ioe) { System.out.println(ioe); dtde.dropComplete(false); return; } } } dtde.dropComplete(true); } public void dragExit(DropTargetEvent dte) { if (!DragSource.isDragImageSupported()) { repaint(ghostImageRect.getBounds()); } treetable.repaint(); } public boolean isDragAcceptable(DropTargetDragEvent e) { // Only accept COPY or MOVE gestures (ie LINK is not supported) if ((e.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { return false; } // Only accept this particular flavor if (!e .isDataFlavorSupported(GanttTransferableTreePath.TREEPATH_FLAVOR)) { return false; } // Do not accept dropping on the source node Point pt = e.getLocation(); TreePath path = treetable.getTree().getClosestPathForLocation(pt.x, pt.y); if (dragPath.isDescendant(path)) { return false; } if (path.equals(dragPath)) { return false; } // Check if the task is a milestone task Task task = (Task) (((DefaultMutableTreeTableNode) path .getLastPathComponent()).getUserObject()); if (task.isMilestone()) return false; return true; } public boolean isDropAcceptable(DropTargetDropEvent e) { // Only accept COPY or MOVE gestures (ie LINK is not supported) if ((e.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { return false; } // Only accept this particular flavor if (!e .isDataFlavorSupported(GanttTransferableTreePath.TREEPATH_FLAVOR)) { return false; } // prohibit dropping onto the drag source Point pt = e.getLocation(); TreePath path = treetable.getTree().getClosestPathForLocation(pt.x, pt.y); if (path.equals(dragPath)) { return false; } return true; } } private static class GanttTransferableTreePath implements Transferable { // The type of DnD object being dragged... public static final DataFlavor TREEPATH_FLAVOR = new DataFlavor( DataFlavor.javaJVMLocalObjectMimeType, "TreePath"); private TreePath _path; private DataFlavor[] _flavors = { TREEPATH_FLAVOR }; /** * Constructs a transferrable tree path object for the specified path. */ public GanttTransferableTreePath(TreePath path) { _path = path; } // Transferable interface methods... public DataFlavor[] getTransferDataFlavors() { return _flavors; } public boolean isDataFlavorSupported(DataFlavor flavor) { return java.util.Arrays.asList(_flavors).contains(flavor); } public synchronized Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { if (flavor.isMimeTypeEqual(TREEPATH_FLAVOR.getMimeType())) // DataFlavor.javaJVMLocalObjectMimeType)) return _path; else throw new UnsupportedFlavorException(flavor); } } /** * Render the cell of the tree */ public class GanttTreeCellRenderer extends DefaultTreeCellRenderer // JLabel-CL implements TreeCellRenderer { public GanttTreeCellRenderer() { setOpaque(true); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { Task task = (Task) ((DefaultMutableTreeTableNode) value).getUserObject();// getTask(value.toString()); if (task == null) { return this; } int type = 0; setFont(Fonts.GANTT_TREE_FONT); if (task.isMilestone()) { setIcon(new ImageIcon(getClass().getResource( "/icons/meeting.gif"))); type = 1; } else if (leaf) { if (task.getPriority() == GanttTask.LOW) { setIcon(new ImageIcon(getClass().getResource( "/icons/task1.gif"))); } else if (task.getPriority() == GanttTask.NORMAL) { setIcon(new ImageIcon(getClass().getResource( "/icons/task.gif"))); } else if (task.getPriority() == GanttTask.HIGHT) { setIcon(new ImageIcon(getClass().getResource( "/icons/task2.gif"))); } type = 2; } else { setIcon(new ImageIcon(getClass() .getResource("/icons/mtask.gif"))); setFont(Fonts.GANTT_TREE_FONT2); } setText(task.toString()); setToolTipText(getToolTip(task, type)); setBackground(selected ? new Color((float) 0.290, (float) 0.349, (float) 0.643) : row % 2 == 0 ? Color.white : new Color( (float) 0.933, (float) 0.933, (float) 0.933)); setForeground(selected ? Color.white : Color.black); return this; } public String getToolTip(Task task, int type) { String res = "<html><body bgcolor=#EAEAEA>"; res += "<b>" + task.toString() + "</b>" + "<br>" + task.getStart(); if (type != 1) { res += " - " + task.getEnd(); } if (type == 1) { res += "<br>" + language.getText("meetingPoint"); } res += "<br><b>Pri</b> " + (task.getPriority() == 0 ? language.getText("low") : task .getPriority() == 1 ? language.getText("normal") : language.getText("hight")); ResourceAssignment[] assignments = task.getAssignments(); if (assignments.length > 0) { res += "<br><b>Assign to </b><br>"; for (int j = 0; j < assignments.length; j++) { res += "&nbsp;&nbsp;" + assignments[j].getResource().getName() + "<br>"; } } if (task.getNotes() != null && !task.getNotes().equals("")) { String notes = task.getNotes(); res += "<br><b>Notes </b>: "; int maxLength = 150; if (notes.length() > maxLength) { notes = notes.substring(0, maxLength); int i = maxLength - 1; for (; i >= 0 && notes.charAt(i) != ' '; i--) ; notes = notes.substring(0, i); notes += " <b>( . . . )</b>"; } notes = notes.replaceAll("\n", "<br>"); res += "<font size=\"-2\">" + notes + "</font>"; } res += "</body></html>"; return res; } } // ----------Newly Added Code--------------//CL /** Temporary treeNode for copy and paste */ private DefaultMutableTreeTableNode cpNode; private ArrayList cpNodesArrayList; private ArrayList allNodes; private ArrayList cpDependencies; // private ArrayList copyID; // private ArrayList pasteID; private Map mapOriginalIDCopyID; /** Cut the current selected tree node */ public void cutSelectedNode() { final TreePath currentSelection = treetable.getTree() .getSelectionPath(); final DefaultMutableTreeTableNode[] cdmtn = getSelectedNodes(); if (currentSelection != null) { getUndoManager().undoableEdit("Cut", new Runnable() { public void run() { cpNodesArrayList = new ArrayList(); cpAllDependencies(cdmtn); GanttTask taskFather = null; DefaultMutableTreeTableNode father = null; DefaultMutableTreeTableNode current = null; for (int i = 0; i < cdmtn.length; i++) { current = getSelectedTaskNode(); if (current != null) { cpNodesArrayList .add((DefaultMutableTreeTableNode) cdmtn[i]); father = getFatherNode(current/* ttask */); where = father.getIndex(current); removeCurrentNode(current); current.setParent(father); taskFather = (GanttTask) father.getUserObject(); AdjustTaskBoundsAlgorithm alg = getTaskManager() .getAlgorithmCollection() .getAdjustTaskBoundsAlgorithm(); alg.run(taskFather); // taskFather.refreshDateAndAdvancement(this); father.setUserObject(taskFather); } } if (father.getChildCount() == 0) ((Task) father.getUserObject()).setProjectTask(false); if (taskFather != null) { selectTask(taskFather, false); } area.repaint(); } }); appli.repaint(); } } int where = -1; private Action myTaskPropertiesAction; /** Copy the current selected tree node */ public void copySelectedNode() { TreePath currentSelection = treetable.getTree().getSelectionPath(); cpNodesArrayList = new ArrayList(); if (currentSelection != null) { final DefaultMutableTreeTableNode[] cdmtn = getSelectedNodes(); cpAllDependencies(cdmtn); for (int i = 0; i < cdmtn.length; i++) { boolean isNodeDescendant = false; for (int j = 0; j < cpNodesArrayList.size(); j++) { if (((DefaultMutableTreeTableNode) cdmtn[i]) .isNodeDescendant((DefaultMutableTreeTableNode) cpNodesArrayList .get(j))) { isNodeDescendant = true; // if a selected node is a descendant of an other // selected one he doesn't have to be copied } } if (!isNodeDescendant) { cpNodesArrayList.add((DefaultMutableTreeTableNode) cdmtn[i]); } } } } /** Paste the node and its child node to current selected position */ public void pasteNode() { if (cpNodesArrayList != null) { final GanttTree2 gt2 = this; getUndoManager().undoableEdit("Paste", new Runnable() { public void run() { TaskNode current = (TaskNode) treetable.getTree() .getLastSelectedPathComponent(); List tasksList = new ArrayList(); if (current == null) { current = rootNode; } boolean isAProjectTaskChild = false; DefaultMutableTreeTableNode father = (DefaultMutableTreeTableNode) current .getParent(); // if the task as a projectTask parent while (father != null) { if (((Task) father.getUserObject()).isProjectTask()) { isAProjectTaskChild = true; } father = (DefaultMutableTreeTableNode) father.getParent(); } mapOriginalIDCopyID = new HashMap(); // copyID = new ArrayList (); // pasteID = new ArrayList (); TaskManagerImpl tmi = (TaskManagerImpl) getTaskManager(); int MaxID = tmi.getMaxID(); // for(int i=0; i < cpNodesArrayList.size(); i++) { for (int i = cpNodesArrayList.size() - 1; i >= 0; i--) { if (isAProjectTaskChild) ((Task) ((TaskNode) cpNodesArrayList.get(i)) .getUserObject()).setProjectTask(false); /* * this will add new custom columns to the newly * created task. */ TreeNode sel = getSelectedTaskNode(); TreeNode parent = null; if (sel != null) { parent = sel.getParent(); if (parent != null) where = parent.getIndex(sel); } tasksList.add((Task) insertClonedNode( current == rootNode ? current : (DefaultMutableTreeTableNode) current .getParent(), (DefaultMutableTreeTableNode) cpNodesArrayList .get(i), where + 1, true) .getUserObject()); nbTasks++; } if(cpDependencies!=null) { for (int i = 0; i < cpDependencies.size(); i++) { // for(int i=cpDependencies.size()-1; i >= 0; i--) { TaskDependency td = ((TaskDependency) cpDependencies .get(i)); Task dependee = td.getDependee(); Task dependant = td.getDependant(); TaskDependencyConstraint constraint = td .getConstraint(); for (int j = 0; j < allNodes.size(); j++) { for (int k = 0; k < allNodes.size(); k++) { if ((dependant .equals((Task) (((DefaultMutableTreeTableNode) allNodes .get(j)).getUserObject()))) && (dependee .equals((Task) (((DefaultMutableTreeTableNode) allNodes .get(k)) .getUserObject())))) { try { TaskDependency newDependency = getTaskManager() .getDependencyCollection() .createDependency( getTaskManager() .getTask( ((Integer) mapOriginalIDCopyID .get(new Integer( dependant .getTaskID()))) .intValue()), getTaskManager() .getTask( ((Integer) mapOriginalIDCopyID .get(new Integer( dependee .getTaskID()))) .intValue()), getTaskManager() .createConstraint( constraint .getID())); newDependency.setDifference(td .getDifference()); newDependency.setHardness(td.getHardness()); } catch (TaskDependencyException e) { myUIFacade.showErrorDialog(e); } } } } } } selectTasks(tasksList); } }); appli.refreshProjectInfos(); } } /** Insert the cloned node and its children */ private TaskNode insertClonedNode(DefaultMutableTreeTableNode parent, DefaultMutableTreeTableNode child, int location, boolean first) { if (parent == null) { return null; // it is the root node } if (first) { GanttTask _t = (GanttTask) (parent.getUserObject()); if (_t.isMilestone()) { _t.setMilestone(false); GanttTask _c = (GanttTask) (child.getUserObject()); _t.setLength(_c.getLength()); _t.setStart(_c.getStart()); } } GanttTask originalTask = (GanttTask) child.getUserObject(); GanttTask newTask = originalTask.Clone(); newTask.setName((first ? language.getText("copy2") + "_" : "") + newTask.toString()); TaskManagerImpl tmi = (TaskManagerImpl) getTaskManager(); newTask.setTaskID(tmi.getMaxID() + 1); mapOriginalIDCopyID.put(new Integer(originalTask.getTaskID()), new Integer(newTask.getTaskID())); // copyID.add (new Integer (originalTask.getTaskID())); // pasteID.add (new Integer (newTask.getTaskID())); ResourceAssignment[] assignment = newTask.getAssignments(); for (int i = 0; i < assignment.length; i++) { assignment[i].delete(); } getTaskManager().registerTask(newTask); DefaultMutableTreeTableNode cloneChildNode = new TaskNode(newTask); for (int i = 0; i < child.getChildCount(); i++) { insertClonedNode(cloneChildNode, (DefaultMutableTreeTableNode) child .getChildAt(i), i, false); } // if(child.getParent() != null) // if(!child.getParent().equals(parent)) // parent = (DefaultMutableTreeTableNode)parent.getParent(); // // if (parent == null) location = 0; if (parent.getChildCount() < location) location = parent.getChildCount(); ((GanttTreeTableModel) treeModel).insertNodeInto(cloneChildNode, parent, location); treetable.getTree().scrollPathToVisible( new TreePath(cloneChildNode.getPath())); // Remove the node from the expand list /* * int index = expand.indexOf(new * Integer(newTask.getTaskID())cloneChildNode.toString()); if (index >= * 0) expand.remove(index); */ newTask.setExpand(false); return (TaskNode) cloneChildNode; } public void forwardScheduling() { RecalculateTaskScheduleAlgorithm alg = getTaskManager() .getAlgorithmCollection().getRecalculateTaskScheduleAlgorithm(); try { alg.run(); } catch (TaskDependencyException e) { myUIFacade.showErrorDialog(e); } } // ///////////////////////////////////////////////////////////////// // --End CL 15-May-2003 private TaskManager getTaskManager() { return myTaskManager; } public void dragEnter(DragSourceDragEvent dsde) { } public void dragOver(DragSourceDragEvent dsde) { } public void dropActionChanged(DragSourceDragEvent dsde) { } public void dragDropEnd(DragSourceDropEvent dsde) { } public void dragExit(DragSourceEvent dse) { } public void dragGestureRecognized(DragGestureEvent dge) { Point ptDragOrigin = dge.getDragOrigin(); TreePath path = treetable.getTree().getPathForLocation(ptDragOrigin.x, ptDragOrigin.y); if (path == null) { return; } // Work out the offset of the drag point from the TreePath bounding // rectangle origin Rectangle raPath = treetable.getTree().getPathBounds(path); offsetPoint.setLocation(ptDragOrigin.x - raPath.x, ptDragOrigin.y - raPath.y); // Get the cell renderer (which is a JLabel) for the path being dragged // JLabel lbl = (JLabel) // treetable.getTree().getCellRenderer().getTreeCellRendererComponent // ( // treetable, // tree // path.getLastPathComponent(), // value // false, // isSelected (dont want a colored background) // treetable.getTree().isExpanded(path), // isExpanded // ((DefaultTreeTableModel)treetable.getModel()).isLeaf(path.getLastPathComponent()), // // isLeaf // 0, // row (not important for rendering) // false // hasFocus (dont want a focus rectangle) // ); JLabel lbl = null; lbl.setSize((int) raPath.getWidth(), (int) raPath.getHeight()); // <-- // The // layout // manager // would // normally // do // this // Get a buffered image of the selection for dragging a ghost image ghostImage = new BufferedImage((int) raPath.getWidth(), (int) raPath .getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); Graphics2D g2 = ghostImage.createGraphics(); // Ask the cell renderer to paint itself into the BufferedImage g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f)); // Make // the // image // ghostlike lbl.paint(g2); // Now paint a gradient UNDER the ghosted JLabel text (but not under the // icon if any) // Note: this will need tweaking if your icon is not positioned to the // left of the text Icon icon = lbl.getIcon(); int nStartOfText = (icon == null) ? 0 : icon.getIconWidth() + lbl.getIconTextGap(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 0.5f)); // Make the gradient ghostlike g2.setPaint(new GradientPaint(nStartOfText, 0, SystemColor.controlShadow, getWidth(), 0, new Color(255, 255, 255, 0))); g2.fillRect(nStartOfText, 0, getWidth(), ghostImage.getHeight()); g2.dispose(); treetable.getTree().setSelectionPath(path); // Select this path in the // tree // Wrap the path being transferred into a Transferable object Transferable transferable = new GanttTransferableTreePath(path); // Remember the path being dragged (because if it is being moved, we // will have to delete it later) dragPath = path; // We pass our drag image just in case it IS supported by the platform dge.startDrag(null, ghostImage, new Point(5, 5), transferable, this); } public void cpAllDependencies(DefaultMutableTreeTableNode[] cdmtn) { // to get all the dependencies who need to be paste. cpDependencies = new ArrayList(); allNodes = new ArrayList(); for (int i = 0; i < cdmtn.length; i++) { getAllNodes(cdmtn[i]); } TaskDependency[] dependencies = getTaskManager() .getDependencyCollection().getDependencies(); for (int i = 0; i < dependencies.length; i++) { Task dependant = dependencies[i].getDependant(); Task dependee = dependencies[i].getDependee(); for (int j = 0; j < allNodes.size(); j++) { for (int k = 0; k < allNodes.size(); k++) if (((Task) (((DefaultMutableTreeTableNode) allNodes.get(j)) .getUserObject())).equals(dependant) && ((Task) (((DefaultMutableTreeTableNode) allNodes .get(k)).getUserObject())).equals(dependee)) { cpDependencies.add(dependencies[i]); } } } } // public int cpId (int index) { // System.out.println("index = " + index + " -> " + // ((Integer)pasteID.get(index)).intValue()); // return ((Integer)pasteID.get(index)).intValue(); // } public void getAllNodes(DefaultMutableTreeTableNode dmt) { // get all the nodes the parent and all his descendance if (!allNodes.contains(dmt)) allNodes.add(dmt); for (int i = 0; i < dmt.getChildCount(); i++) { getAllNodes((DefaultMutableTreeTableNode) dmt.getChildAt(i)); } } public boolean hasAProjectTaskDescendant(DefaultMutableTreeTableNode node) { ArrayList child = getAllChildTask(node); for (int i = 0; i < child.size(); i++) { if (((Task) ((DefaultMutableTreeTableNode) child.get(i)).getUserObject()) .isProjectTask()) return true; if (hasAProjectTaskDescendant((DefaultMutableTreeTableNode) child.get(i))) return true; } return false; } public ArrayList getProjectTasks() { ArrayList projectTasks = new ArrayList(); // for (int i = 0 ; i < getAllTasks().size() ; i++) { // TaskNode node = (TaskNode)getAllTasks().get(i); // if (((Task)node.getUserObject()).isProjectTask()) // projectTasks.add (node); // } getProjectTasks(this.rootNode, projectTasks); return projectTasks; } public void getProjectTasks(DefaultMutableTreeTableNode node, ArrayList list) { ArrayList child = getAllChildTask(node); for (int i = 0; i < child.size(); i++) { DefaultMutableTreeTableNode taskNode = (DefaultMutableTreeTableNode) child .get(i); if (((Task) taskNode.getUserObject()).isProjectTask()) list.add(taskNode); else getProjectTasks(taskNode, list); } } public GanttTreeTableModel getModel() { return treeModel; } private GPUndoManager getUndoManager() { return myUIFacade.getUndoManager(); } /////////////////////////////////////////////////////////////////////////// // ProjectEventListener public void projectModified() { // TODO Auto-generated method stub } public void projectSaved() { // TODO Auto-generated method stub } public void projectClosed() { clearTree(); //getTreeTable().reloadColumns(); } public void projectWillBeOpened() { // TODO Auto-generated method stub } //////////////////////////////////////////////////////////////////////// //TaskTreeUIFacade public Component getTreeComponent() { return this; } public Action getExpandAllAction() { return myExpandAllAction; } public Action getCollapseAllAction() { return myCollapseAllAction; } public Action getIndentAction() { return myIndentAction; } public Action getUnindentAction() { return myDedentAction; } public Action getMoveDownAction() { return myMoveUpAction; } public Action getMoveUpAction() { return myMoveDownAction; } public void setLinkTasksAction(Action action) { myLinkTasksAction = action; } private Action getLinkTasksAction() { return myLinkTasksAction; } // public void setUnlinkTasksAction(Action action) { myUnlinkTasksAction = action; } private Action getUnlinkTasksAction() { return myUnlinkTasksAction; } void setTaskPropertiesAction(Action action) { myTaskPropertiesAction = action; treetable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.ALT_DOWN_MASK), action.getValue(Action.NAME)); treetable.getActionMap().put(action.getValue(Action.NAME), action); } private Action getTaskPropertiesAction() { return myTaskPropertiesAction; } public TableHeaderUIFacade getVisibleFields() { return treetable.getVisibleFields(); } public TaskSelectionManager getTaskSelectionManager() { return mySelectionManager; } }

The table below shows all metrics for GanttTree2.java.

MetricValueDescription