AbstractReportScreen.java

net.minecraft.client.gui.screens.reporting.AbstractReportScreen

信息

  • 全限定名:net.minecraft.client.gui.screens.reporting.AbstractReportScreen
  • 类型:public abstract class
  • 包:net.minecraft.client.gui.screens.reporting
  • 源码路径:src/main/java/net/minecraft/client/gui/screens/reporting/AbstractReportScreen.java
  • 起始行号:L31
  • 继承:Screen
  • 职责:

    TODO

字段/常量

  • REPORT_SENT_MESSAGE

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L32
    • 说明:

      TODO

  • REPORT_SENDING_TITLE

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L33
    • 说明:

      TODO

  • REPORT_SENT_TITLE

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L34
    • 说明:

      TODO

  • REPORT_ERROR_TITLE

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L35
    • 说明:

      TODO

  • REPORT_SEND_GENERIC_ERROR

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L36
    • 说明:

      TODO

  • SEND_REPORT

    • 类型: Component
    • 修饰符: protected static final
    • 源码定位: L37
    • 说明:

      TODO

  • OBSERVED_WHAT_LABEL

    • 类型: Component
    • 修饰符: protected static final
    • 源码定位: L38
    • 说明:

      TODO

  • SELECT_REASON

    • 类型: Component
    • 修饰符: protected static final
    • 源码定位: L39
    • 说明:

      TODO

  • DESCRIBE_PLACEHOLDER

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L40
    • 说明:

      TODO

  • MORE_COMMENTS_LABEL

    • 类型: Component
    • 修饰符: protected static final
    • 源码定位: L41
    • 说明:

      TODO

  • MORE_COMMENTS_NARRATION

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L42
    • 说明:

      TODO

  • ATTESTATION_CHECKBOX

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L43
    • 说明:

      TODO

  • BUTTON_WIDTH

    • 类型: int
    • 修饰符: protected static final
    • 源码定位: L44
    • 说明:

      TODO

  • MARGIN

    • 类型: int
    • 修饰符: protected static final
    • 源码定位: L45
    • 说明:

      TODO

  • SCREEN_WIDTH

    • 类型: int
    • 修饰符: protected static final
    • 源码定位: L46
    • 说明:

      TODO

  • SPACING

    • 类型: int
    • 修饰符: protected static final
    • 源码定位: L47
    • 说明:

      TODO

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L48
    • 说明:

      TODO

  • lastScreen

    • 类型: Screen
    • 修饰符: protected final
    • 源码定位: L49
    • 说明:

      TODO

  • reportingContext

    • 类型: ReportingContext
    • 修饰符: protected final
    • 源码定位: L50
    • 说明:

      TODO

  • layout

    • 类型: LinearLayout
    • 修饰符: protected final
    • 源码定位: L51
    • 说明:

      TODO

  • reportBuilder

    • 类型: B
    • 修饰符: protected
    • 源码定位: L52
    • 说明:

      TODO

  • attestation

    • 类型: Checkbox
    • 修饰符: private
    • 源码定位: L53
    • 说明:

      TODO

  • sendButton

    • 类型: Button
    • 修饰符: protected
    • 源码定位: L54
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.gui.screens.reporting.AbstractReportScreen.DiscardReportWarningScreen
    • 类型: class
    • 修饰符: private
    • 源码定位: L189
    • 说明:

      TODO

构造器

protected AbstractReportScreen(Component title, Screen lastScreen, ReportingContext reportingContext, B reportBuilder) @ L56

  • 构造器名:AbstractReportScreen
  • 源码定位:L56
  • 修饰符:protected

参数:

  • title: Component
  • lastScreen: Screen
  • reportingContext: ReportingContext
  • reportBuilder: B

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected MultiLineEditBox createCommentBox(int width, int height, Consumer<String> valueListener) @ L63

  • 方法名:createCommentBox
  • 源码定位:L63
  • 返回类型:MultiLineEditBox
  • 修饰符:protected

