BeeSoft®
Since 1992
 

Content

 Welcome
 Products
       Abeona
       Gaia
       Hephaistos
       JavaGantt
             Features
             News
             Documentation
                   Programming domain objects
                   About JavaGantt model
                   Undo / Redo support
                   Localization support
                   Building a treetable
                   Painting a chart
                   Working with the time scale
                   JavaGantt actions
             License
             Download
             Purchase
 Services
       Promote your software
 Contact Us
 Links
      
  JavaGanttI®
© 2012 BeeSoft ®
 

Programming domain objects for JavaGantt

Every application works with data objects. These objects are important for the problem area that an application solves and they are called domain objects. For application, which uses gantt chart, are domain objects - tasks.

So the domain object class for our example is Task. What do you have to do to let it work with JavaGantt?

JavaGantt does not prescribe what objects you can use. But it requires to implement interface eu.beesoft.gantt.TimelineObject. It is a simple interface with methods like getStartDate(), isMilestone(), and so on. You can implement them very easy.

It is a bit complicated, if you use a summary tasks. This is the task which has subtasks - it is like container in the task hierarchy (non leaf node). Then you have to arrange synchronization of date changes in subtasks and in summary task.

In our demo you can see this code for class Task:


public class Task extends AbstractBean implements TimelineObject {

	private String taskId;
	private String name;
	private String description;
	private Date startDate;
	private Date endDate;
	private long effort;
	private boolean milestone;
	private Task supertask;
	private List<Task> subtask;
	private List<Dependency> dependencies;
	private Resource assignee;



	public Task () {
		// empty
	}



	/** Standard getter for property 'name' */
	public String getName () {
		return name;
	}


	/** Standard setter for property 'name' */
	public void setName (String name) {
		String old = this.name;
		this.name = name;
		firePropertyChange ("name", old, name);
	}



	/**
         * Getter for property 'startDate'. Implementation of TimelineObject interface.
         * If this task is summary, calculates start date from subtasks.
         */
	public Date getStartDate () {
		if ((startDate == null) && isSummary ()) {
			updateStart ();
		}
		return startDate;
	}



	/**
         * Setter for property 'startDate'. Implementation of TimelineObject interface.
         * If this task has a supertask, notifies it about the change - invokes method updateStart().
         */
	public void setStartDate (Date start) {
		if (Objects.equals (this.startDate, start)) {
			return;
		}
		Date old = this.startDate;
		this.startDate = start;
		if (supertask != null) {
			supertask.updateStart ();
		}
		firePropertyChange ("startDate", old, start);
	}



	/**
         * For summary task calculates its start date from subtasks.
         */
	private void updateStart () {
		if (isSummary ()) {
			Date thisStart = null;
			List<Task> tasks = getSubtask ();
			for (Task task : tasks) {
				Date taskStart = task.getStartDate ();
				if (taskStart != null) {
					if ((thisStart == null) || thisStart.after (taskStart)) {
						thisStart = taskStart;
					}
				}
			}
			if (thisStart != null) {
				setStartDate (thisStart);
			}
		}
	}


	......

}

Remaining methods are implemented in the similar way. Of course, your implementation can be quite different. TimelineObject interface prescribes some methods, not their body.

Maybe you want to know, what is AbstractBean, which is used as parent class of our Task. It is class from our Gaia library (it is shipped with JavaGantt) and it serves as support for property change listeners and their notification.