Advanced Modding - GUI without Inventory

Goal

I want to show you how to create a GUI without a linked Inventory.

Difficulty


2/10 - Quite Simple

Prerequisites

Forge Version

This Tutorial was created with Forge 11.14.1.1334 for Minecraft 1.8. If anything doesn't work with other versions, please contact me!


The class GuiScreen

To create GUIs without an inventory, we need to create a new class that extends GuiScreen.

GuiTutorial.java:
package com.bedrockminer.tutorial.client.gui;

import net.minecraft.client.gui.GuiScreen;

public class GuiTutorial extends GuiScreen {
}

This is already a functional GUI, however it does nothing. So, we want to add some features to it.
The first thing I want to add here is the drawScreen method. This method is used to draw GUI content onto the Screen.

GuiTutorial.java:
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
    super.drawScreen(mouseX, mouseY, partialTicks);
}

It is necessary to call the superclass method here, I'll expain why in a minute.
However, we can add rendering elements now. I won't explain GUI drawing here, because there are different ways that are explained in detail in the corresponding tutorials. What I want to show you here is the method drawDefaultBackground():

GuiTutorial.java:
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
    this.drawDefaultBackground();
    super.drawScreen(mouseX, mouseY, partialTicks);
}

This method draws a dark tint over the normal world background to generate a greater contrast between GUI and the world. You may have noticed it before in other GUIs. In the GuiContainer class for GUIs with Inventory, this method is called by default, for GuiScreen subclasses we need to call it on our own.
The next methods that we need to take care for is doesGuiPauseGame(). By default, this method returns true (not in the GuiContainer class, there it returns false). If the method returns true, the game pauses when the GUI is opened (Of course only in Singleplayer, a Server cannot pause). Also the game is saved then (Singleplayer only again). In vanilla Minecraft, this is true for the Options screen, the Command Block editing GUI, Sign and Book editing GUI and some others.
You can decide on your own whether you want to turn this option on or off, but basically it is better to pause the Game only when the task you want to do in the GUI can take a very long time in which the player is probably not protected from monsters. If your GUI is used to edit the state of a Tile Entity, like a pipe or a ChunkLoader you should turn pausing off.

GuiTutorial.java:
@Override
public boolean doesGuiPauseGame() {
    return false;
}

Last but not least, I want to show you how to add buttons to the GUI.
With vanilla methods, Buttons should be added within the initGui() method.

GuiTutorial.java:
@Override
public void initGui() {
}

In this method, you can create instances of GuiButton and add them to the buttonList of the GuiScreen.

GuiTutorial.java:
public void initGui() {
    this.buttonList.add(this.a = new GuiButton(0, this.width / 2 - 100, this.height / 2 - 24, "This is button a"));
    this.buttonList.add(this.b = new GuiButton(1, this.width / 2 - 100, this.height / 2 + 4, "This is button b"));
}

Note that this.a and this.b are variables I created.
The arguments for the GuiButton constructor are a unique ID, the coordinates (here calculated to be in the center of the GUI) and a caption. There is also a second Constructor available where you can set width and height of the button after the coordinates. The default size is 200*20, the size should be between 20*20 and 200*20, but for smaller buttons it can look a bit weird if you have a resource pack installed.
You can react to button clicks by overriding actionPerformed():

GuiTutorial.java:
@Override
protected void actionPerformed(GuiButton button) throws IOException {
}

Here you can check which button has been pressed. For this example, I'll just close the GUI when a button has been clicked, but you can send a message to the server using a packet handler or directly process the click.

GuiTutorial.java:
@Override
protected void actionPerformed(GuiButton button) throws IOException {
    if (button == this.a) {
        //Main.packetHandler.sendToServer(...);
        this.mc.displayGuiScreen(null);
        if (this.mc.currentScreen == null)
            this.mc.setIngameFocus();
    }
    if (button == this.b){
        //Main.packetHandler.sendToServer(...);
        this.mc.displayGuiScreen(null);
        if (this.mc.currentScreen == null)
            this.mc.setIngameFocus();
    }
}

Adding a Gui without Inventory to the Gui Handler

A Gui without inventory can be added to the GuiHandler similar to a Gui with inventory, however no Container needs to be returned for the server side.

GuiHandler.java:
public static final int TUTORIAL_GUI = 0;

@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
    return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
    if (ID == TUTORIAL_GUI)
        return new GuiTutorial();
    return null;
}

Opening a Gui without Inventory

As opposed to the Gui with Inventory, a Gui without Inventory may only be called from the client side. If you tried opening it from the server side, you would get a NullPointerException. To open a Gui without Inventory from the Server, you need to create a custom packet that opens it.
Here, I've created an item that opens the Gui on right-click. The item is not meant to look good or be complete, it just does what it's supposed to do.

ModItems.java:
GameRegistry.registerItem(new Item() {
    @Override
    public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn) {
        if (worldIn.isRemote) {
            playerIn.openGui(Main.instance, 0, worldIn, (int) playerIn.posX, (int) playerIn.posY, (int) playerIn.posZ);
        }
        return itemStackIn;
    }
}.setCreativeTab(CreativeTabs.tabMisc), "packetitem");

With this Item out test GUI can be opened.


You can download all the code used in this tutorial as a .zip file from here.


Recommended tutorials to continue with

´╗┐Advanced Modding:

Comments and Questions:

If you want to report modding problems, please make sure to include the code in a pastebin link or something else! Don't just write "It doesn't work", otherwise your post will be deleted. For more complicated problems, please use the troubleshooter form.