将某些字符串切割成切片时获取stackoverflow

时间:2016-11-25 14:34:57

标签: java minecraft forge

    @NotNull
public String text;
public int x;
public int y;
@NotNull
public ComponentText component;

public TextModule(@NotNull String text, int x, int y) {
    fr.setBidiFlag(true);
    fr.setUnicodeFlag(true);
    this.text = text;
    this.x = x;
    this.y = y;

    component = new ComponentText(x, y, ComponentText.TextAlignH.LEFT, ComponentText.TextAlignV.MIDDLE);
    component.getUnicode().setValue(true);

    if (this.x + fr.getStringWidth(text) > TextAdapter.wrapLength) {
        component.setPos(new Vec2d(0, 0));
        String[] strings = clipString(text);

        ComponentText string1 = new TextModule(strings[0], this.x, this.y).getComponent();
        component.add(string1);
        this.x = 0;
        this.y += fr.FONT_HEIGHT;

        TextModule string2 = new TextModule(strings[1], this.x, this.y);
        component.add(string2.getComponent());
        this.x = string2.x;
        this.y = string2.y;
    } else {
        component.getText().setValue(this.text);
        this.x += fr.getStringWidth(text);
    }
    fr.setBidiFlag(false);
    fr.setUnicodeFlag(false);
}

public String[] clipString(String string) {
    if (x + fr.getStringWidth(string) >= TextAdapter.wrapLength) {
        List<String> lines = fr.listFormattedStringToWidth(string, TextAdapter.wrapLength - x);
        if (!lines.isEmpty()) {
            String[] parts = new String[2];
            if (x + fr.getStringWidth(lines.get(0)) > TextAdapter.wrapLength) {
                parts[0] = "";
                parts[1] = string;
            }
            else {
                String line = lines.get(0);
                parts[0] = line;
                parts[1] = string.substring(parts[0].length());
            }
            return parts;
        }
    }
    return new String[0];
}

我正在制作一本从json读取文本文件的指南。它正在崩溃堆栈溢出:

这是文本模块,有多个模块,如StackModule和PlayerModule,他们所做的就是将自己的文本设置为特殊的颜色,如彩色或其他东西。

无论如何,这里的亮点是cutString。基本上,我正在做的是从json中获取下一个字符串,例如:

...
"learn how to manipulate light using reflection and refraction!",
"Ever wanted to suck items and entities with a single beam of light? Ever wanted to create a disco ball based quarry? How about creating a laser defense system? Or, heck, maybe you just wanted to make an epic laser show?",
...

我正在使用cutString来获取下一个字符串,例如上面的第二行“我想要......”,并将其切成两半。一半是开头的单词,用于填充前一个字符串中的任何尾随空格。另一半将自己置于一条新线上。这就是很好地包装字符串。

我在cutString中得到一个stackoverflow我认为。日志不够具体,但在textModule中注释掉任何使用cutString的内容都会消除崩溃,但当然会删除屏幕上的所有包装和路径。

日志是:

[16:19:29] [Client thread/FATAL]: Unreported exception thrown!
java.lang.StackOverflowError
at net.minecraft.client.gui.FontRenderer.getFormatFromString(FontRenderer.java:945) ~[FontRenderer.class:?]
at net.minecraft.client.gui.FontRenderer.wrapFormattedStringToWidth(FontRenderer.java:848) ~[FontRenderer.class:?]
at net.minecraft.client.gui.FontRenderer.wrapFormattedStringToWidth(FontRenderer.java:849) ~[FontRenderer.class:?]

...

该方法是:

    String wrapFormattedStringToWidth(String str, int wrapWidth)
{
    int i = this.sizeStringToWidth(str, wrapWidth);

    if (str.length() <= i)
    {
        return str;
    }
    else
    {
        String s = str.substring(0, i);
        char c0 = str.charAt(i);
        boolean flag = c0 == 32 || c0 == 10;
        String s1 = getFormatFromString(s) + str.substring(i + (flag ? 1 : 0));
        return s + "\n" + this.wrapFormattedStringToWidth(s1, wrapWidth);
    }
}

整个FontRenderer类:https://gist.github.com/anonymous/1cc0ae9b294ac7b27e4d64612d0da4bc

TextModule类:https://github.com/TeamWizardry/TMT-Refraction/blob/master/src/main/java/com/teamwizardry/refraction/api/book/TextModule.java

使用TextModule生成的组件对象的TextAdapter类:https://github.com/TeamWizardry/TMT-Refraction/blob/master/src/main/java/com/teamwizardry/refraction/api/book/TextAdapter.java

通过阅读json:https://github.com/TeamWizardry/TMT-Refraction/blob/master/src/main/java/com/teamwizardry/refraction/client/gui/GuiBook.java

使用TextAdapter的类

json文件:https://github.com/TeamWizardry/TMT-Refraction/blob/master/src/main/resources/assets/refraction/tablet/en_US.json

什么可能导致此堆栈溢出?如果您需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

跟踪表明错误在此方法中(在此处简化);

String wrapFormattedStringToWidth(String str, int wrapWidth)
{
    int i = this.sizeStringToWidth(str, wrapWidth);

    if (str.length() <= i)
    {
        return str;  // exit of recursive call
    }
    else
    {
        ...
        // recursive call
        return s + "\n" + this.wrapFormattedStringToWidth(s1, wrapWidth);
    }
}

此方法以递归方式调用自身,仅在字符串的长度小于或等于sizeStringToWidth返回的值时返回。可能这种情况从未发生在导致堆栈溢出的特定情况下。可能是计算错误,或字符串中的奇怪字符,...

如果不知道方法在做什么就很难说清楚 - 我无法获得与AxelH相同的问题。