Project#preview#

Applies hypothetical changes to a copy of the solved baseline of a Project and schedules the copy. The project isn't modified. Use it to show what an edit would do before committing it with apply. Needs a solved project.

Signature#

public ScheduleResult preview(SchedulingChanges changes, PreviewOptions options)

Synchronous and CPU-only. Not synchronized: serialize calls on one Project instance.

Parameters#

Name Type Description
changes SchedulingChanges The edits to try. Not null
options PreviewOptions Subtree, analytics, reasons, baseline check and an optional load profile. Not null; new PreviewOptions() for defaults

Behavior#

  • updates are relative to the baseline. An empty change set gives empty updates.
  • The result's baselineId is the baseline the preview read, so a following preview accepts it.
  • The change set isn't partially accepted: one rejected operation fails the whole call.
  • options.baselineId and changes.baselineId are checked separately. null skips a check.

Returns#

A ScheduleResult for the previewed state.

Errors#

All engine exceptions are unchecked.

Error When
ProjectException NO_BASELINE The project is unsolved, including after apply
ProjectException STALE_BASELINE options.baselineId or changes.baselineId doesn't name the current baseline
InputException An operation in changes is rejected (the exception reports the first one, with its path and message), or the profile query is invalid
NullPointerException changes or options is null

Example#

Preview a drag of task b, guarded by the baseline token, and check that the project keeps its dates.

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

public class PreviewDrag {
  static Moment day(int d) {
    return Moment.fromYmdHm(2026, 1, d, 0, 0);
  }

  public static void main(String[] args) throws Exception {
    ProjectData data = new ProjectData()
        .withTasks(List.of(new TaskData(Id.str("b")).withStartDate(day(1)).withDuration(1.0)));
    data.config.useCalendars = false;

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

    SchedulingChanges drag = new SchedulingChanges();
    drag.tasks.update.add(new TaskUpdate(Id.str("b")).withStartDate(Patch.of(day(5))));

    PreviewOptions options = new PreviewOptions().withBaselineId(solved.baselineId);
    ScheduleResult preview = project.preview(drag, options);
    for (Mutation update : preview.updates) {
      // task b: 2026-01-05 00:00 .. 2026-01-06 00:00
      System.out.println("task " + update.id + ": " + update.startDate + " .. " + update.endDate);
    }

    // The project is unchanged: an empty preview reports no updates.
    ScheduleResult unchanged = project.preview(new SchedulingChanges(), new PreviewOptions());
    System.out.println("updates: " + unchanged.updates.size()); // updates: 0
  }
}