# Option\<T> class

### Option

The `Option` class is an abstract base class for configurable settings in a context menu. It holds the option’s value, name, and description, and interacts with `SkinRenderer` for rendering and input handling.

**Key Responsibilities**

* **Value Management**: Uses `getter` and `setter` to manage the option’s value.
* **Rendering**: Delegates rendering to its associated `SkinRenderer`.
* **Input Handling**: Provides default input handling, customizable by subclasses.
* **Complexity**: Supports a `Complexity` enum to control visibility based on user expertise.

**Key Methods**

* `get()`: Retrieves the current value.
* `set(T)`: Updates the value.
* `render(DrawContext, int, int, int, int)`: Delegates to the renderer.
* `updateProperties(ContextMenuProperties)`: Sets the renderer based on the skin.
* `shouldRender()`: Determines if the option is visible based on complexity and conditions.
* `description(String)` : is used to set tooltips/descriptions that is rendered by the Skin of the context menu.

**Common Issues**

* **Null Renderer**: If the skin lacks a renderer for the option type, a `RuntimeException` occurs.
  * **Fix**: Ensure the skin registers a renderer for the option class.
* **Complexity Mismatch**: Options may not render if the user’s complexity setting is too low.
  * **Fix**: Set appropriate `Complexity`:

    ```java
    option.withComplexity(Option.Complexity.Simple);
    ```

{% hint style="warning" %}
Always provide a valid `getter` and `setter` to avoid null pointer exceptions.
{% endhint %}

### Usage

To use the `Option<T>` class, extend it and implement the abstract `render` method to define the option’s appearance and behavior.  Use the `setShouldRender` method to specify conditions under which the option should be displayed.

This is an example usage of all options from TextWidget:<br>

{% code title="TextWidget.java" fullWidth="true" %}

```java
public void createMenu() {
    AtomicReference<Enum> enums = new AtomicReference<>(Enum.Enum1);
    AtomicReference<String> option = new AtomicReference<>("Enum1");
    List<String> options = Arrays.asList("List1", "List2", "List3");
    AtomicBoolean running = new AtomicBoolean(false);
    AtomicBoolean subMenu = new AtomicBoolean(false);
    menu = new ContextMenu(getX(), getY());
    menu.addOption(new BooleanOption("Shadow", () -> this.shadow, value -> this.shadow = value));
    menu.addOption(new BooleanOption("Rainbow", () -> this.rainbow, value -> this.rainbow = value));
    menu.addOption(new ColorOption("TextColor", menu, () -> this.textColor, value -> this.textColor = value));
    menu.addOption(new DoubleOption("RainbowSpeed", 1, 4, 1.0f, () -> (double) this.rainbowSpeed, value -> this.rainbowSpeed = value.intValue(),menu));
    menu.addOption(new EnumOption<>("Enum", enums::get, enums::set, Enum.values()));
    menu.addOption(new ListOption<>("List", option::get, option::set, options));
    menu.addOption(new RunnableOption("Runnable Test",running::get,running::set, this::printStuff));
    SubMenuOption subMenuOption = new SubMenuOption("SubMenu",menu,subMenu::get,subMenu::set);
    subMenuOption.getSubMenu().addOption(new BooleanOption("Shadows2", () -> this.shadow, value -> this.shadow = value));
    menu.addOption(subMenuOption);
}
public void printStuff(){
    System.out.println("Runnable works");
}
```

{% endcode %}
