📄 task.java
字号:
/** * Copyright 2004 Carlos Silva A. * * 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 jgantt.model;import java.io.IOException;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.Stack;import java.util.Vector;import jgantt.Messages;import jgantt.cmds.Command;import jgantt.cmds.SetCommand;import jgantt.cmds.TaskCommand;/** * Tarea de una carta gantt, contiene los datos necesarios * para cada tarea. Se enlaza con sus tareas hijas a traves * de {@link #getChilds()} y {@link #addChild()}. * * Los plugins pueden acceder y modificar el arbol de tareas * directamente a traves de este objeto y desde las funciones * del objeto {@link Project}. * * * @version $Header: /cvs/java/App_JGantt/source/jgantt/model/Task.java,v 1.51 2005/08/19 15:50:42 csilva Exp $ * @author Carlos Silva */public class Task { // Instancia /** * id */ protected int id = 0; /** * Nombre */ protected String name = Messages.getString("task.defaultName"); //$NON-NLS-1$ /** * Largo de la tarea en minutos habiles. */ protected int length = 0; /** * Fecha antes de la cual la tarea no debe comenzar. * Esta restriccion solo aplica a tareas no contenedoras. */ protected Date notBeforeDate = null; /** * Comentarios */ protected String comments = Messages.getString("task.defaultComment"); //$NON-NLS-1$ /** * Porcentaje completado de la tarea */ protected int completed = 0; /** * Prioridad de la tarea (numero entero) */ protected int priority = 0; /** * indicador si ta tarea se marca como hito. */ protected boolean hito = false; /** * notas */ protected String notes = ""; /** * Largo minimo de la tarea en minutos habiles. */ int minLength = 0; /** * Largo maximo de la tarea en minutos habiles. */ int maxLength = 0; /** * Datos para ser utilizados por la aplicacion de despliege/edicion. * los datos son no transientes. sin embargo, al serializar, solo * se graban objetos de clases String, Number y Date. */ protected Hashtable attributes = new Hashtable(); // Asociaciones con otros objetos /** * Lista de tareas que componen un resumen. * Esta tarea es un resumen si childTasks.size()>0 */ protected Vector childTasks = new Vector(); /** * Tarea padre (o resumen) de esta tarea. */ protected Task parentTask = null; /** * lista de dependencias que nacen de esta tarea * Esta variable es llenada por la clase {@link Constraint} */ protected Vector childConstraints = new Vector(); /** * lista de dependencias que afectan a esta tarea. * Esta variable es llenada por la clase {@link Constraint} */ protected Vector constraints = new Vector(); /** * Referencia al proyecto al cual pertenecen las tareas */ protected Project project = null; /** * Recursos asociados a la ejecucion de la tarea * Contiene elementos de tipo {@link Asignation} */ protected Vector resources = new Vector(); // Transientes /** * Fecha de inicio calculada segun el {@link DateOrganizer}. * Solo es valida si dirty==false */ transient Date startDate = null; /** * Indicacion de si la tarea requiere recalcularse */ transient boolean dirty = true; /** * fecha de termino de la tarea * solo es valida si dirty==false */ transient Date finishDate = null; /** * indicacion de si la tarea se esta borrando * para no enviar multiples notificaciones al borrar un arbol. * @param p */ transient boolean removed = false; /** * Contructor de una tarea. * Inicializa el proyecto como una referencia interna. */ public Task(Project p) { project = p; } /** * Crea una tarea a partir de un proyecto y un nombre * @param p * @param name */ public Task(Project p, String name) { project = p; setName(name); } /** * Crea una tarea a partir de un proyecto, un nombre y una duracion en dias. * @param p * @param name * @param length */ public Task(Project p, String name, int length) { project = p; this.name = name; try { // En teoria se deberia llamar a setLength, pero esta genera un Comando (undo/redo) // que no deberia funcionar aparte de crear una tarea this.length = length; setDirty(); } catch (Exception e) { // nunca ocurrira, esta tarea nueva no tiene hijos. } } /** * Datos para ser utilizados por la aplicacion de despliege/edicion * En la lista de atributos se puede almacenar cualquier valor (no null) */ public Object getAttribute(String name) { return attributes.get(name); } /** * Datos para ser utilizados por la aplicacion de despliege/edicion. * En la lista de atributos se puede almacenar cualquier valor. */ public void setAttribute(String name, Object data) { attributes.put(name, data); } /** * Datos para ser utilizados por la aplicacion de despliege/edicion */ public void removeAttribute(String name) { attributes.remove(name); } // Metodos protegidos /** * Asigna el Id de la tarea. * Este Id es interno, parte de 0 para la tarea principal (invisible) * del proyecto y es asignada por el proyecto. */ protected void setId(int i) { id = i; } /** * retorna el Id de la tarea. La tarea * principal del proyecto (invisible) tiene Id ==0. */ public int getId() { return id; } /** * indica si la tarea es un resumen de otras tareas. */ public boolean isResume() { return childTasks.size() > 0; } /** * Remueve la tarea del proyecto. * para remover la tarea se remueven sus constraints de la lista de objetos. * ademas se remueve de la lista de hijos de la tarea resumen * y llama a la funcion removeTask() del proyecto.</P> * </P>Esta funcion puede ser llamada por los elementos externos. * notifica del borrado llamando a la funcion {@link Project#removeTask}.</P> * <P>Esta funcion solo notifica la eliminacion del primer hijo. No envia * notificaciones para las tareas hijas que dependen.</P> */ public void remove() { removed = true; for (Enumeration e = childConstraints.elements(); e.hasMoreElements(); ) { Constraint c = (Constraint) e.nextElement(); c.getSlaveTask().setDirty(); c.remove(); } for (Enumeration e = constraints.elements(); e.hasMoreElements();) { Constraint c = (Constraint) e.nextElement(); c.remove(); } // borrar los hijos. for (Enumeration e = childTasks.elements(); e.hasMoreElements();) { Task t = (Task) e.nextElement(); t.remove(); } parentTask.childTasks.remove(this); parentTask.setDirty(); // Solo notifica si esta es la tarea principal borrada. if (!parentTask.removed) { project.removeTask(this); TaskCommand cmd = new TaskCommand(this) { public void execute() { task.remove(); } public void undo() { parentTask.addChild(task); } }; project.registerCommand(cmd); } } /** * marca esta tarea como una tarea resumen al agregar una * tarea hija. * Esta funcion asigna el Id de la tarea hija dejandola como * el ultimo hijo. */ public void addChild(Task t) { notBeforeDate = null; t.parentTask = this; int idx = id; int childs = childTasks.size(); childTasks.addElement(t); TaskCommand cmd = new TaskCommand(t) { public void execute() { addChild(task); } public void undo() { task.remove(); } }; project.registerCommand(cmd); project.childInserted(t); setDirty(); } /** * Agrega como hijas de esta tarea el contenido de otro proyecto. * @param p proyecto a cargar */ public void addChild(Project p ){ notBeforeDate = null; int idx = id; int childs = childTasks.size(); for (int i=0;i<p.taskList.size(); i++){ ((Task)p.taskList.get(i)).project=project; } for (int i=0;i<p.mainTask.childTasks.size(); i++){ ((Task)p.mainTask.childTasks.get(i)).parentTask=this; } childTasks.addAll(p.mainTask.childTasks); //TODO: Soporte undo/redo para esta operacion project.childInserted(this); setDirty(); } /** * Agrega una tarea como hija pero antes que otra. * Esta funcion asigna el Id de la tarea hija dejandola como * el ultimo hijo. */ private void addChildBefore(Task newTask, Task before) { notBeforeDate = null; newTask.parentTask = this; newTask.setId(before.getId()); int childs = childTasks.size(); if (before != null) { int i = childTasks.indexOf(before); if (i >= 0) childTasks.add(i, newTask); else childTasks.add(newTask); } else childTasks.add(newTask); TaskCommand cmd = new TaskCommand(newTask, before) { public void execute() { addChildBefore(task, refTask); } public void undo() { task.remove(); } }; project.registerCommand(cmd); project.childInserted(newTask); } /** * Agrega una tarea como hermana anterior * @param newTask tarea nueva */ public void addBefore(Task newTask) { getParentTask().addChildBefore(newTask, this); } /** * Agrega una tarea como hija pero antes que otra. * Esta funcion asigna el Id de la tarea hija dejandola como * el ultimo hijo. */ private void addChildAfter(Task newTask, Task after) { notBeforeDate = null; newTask.parentTask = this; newTask.setId(after.getId()); int childs = childTasks.size(); if (after != null) { int i = childTasks.indexOf(after); if (i >= 0) childTasks.add(i + 1, newTask); else childTasks.add(newTask); } else childTasks.add(newTask); TaskCommand cmd = new TaskCommand(newTask, after) { public void execute() { addChildAfter(task, refTask); } public void undo() { task.remove(); } }; project.registerCommand(cmd); project.childInserted(newTask); } /** * Agrega una tarea como hermana posterior * @param newTask tarea nueva */ public void addAfter(Task newTask) { getParentTask().addChildAfter(newTask, this); } /** * Retorna el nombre de la tarea(titulo) */ public String getName() { return name; } /** * Transforma esta tarea en hija de su hermana anterior * No deben haber contraints entre hermana y hermana (eliminar) * */ public void asChild() { int i = parentTask.childTasks.indexOf(this); if (i == 0) return; parentTask.childTasks.remove(i); Task t = (Task) parentTask.childTasks.elementAt(i - 1); //System.out.println("childing " + getId() + " -> " + t.getId()); for (int j = 0; j < t.childConstraints.size(); j++) { //System.out.println(j); Constraint c = (Constraint) t.childConstraints.get(j); //System.out.println("Constraint "+ c.getMasterTask().getId()+ " -> "+ c.getSlaveTask().getId()); if (hasChild(c.getSlaveTask())) c.remove(); } t.addChild(this); project.taskMoved(this); } /** * Retorna verdadero si esta tarea depende de otra. * <p>Una tarea <code>A</code> depende de otra <code>B</code> si:</p> * <ol> * <li>A==B * <li>A es descendiente de B * <li>algun ancestro de B tiene un Constraint hacia algun ancestro de A * <li>algun descendiente de B tiene un constraint hacia algun descendiente de A * </ol> * <p>Otra forma de verlo es: Una tarea <code>A</code> depende de otra <code>B</code> si:</p> * <ol> * <li>El conjunto de descendientes y restrictos de descendientes y restrictos incluye a A. * </ol> * * @param master Task que puede ser una tarea que contiene una dependencia. * @return verdadero segun las condiciones enumeradas. */ public void checkConstrained(Task master) throws GanttException { Task t = null; // 1.- A==B if (master == this) throw new GanttException(Messages.getString("task.error.selfConstraint")); //$NON-NLS-1$ // 2.- A es descendiente de B if (isChildOf(master)) throw new GanttException(Messages.getString("task.error.parentConstraint")); //$NON-NLS-1$ // 3.- Conjunto de restrictos. Vector set = new Vector(); Stack porRevisar = new Stack(); porRevisar.push(master); t = master; while (t != null) { set.add(t); // add constrained tasks for (Iterator it = t.childConstraints.iterator(); it.hasNext();) { Constraint c = (Constraint) it.next(); porRevisar.push(c.getSlaveTask()); } t = t.parentTask; } while (!porRevisar.empty()) { t = (Task) porRevisar.pop(); set.add(t); // agregar hijos for (Iterator it = t.childTasks.iterator(); it.hasNext();) porRevisar.push(it.next()); // agregar tasks constrained for (Iterator it = t.childConstraints.iterator(); it.hasNext();) { Constraint c = (Constraint) it.next(); porRevisar.push(c.getSlaveTask()); } } if (set.contains(this)) throw new GanttException(Messages.getString("task.error.dependantConstraint")+" Task '"+this.name+"' depends on '"+master.name+"'."); } /** * Convierte una tarea en hermana de su padre. */ public void deChild() { if (getChildLevel() == 1) return; Task parent = parentTask; parentTask.childTasks.remove(this); parentTask.parentTask.addChild(this); parent.setDirty(); setDirty(); project.taskMoved(this); } /** * Convierte mueve una herma a su tarea anterior */ public void goUp() { int i = parentTask.childTasks.indexOf(this); if (i == 0) return; parentTask.childTasks.add(i - 1, this); parentTask.childTasks.remove(i + 1); setDirty(); project.taskMoved(this); } /** * Convierte mueve una herma a su tarea anterior */ public void goDown() { int i = parentTask.childTasks.indexOf(this); if (i + 1 >= parentTask.childTasks.size()) return; parentTask.childTasks.add(i + 2, this); parentTask.childTasks.remove(i); parentTask.setDirty(); project.taskMoved(this); } /** * Determina si una tarea es hija de esta. * * @param child * @return true si this tiene como descendiente child */ public boolean hasChild(Task child) { if (this == child) return true; for (Iterator it = childTasks.iterator(); it.hasNext();) { Task c = (Task) it.next(); if (c.hasChild(child)) return true; } return false; } /** * getChildLevel retorna el nivel de profundidad de la tarea * comienza desde 1. * @return profundidad desde 1. */ public int getChildLevel() { if (parentTask == null) return 0; return parentTask.getChildLevel() + 1; } /** * Retorna el nombre de la tarea(titulo) con indentacion dependiendo * de la profundidad en descendientes de la tarea principal del proyecto. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -