So, I was trying to create a screen. I created an init method which adds all the buttons: (1.19.2)
@Override
protected void init() {
this.addRenderableWidget(new Button(this.width / 2 - (18 / 2), this.height / 2 - (50 / 2), 18, 50, Component.literal("Test"), button -> {
this.minecraft.setScreen(null);
}));
}
But it didn't work. At first I thought it was my fault, but after some digging I found out this:
public final void init(Minecraft p_96607_, int p_96608_, int p_96609_) {
this.minecraft = p_96607_;
this.itemRenderer = p_96607_.getItemRenderer();
this.font = p_96607_.font;
this.width = p_96608_;
this.height = p_96609_;
java.util.function.Consumer<GuiEventListener> add = (b) -> {
if (b instanceof Widget w)
this.renderables.add(w);
if (b instanceof NarratableEntry ne)
this.narratables.add(ne);
children.add(b);
};
if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.children, add, this::removeWidget))) {
this.rebuildWidgets();
this.triggerImmediateNarration(false);
this.suppressNarration(NARRATE_SUPPRESS_AFTER_INIT_TIME);
}
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Post(this, this.children, add, this::removeWidget));
}
Now, it's not the entire code. Only one part of it:
if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.children, add, this::removeWidget))) {
this.rebuildWidgets();
this.triggerImmediateNarration(false);
this.suppressNarration(NARRATE_SUPPRESS_AFTER_INIT_TIME);
}
Apparently, Minecraft Forge made it so that if it succeeds in posting a message to the event bus, it does not call the [rebuildWidgets()] method, which results in [init()] not being called (since rebuildWidgets is responsible for calling init() without arguments):
protected void rebuildWidgets() {
this.clearWidgets();
this.setFocused((GuiEventListener)null);
this.init();
}
I was relying on the fact, that [public final void init(Minecraft minecraft, int width, int height)] would call the [protected void init()] method (via the [rebuildWidgets()] method), but it doesn't. I can't overwrite the method with 3 arguments since it's [final]. Is there any other place which is called to init the screen? I tried doing it on the constructor, but before [public final void init(Minecraft minecraft, int width, int height)] was called, width and height were 0.
How can I init my screen? I don't think doing it in the render method would be the correct way.