Search code examples
javalibgdxnumberformatexception

libgdx - Error reading uiskin.json, NumberFormatException while parsing default.fnt


I'm having trouble implementing the default user interface skin for libgdx. When I attempt to load the uiskin.json as a texture atlas, errors are thrown my way talking about a NumberFormatException while trying to parse a line including default.fnt.

Here is my stack trace with the errors.

Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Error reading pack file: uiskin.json
    at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:560)
    at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:365)
    at com.dizydev.robotwars.screens.LoadScreen.update(LoadScreen.java:64)
    at com.dizydev.robotwars.screens.AbstractScreen.render(AbstractScreen.java:55)
    at com.dizydev.robotwars.RobotWars.render(RobotWars.java:41)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error reading pack file: uiskin.json
    at com.badlogic.gdx.graphics.g2d.TextureAtlas$TextureAtlasData.<init>(TextureAtlas.java:187)
    at com.badlogic.gdx.assets.loaders.TextureAtlasLoader.getDependencies(TextureAtlasLoader.java:58)
    at com.badlogic.gdx.assets.loaders.TextureAtlasLoader.getDependencies(TextureAtlasLoader.java:34)
    at com.badlogic.gdx.assets.AssetLoadingTask.handleSyncLoader(AssetLoadingTask.java:99)
    at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:88)
    at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:488)
    at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:363)
    ... 5 more
Caused by: java.lang.NumberFormatException: For input string: "{ default-font: { file: default.fnt } }"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at com.badlogic.gdx.graphics.g2d.TextureAtlas$TextureAtlasData.<init>(TextureAtlas.java:116)
    ... 11 more

Here is the code I am using to load the default user interface skin.

game.manager.load("uiskin.json", TextureAtlas.class);
skin = new Skin(game.manager.get("uiskin.json", TextureAtlas.class));

I have all of the required files in my assets folder, here is a list of the files. They are all in the default assets folder.

default.fnt
default.png
uiskin.atlas
uiskin.json
uiskin.png

Since it looks like the error is within the parsing of the uiskin.json file, here is a copy of the uiskin.json file that I have.

{
com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: { file: default.fnt } },
com.badlogic.gdx.graphics.Color: {
    green: { a: 1, b: 0, g: 1, r: 0 },
    white: { a: 1, b: 1, g: 1, r: 1 },
    red: { a: 1, b: 0, g: 0, r: 1 },
    black: { a: 1, b: 0, g: 0, r: 0 },
},
com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: {
    dialogDim: { name: white, color: { r: 0, g: 0, b: 0, a: 0.45 } },
},
com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: {
    default: { down: default-round-down, up: default-round },
    toggle: { down: default-round-down, checked: default-round-down, up: default-round }
},
com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: {
    default: { down: default-round-down, up: default-round, font: default-font, fontColor: white },
    toggle: { down: default-round-down, up: default-round, checked: default-round-down, font: default-font, fontColor: white, downFontColor: red }
},
com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: {
    default: { vScroll: default-scroll, hScrollKnob: default-round-large, background: default-rect, hScroll: default-scroll, vScrollKnob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: {
    default: {
        font: default-font, fontColor: white, background: default-select,
        scrollStyle: default,
        listStyle: { font: default-font, selection: default-select-selection }
    }
},
com.badlogic.gdx.scenes.scene2d.ui.SplitPane$SplitPaneStyle: {
    default-vertical: { handle: default-splitpane-vertical },
    default-horizontal: { handle: default-splitpane }
},
com.badlogic.gdx.scenes.scene2d.ui.Window$WindowStyle: {
    default: { titleFont: default-font, background: default-window, titleFontColor: white },
    dialog: { titleFont: default-font, background: default-window, titleFontColor: white, stageBackground: dialogDim }
},
com.badlogic.gdx.scenes.scene2d.ui.ProgressBar$ProgressBarStyle: {
    default-horizontal: { background: default-slider, knob: default-slider-knob },
    default-vertical: { background: default-slider, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle: {
    default-horizontal: { background: default-slider, knob: default-slider-knob },
    default-vertical: { background: default-slider, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: {
    default: { font: default-font, fontColor: white }
},
com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: {
    default: { selection: selection, background: textfield, font: default-font, fontColor: white, cursor: cursor }
},
com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle: {
    default: { checkboxOn: check-on, checkboxOff: check-off, font: default-font, fontColor: white }
},
com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: {
    default: { fontColorUnselected: white, selection: selection, fontColorSelected: white, font: default-font }
},
com.badlogic.gdx.scenes.scene2d.ui.Touchpad$TouchpadStyle: {
    default: { background: default-pane, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Tree$TreeStyle: {
    default: { minus: tree-minus, plus: tree-plus, selection: default-select-selection }
},
com.badlogic.gdx.scenes.scene2d.ui.TextTooltip$TextTooltipStyle: {
    default: {
        label: { font: default-font, fontColor: white },
        background: default-pane, wrapWidth: 150
    }
},
}

Does anyone know why I am getting this error? It doesn't seem intuitive to me, and I'm not sure if it's a parsing error or something else because all of the files required for the default user interface skin are the latest versions available. If anyone could help me out that would be greatly appreciated.

Edit:

The first answer given to me did not solve my problem. Here are the changes to the code that I have made to attempt that first solution.

game.manager.load("uiskin.png", TextureAtlas.class);
skin = new Skin(Gdx.files.internal("uiskin.json"), game.manager.get("uiskin.png", TextureAtlas.class));

And here is the error stack trace that it has provided me.

Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Error reading pack file: uiskin.png
    at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:560)
    at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:365)
    at com.dizydev.robotwars.screens.LoadScreen.update(LoadScreen.java:64)
    at com.dizydev.robotwars.screens.AbstractScreen.render(AbstractScreen.java:55)
    at com.dizydev.robotwars.RobotWars.render(RobotWars.java:41)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error reading pack file: uiskin.png
    at com.badlogic.gdx.graphics.g2d.TextureAtlas$TextureAtlasData.<init>(TextureAtlas.java:187)
    at com.badlogic.gdx.assets.loaders.TextureAtlasLoader.getDependencies(TextureAtlasLoader.java:58)
    at com.badlogic.gdx.assets.loaders.TextureAtlasLoader.getDependencies(TextureAtlasLoader.java:34)
    at com.badlogic.gdx.assets.AssetLoadingTask.handleSyncLoader(AssetLoadingTask.java:99)
    at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:88)
    at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:488)
    at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:363)
    ... 5 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Invalid line: 
    at com.badlogic.gdx.graphics.g2d.TextureAtlas.readTuple(TextureAtlas.java:443)
    at com.badlogic.gdx.graphics.g2d.TextureAtlas$TextureAtlasData.<init>(TextureAtlas.java:115)
    ... 11 more

Edit:

With help from below I was able to figure out my problem. I had to remove a setting from the uiskin.json file as it was not being parsed correctly.

I had to change this.

com.badlogic.gdx.scenes.scene2d.ui.TextTooltip$TextTooltipStyle: {
    default: {
        label: { font: default-font, fontColor: white },
        background: default-pane, wrapWidth: 150
    }
},

To this.

com.badlogic.gdx.scenes.scene2d.ui.TextTooltip$TextTooltipStyle: {
    default: {
        label: { font: default-font, fontColor: white },
        background: default-pane
    }
},

And my new code looks like this.

game.manager.load("uiskin.json", Skin.class);
skin = game.manager.get("uiskin.json", Skin.class);

Solution

  • The libgdx engine is open and you can look into source in github so it's generally good idea to have a look at place of your error. As you see the issue is in lines

        116.    width = Integer.parseInt(tuple[0]);      // <- this especially
        117.    height = Integer.parseInt(tuple[1]);
    

    What we know now is that the error is connected with creating of TextureAtlas instance.

    Take a look at the way you are loading your textureAtlas into AssetManager ('cause I suppose that the game.manager is AssetManager). You should use

        game.manager.load("uiskin.atlas", TextureAtlas.class);
    

    instead of

        game.manager.load("uiskin.json", TextureAtlas.class);
    

    The .json file is not kind of atlas definition you need to create the TextureAtlas instance. Atlas definition contains positions and sizes of images on atlas graphic.

    Then, having TextureAtlas loaded, you should use Skin's contructor

        Skin(FileHandle skinFile, TextureAtlas atlas)
    

    like

        skin = new Skin(Gdx.files.internal("uiskin.json"), game.manager.get("uiskin.png", TextureAtlas.class));
    

    You are providing JSON definition for a Skin and then the TextureAtlas for it.

    This is the way you should do it.