[solved] [libgdx] ClickListener fails


public class MyClass extends Image{
	
	private TextureRegion[] regions = new TextureRegion[2];
	
	private Chromosome chrome;
	private int value;
	
	public MyClass(Chromosome chromosome, TextureRegion region1, TextureRegion region2, int value) {
		super(region1);
		this.chrome = chromosome;
		this.value = value;
		this.regions[0] = region1;
		this.regions[1] = region2;
		this.setRegion(regions[value]);
		this.setClickListener(new ClickListener(){
			@Override
			public void click(Actor actor, float x, float y) {
				// TODO Auto-generated method stub
				System.out.println(x + " " + y);
			}
		});
	}
}

The println doesn’t triggered. This class already added to screen’s stage. Any idea?

Give the actor a size.

So it appears that I have to give the region’s dimension (width and height) to Image’s ImageWidth, ImageHeight, width, and height. Thanks!

That is one way of setting the size, yes.

An actor doesn’t set its own size, instead the size is always set externally. If an actor implements Layout (which Image and all of scene2d.ui do) then the actor provides a minimum, preferred, and maximum size. These are hints that can be used by something external to size the actor. Often “something external” is a Table. Tables make everything super easy.

When not using tables or other groups that size and position children, the pack method is very useful. This method sets the width and height of the widget to the preferred width and height, calls invalidate if the widget’s size was changed, and then calls validate so that the widget adjusts itself to the new size.

You could just call pack, since the preferred size of an Image is the size of the texture region (or ninepatch, sprite, drawable, etc). Often this is what you want to do to adjust an actor’s size when not using Table, Stack, VerticalGroup, etc. However, there is a small gotcha if you need to do this in an actor’s constructor. From the Layout#pack() javadocs: “Generally this method should not be called in a constructor because it calls {@link #layout()}, which means a subclass would have layout() called before the subclass’ constructor. Instead, in a constructor simply sets the actors width and height to {@link #getPrefWidth()} and {@link #getPrefHeight()}. This allows the actor to have a size at construction time for more convenient use outside of a {@link Table}.” Because of this, all scene2d.ui widgets do this in their constructor:


setWidth(getPrefWidth());
setHeight(getPrefHeight());

Normally Image does this very thing and you don’t have to worry about it, but since you are using setRegion, you will have to do it yourself. Calling pack in your constructor is fine if you don’t subclass your actor.

Separate from all that, note you can pass null to the Image constructor if you don’t want to specify an Drawable there.