参数:

  • width: int
  • height: int
  • valueListener: Consumer

说明:

TODO

protected void init() @ L72

  • 方法名:init
  • 源码定位:L72
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void createHeader() @ L83

  • 方法名:createHeader
  • 源码定位:L83
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected abstract void addContent() @ L87

  • 方法名:addContent
  • 源码定位:L87
  • 返回类型:void
  • 修饰符:protected abstract

参数:

说明:

TODO

protected void createFooter() @ L89

  • 方法名:createFooter
  • 源码定位:L89
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void onReportChanged() @ L102

  • 方法名:onReportChanged
  • 源码定位:L102
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void repositionElements() @ L108

  • 方法名:repositionElements
  • 源码定位:L108
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void sendReport() @ L114

  • 方法名:sendReport
  • 源码定位:L114
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

private void onReportSendSuccess() @ L137

  • 方法名:onReportSendSuccess
  • 源码定位:L137
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void onReportSendError(Throwable throwable) @ L145

  • 方法名:onReportSendError
  • 源码定位:L145
  • 返回类型:void
  • 修饰符:private

参数:

  • throwable: Throwable

说明:

TODO

private void displayReportSendError(Component message) @ L157

  • 方法名:displayReportSendError
  • 源码定位:L157
  • 返回类型:void
  • 修饰符:private

参数:

  • message: Component

说明:

TODO

