SolveOptions#

Options for Project#solve and Engine.schedule. They set which part of the project is scheduled and which extra data the ScheduleResult carries. new SolveOptions() schedules the whole project and reports only the changed tasks.

Declaration#

public class SolveOptions extends ValueRecord implements DeepCloneable<SolveOptions>

Set fields with the fluent withX setters: new SolveOptions().withReasons(true). Two instances are equal when all four fields are equal, compared by value. For how Project#solve uses that equality to return its cached result, see Project#solve.

Constructors#

SolveOptions()#

public SolveOptions()

Creates options with every field at its default.

Fields#

Field Type Default Description
subtree Subtree null Schedules only one task's subtree and the tasks that depend on it. null schedules the whole project.
analytics AnalyticsOptions new AnalyticsOptions() (no analytics) Requests critical path and slack. Fills ScheduleResult.analytics.
reasons boolean false Fills Mutation.reason on each update with the Reason the task moved.
includeUnchanged boolean false Also reports unchanged tasks in ScheduleResult.updates, so the result holds the full date list.

subtree#

public Subtree subtree = null;

Limits scheduling to the scope the Subtree value describes. Build the value with new Subtree(id).

analytics#

public AnalyticsOptions analytics = new AnalyticsOptions();

Turns on AnalyticsOptions.slack and AnalyticsOptions.criticalPath. With both flags false (the default), ScheduleResult.analytics is null. With either flag set, it holds an Analytics value. Check its status before reading the data.

reasons#

public boolean reasons = false;

When true, each Mutation in updates carries a Reason in its reason field. When false, reason is always null.

Mutation.reason lists the cases where it stays null even with reasons = true.

includeUnchanged#

public boolean includeUnchanged = false;

When false, updates holds only the tasks the solve changed or that edits touched. When true, updates also holds every scheduled task that didn't change, each with startDate, endDate and duration set. The result is the full normalized date list for an initial load.

  • Every scheduled task is reported: leaves, summaries and milestones. Unscheduled tasks are never reported.
  • With subtree, every task in the subtree is reported, ancestors of subtree tasks included, plus the usual changed or touched updates outside the subtree.
  • On a project with cycles, every scheduled task is reported in model order (subtree is ignored), with its stored dates and durations.
  • levelingDelay and pauses are never set in these entries.

The extra entries don't affect ScheduleResult.baselineId, which follows real date changes only. Every other result field matches what the same solve returns with includeUnchanged = false.

Methods#

withSubtree, withAnalytics, withReasons, withIncludeUnchanged#

public SolveOptions withSubtree(Subtree value)
public SolveOptions withAnalytics(AnalyticsOptions value)
public SolveOptions withReasons(boolean value)
public SolveOptions withIncludeUnchanged(boolean value)

Each setter assigns its field and returns this instance for chaining.

Returns - this SolveOptions.

deepClone#

public SolveOptions deepClone()

Returns a copy that shares no nested object (subtree, analytics) with this instance.

Returns - a new SolveOptions with the same values.

copy#

public SolveOptions copy()

Returns a shallow copy. The copy shares the subtree and analytics objects with this instance.

Returns - a new SolveOptions with the same field values.

equals, hashCode, toString#

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

Inherited from ValueRecord. Two SolveOptions are equal when their public fields are equal, nested records compared by value. toString() lists the fields.

Example#

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

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

    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("design")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("build")).withStartDate(monday).withDuration(3.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1")).withSource(Id.str("design")).withTarget(Id.str("build"))));

    SolveOptions options = new SolveOptions()
        .withAnalytics(new AnalyticsOptions().withCriticalPath(true))
        .withReasons(true)
        .withIncludeUnchanged(true);

    Project project = new Project();
    ScheduleResult result = project.solve(data, options);

    // Every scheduled task, changed or not.
    for (Mutation update : result.updates) {
      System.out.println(update.id + ": " + update.startDate + " - " + update.endDate + " (" + update.reason + ")");
    }
  }
}