[libGDX] [box2D] TextButton don't work

Hi, I have a problem. I have a TextButton implemented on my MenuScreen, but it don’t work. When I click it, it don’t do anything…

This is my code:


package com.unclain.udevelop.prueba1;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;

public class MenuScreen implements Screen{

	private Stage stage;
	private SpriteBatch spriteBatch;
	private Skin skin;
	private TextureAtlas textureAtlas;
	private TextButton textButton;
	private TextButtonStyle textButtonStyle;
	private BitmapFont buttonLevelsFont;
	private Texture background;
	private Sprite window;
	private Texture textureWindow;
	private Sprite mainImage;
	
	public MenuScreen instance = this;
	
	public GameScreen gamescreen;
	
	public MenuScreen(GameScreen gamescreen){
		this.gamescreen = gamescreen;
	}
	
	@Override
	public void render(float delta) {
		// TODO Auto-generated method stub
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		Gdx.gl.glClearColor(0, 0, 0, 1);
		stage.act(delta);
		
		spriteBatch.begin();
		spriteBatch.draw(background,0, 0);
		window.draw(spriteBatch);
		mainImage.draw(spriteBatch);
		mainImage.draw(spriteBatch);
		buttonLevelsFont.draw(spriteBatch, "Demostración de mecánicas de Unclain Entertainment 2013 - Powered by libGDX and Box2D physics.", 6, 18);
		spriteBatch.end();
		stage.draw();
		
		if(Gdx.input.isKeyPressed(Keys.ENTER)) gamescreen.udevelop.setScreen(new ScreenLevels(instance));
		
	}

	@Override
	public void resize(int width, int height) {
		// TODO Auto-generated method stub
		stage.addActor(textButton);
		background.setFilter(TextureFilter.Linear, TextureFilter.Linear);
	}

	@Override
	public void show() {
		Gdx.input.setInputProcessor(stage);
		stage = new Stage();
		spriteBatch = new SpriteBatch();
		textureAtlas = new TextureAtlas(Gdx.files.internal("AdyliumUserInterface.pack"));
		skin = new Skin(textureAtlas);
		
		buttonLevelsFont = new BitmapFont();
		
		textButtonStyle = new TextButtonStyle();
		textButtonStyle.up = skin.getDrawable("BotonNivelesA");
		textButtonStyle.down = skin.getDrawable("BotonNivelesB");
		textButtonStyle.over = skin.getDrawable("BotonNivelesB");
		textButtonStyle.
		
		textButton = new TextButton("", textButtonStyle);
		textButton.setX(Gdx.graphics.getWidth() / 2 - (textButton.getWidth() / 2));
		textButton.setY(Gdx.graphics.getHeight() / 2);
		textButton.setTouchable(Touchable.enabled);
		
		background = new Texture(Gdx.files.internal("BackgroundMenuScreen1.png"));
		
		textureWindow = new Texture(Gdx.files.internal("WindowMenuScreen.png"));
		window = new Sprite(textureWindow);
		window.setX(Gdx.graphics.getWidth() / 2 - (window.getRegionWidth() / 2));
		window.setY(Gdx.graphics.getHeight() / 2 - (window.getRegionHeight() / 2) + 20);
		window.scale(0.1f);
				
		Texture textureMainImage = new Texture(Gdx.files.internal("Logo.png"));
		mainImage = new Sprite(textureMainImage);
		mainImage.setX(Gdx.graphics.getWidth() / 2 - 128);
		mainImage.setY((Gdx.graphics.getHeight() / 2) + 86);
		
	}

	@Override
	public void hide() {
		
	}

	@Override
	public void pause() {
		
	}

	@Override
	public void resume() {
		
	}

	@Override
	public void dispose() {
		skin.dispose();
		stage.dispose();
		textureAtlas.dispose();
		buttonLevelsFont.dispose();
	}

}

Why it don’t work?

Thanks.

You are doing some awfully weird things here…

[]You are rendering your actors manually instead of adding them to the stage and letting stage do the rendering.
[
]You are adding a text button every time resize() is called.
[]You are changing the filter on a texture every time resize() is called – no reason to do that…
[
]You are allocating a lot of objects every time the Screen is shown. So if somebody opens your Game screen, and then returns to your Menu screen, all those objects are re-created, which can lead to some big issues. You are also loading Textures here; you should not be doing that every time the screen is shown, as it will lead to eventually running out of memory.
[]You are creating a new Screen every frame that the ENTER key is pressed… ? At the very least; you should only do this on keyDown input. Using isKeyPressed checks every frame.
[
]You have a syntax error in your “textButtonStyle” block of code. This probably won’t even compile…
[*]For UI elements it’s much better to use tables for layout instead of specifying absolute positions and using magic numbers

My suggestion would be to “start small.” Write a game with LibGDX that doesn’t rely on multiple screens. Maybe Pong or Tic-Tac-Toe. Get familiar with Scene2D UI just using the default skin.

Here is an example of a menu that uses the default skin and a Table for layout:

You can see how simple the code for that looks:

Move object creation to constructor. And about TextButton, doesn’t you forget to add listener to it?

As for why the TextButton doesn’t do anything…

You call Gdx.input.setInputProcessor(stage) before instantiating the stage. Also, you don’t add an event listener, so even once the stage begins to process input, it still won’t do anything until you do that. The other comments also apply - there are very ‘wrong’ things being done here.