[LibGDX] How do you make your UIs?

Hi,

I’ve spent quite some time developing with LibGDX, but I never cared much for UIs since hard coding everything always feels really messy.
So, I would like to know how you fellow developers always create your UIs.
Do you hard code everything? Use an editor like Overlap2d or VisEditor? Or do you have your own tools?

Greets
Stampler ;D

I use an awful home grown XML system! It makes me want to cry every day, but hey ho, I made this bed so I shall have to lie in it.

It looks like this (shield your eyes before looking):


<?xml version='1.0' encoding='utf-8'?>

<!-- HUD overlay at the top of the screen -->
<resources>

	<package name="bots.screens.hud"/>
	<class name="HUDOverlay"/>

	<property key="button.tab.w" value="64"/>
	<property key="button.tab.h" value="64"/>
	<property key="button.tab.break.w" value="12"/>
	<property key="button.tab.gap" value="10"/>
	<property key="button.tabs.y" value="30"/>
	<property key="button.tabs.margin" value="120"/>
	<property key="button.tabs.w" value="=($button.tab.w*7)+($button.tab.break.w*2)+($button.tab.gap*8)"/>
	<property key="hud.height" value="180"/>
	<property key="hud.total.height" value="=$hud.height + 130"/>
	<property key="hud.main.width" value="=$button.tabs.w + $button.tabs.margin"/>
	<property key="hud.left.width" value="290"/>
	<property key="hud.right.width" value="252"/>
	<property key="hud.left.arm.width" value="=$hud.left.width + ($hud.main.width * 0.5) + 0.1" />
	<property key="hud.right.arm.width" value="=$hud.right.width + ($hud.main.width * 0.5) - 0.1" />
	<property key="user.id.x" value="131"/>
	<property key="user.id.y" value="10"/>
	<property key="user.id.w" value="600"/>
	<property key="user.avatar.x" value="20"/>
	<property key="user.avatar.y" value="70"/>
	<property key="user.avatar.size" value="$#AVATAR_SIZE"/>
	<property key="messages.x" value="=$user.id.w + $user.id.x + 42"/>
	<property key="messages.y" value="130"/>
	<property key="dropdown.position" value="106"/>
	<property key="rhs.dropdowns.w" value="730"/>
	<property key="rhs.dropdowns.x" value="100% - 20"/>

	<!-- tab buttons -->
	<include resource="gui/hud/tabs.xml"/>

	<!-- Backgrounds -->

	<!-- top hud panel -->

	<background name="widget.panel.main" texture="widgets-glowing/widget.panel.main.png" coords="150,150,150,70" insets="-40,0,-20,0" blend="GLOWING" topColor="panel.top" bottomColor="panel.bottom" />
	<background name="widget.panel.main.back" texture="widgets-solid/widget.panel.main.back.png" coords="150,150,150,70" insets="-40,0,-20,0"  color="panel.back"/>

	<background name="widget.panel.main.L" texture="widgets-glowing/widget.panel.main.L.png" coords="60,150,60,70" insets="-40,-30,-20,0" blend="GLOWING"  topColor="panel.top" bottomColor="panel.bottom" />	
	<background name="widget.panel.main.L.back" texture="widgets-solid/widget.panel.main.L.back.png" coords="60,150,60,70" insets="-40,-30,-20,0" color="panel.back"/>
		
	<background name="widget.panel.main.R" texture="widgets-glowing/widget.panel.main.R.png" coords="60,150,60,70" insets="-40,0,-20,-25" blend="GLOWING" topColor="panel.top" bottomColor="panel.bottom" />		
	<background name="widget.panel.main.R.back" texture="widgets-solid/widget.panel.main.R.back.png" coords="60,150,60,70" insets="-40,0,-20,-25"  color="panel.back"/>

	<background name="widget.panel.main.arm.L" texture="widgets-glowing/widget.panel.main.arm.L.png" coords="60,150,60,70" insets="-40,0,-20,0"	scale="=$widget.scale" blend="GLOWING" topColor="panel.top" bottomColor="panel.bottom" />	
	<background name="widget.panel.main.arm.L.back" texture="widgets-solid/widget.panel.main.arm.L.back.png" coords="60,150,60,70" insets="-40,0,-20,0"  color="panel.back"/>

	<background name="widget.panel.main.arm.R" texture="widgets-glowing/widget.panel.main.arm.R.png" coords="60,150,60,70" insets="-40,0,-20,0" blend="GLOWING" topColor="panel.top" bottomColor="panel.bottom" />	
	<background name="widget.panel.main.arm.R.back" texture="widgets-solid/widget.panel.main.arm.R.back.png" coords="60,150,60,70" insets="-40,0,-20,0"  color="panel.back"/>
	
	<layers name="icon.connection.warning.init.layers"><sprite layer="1000" animation="icon.connection.warning.init.anim"><sprite image="img.icon.connection.warning.glow"/></sprite></layers>
	<layers name="icon.connection.warning.mouseon.layers"><sprite layer="1000" animation="icon.connection.warning.mouseon.anim"><sprite image="img.icon.connection.warning.glow"/></sprite></layers>
	<layers name="icon.connection.warning.mouseoff.layers"><sprite layer="1000" animation="icon.connection.warning.mouseoff.anim"><sprite image="img.icon.connection.warning.glow"/></sprite></layers>	
	
	<animation name="icon.connection.warning.init.anim"><frame i="img.icon.connection.warning"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.connection.warning.mouseon.anim"><frame i="img.icon.connection.warning"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.connection.warning.mouseoff.anim"><frame i="img.icon.connection.warning"/><frame i="icon.mouseoff.anim"/></animation>

	<layers name="icon.connection.error.init.layers"><sprite layer="1000" animation="icon.connection.error.init.anim"><sprite  image="img.icon.connection.error.glow"/></sprite></layers>
	<layers name="icon.connection.error.mouseon.layers"><sprite layer="1000" animation="icon.connection.error.mouseon.anim"><sprite  image="img.icon.connection.error.glow"/></sprite></layers>
	<layers name="icon.connection.error.mouseoff.layers"><sprite layer="1000" animation="icon.connection.error.mouseoff.anim"><sprite  image="img.icon.connection.error.glow"/></sprite></layers>	
	
	<animation name="icon.connection.error.init.anim"><frame i="img.icon.connection.error"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.connection.error.mouseon.anim"><frame i="img.icon.connection.error"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.connection.error.mouseoff.anim"><frame i="img.icon.connection.error"/><frame i="icon.mouseoff.anim"/></animation>
	
	<layers name="icon.connection.online.init.layers"><sprite layer="1000" animation="icon.connection.online.init.anim"><sprite  image="img.icon.connection.online.glow"/></sprite></layers>
	<layers name="icon.connection.online.mouseon.layers"><sprite layer="1000" animation="icon.connection.online.mouseon.anim"><sprite  image="img.icon.connection.online.glow"/></sprite></layers>
	<layers name="icon.connection.online.mouseoff.layers"><sprite layer="1000" animation="icon.connection.online.mouseoff.anim"><sprite  image="img.icon.connection.online.glow"/></sprite></layers>	
	
	<animation name="icon.connection.online.init.anim"><frame i="img.icon.connection.online"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.connection.online.mouseon.anim"><frame i="img.icon.connection.online"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.connection.online.mouseoff.anim"><frame i="img.icon.connection.online"/><frame i="icon.mouseoff.anim"/></animation>

	<layers name="icon.connection.active.init.layers"><sprite layer="1000" animation="icon.connection.active.init.anim"><sprite  animation="icon.connection.active.blink.anim"/></sprite></layers>
	<layers name="icon.connection.active.mouseon.layers"><sprite layer="1000" animation="icon.connection.active.mouseon.anim"><sprite animation="icon.connection.active.blink.anim"/></sprite></layers>
	<layers name="icon.connection.active.mouseoff.layers"><sprite layer="1000" animation="icon.connection.active.mouseoff.anim"><sprite  animation="icon.connection.active.blink.anim"/></sprite></layers>	
	
	<animation name="icon.connection.active.init.anim"><frame i="img.icon.connection.online"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.connection.active.mouseon.anim"><frame i="img.icon.connection.online"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.connection.active.mouseoff.anim"><frame i="img.icon.connection.online"/><frame i="icon.mouseoff.anim"/></animation>

	<animation name="icon.connection.active.blink.anim">
		<frame i="img.icon.connection.online.glow"/>
		<interpolate var="alpha" f="ease-in" start="255" end="64" duration="30" forever="true" />
	</animation>

	<layers name="icon.connection.offline.init.layers"><sprite layer="1000" animation="icon.connection.offline.init.anim"><sprite  image="img.icon.connection.offline.glow"/></sprite></layers>
	<layers name="icon.connection.offline.mouseon.layers"><sprite layer="1000" animation="icon.connection.offline.mouseon.anim"><sprite image="img.icon.connection.offline.glow"/></sprite></layers>
	<layers name="icon.connection.offline.mouseoff.layers"><sprite layer="1000" animation="icon.connection.offline.mouseoff.anim"><sprite  image="img.icon.connection.offline.glow"/></sprite></layers>	
	
	<animation name="icon.connection.offline.init.anim"><frame i="img.icon.connection.offline"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.connection.offline.mouseon.anim"><frame i="img.icon.connection.offline"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.connection.offline.mouseoff.anim"><frame i="img.icon.connection.offline"/><frame i="icon.mouseoff.anim"/></animation>

	<animation name="icon.account.init.anim"><color c="button.text.off"/><frame i="img.icon.account"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.account.mouseon.anim"><color c="button.text.on"/><frame i="img.icon.account"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.account.mouseoff.anim"><color c="button.text.off"/><frame i="img.icon.account"/><frame i="icon.mouseoff.anim"/></animation>
	<animation name="icon.account.disabled.anim"><color c="button.text.disabled"/><frame i="img.icon.account"/><frame i="icon.disabled.anim"/></animation>
	
	<animation name="icon.connection.init.anim"><color c="button.text.off"/><frame i="img.icon.connection"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.connection.mouseon.anim"><color c="button.text.on"/><frame i="img.icon.connection"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.connection.mouseoff.anim"><color c="button.text.off"/><frame i="img.icon.connection"/><frame i="icon.mouseoff.anim"/></animation>

	<animation name="icon.options.init.anim"><color c="button.text.off"/><frame i="img.icon.options"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.options.mouseon.anim"><color c="button.text.on"/><frame i="img.icon.options"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.options.mouseoff.anim"><color c="button.text.off"/><frame i="img.icon.options"/><frame i="icon.mouseoff.anim"/></animation>

	<animation name="icon.help.init.anim"><color c="button.text.off"/><frame i="img.icon.help"/><frame i="icon.init.anim"/></animation>
	<animation name="icon.help.mouseon.anim"><color c="button.text.on"/><frame i="img.icon.help"/><frame i="icon.mouseon.anim"/></animation>
	<animation name="icon.help.mouseoff.anim"><color c="button.text.off"/><frame i="img.icon.help"/><frame i="icon.mouseoff.anim"/></animation>
	
	<area name="connection.icon.spec" type="active" width="100%" height="100%" offsetX="+-18" offsetY="16"/>
	<define tag="connection" inherit="connection.icon.spec" base="area"/>
	
	<area name="tab.break.spec" type="none" width="=$button.tab.break.w"/>
	<define tag="tab-break" inherit="tab.break.spec" base="area"/>
	
	<button name="tab.button.spec" width="=$button.tab.w" height="=$button.tab.h"/>
	<define tag="tab-button" inherit="tab.button.spec" base="button-widget"/>
	
	<instance
		name="hud.overlay"
		class="bots.screens.hud.HUDOverlay"
	>
	
		<!-- Tab hotkeys. Defined here so that they call Screen.onCommand -->
		<hotkey key="F1" area="$#@homeTabButton"/>
		<hotkey key="F2" area="$#@worldTabButton"/>
		<hotkey key="F3" area="$#@deployTabButton"/>
		<hotkey key="F4" area="$#@battleTabButton"/>
		<hotkey key="F5" area="$#@armyTabButton"/>
		<hotkey key="F6" area="$#@commanderTabButton"/>
		<hotkey key="F7" area="$#@eventsTabButton"/>

		<area
			y="north"
			width="100%"
			height="$hud.height"
		>
		
			<!-- Top left corner -->
			<area
				x="west"
				y="south"
				width="$hud.left.width"
				height="$hud.height"
			>
				<background id="back" layer="-1" subLayer="0" background="widget.panel.main.L.back" />
				<background id="glow" layer="-1" subLayer="1" background="widget.panel.main.L" />
			</area>
		
			<!-- Left extending arm. 625 = top left width + half of the centre piece width; 0.1 prevents hairline cracks -->
			<area
				x="=$hud.left.width"
				y="south"
				width="50% - $hud.left.arm.width"
				height="$hud.height"
			>
				<background id="back" layer="-1" subLayer="0" background="widget.panel.main.arm.L.back" />
				<background id="glow" layer="-1" subLayer="1" background="widget.panel.main.arm.L" />
			</area>
		
			<!-- Middle part with tabs inside it -->
			<area
				x="centre"
				y="south"
				width="$hud.main.width"
				height="$hud.height"
			>
				<layout><flow vpos="$button.tabs.y" hgap="$button.tab.gap"/></layout>
				
				<background id="back" layer="-1" subLayer="0" background="widget.panel.main.back" />
				<background id="glow" layer="-1" subLayer="1" background="widget.panel.main" />
				
				<tab-button id="$#@homeTabButton"	init="tab.icon.home.init.layers" normal="tab.icon.home.mouseoff.layers" armed="tab.icon.home.mouseon.layers"/>
				<tab-break/>
				<tab-button id="$#@worldTabButton" 	init="tab.icon.world.init.layers" normal="tab.icon.world.mouseoff.layers" disabled="tab.icon.world.disabled.layers" armed="tab.icon.world.mouseon.layers"/>
				<tab-button id="$#@deployTabButton"	init="tab.icon.deploy.init.layers" normal="tab.icon.deploy.mouseoff.layers" disabled="tab.icon.deploy.disabled.layers" armed="tab.icon.deploy.mouseon.layers"/>
				<tab-button id="$#@battleTabButton"	init="tab.icon.battle.init.layers" normal="tab.icon.battle.mouseoff.layers" disabled="tab.icon.battle.disabled.layers" armed="tab.icon.battle.mouseon.layers"/>
				<tab-break/>
				<tab-button id="$#@armyTabButton" 	init="tab.icon.army.init.layers" normal="tab.icon.army.mouseoff.layers" disabled="tab.icon.army.disabled.layers" armed="tab.icon.army.mouseon.layers"/>
				<tab-button id="$#@commanderTabButton"	init="tab.icon.user.init.layers" normal="tab.icon.user.mouseoff.layers" disabled="tab.icon.user.disabled.layers" armed="tab.icon.user.mouseon.layers"/>
				<tab-button id="$#@eventsTabButton" 	init="tab.icon.events.init.layers" normal="tab.icon.events.mouseoff.layers" disabled="tab.icon.events.disabled.layers" armed="tab.icon.events.mouseon.layers"/>
				
			</area>
			
			<!-- The messages widget -->
			<messages id="$#@messages"
				x="east"
				y="$messages.y"
				width="100%-$messages.x"
			/>
			
			<!-- Right extending arm. 565 = top right width + half of the centre piece width. -->
			<area
				x="100% - $hud.right.width"
				y="south"
				width="50% - $hud.right.arm.width"
				height="$hud.height"
			>
				<background id="back" layer="-1" subLayer="0" background="widget.panel.main.arm.L.back"/>
				<background id="glow" layer="-1" subLayer="1" background="widget.panel.main.arm.L"/>
			</area>
		
			<!-- Top right corner -->		
			<area
				x="east"
				y="0"
				width="$hud.right.width"
				height="$hud.height"
			>
				<background id="back" layer="-1" subLayer="0" background="widget.panel.main.R.back" />
				<background id="glow" layer="-1" subLayer="1" background="widget.panel.main.R" />
			</area>

			<!-- User's avatar -->		
			<area id="$#@hudTopUserAvatar"
				x="$user.avatar.x"
				y="$user.avatar.y"
				width="$user.avatar.size"
				height="$user.avatar.size"
				
				contentInsets="0,0,0,0"
				
				font="bd.M"
				textColor="text.bold"
				textLayer="1"
				textSubLayer="1"
				halign="left"
				valign="top"
			/>

			<!-- User ID and mini-stats -->
			<area id="aaa"
				x="$user.id.x"
				y="100%-$user.id.y"
			>
				<layout><flow hgap="8"/></layout>		

				<area id="$#@hudTopUserRank"
					offsetX="50%-0"
					offsetY="50%-0"
					width="50"
					height="60"
				/>

				<area
					width="$user.id.w"
					height="60"
				>				
					<area id="$#@hudTopUser"
						x="west"
						y="north"
						
						contentInsets="0,0,0,0"
						
						font="bd.M"
						textColor="text.bold"
						textLayer="1"
						textSubLayer="1"
						halign="left"
						valign="top"
					/>
					
					<area id="$#@hudTopUserInfo"
						x="west"
						y="south"
						width="400"
						height="30"
		
						font="bd.S"
						textColor="text"
						text="0Au 0(0)"
						textLayer="1"
						textSubLayer="1"
						halign="left"
						valign="top"
					/>
				</area>
			</area>
			
			<toggle id="$#@accountCbx"
				x="$user.id.x"
				y="100%-78"
				width="50"
				height="35"
			>
				<toggle-off
					init="icon.account.init.anim"
					normal="icon.account.mouseoff.anim"
					armed="icon.account.mouseon.anim"
					selected="icon.account.mouseon.anim"
					disabled="icon.account.disabled.anim"
				/>
				<toggle-on
					init="icon.account.init.anim"
					normal="icon.account.mouseoff.anim"
					armed="icon.account.mouseon.anim"
					selected="icon.account.mouseon.anim"
					disabled="icon.account.disabled.anim"
				/>
			</toggle>
				
			<!-- Container for the three toggle buttons in the top right, connection, options and help -->
			<area
				x="100%-22"
				y="100%-65"
				height="35"
			>		
				<layout><flow inflate="true" hgap="12"/></layout>
				
				<toggle id="$#@connectionCbx"
					height="100%"
					width="50"
				>
					<toggle-off
						init="icon.connection.init.anim"
						normal="icon.connection.mouseoff.anim"
						armed="icon.connection.mouseon.anim"
						selected="icon.connection.mouseon.anim"
					/>
					<toggle-on
						init="icon.connection.init.anim"
						normal="icon.connection.mouseoff.anim"
						armed="icon.connection.mouseon.anim"
						selected="icon.connection.mouseon.anim"
					/>
					<connection id="$#@connectionWarning" 	init="icon.connection.warning.init.layers" armed="icon.connection.warning.mouseon.layers" normal="icon.connection.warning.mouseoff.layers"/>
					<connection id="$#@connectionError" 	init="icon.connection.error.init.layers" armed="icon.connection.error.mouseon.layers" normal="icon.connection.error.mouseoff.layers"/>
					<connection id="$#@connectionOnline" 	init="icon.connection.online.init.layers" armed="icon.connection.online.mouseon.layers" normal="icon.connection.online.mouseoff.layers"/>
					<connection id="$#@connectionActive" 	init="icon.connection.active.init.layers" armed="icon.connection.active.mouseon.layers" normal="icon.connection.active.mouseoff.layers"/>
					<connection id="$#@connectionOffline" 	init="icon.connection.offline.init.layers" armed="icon.connection.offline.mouseon.layers" normal="icon.connection.offline.mouseoff.layers"/>
				</toggle>
							
				<toggle id="$#@optionsCbx"
					height="100%"
					width="50"
				>
					<toggle-off
						init="icon.options.init.anim"
						normal="icon.options.mouseoff.anim"
						armed="icon.options.mouseon.anim"
						selected="icon.options.mouseon.anim"
					/>
					<toggle-on
						init="icon.options.init.anim"
						normal="icon.options.mouseoff.anim"
						armed="icon.options.mouseon.anim"
						selected="icon.options.mouseon.anim"
					/>
				</toggle>
							
				<toggle id="$#@helpCbx"
					height="100%"
					width="50"
				>
					<toggle-off
						init="icon.help.init.anim"
						normal="icon.help.mouseoff.anim"
						armed="icon.help.mouseon.anim"
						selected="icon.help.mouseon.anim"
					/>
					<toggle-on
						init="icon.help.init.anim"
						normal="icon.help.mouseoff.anim"
						armed="icon.help.mouseon.anim"
						selected="icon.help.mouseon.anim"
					/>
				</toggle>
			</area>
									
		</area>
	</instance>
	
	<class />
	
	<panel-small-titled name="top.dropdown.panel.spec"
		layoutState="$hidden"
	>
		<layout-transition from="{init,hidden}" to="normal" f="ease-out" duration="10" interrupt="immediate"/>
		<layout-transition from="normal" to="{init,hidden}" f="ease-out" delay="5" duration="10" interrupt="immediate"/>

		<layout-transition from="normal" to="expanded" f="ease-out" duration="10" interrupt="immediate"/>
		<layout-transition from="expanded" to="normal" f="ease-out" delay="5" duration="10" interrupt="immediate"/>
		
		<layout-transition from="{init,hidden}" to="expanded" f="ease-out" duration="10" interrupt="immediate"/>
		<layout-transition from="expanded" to="hidden" f="ease-out" delay="5" duration="10" interrupt="immediate"/>
	</panel-small-titled>
	
	<define tag="hud-dropdown-panel" inherit="top.dropdown.panel.spec" base="area"/>
	
	<include resource="gui/hud/options.overlay.xml"/>
	<include resource="gui/hud/help.overlay.xml"/>
	<include resource="gui/hud/connection.overlay.xml"/>
	<include resource="gui/hud/account.overlay.xml"/>
	<include resource="gui/hud/steam.login.overlay.xml"/>
	
