You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JDA消息中点击按钮后删除其余按钮?

JDA点击按钮后移除其他按钮的解决方法

问题场景

我用JDA发送了一条带两个按钮的嵌入消息(「Принять」接受和「Отклонить」拒绝),想要实现点击「Принять」按钮时删除另一个按钮,但调用以下代码没有效果(操作返回结果为0):

event.getMessage().getActionRows().clear();
event.getMessage().getComponents().clear();

问题原因

JDA中event.getMessage()返回的是不可变的消息对象,调用clear()只是修改了本地内存里的组件副本,并不会同步到Discord服务器,所以消息的按钮不会有任何变化。

正确实现方式

要更新消息的按钮,必须通过editMessageComponents()方法向Discord服务器发送修改请求,具体步骤如下:

1. 注册按钮交互监听器

创建监听器类处理按钮点击事件:

public class ButtonActionListener extends ListenerAdapter {
    @Override
    public void onButtonInteraction(ButtonInteractionEvent event) {
        // 判断点击的是「Принять」按钮
        if ("yes".equals(event.getButton().getId())) {
            // 编辑消息,只保留「Принять」按钮(可选禁用防止重复点击)
            event.editMessageComponents(
                    ActionRow.of(Button.success("yes", "Принять").asDisabled())
            ).queue(
                    success -> System.out.println("按钮更新成功"),
                    error -> error.printStackTrace()
            );
        }
    }
}

2. 注册监听器到JDA实例

确保Bot启动时加载该监听器:

JDA jda = JDABuilder.createDefault("你的Bot令牌")
        .addEventListeners(new ButtonActionListener())
        .build();

原发送消息代码(保留)

EmbedBuilder eb = new EmbedBuilder();
User user = event.getUser();
eb.setAuthor(user.getAsTag(), null, user.getAvatarUrl());
eb.addField("Ник", Objects.requireNonNull(event.getValue("nick")).getAsString(), true);
eb.addField("О себе", Objects.requireNonNull(event.getValue("biography")).getAsString(), true);
event.replyEmbeds(eb.build())
        .addActionRow(
                Button.success("yes", "Принять"),
                Button.danger("no", "Отклонить")
        )
        .queue();

补充说明

如果消息包含多组按钮,可通过流式处理灵活保留指定按钮:

List<ActionRow> updatedRows = event.getMessage().getActionRows().stream()
        .map(row -> row.getButtons().stream()
                .filter(btn -> "yes".equals(btn.getId())) // 只保留「Принять」按钮
                .map(btn -> btn.asDisabled()) // 禁用按钮
                .collect(Collectors.toList()))
        .map(ActionRow::of)
        .collect(Collectors.toList());

event.editMessageComponents(updatedRows).queue();

内容的提问来源于stack exchange,提问作者Artur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 16:30:58