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


# Subtree

The scope of a scoped run. Set it as `subtree` in [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md>) or [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/preview-options.md>) to reschedule one task's branch instead of the whole project. Create it with `new Subtree(task)` and chain `withInclusive(false)` to follow outgoing links only.

## Declaration

```java
package org.dhtmlx.plen;

public class Subtree extends ValueRecord implements DeepCloneable<Subtree>
```

## Constructors

### Subtree(Id)

```java
public Subtree(Id task)
```

Creates a scope rooted at `task` with `inclusive = true`. `Subtree` has no parameterless constructor.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | Root task ID, for example `Id.str("a")` or `Id.num(1)` |

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | set by the constructor | Root task of the scope. The scope covers this task, its ancestors and descendants, and every task reached from them through outgoing links, transitively. Each task reached this way brings its own ancestors and descendants. |
| `inclusive` | `boolean` | `true` | `true` also follows incoming links, so predecessors and their branches join the scope. `false` follows outgoing links only. The root is in scope either way. |

Both fields are public and mutable.

## Methods

### withTask

```java
public Subtree withTask(Id value)
```

Sets `task` and returns this instance for chaining.

### withInclusive

```java
public Subtree withInclusive(boolean value)
```

Sets `inclusive` and returns this instance for chaining.

### deepClone

```java
public Subtree deepClone()
```

Returns a new `Subtree` with the same `task` and `inclusive`. Implements [`DeepCloneable`](<https://docs.dhtmlx.com/planning-engine/java/api/data/deep-cloneable.md>).

### copy

```java
public Subtree copy()
```

Returns a shallow copy. `Id` is immutable, so the copy is independent of the original.

### equals, hashCode, toString

```java
public boolean equals(Object other)
public int hashCode()
public String toString()
```

Value semantics, inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). Two scopes are equal when `task` and `inclusive` are equal, and `hashCode` follows the same fields. `toString` returns a readable form for logging, such as `Subtree{task=a, inclusive=true}`.

## Errors

If `task` is unknown or unscheduled, the call that receives the options throws [`InputException`](<https://docs.dhtmlx.com/planning-engine/java/api/errors/input-exception.md>) (unchecked) with `kind = InputErrorKind.VALIDATION` and `path = "subtree.task"`.

## Example

Commit an edit to task `a`, then reschedule only `a` and the tasks linked downstream of it.

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

public class SubtreeExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 8, 10, 8, 0);
    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("a")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("b")).withStartDate(monday).withDuration(1.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1")).withSource(Id.str("a")).withTarget(Id.str("b"))));

    Project project = new Project();
    project.solve(data, new SolveOptions());

    SchedulingChanges changes = new SchedulingChanges();
    changes.tasks.update.add(new TaskUpdate(Id.str("a")).withDuration(Patch.of(3.0)));
    project.apply(changes);

    SolveOptions options = new SolveOptions()
        .withSubtree(new Subtree(Id.str("a")).withInclusive(false));
    ScheduleResult result = project.solve(null, options);
    for (Mutation update : result.updates) {
      System.out.println("task " + update.id + ": " + update.startDate + " .. " + update.endDate);
    }
    // task a: 2026-08-10 08:00 .. 2026-08-13 08:00
    // task b: 2026-08-13 08:00 .. 2026-08-14 08:00
  }
}
```

## Related

- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md>) - carries it for solve and schedule
- [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/preview-options.md>) - carries it for preview
- [Reschedule a branch](<https://docs.dhtmlx.com/planning-engine/java/how-to/reschedule-a-branch.md>) - solving and previewing one branch
- [Scheduling a project](<https://docs.dhtmlx.com/planning-engine/java/scheduling/scheduling-a-project.md#solve-options>) - where the scope fits among the options