</resources>

Cas :slight_smile:

I see it even upsets the forum’s code tag syntax highlighter :slight_smile:

Cas :slight_smile:

Thanks alot for the insights. @princec Your XML system doesn’t look that awful, it’s better than lying on the floor. :point:

I was hoping to have some more opinions on doing UIs with LibGDX. I tried Overlap2D and I either failed to learn the proper usage of it or it actually isn’t what I am looking for.
I’m sticking with hard coding my UIs for now since my current project isn’t so UI heavy.

Stampler ;D

I generally just code them in, I went through a phase of similar to the above, also tried some of the libs like Nifty. In the end most of my UIs are so simple I don’t need much more than a simple Swing like API.

Only bit I externalise is the strings/text for i8n later.

Cheers,

Kev

For my game with libGdx I simple code them like this…


    public Skin getSkin() {
        return skin;
    }

    public void dispose() {
        skin.dispose();
    }

    private void loadSkin() {
        skin.addRegions(new TextureAtlas(Gdx.files.internal("Skin.pack")));
        skin.add("font", generateFont(), BitmapFont.class);
        skin.add("textButtonNine", generateTextButtonStyle(), TextButtonStyle.class);
        skin.add("imageButton", generateImageButtonStyle(), ImageButtonStyle.class);
    }
 
    private BitmapFont generateFont() {
        FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("DroidSerif-Bold.ttf"));
        FreeTypeFontParameter parameter = new FreeTypeFontParameter();
        BitmapFont font = null;
 
        parameter.color = Color.WHITE;
        parameter.size = 24;
        parameter.borderColor = Color.BLACK;
        parameter.borderWidth = 2;
        parameter.minFilter = TextureFilter.Linear;
        parameter.magFilter = TextureFilter.Linear;
 
        font = generator.generateFont(parameter);
        generator.dispose();
 
        return font;
    }
 
    private TextButtonStyle generateTextButtonStyle() {
        TextButtonStyle styleTextButton = new TextButtonStyle();
 
        styleTextButton.up = skin.getDrawable("button");
        styleTextButton.font = skin.getFont("font");
        styleTextButton.fontColor = Color.GREEN;
        styleTextButton.downFontColor = Color.GRAY; 
 
        return styleTextButton;
    }
 
    private ImageButtonStyle generateImageButtonStyle() {
        ImageButtonStyle styleImageButton = new ImageButtonStyle();
 
        styleImageButton.imageUp = skin.getDrawable("pauseOn");
        styleImageButton.imageChecked = skin.getDrawable("pauseOff");
        styleImageButton.up = skin.getDrawable("button");
 
        return styleImageButton;
    }

