模态表单 - Easy4Form 主代理 API
返回: 主 API 文档
模态表单是对话框样式的表单,为用户提供两个选择,通常是"是/否"、"确认/取消"或类似的二元决策。它们非常适合确认、警告以及任何需要简单二元选择的场景。
目录
概述
什么是模态表单?
模态表单显示:
- 顶部的标题
- 解释情况或问题的内容文本
- 两个按钮:通常代表"是/否"、"确认/取消"等
- 返回布尔值:第一个按钮返回
true,第二个按钮返回false
何时使用模态表单
✅ 适用于:
- 确认对话框("您确定吗?")
- 是/否问题
- 接受/拒绝提示
- 警告确认
- 二元选择
❌ 不适用于:
基本用法
简单示例
java
import cn.enderrealm.easy4form.api.Easy4FormAPI;
public void confirmPlayerKick(Player admin, Player target) {
Easy4FormAPI.sendModalForm(
admin,
"确认操作", // 标题
String.format("您确定要踢出 %s 吗?", // 内容
target.getName()),
"是的,踢出", // True 按钮(第一个按钮)
"取消", // False 按钮(第二个按钮)
response -> { // 响应处理器
if (response != null) {
if (response) {
// 用户点击了"是的,踢出"(true)
target.kickPlayer("您已被 " + admin.getName() + " 踢出");
admin.sendMessage("玩家 " + target.getName() + " 已被踢出。");
} else {
// 用户点击了"取消"(false)
admin.sendMessage("踢出已取消。");
}
} else {
// 表单被关闭而没有点击任何按钮
admin.sendMessage("操作已取消。");
}
}
);
}响应处理
响应处理器接收一个 Boolean,可能是:
- true:第一个按钮(通常是"是"、"确认"、"接受")被点击
- false:第二个按钮(通常是"否"、"取消"、"拒绝")被点击
- null:表单被关闭而没有点击任何按钮
java
response -> {
if (response == null) {
// 表单被关闭而没有选择
player.sendMessage("没有做出选择。");
return;
}
if (response) {
// 第一个按钮被点击(true)
handleConfirmation(player);
} else {
// 第二个按钮被点击(false)
handleCancellation(player);
}
}高级功能
动态内容
java
public void confirmPurchase(Player player, String itemName, double price) {
double playerBalance = getPlayerBalance(player);
String content;
String confirmButton;
if (playerBalance >= price) {
content = String.format(
"购买 %s,价格 $%.2f?\n\n您的余额:$%.2f\n购买后余额:$%.2f",
itemName, price, playerBalance, playerBalance - price
);
confirmButton = "立即购买";
} else {
content = String.format(
"余额不足!\n\n%s 价格 $%.2f\n您的余额:$%.2f\n还需要 $%.2f",
itemName, price, playerBalance, price - playerBalance
);
confirmButton = "确定";
}
Easy4FormAPI.sendModalForm(
player,
"购买确认",
content,
confirmButton,
"取消",
response -> {
if (response != null && response && playerBalance >= price) {
// 处理购买
processPurchase(player, itemName, price);
} else if (response != null && !response) {
player.sendMessage("购买已取消。");
}
}
);
}错误处理与重试
java
public void confirmDangerousAction(Player player, String action, int attempts) {
if (attempts > 3) {
player.sendMessage("尝试次数过多。为了安全,操作已取消。");
return;
}
Easy4FormAPI.sendModalForm(
player,
"危险操作",
String.format(
"警告:此操作无法撤销!\n\n" +
"操作:%s\n\n" +
"您确定要继续吗?\n" +
"(第 %d/3 次尝试)",
action, attempts
),
"是的,我确定",
"取消",
response -> {
try {
if (response == null) {
player.sendMessage("操作已取消。");
} else if (response) {
// 执行危险操作
performDangerousAction(player, action);
} else {
player.sendMessage("操作已取消。");
}
} catch (Exception e) {
player.sendMessage("发生错误。请重试。");
getLogger().severe("危险操作错误:" + e.getMessage());
// 增加尝试计数器后重试
confirmDangerousAction(player, action, attempts + 1);
}
}
);
}构建器模式
对于更复杂的模态表单,使用构建器模式:
java
import cn.enderrealm.easy4form.api.ModalFormBuilder;
public void showAdvancedConfirmation(Player player) {
new ModalFormBuilder()
.title("高级确认")
.content("这是一个需要仔细考虑的复杂决定。")
.trueButton("我接受")
.falseButton("我拒绝")
.responseHandler(response -> {
if (response != null) {
handleAdvancedResponse(player, response);
}
})
.errorHandler(error -> {
player.sendMessage("发生错误:" + error.getMessage());
})
.send(player);
}构建器方法
java
ModalFormBuilder builder = new ModalFormBuilder()
.title("表单标题") // 设置表单标题
.content("表单内容和问题") // 设置表单内容
.trueButton("是") // 设置第一个按钮文本(返回 true)
.falseButton("否") // 设置第二个按钮文本(返回 false)
.responseHandler(response -> { ... }) // 设置响应处理器
.errorHandler(error -> { ... }); // 设置错误处理器(可选)
// 发送表单
builder.send(player);最佳实践
1. 使用清晰、面向操作的按钮文本
java
// 好 - 清晰且具体
Easy4FormAPI.sendModalForm(
player,
"删除物品",
"您确定要删除此物品吗?此操作无法撤销。",
"永久删除", // 明确后果
"保留物品", // 明确替代选择
handler
);
// 避免 - 通用且不清楚
Easy4FormAPI.sendModalForm(
player,
"确认",
"您要继续吗?",
"是", // 不清楚"是"意味着什么
"否", // 不清楚"否"意味着什么
handler
);2. 在内容中提供上下文
java
// 好 - 提供完整上下文
String content = String.format(
"您即将传送到 %s。\n\n" +
"这将花费 $%.2f 并有 10 秒冷却时间。\n\n" +
"继续传送?",
destination, cost
);
// 避免 - 缺乏上下文
String content = "传送?";3. 处理所有响应情况
java
response -> {
if (response == null) {
// 始终处理表单关闭
player.sendMessage("操作已取消。");
} else if (response) {
// 处理确认
confirmAction(player);
} else {
// 处理取消
cancelAction(player);
}
}4. 使用适当的标题
java
// 好 - 描述性标题
"确认购买"
"删除警告"
"传送请求"
"需要权限"
// 避免 - 通用标题
"确认"
"问题"
"对话框"
"表单"5. 考虑后果
java
// 对于不可逆操作,要明确说明
Easy4FormAPI.sendModalForm(
player,
"永久操作",
"警告:此操作无法撤销!\n\n" +
"您的所有进度都将丢失。\n\n" +
"您绝对确定吗?",
"是的,删除所有内容",
"否,保留我的进度",
handler
);示例
示例 1:服务器规则接受
java
public void showRulesAcceptance(Player player) {
String rules =
"服务器规则:\n\n" +
"1. 不得破坏或摧毁他人建筑\n" +
"2. 尊重所有玩家\n" +
"3. 不得作弊或利用漏洞\n" +
"4. 遵循管理员指示\n\n" +
"点击'我接受'即表示您同意遵守这些规则。";
Easy4FormAPI.sendModalForm(
player,
"服务器规则",
rules,
"我接受",
"我拒绝",
response -> {
if (response == null) {
// 玩家关闭表单 - 延迟后再次询问
Bukkit.getScheduler().runTaskLater(plugin, () -> {
showRulesAcceptance(player);
}, 100L); // 5秒
} else if (response) {
// 规则已接受
setPlayerRulesAccepted(player, true);
player.sendMessage("欢迎来到服务器!祝您游戏愉快。");
teleportToSpawn(player);
} else {
// 规则被拒绝
player.kickPlayer("您必须接受服务器规则才能游戏。");
}
}
);
}示例 2:经济交易
java
public void confirmTransaction(Player sender, Player receiver, double amount) {
double senderBalance = getPlayerBalance(sender);
if (senderBalance < amount) {
sender.sendMessage("余额不足!");
return;
}
String content = String.format(
"向 %s 发送 $%.2f?\n\n" +
"您当前余额:$%.2f\n" +
"交易后余额:$%.2f\n\n" +
"此操作无法撤销。",
receiver.getName(), amount, senderBalance, senderBalance - amount
);
Easy4FormAPI.sendModalForm(
sender,
"确认付款",
content,
"发送金钱",
"取消",
response -> {
if (response != null && response) {
// 双重检查余额(以防发生变化)
if (getPlayerBalance(sender) >= amount) {
// 处理交易
removePlayerBalance(sender, amount);
addPlayerBalance(receiver, amount);
sender.sendMessage(String.format("已向 %s 发送 $%.2f", receiver.getName(), amount));
receiver.sendMessage(String.format("从 %s 收到 $%.2f", sender.getName(), amount));
// 记录交易
logTransaction(sender, receiver, amount);
} else {
sender.sendMessage("交易失败:余额不足。");
}
} else if (response != null) {
sender.sendMessage("交易已取消。");
}
}
);
}示例 3:PvP 挑战
java
public void sendPvPChallenge(Player challenger, Player target) {
// 首先,让挑战者确认
Easy4FormAPI.sendModalForm(
challenger,
"PvP 挑战",
String.format("挑战 %s 进行 PvP 决斗?\n\n双方玩家都将被传送到竞技场。",
target.getName()),
"发送挑战",
"取消",
response -> {
if (response != null && response) {
// 向目标发送挑战
sendChallengeToTarget(challenger, target);
} else if (response != null) {
challenger.sendMessage("挑战已取消。");
}
}
);
}
private void sendChallengeToTarget(Player challenger, Player target) {
Easy4FormAPI.sendModalForm(
target,
"收到 PvP 挑战",
String.format("%s 向您发起了 PvP 决斗挑战!\n\n" +
"您接受这个挑战吗?", challenger.getName()),
"接受决斗",
"拒绝",
response -> {
if (response != null && response) {
// 挑战被接受
challenger.sendMessage(target.getName() + " 接受了您的挑战!");
target.sendMessage("挑战已接受!正在准备竞技场...");
startPvPDuel(challenger, target);
} else if (response != null) {
// 挑战被拒绝
challenger.sendMessage(target.getName() + " 拒绝了您的挑战。");
target.sendMessage("挑战已拒绝。");
} else {
// 没有响应
challenger.sendMessage(target.getName() + " 没有回应您的挑战。");
}
}
);
}示例 4:管理员确认
java
public void confirmAdminAction(Player admin, String action, Runnable actionToPerform) {
// 检查玩家是否有管理员权限
if (!admin.hasPermission("server.admin")) {
admin.sendMessage("您没有此操作的权限。");
return;
}
Easy4FormAPI.sendModalForm(
admin,
"需要管理员操作",
String.format(
"需要管理员确认\n\n" +
"操作:%s\n\n" +
"此操作将影响服务器和/或玩家。\n" +
"请确认您要继续。\n\n" +
"记录为:%s",
action, admin.getName()
),
"确认并执行",
"取消",
response -> {
if (response != null && response) {
try {
// 记录管理员操作
getLogger().info(String.format("管理员 %s 执行了:%s", admin.getName(), action));
// 执行操作
actionToPerform.run();
admin.sendMessage("管理员操作执行成功。");
} catch (Exception e) {
admin.sendMessage("执行管理员操作时出错:" + e.getMessage());
getLogger().severe("管理员操作失败:" + e.getMessage());
}
} else if (response != null) {
admin.sendMessage("管理员操作已取消。");
}
}
);
}
// 使用示例
public void clearAllPlayerInventories(Player admin) {
confirmAdminAction(admin, "清空所有玩家背包", () -> {
for (Player player : Bukkit.getOnlinePlayers()) {
player.getInventory().clear();
player.sendMessage("您的背包已被管理员清空。");
}
});
}故障排除
常见问题
表单不显示:
- 确保玩家是基岩版玩家
- 检查 Floodgate 是否正确安装
- 验证 Easy4Form 是否已启用
意外的响应值:
- 记住:
true= 第一个按钮,false= 第二个按钮,null= 关闭 - 检查响应处理器中的布尔逻辑
- 使用调试来记录响应值
按钮文本显示不正确:
- 确保按钮文本不为 null 或空
- 检查可能无法正确显示的特殊字符
- 保持按钮文本合理简短
调试示例
java
Easy4FormAPI.sendModalForm(
player,
"调试模态",
"这是一个测试模态表单。",
"True 按钮",
"False 按钮",
response -> {
// 记录响应以进行调试
getLogger().info(String.format("玩家 %s 模态响应:%s",
player.getName(),
response != null ? response.toString() : "null"));
if (response == null) {
player.sendMessage("表单被关闭");
} else if (response) {
player.sendMessage("您点击了 TRUE 按钮");
} else {
player.sendMessage("您点击了 FALSE 按钮");
}
}
);相关文档
相关文档: