Проблема с TextArea при использовании Kryonet и Libgdx Project

Я новичок в stackoverflow, Kryonet и libgdx. Здесь, изучая процесс libgdx, я хочу сделать онлайн-игру «камень-ножницы-бумага», чтобы испытать как libgdx kryonet. Сначала я хотел внедрить в свою игру систему чата, чтобы опробовать Kryonet. Идея очень проста; окно чата (текстовое поле), кнопки отправки и присоединения, текстовые поля имени пользователя и сообщения. Когда кто-то нажимает кнопку отправки, сообщение будет отправлено каждому клиенту, подключенному к серверу. Но когда я спамлю кнопку отправки, она выдает некоторые типы ошибок (иногда 1, иногда 2 или иногда еще одну) и закрывает игру:

Ошибка типа 1

Исключение в потоке Приложение LWJGL java.lang.NullPointerException в com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:144) в com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java: 63) в com.badlogic.gdx.scenes.scene2d.ui.TextArea.calculateOffsets(TextArea.java:288) в com.badlogic.gdx.scenes.scene2d.ui.TextField.draw(TextField.java:330) в com .badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d .ui.WidgetGroup.draw(WidgetGroup.java:170) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren (Group.java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170 ) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) в com.bad logic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) в com.mygdx.game.screens.PlayScreen. render(PlayScreen.java:118) в com.badlogic.gdx.Game.render(Game.java:46) в com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:233) в com.badlogic .gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)

Ошибка типа 2

Исключение в потоке Приложение LWJGL java.lang.ArrayIndexOutOfBoundsException: 2980 в com.badlogic.gdx.graphics.g2d.BitmapFontCache.addGlyph(BitmapFontCache.java:408) в com.badlogic.gdx.graphics.g2d.BitmapFontCache.addToCache(BitmapFontCache. java:379) в com.badlogic.gdx.graphics.g2d.BitmapFontCache.addText(BitmapFontCache.java:511) в com.badlogic.gdx.graphics.g2d.BitmapFontCache.addText(BitmapFontCache.java:505) в com.badlogic .gdx.graphics.g2d.BitmapFontCache.addText(BitmapFontCache.java:486) в com.badlogic.gdx.graphics.g2d.BitmapFont.draw(BitmapFont.java:214) в com.badlogic.gdx.scenes.scene2d.ui .TextField.drawText(TextField.java:376) в com.badlogic.gdx.scenes.scene2d.ui.TextField.draw(TextField.java:349) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group .java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes. scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) в com.badlogic.gdx.scenes.scene2d.Group. drawChildren(Group.java:110) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) на com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:118) на com.badlogic.gdx.Game.render(Game.java:46) на com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop (LwjglApplication.java:233) в com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)

Ошибка типа 3

Исключение в потоке Приложение LWJGL java.lang.NullPointerException в com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:144) в com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java: 63) в com.badlogic.gdx.scenes.scene2d.ui.TextArea.calculateOffsets(TextArea.java:288) в com.badlogic.gdx.scenes.scene2d.ui.TextField.draw(TextField.java:330) в com .badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d .ui.WidgetGroup.draw(WidgetGroup.java:170) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren (Group.java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170 ) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) в com.bad logic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) в com.mygdx.game.screens.PlayScreen. render(PlayScreen.java:118) в com.badlogic.gdx.Game.render(Game.java:46) в com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:233) в com.badlogic .gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)

строка at com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:118), на которую ссылается ошибка: stage.draw(); строка в моем методе render() текущего экрана. Я не знаю, в чем проблема, но я предполагаю, что чего-то не хватает, когда клиенты получают спам-пакеты сообщений.

Ниже приведен мой код, чтобы получить помощь и подсказки, которые будут оценены.

метод рендеринга()

public void render(float delta) {

    //inputHandler();

    Gdx.gl20.glClearColor(0, 0, 0, 1);
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);

    app.camera.update();
    app.viewport.apply();
    app.batch.setProjectionMatrix(app.camera.combined);


    app.batch.begin();
    //app.batch.setColor(0.85f, 0.85f, 0.85f, 1);
    app.batch.draw(wallpaper,0,0);
    app.batch.end();

    //stage.getCamera().update();
    //stage.getViewport().apply();
    stage.act(delta);
    stage.draw();

}

метод startServer()

