User Tools

Site Tools


tutorial:screen

This is an old revision of the document!


Creating a screen

:!: The page is still in progress.

A screen is a graphical user interface that extends Screen, allowing the user to interact and fulfill some functionalities. Screens only exist in the client, so you must annotate them with @Environment(EnvType.CLIENT).

Usually you need to use mixins to add a button to that screen into an existing screen. But in most cases, we just implement the ModMenuApi of Mod Menu mod, and make it possible to access the screen via the config button in the Mod Menu screen. The page will not document how to implement ModMenuApi.

Adding widgets

A screen should have several “widgets”, which refer to elements in the screen. We add widgets in the init method.

@Environment(EnvType.CLIENT)
public class TutorialScreen extends Screen {
  protected TutorialScreen() {
    // The parameter is the title of the screen,
    // which will be narrated when you enter the screen.
    super(Text.literal("My tutorial screen"));
  }
 
 
  public ButtonWidget button1;
  public ButtonWidget button2;
 
  @Override
  protected void init() {
    button1 = ButtonWidget.builder(Text.literal("Button 1"), button -> {
      System.out.println("You clicked button1!");
    })
        .dimensions(width / 2 - 205, 20, 200, 20)
        .tooltip(Tooltip.of(Text.literal("Tooltip of button1")))
        .build();
    button2 = ButtonWidget.builder(Text.literal("Button 2"), button -> {
      System.out.println("You cliced button2!");
    })
        .dimensions(width / 2 + 5, 20, 200, 20)
        .tooltip(Tooltip.of(Text.literal("Tooltip of button2")))
        .build();
 
    addDrawableChild(button1);
    addDrawableChild(button2);
  }
}

The ''init'' method

The init method is called then: - The screen is created. - The screen is resized. Before invoking this, all child elements are removed.

You must use add the elements to the screen via using addDrawable, addSelectableChild or addDrawableChild. The difference is: - addDrawable: The element will be rendered, but you cannot select it, either by using mouse or keyboard. - addSelectableChild: You can select and interact it, but it will not be rendered. - addDrawableChild: The element will be both rendered and interactable, which is the most common case.

In the ButtonWidget.builder(…).builder(), you can specify the size and position of the button by using size and position respectively, or directly using dimensions. The tooltip specifies the tooltip, which will be rendered and narrated when your mouse hovers on, or use Tab to focus on it. Tooltip.of takes two arguments, the first to be shown, and the second (optional) to be narrated.

For versions before 1.19.3, ButtonWidget.builder(…) does not exist. In that case, please directly use the constructor of ButtonWidget.

Can I instantiate widgets in the constructor

Some users may instantiaze the widgets in the constructor, or the initialization. For example, they may write the code like this:

  public ButtonWidget button1 = ButtonWidget.builder(...).build();
  public ButtonWidget button2 = ButtonWidget.builder(...).build();
 
  @Override
  protected void init() {
    addDrawableChild(button1);
    addDrawableChild(button2);
  }

This is also OK. Its advantage is, if the widgets have some several states (such as the current selections of CyclingWidget, or typed text in the TextFieldWidget), they will not be reset when you resize the screen, because they will not be created again. However, when resizing, the width and height is changed, but you did not update. Therefore, in this case, you have to update the size or positions in the init method.

  @Override
  protected void init() {
    button1.setPosition(width / 2 - 205, 20);
    button2.setPosition(width / 2 + 5, 20);
 
    addDrawableChild(button1);
    addDrawableChild(button2)
  }

Notice about the order

After adding amounts of elements, all of them are added. Some people don't care about the order they are added, because all of the widgets are rendered at the sametime. However, if you select widgets by pressing the Tab key, you may find they are focused in a messy order. Therefore, please ensure that the widgets are added in a correct order.

The parent screen

I accessed the screen via another screen, such as the Mod Menu screen, but when I press Esc to go back, it just jumped to the main screen, not the previous screen, why? This is because you did not specify a parent screen, and the close method just directly jumps to the main screen.

Add a parent as a parameter and field, and use it in the close method:

  private final Screen parent;
 
  protected TutorialScreen(Screen parent) {
    super(Text.literal("My tutorial screen"));
    this.parent = parent;
  }
 
  @Override
  public void close() {
    client.setScreen(parent);
  }

[WIP]

tutorial/screen.1682044743.txt.gz · Last modified: 2023/04/21 02:39 by solidblock