private void saveDraft() @ L163

  • 方法名:saveDraft
  • 源码定位:L163
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void clearDraft() @ L169

  • 方法名:clearDraft
  • 源码定位:L169
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public void onClose() @ L173

  • 方法名:onClose
  • 源码定位:L173
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void removed() @ L182

  • 方法名:removed
  • 源码定位:L182
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public abstract class AbstractReportScreen<B extends Report.Builder<?>> extends Screen {
    private static final Component REPORT_SENT_MESSAGE = Component.translatable("gui.abuseReport.report_sent_msg");
    private static final Component REPORT_SENDING_TITLE = Component.translatable("gui.abuseReport.sending.title").withStyle(ChatFormatting.BOLD);
    private static final Component REPORT_SENT_TITLE = Component.translatable("gui.abuseReport.sent.title").withStyle(ChatFormatting.BOLD);
    private static final Component REPORT_ERROR_TITLE = Component.translatable("gui.abuseReport.error.title").withStyle(ChatFormatting.BOLD);
    private static final Component REPORT_SEND_GENERIC_ERROR = Component.translatable("gui.abuseReport.send.generic_error");
    protected static final Component SEND_REPORT = Component.translatable("gui.abuseReport.send");
    protected static final Component OBSERVED_WHAT_LABEL = Component.translatable("gui.abuseReport.observed_what");
    protected static final Component SELECT_REASON = Component.translatable("gui.abuseReport.select_reason");
    private static final Component DESCRIBE_PLACEHOLDER = Component.translatable("gui.abuseReport.describe");
    protected static final Component MORE_COMMENTS_LABEL = Component.translatable("gui.abuseReport.more_comments");
    private static final Component MORE_COMMENTS_NARRATION = Component.translatable("gui.abuseReport.comments");
    private static final Component ATTESTATION_CHECKBOX = Component.translatable("gui.abuseReport.attestation").withColor(-2039584);
    protected static final int BUTTON_WIDTH = 120;
    protected static final int MARGIN = 20;
    protected static final int SCREEN_WIDTH = 280;
    protected static final int SPACING = 8;
    private static final Logger LOGGER = LogUtils.getLogger();
    protected final Screen lastScreen;
    protected final ReportingContext reportingContext;
    protected final LinearLayout layout = LinearLayout.vertical().spacing(8);
    protected B reportBuilder;
    private Checkbox attestation;
    protected Button sendButton;
 
    protected AbstractReportScreen(Component title, Screen lastScreen, ReportingContext reportingContext, B reportBuilder) {
        super(title);
        this.lastScreen = lastScreen;
        this.reportingContext = reportingContext;
        this.reportBuilder = reportBuilder;
    }
 
    protected MultiLineEditBox createCommentBox(int width, int height, Consumer<String> valueListener) {
        AbuseReportLimits reportLimits = this.reportingContext.sender().reportLimits();
        MultiLineEditBox commentBox = MultiLineEditBox.builder().setPlaceholder(DESCRIBE_PLACEHOLDER).build(this.font, width, height, MORE_COMMENTS_NARRATION);
        commentBox.setValue(this.reportBuilder.comments());
        commentBox.setCharacterLimit(reportLimits.maxOpinionCommentsLength());
        commentBox.setValueListener(valueListener);
        return commentBox;
    }
 
    @Override
    protected void init() {
        this.layout.defaultCellSetting().alignHorizontallyCenter();
        this.createHeader();
        this.addContent();
        this.createFooter();
        this.onReportChanged();
        this.layout.visitWidgets(x$0 -> this.addRenderableWidget(x$0));
        this.repositionElements();
    }
 
    protected void createHeader() {
        this.layout.addChild(new StringWidget(this.title, this.font));
    }
 
    protected abstract void addContent();
 
    protected void createFooter() {
        this.attestation = this.layout
            .addChild(
                Checkbox.builder(ATTESTATION_CHECKBOX, this.font).selected(this.reportBuilder.attested()).maxWidth(280).onValueChange((checkbox, value) -> {
                    this.reportBuilder.setAttested(value);
                    this.onReportChanged();
                }).build()
            );
        LinearLayout buttonsLayout = this.layout.addChild(LinearLayout.horizontal().spacing(8));
        buttonsLayout.addChild(Button.builder(CommonComponents.GUI_BACK, b -> this.onClose()).width(120).build());
        this.sendButton = buttonsLayout.addChild(Button.builder(SEND_REPORT, b -> this.sendReport()).width(120).build());
    }
 
    protected void onReportChanged() {
        Report.CannotBuildReason cannotBuildReason = this.reportBuilder.checkBuildable();
        this.sendButton.active = cannotBuildReason == null && this.attestation.selected();
        this.sendButton.setTooltip(Optionull.map(cannotBuildReason, Report.CannotBuildReason::tooltip));
    }
 
    @Override
    protected void repositionElements() {
        this.layout.arrangeElements();
        FrameLayout.centerInRectangle(this.layout, this.getRectangle());
    }
 
    protected void sendReport() {
        this.reportBuilder.build(this.reportingContext).ifLeft(result -> {
            CompletableFuture<?> sendFuture = this.reportingContext.sender().send(result.id(), result.reportType(), result.report());
            this.minecraft.setScreen(GenericWaitingScreen.createWaiting(REPORT_SENDING_TITLE, CommonComponents.GUI_CANCEL, () -> {
                this.minecraft.setScreen(this);
                sendFuture.cancel(true);
            }));
            sendFuture.handleAsync((ok, throwable) -> {
                if (throwable == null) {
                    this.onReportSendSuccess();
                } else {
                    if (throwable instanceof CancellationException) {
                        return null;
                    }
 
                    this.onReportSendError(throwable);
                }
 
                return null;
            }, this.minecraft);
        }).ifRight(reason -> this.displayReportSendError(reason.message()));
    }
 
    private void onReportSendSuccess() {
        this.clearDraft();
        this.minecraft
            .setScreen(
                GenericWaitingScreen.createCompleted(REPORT_SENT_TITLE, REPORT_SENT_MESSAGE, CommonComponents.GUI_DONE, () -> this.minecraft.setScreen(null))
            );
    }
 
    private void onReportSendError(Throwable throwable) {
        LOGGER.error("Encountered error while sending abuse report", throwable);
        Component message;
        if (throwable.getCause() instanceof ThrowingComponent error) {
            message = error.getComponent();
        } else {
            message = REPORT_SEND_GENERIC_ERROR;
        }
 
        this.displayReportSendError(message);
    }
 
    private void displayReportSendError(Component message) {
        Component styledMessage = message.copy().withStyle(ChatFormatting.RED);
        this.minecraft
            .setScreen(GenericWaitingScreen.createCompleted(REPORT_ERROR_TITLE, styledMessage, CommonComponents.GUI_BACK, () -> this.minecraft.setScreen(this)));
    }
 
    private void saveDraft() {
        if (this.reportBuilder.hasContent()) {
            this.reportingContext.setReportDraft(this.reportBuilder.report().copy());
        }
    }
 
    private void clearDraft() {
        this.reportingContext.setReportDraft(null);
    }
 
    @Override
    public void onClose() {
        if (this.reportBuilder.hasContent()) {
            this.minecraft.setScreen(new AbstractReportScreen.DiscardReportWarningScreen());
        } else {
            this.minecraft.setScreen(this.lastScreen);
        }
    }
 
    @Override
    public void removed() {
        this.saveDraft();
        super.removed();
    }
 
    @OnlyIn(Dist.CLIENT)
    private class DiscardReportWarningScreen extends WarningScreen {
        private static final Component TITLE = Component.translatable("gui.abuseReport.discard.title").withStyle(ChatFormatting.BOLD);
        private static final Component MESSAGE = Component.translatable("gui.abuseReport.discard.content");
        private static final Component RETURN = Component.translatable("gui.abuseReport.discard.return");
        private static final Component DRAFT = Component.translatable("gui.abuseReport.discard.draft");
        private static final Component DISCARD = Component.translatable("gui.abuseReport.discard.discard");
 
        protected DiscardReportWarningScreen() {
            Objects.requireNonNull(AbstractReportScreen.this);
            super(TITLE, MESSAGE, MESSAGE);
        }
 
        @Override
        protected Layout addFooterButtons() {
            LinearLayout footer = LinearLayout.vertical().spacing(8);
            footer.defaultCellSetting().alignHorizontallyCenter();
            LinearLayout firstFooterRow = footer.addChild(LinearLayout.horizontal().spacing(8));
            firstFooterRow.addChild(Button.builder(RETURN, button -> this.onClose()).build());
            firstFooterRow.addChild(Button.builder(DRAFT, button -> {
                AbstractReportScreen.this.saveDraft();
                this.minecraft.setScreen(AbstractReportScreen.this.lastScreen);
            }).build());
            footer.addChild(Button.builder(DISCARD, button -> {
                AbstractReportScreen.this.clearDraft();
                this.minecraft.setScreen(AbstractReportScreen.this.lastScreen);
            }).build());
            return footer;
        }
 
        @Override
        public void onClose() {
            this.minecraft.setScreen(AbstractReportScreen.this);
        }
 
        @Override
        public boolean shouldCloseOnEsc() {
            return false;
        }
    }
}

引用的其他类

  • Optionull

    • 引用位置: 方法调用
    • 关联成员: Optionull.map()
  • Button

    • 引用位置: 字段/方法调用
    • 关联成员: Button.builder()
  • Checkbox

    • 引用位置: 字段/方法调用
    • 关联成员: Checkbox.builder()
  • MultiLineEditBox

    • 引用位置: 方法调用/返回值
    • 关联成员: MultiLineEditBox.builder()
  • StringWidget

    • 引用位置: 构造调用
    • 关联成员: StringWidget()
  • FrameLayout

    • 引用位置: 方法调用
    • 关联成员: FrameLayout.centerInRectangle()
  • LinearLayout

    • 引用位置: 字段/方法调用
    • 关联成员: LinearLayout.horizontal(), LinearLayout.vertical()
  • GenericWaitingScreen

    • 引用位置: 方法调用
    • 关联成员: GenericWaitingScreen.createCompleted(), GenericWaitingScreen.createWaiting()
  • Screen

    • 引用位置: 参数/字段/继承
  • ReportingContext

    • 引用位置: 参数/字段
  • Component

    • 引用位置: 参数/字段/方法调用
    • 关联成员: Component.translatable()