private void startServer() {
    server = new Server(25565,25565);

    server.getKryo().register(LoginRequest.class);
    server.getKryo().register(LoginResponse.class);
    server.getKryo().register(MessageRequest.class);
    server.getKryo().register(MessageResponse.class);
    server.getKryo().register(String.class);

    server.start();
    try {
        server.bind(25565,25565);
        server.addListener(new Listener(){
            @Override
            public void received(Connection connection, Object o) {
                super.received(connection, o);

                if(o instanceof LoginRequest) {
                    LoginRequest req = (LoginRequest) o;
                    LoginResponse response = new LoginResponse();
                    response.setResponseMessage("\n   -> " + req.getUsername() + " has joined the server!");
                    server.sendToAllTCP(response);
                }

                if(o instanceof MessageRequest) {
                    MessageRequest req = (MessageRequest) o;
                    MessageResponse response = new MessageResponse();
                    response.setMessage("\n   -> " + req.getUsername() + " : " + req.getMessage());
                    server.sendToAllTCP(response);
                }

            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }


    //btn_server.setDisabled(true);
    //btn_server.clearListeners();
}

Метод createButton() (btn_server => кнопка отправки сообщения, я забыл изменить имя переменной, не обращайте внимания)

private void createButton() {

    btn_style = new TextButton.TextButtonStyle();
    btn_style.font = font;
    btn_style.up = new TextureRegionDrawable(texUp);
    btn_style.down = new TextureRegionDrawable(texDown);
    btn_style.over = new TextureRegionDrawable(texOver);
    btn_style.disabled = new TextureRegionDrawable(texLock);

    btn_join = new TextButton("Join Server", btn_style);
    btn_server = new TextButton("Send Message", btn_style);


    btn_server.addListener(new ClickListener() {

        @Override
        public void clicked(InputEvent event, float x, float y) {
            if(client.isConnected()) {

                MessageRequest req = new MessageRequest();
                req.setUsername(name.getText());
                req.setMessage(message.getText());
                client.sendTCP(req);
            }


            //btn_server.setDisabled(true);
            //btn_server.clearListeners();
        }
    });

    btn_join.addListener(new InputListener() {

        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

            client = new Client(25565,25565);

            client.getKryo().register(LoginRequest.class);
            client.getKryo().register(LoginResponse.class);
            client.getKryo().register(MessageRequest.class);
            client.getKryo().register(MessageResponse.class);
            client.getKryo().register(String.class);

            try {
                client.start();
                client.connect(5000, myIP, 25565, 25565);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if(client.isConnected()) {
                btn_join.setDisabled(true);
                name.setDisabled(true);
                btn_join.clearListeners();
                LoginRequest req = new LoginRequest();
                req.setUsername(name.getText());
                client.sendTCP(req);
                client.addListener(new Listener(){
                    @Override
                    public void received(Connection connection, Object o) {
                        super.received(connection, o);

                        if(o instanceof LoginResponse) {
                            LoginResponse response = (LoginResponse) o;
                            textArea.appendText(response.getResponseMessage());
                        }

                        if(o instanceof MessageResponse) {
                            MessageResponse response = (MessageResponse) o;
                            textArea.appendText(response.getMessage());
                        }
                    }
                });
            }

            return true;
        }
    });
}

person Redarchy    schedule 31.07.2020    source источник
comment
Это слишком много кода, чтобы я мог его просмотреть и отладить для вас, но я предлагаю прочитать оба, чтобы узнать, как самостоятельно отлаживать распространенные ошибки, такие как NullPointerException. stackoverflow.com/questions/218384/ stackoverflow.com/questions/3988788/   -  person Tenfour04    schedule 31.07.2020
comment
Спасибо за внимание. Я пытаюсь избавиться от проблемы с использованием if... != null. Я сделаю обновление, я добьюсь успеха.   -  person Redarchy    schedule 01.08.2020
comment
Все ошибки связаны и говорят вам, что что-то не так с текстом текстовой области. Установите точку останова на textArea.appendText и проверьте   -  person MrStahlfelge    schedule 01.08.2020
comment
Я сделал, но не смог получить ни одного хорошего трека. После этого я попытался использовать List/ScrollPane вместо TextArea, чтобы показать все сообщения клиентам. Я все еще получаю сообщение об ошибке, как показано в моем новом ответе.   -  person Redarchy    schedule 01.08.2020


Ответы (1)


Я пытался использовать List и ScrollPane вместо TextArea, но аналогичная ошибка все еще заставляет меня застрять. Ошибка, как это было, происходит, когда я сильно спамлю кнопку «Отправить сообщение» (например, 2-3 раза в секунду).

Вот новая ошибка:

Исключение в потоке Приложение LWJGL java.lang.NullPointerException в com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:144) в com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java: 63) в com.badlogic.gdx.scenes.scene2d.ui.List.layout(List.java:184) в com.badlogic.gdx.scenes.scene2d.ui.Widget.validate(Widget.java:88) в com .badlogic.gdx.scenes.scene2d.ui.ScrollPane.layout(ScrollPane.java:535) в com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.validate(WidgetGroup.java:113) в com.badlogic.gdx .scene.scene2d.ui.ScrollPane.draw(ScrollPane.java:580) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) в com.badlogic.gdx.scenes.scene2d.ui .Table.draw(Table.java:115) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java :57) в com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) в com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Tab le.java:119) в com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) в com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) в com .badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) в com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:126) в com.badlogic.gdx.Game.render(Game .java:46) в com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:233) в com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)

at com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:126) ссылается на stage.draw() в методе render() экрана.

Вот моя новая функция Received():

if(o instanceof MessageResponse) {
MessageResponse response = (MessageResponse) o;
String n = "\n" + response.getMessage();
list.getItems().add(n);

scrollPane.setHeight(scrollPane.getPrefHeight() + list.getItemHeight());
System.out.println(list.getItemHeight());

scrollPane.layout();
//scrollPane.updateVisualScroll();
scrollPane.scrollTo(0,0,0,0);

}
person Redarchy    schedule 01.08.2020