Note: GUIEngine is an API, not a standalone plugin. It is designed to be used as a dependency in other plugins. It does not add any commands or menus on its own.
# GUIEngine
GUIEngine is a lightweight, flexible API for creating interactive GUI menus in Minecraft Paper servers (1.21.4). Instead of writing repetitive inventory code for each menu in your plugins, GUIEngine provides a clean, reusable system to create rich interactive interfaces.
## Purpose
GUIEngine is designed as a dependency for other plugins, providing a standardized way to:
- Create custom inventory menus with interactive buttons
- Handle player clicks and interactions
- Manage menu navigation and state
- Create dynamic, responsive interfaces
It functions similar to other utility plugins like Vault or ProtocolLib, but focused exclusively on GUI management.
## Key Features
- **Simple API**: Create complex menus with minimal code
- **Interactive Buttons**: Add clickable buttons with custom actions
- **Menu Navigation**: Easily handle sub-menus and menu linking
- **Dynamic Updates**: Update menu contents in real-time
- **Builder Pattern**: Create menus using a clean, fluent API
- **Resource Management**: Automatic cleanup of resources
- **Event Handling**: Properly integrates with Bukkit's event system
- **Clean Architecture**: Well-organized code for easy extension
## How It Works
GUIEngine consists of five core components:
### 1. GUIEngine (Core)
The main plugin class that initializes the system, registers event listeners, and provides access points for other plugins.
### 2. GUI (Menu)
Represents an inventory menu with slots for buttons. Each GUI handles its own layout and button mapping.
### 3. GUIButton (Buttons)
Interactive items within menus that can trigger actions when clicked. Buttons can execute code, send messages, open other menus, etc.
### 4. GUIManager (State Manager)
Keeps track of which menu is open for each player and manages the opening/closing of menus.
### 5. InventoryListener (Event Handler)
Intercepts inventory events and routes them to the appropriate GUI components.
## How to Use
### Adding as a Dependency
First, add GUIEngine as a dependency in your plugin.yml:
```yaml
depend: [GUIEngine]
```
Then, add it to your Maven/Gradle build file.
For Maven:
```xml
<dependencies>
<dependency>
<groupId>com.gui.engine</groupId>
<artifactId>gui-engine</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
### Creating a Basic Menu
Here's a simple example showing how to create and display a menu:
```java
// Create a new GUI with 3 rows (27 slots)
GUI myMenu = new GUI("§6§lMy Menu", 3);
// Add a button that sends a message when clicked
GUIButton messageButton = new GUIButton(
Material.PAPER,
"§e§lClick Me",
Arrays.asList("§7Click to receive", "§7a message"),
(player, gui, button, slot) -> {
player.sendMessage("§aYou clicked the button!");
return true;
}
);
// Add a button that closes the menu
GUIButton closeButton = new GUIButton(
Material.BARRIER,
"§c§lClose",
(player, gui, button, slot) -> {
player.closeInventory();
return true;
}
);
// Place buttons in specific slots
myMenu.setButton(13, messageButton);
myMenu.setButton(26, closeButton);
// Open the menu for a player
myMenu.open(player);
```
### Using the Builder Pattern
You can also use the builder pattern for cleaner menu creation:
```java
GUI menu = new GUI.Builder()
.title("§6§lMy Menu")
.rows(3)
.build();
// Then add buttons and open as normal
```
### Dynamic Button Updates
Buttons can update themselves in response to clicks:
```java
GUIButton counterButton = new GUIButton(
Material.EMERALD,
"§a§lClicks: §f0",
(player, gui, button, slot) -> {
// Extract current count from name
String name = ChatColor.stripColor(button.getItem().getItemMeta().getDisplayName());
int count = Integer.parseInt(name.split(": ")[1]) + 1;
// Update button name
button.setName("§a§lClicks: §f" + count);
// Update the inventory display
gui.updateInventory();
return true;
}
);
```
### Sub-Menus and Navigation
You can easily create navigation systems between menus:
```java
// In your main menu creation:
GUIButton settingsButton = new GUIButton(
Material.REDSTONE_TORCH,
"§b§lSettings",
(player, gui, button, slot) -> {
openSettingsMenu(player); // Your method to create/open settings menu
return true;
}
);
// And in your settings menu:
GUIButton backButton = new GUIButton(
Material.ARROW,
"§e§lBack",
(player, gui, button, slot) -> {
openMainMenu(player); // Your method to create/open main menu
return true;
}
);
```
## Advanced Features
### Custom Button Actions
You can create different types of button actions:
```java
// Teleport button
GUIButton teleportButton = new GUIButton(
Material.ENDER_PEARL,
"§5§lTeleport to Spawn",
(player, gui, button, slot) -> {
player.closeInventory();
player.teleport(player.getWorld().getSpawnLocation());
player.sendMessage("§aTeleported to spawn!");
return true;
}
);
// Command execution button
GUIButton commandButton = new GUIButton(
Material.COMMAND_BLOCK,
"§c§lExecute Command",
(player, gui, button, slot) -> {
player.closeInventory();
player.performCommand("spawn");
return true;
}
);
```
### Item Builders
Use the GUIButton builder for even cleaner button creation:
```java
GUIButton button = new GUIButton.Builder()
.material(Material.DIAMOND)
.name("§b§lPremium Features")
.lore("§7Click to view premium options")
.lore("§7Cost: $10")
.onClick((player, gui, button, slot) -> {
// Handle click
return true;
})
.build();
```
## Best Practices
1. **Resource Management**: Close GUIs when your plugin disables.
2. **Error Handling**: Check for null values when dealing with inventories.
3. **Performance**: Create menus on-demand rather than pre-creating all possible menus.
4. **Organization**: Create a separate manager class in your plugin for all your GUIs.
5. **Player Data**: Store player-specific data externally, not in the GUI itself.
## Complete Example
See the `ExampleGUI.java` class in the GUIEngine source code for a complete example of creating menus, submenus, and various button types.
## License
GUIEngine is licensed under the MIT License. Feel free to use, modify, and distribute as needed.