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


# LevelingResult

The result of [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>). It holds the leveled schedule and the number of leveling rounds that proposed a correction.

## Declaration

```java
package org.dhtmlx.plen;

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

## Fields

Each field has a fluent setter of the same name, `withX(value)`, that returns this result.

| Field | Type | Default | Description |
|---|---|---|---|
| `schedule` | [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) | `null` | The schedule after leveling. Always set in a result from `level`. |
| `rounds` | `int` | `0` | The number of rounds that proposed a correction. |

### schedule

The schedule of the final replan, with these values in its fields:

- `updates` include the `levelingDelay` and `pauses` changes as ordinary [`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) entries. The diff is against the state the `level` call started from, so the entries apply to the model the caller already holds.
- Each [`OverallocationWindow`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/resource-overallocation.md#overallocationwindow>) left in `overallocations` has a `reason`.
- `conflicts`, `notes` and `converged` come from the final replan.

The project keeps this `ScheduleResult` as its baseline and shares it with copies. It's read-only by contract. Call `schedule.deepClone()` before changing it.

### rounds

Counts only the rounds that proposed a delay or a pause. A contended bucket that leveling can't resolve doesn't add a round. On a cyclic project, `rounds` is `0` and `schedule` is the initial solve's result. There is no cap on rounds. See [Leveling resources](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/leveling-resources.md#reading-the-result>).

## Methods

### deepClone

```java
public LevelingResult deepClone()
```

Returns a new `LevelingResult` with the same `rounds` and the same `schedule` reference. The `ScheduleResult` isn't cloned. Call `schedule.deepClone()` for an independent copy of the schedule.

**Returns** - a new `LevelingResult` that shares `schedule` with this one.

### copy

```java
public LevelingResult copy()
```

Returns a shallow copy. The copy shares `schedule` with this result.

**Returns** - a new `LevelingResult` with the same field values.

### equals, hashCode, toString

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

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). `equals` and `hashCode` compare `schedule` and `rounds` by value. `toString()` lists both fields, e.g. `LevelingResult{schedule=ScheduleResult{…}, rounds=1}`.

## Example

Two tasks share one resource. Leveling delays one of them and reports the change in `schedule.updates`.

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

public class LevelingResultExample {
  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(2.0)))
        .withResources(List.of(new ResourceData().withId(Id.str("dev"))))
        .withAssignments(List.of(
            new AssignmentData().withTask(Id.str("a")).withResource(Id.str("dev")).withValue(1.0),
            new AssignmentData().withTask(Id.str("b")).withResource(Id.str("dev")).withValue(1.0)));

    Project project = new Project();
    project.solve(data, new SolveOptions());
    LevelingResult result = project.level(new LevelingOptions());

    System.out.println(result.rounds + " round(s), converged " + result.schedule.converged);
    for (Mutation update : result.schedule.updates) {
      System.out.println("task " + update.id + " delay " + update.levelingDelay);
      // task b delay 2.0
    }
  }
}
```

## Related

- [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) - the call that returns the result
- [`LevelingOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md>) - options of `level`
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) - the leveled schedule
- [Leveling Resources](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/leveling-resources.md#reading-the-result>) - reading the result
- [Clear leveling](<https://docs.dhtmlx.com/planning-engine/java/how-to/clear-leveling.md>) - removing leveling delays and pauses
