[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# TaskData

One task in [`ProjectData.tasks`](<https://docs.dhtmlx.com/planning-engine/java/api/data/project-data.md>) or in the `add` list of [`SchedulingChanges.tasks`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/scheduling-changes.md>). Create it with `new TaskData(id)` and set the other fields with the fluent `withX` setters. To change a task that a project already holds, send a [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/task-update.md>) instead.

## Declaration

```java
public class TaskData extends ValueRecord implements DeepCloneable<TaskData>
```

Every field is public and mutable, and has a `withX(value)` setter that assigns it and returns `this`: `new TaskData(Id.str("a")).withStartDate(start).withDuration(2.0)`. Optional fields use reference types (`Id`, `Moment`, `Double`, enums), and `null` means absent.

A leaf task needs two of `startDate`, `endDate` and `duration`. A summary takes both dates or neither, and a milestone takes one date. [Project data](<https://docs.dhtmlx.com/planning-engine/java/scheduling/project-data.md#tasks>) explains these date rules, and [Validation rules](<https://docs.dhtmlx.com/planning-engine/java/scheduling/project-data.md#validation-rules>) lists the input that strict validation rejects.

## Constructors

### TaskData(Id)

```java
public TaskData(Id id)
```

Creates an auto-scheduled task of type `TASK` with priority 500, no dates and every other field at its default.

| Name | Type | Description |
|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | Task id, e.g. `Id.num(1)` or `Id.str("design")`. |

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | constructor argument | Task id. Unique among the project's tasks. |
| `parent` | `Id` | `null` | Id of the parent summary. `null`, `Id.str("")` and a value equal to [`SchedulingConfig.rootId`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#rootid>) all mean a root task. |
| `taskType` | [`TaskType`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#tasktype>) | `TaskType.TASK` | Leaf task, summary or milestone. Wire name `type`. |
| `startDate` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | `null` | Start date. |
| `endDate` | `Moment` | `null` | End date. |
| `duration` | `Double` | `null` | Working time in `durationUnit`. |
| `durationUnit` | [`TimeUnit`](<https://docs.dhtmlx.com/planning-engine/java/api/data/time-unit.md>) | `null` | Unit of `duration`, `levelingDelay` and `pauses`. `null` uses [`SchedulingConfig.durationUnit`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#durationunit>). |
| `constraintType` | [`ConstraintType`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#constrainttype>) | `null` | Scheduling constraint. `null` means no constraint. Constraints act only when [`SchedulingConfig.applyConstraints`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#applyconstraints>) is `true`. |
| `constraintDate` | `Moment` | `null` | Date of a dated constraint. Required when `constraintType` is a dated constraint. |
| `autoScheduling` | `boolean` | `true` | `false` makes the task fixed: the planner never moves it. |
| `unscheduled` | `boolean` | `false` | `true` keeps the task in the data but out of the plan. An unscheduled task needs no dates and isn't reported. |
| `progress` | `double` | `0.0` | Completed fraction, from 0 to 1. With [`SchedulingConfig.useProgress`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#useprogress>) on, `1` marks the task as completed. |
| `priority` | `int` | `500` | Leveling priority, 0 to 1000. `1000` means the task is never leveled. A value outside the range fails validation at `tasks[i].priority`. |
| `levelingDelay` | `double` | `0.0` | Delay added by leveling, as elapsed (wall-clock) time in the task's duration unit. Rounded to whole minutes on use. |
| `pauses` | `Vec<`[`Pause`](<https://docs.dhtmlx.com/planning-engine/java/api/data/pause.md>)`>` | empty | Leveling splits in the task's work, sorted by `at` and non-overlapping. Empty means uninterrupted work. Ignored on summaries, milestones and unscheduled tasks. |
| `calendarId` | `Id` | `null` | The task's own calendar. `null` uses the global calendar, or the parent's calendar in [`CalendarMode.TASK_INHERITED`](<https://docs.dhtmlx.com/planning-engine/java/api/data/calendar-mode.md>). |

`levelingDelay` and `pauses` normally come from [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>). Setting `pauses` to an empty list and `levelingDelay` to `0` clears a task's leveling. See [Leveling resources](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/leveling-resources.md>).

`pauses` has two setters. `withPauses(Vec<Pause>)` stores the list it's given. `withPauses(Collection<? extends Pause>)` copies the elements into a new [`Vec`](<https://docs.dhtmlx.com/planning-engine/java/api/support/vec.md>), so `List.of(...)` works; `null` sets the field to `null`.

## Methods

### deepClone

```java
public TaskData deepClone()
```

Returns a copy that shares no list or nested record with this task, including `pauses`.

**Returns**: a new `TaskData` with the same values.

### copy

```java
public TaskData copy()
```

Returns a shallow copy. The copy shares the `pauses` list with this task.

**Returns**: a new `TaskData` with the same field values.

### equals / hashCode / toString

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). `equals` and `hashCode` compare all public fields by value. `toString` returns a field dump, e.g. `TaskData{id=a, parent=null, taskType=TASK, …}`.

## TaskType

The kind of a task, set in `TaskData.taskType`.

```java
public enum TaskType { TASK, SUMMARY, MILESTONE }
```

| Value | Description |
|---|---|
| `TASK` | A leaf task. The default. |
| `SUMMARY` | A summary task whose span covers its children. Wire value `"summary"`; `"project"` also reads as `SUMMARY`. |
| `MILESTONE` | A zero-duration milestone. |

## ConstraintType

A task's scheduling constraint, set in `TaskData.constraintType`. All values except `ASAP` and `ALAP` are dated and need `constraintDate`.

```java
public enum ConstraintType { ASAP, ALAP, SNET, SNLT, FNET, FNLT, MSO, MFO }
```

| Value | Description |
|---|---|
| `ASAP` | As soon as possible. |
| `ALAP` | As late as possible. |
| `SNET` | Start no earlier than `constraintDate`. |
| `SNLT` | Start no later than `constraintDate`. |
| `FNET` | Finish no earlier than `constraintDate`. |
| `FNLT` | Finish no later than `constraintDate`. |
| `MSO` | Must start on `constraintDate`. |
| `MFO` | Must finish on `constraintDate`. |

Wire spellings are the lowercase names (`"snet"`, `"mfo"`). See [Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/java/scheduling/links-constraints-summaries.md#constraints>) for how the planner applies each constraint.

## Example

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class TaskDataExample {
    public static void main(String[] args) throws Exception {
        Moment monday = Moment.fromYmdHm(2026, 3, 2, 8, 0);

        ProjectData data = new ProjectData()
                .withConfig(new SchedulingConfig().withApplyConstraints(true))
                .withTasks(List.of(
                        new TaskData(Id.str("phase")).withTaskType(TaskType.SUMMARY),
                        new TaskData(Id.str("design"))
                                .withParent(Id.str("phase"))
                                .withStartDate(monday)
                                .withDuration(3.0),
                        new TaskData(Id.str("review"))
                                .withParent(Id.str("phase"))
                                .withStartDate(monday)
                                .withDuration(4.0)
                                .withDurationUnit(TimeUnit.HOUR)
                                .withConstraintType(ConstraintType.SNET)
                                .withConstraintDate(Moment.fromYmdHm(2026, 3, 9, 8, 0)),
                        new TaskData(Id.str("release"))
                                .withTaskType(TaskType.MILESTONE)
                                .withStartDate(monday)
                                .withAutoScheduling(false)));

        ScheduleResult result = Engine.schedule(data, new SolveOptions());
        for (Mutation update : result.updates) {
            System.out.println(update.id + ": " + update.startDate + " .. " + update.endDate);
        }
    }
}
```

## Related

- [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/project-data.md>) - where tasks are listed
- [`LinkData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/link-data.md>) - dependencies between tasks
- [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/task-update.md>) - editing a task in a live project
- [Tasks](<https://docs.dhtmlx.com/planning-engine/java/scheduling/project-data.md#tasks>) - date rules for tasks, summaries and milestones
- [Constraints](<https://docs.dhtmlx.com/planning-engine/java/scheduling/links-constraints-summaries.md#constraints>) - constraint types and how they bind
