Repository navigation
onClose
除了点击槽位,界面被关闭时也能触发逻辑。用 gui.onClose(...) 注册:
Besides slot clicks, the GUI can fire logic on close. Register with gui.onClose(...):
gui.onClose(() -> {
player p = @s;
runcmd(p.name, "msg 界面已关闭");
});
注册在 GUI 上,不是槽位上。整个界面只支持一个 onClose 回调。
Registered on the GUI, not on a slot. Each GUI supports a single onClose.
onClose 在这些情况下触发:
onClose fires in these cases:
-
玩家按 Esc 关闭界面。
-
脚本调用
gui.close(p)。 -
玩家打开另一个界面替换掉当前的。
-
Player presses Esc.
-
Script calls
gui.close(p). -
Player opens another inventory, replacing the current one.
不触发的情况:
Not fired for:
-
玩家断线(此时没有"关闭"动作)。
-
服务器关闭。
-
Player disconnect.
-
Server shutdown.
和点击回调一样,@s 指向关闭界面的玩家:
Like click callbacks, @s is the player who closed:
gui.onClose(() -> {
player p = @s;
runcmd("CONSOLE", "say " + p.name + " 关闭了界面");
});
玩家打开界面时锁定某些操作,关闭时解锁:
Lock something on open, unlock on close:
gui.onClose(() -> {
player p = @s;
// 例如:移除无敌标记
runcmd("CONSOLE", "effect clear " + p.name + " resistance");
});
gui.onClose(() -> {
player p = @s;
runcmd("CONSOLE", "say [GUI] " + p.name + " 离开了菜单");
});
gui.onClose(() -> {
player p = @s;
// 假设 secondGui 是另一个已定义的 GUI
// secondGui.open(p);
});
注意:open 是延迟下一 tick 执行的,不会与当前的关闭冲突。但不要在 onClose 里打开同一个 GUI,会造成无限循环。
Note: open is delayed to the next tick and does not clash with the current close. But do not open the same GUI inside its own onClose — infinite loop.
打开界面时给玩家加个标记,关闭时清除:
Add a flag on open, clear it on close:
bool inMenu;
int main() {
var gui = new GUI(1, "菜单");
var slot = new GUISlot(Material.PAPER);
slot.name = "§a继续";
slot.onLeftClick = () -> {
gui.close(@s);
};
gui[0][4] = slot;
gui.onClose(() -> {
player p = @s;
inMenu = false;
runcmd(p.name, "msg 已退出菜单");
});
gui.updateAll();
var p = @p;
inMenu = true;
gui.open(p);
}
inMenu 变量由闭包捕获。它在 main 里被声明,onClose lambda 和 main 都能访问同一个变量。
inMenu is captured by closure. Declared in main, both main and the onClose lambda see the same variable.
同一个 GUI 只能有一个 onClose。再次调用 onClose 会覆盖之前注册的:
A GUI has only one onClose. Calling onClose again overwrites the previous:
gui.onClose(() -> { /* 第一版 */ });
gui.onClose(() -> { /* 第二版 */ }); // 覆盖第一版
想清除已注册的回调,传 null:
To clear a registered callback, pass null:
gui.onClose(null);
onClose 和点击回调独立触发:
onClose and click callbacks fire independently:
-
点击"关闭"按钮 → 先触发
onLeftClick,然后触发onClose(如果按钮的 lambda 里调用了gui.close)。 -
玩家按 Esc → 只触发
onClose。 -
点击一个普通槽位 → 只触发槽位回调,界面没有关闭,所以
onClose不触发。 -
Click a "close" button →
onLeftClickfires, thenonClose(if the lambda calledgui.close). -
Press Esc → only
onClose. -
Click a normal slot → only the slot callback; the GUI stays open, so no
onClose.
onClose 不是"每次点击后触发",是"界面真的被关闭时触发"。区别很重要。
onClose is not "after every click"; it is "when the GUI is actually closed". The distinction matters.
slot.onClose = () -> { ... }; // ✗ 槽位没有 onClose
正确写法是 gui.onClose(lambda)。
onClose 只在界面关闭时触发,与点击无关。
gui.onClose(() -> {
gui.open(@s); // ✗ 无限循环
});
关闭后立刻打开会让关闭再触发,进入循环。用 @BukkitRunnable 延迟几 tick 再打开。
Use gui.onClose(lambda).
Only when the GUI closes.
Infinite loop. Use @BukkitRunnable with a delay.
-
gui.onClose(lambda)注册关闭回调。 -
触发时机:玩家关闭、脚本关闭、切换界面。
-
@s是关闭的玩家。 -
每个 GUI 只有一个
onClose,重复注册会覆盖。 -
传
null清除。 -
不要在
onClose里打开同一个 GUI。 -
gui.onClose(lambda)registers the close callback. -
Fires on player-close, script-close, or inventory switch.
-
@sis the closing player. -
One
onCloseper GUI; re-registering overwrites. -
Pass
nullto clear. -
Do not reopen the same GUI inside
onClose.
下一章 [GUI 刷新 / GUI-Refresh] 系统讲 update / updateAll 的时机和性能影响。
Next, [GUI 刷新 / GUI-Refresh] covers when to call update / updateAll and the performance implications.
- 首页 / Home
- 安装与快速开始 / Installation & Quick Start
- 第一个脚本 / Your First Script
- 命令速查 / Command Reference
- 自动执行脚本 / Auto-run Scripts
- 定义函数 / Defining Functions
- 函数重载 / Function Overloading
- Lambda 表达式 / Lambda Expressions
- 函数式接口 / Functional Interfaces
- 选择器总览 / Selectors Overview
- 选择器过滤器 / Selector Filters
- EntityRef 引用 / EntityRef
- 占位符参考 / Placeholders Reference
- PlaceholderAPI 桥接 / PAPI Bridge
- 创建 GUI / Creating a GUI
- GUISlot 槽位 / GUISlot
- 点击回调 / Click Callbacks
- onClose 回调 / onClose Callback
- GUI 刷新 / GUI Refresh
- 数学函数 / Math Built-ins
- 高精度计算 / BigDecimal Built-ins
- 字符串函数 / String Built-ins
- 集合函数 / Collection Built-ins
- 文件 I/O / File I/O
- 命令与 sleep / Commands & sleep