And if I have different types of ImageButton(That I will have), for example, I just…


    // This is usually big but readable
 
    private void loadSkin() {
        skin.addRegions(new TextureAtlas(Gdx.files.internal("Skin.pack")));
        ..
        ..
        skin.add("imageButton", generateImageButtonStyle("pauseOn", null, "button"), ImageButtonStyle.class);
        ..
        ..
        ..
    }

    .....

    private ImageButtonStyle generateImageButtonStyle(... String imgUp, String checked, String up ...) {
        ImageButtonStyle styleImageButton = new ImageButtonStyle();
 
        // And here check null
        if (imgUp!=null) styleImageButton.imageUp = skin.getDrawable(imgUp);
        if (checked!=null) styleImageButton.imageChecked = skin.getDrawable(checked);
        ...
        ...

        return styleImageButton;
    }

In this way, we have all in one place. Yes, I know, passes as an argument something null and that’s wrong but at the cost of that small mistake (if you are carefully, there should be no problems) we have everything well organized, structured and highly customizable.

Btw if anyone is thinking of making a UI-heavy Java game any time in the future I strongly suggest you take a long, hard look at JavaFX, which is really very good, and getting better.

Cas :slight_smile:

@princec i did look and it was awful … but do you use a selfmade editor to handle that ?

Made me laugh.

I also appreciate the JavaFX suggestion.

I think the “if” clause (“if UI-heavy”) is worth highlighting. UI components and Canvas and Image (WritableImage ~= BufferedImage, and ImageView allows easy transformations) – they are all Nodes. This equivalence of status is very helpful for coding a UI-heavy game.

But of course, that doesn’t help if you’re already committed to libgdx.

All hand edited :S

Cas :slight_smile: