Android Question LibGdx - Scene2d - Remove listener

notedop

Member
Licensed User
Longtime User
Hi,

I've implemented the LibGDX screen manager in my project.
It create 4 screens, Start, Play, Game_over and Settings.

On the Start screen i've created 3 buttons which link to the Start, Play and Settings screen.
These buttons have been created with Scene2d.

When I load the game and press the play button, the app goes to Play screen and loads as usual.
But when I touch the screen it triggers an Eventlistener for the Scene2d which was used on Screen Start (loading screen which holds the buttons)

B4X:
java.lang.NullPointerException
    at anywheresoftware.b4a.libgdx.scene2d.lgStage.touchDown(SourceFile:116)
    at com.badlogic.gdx.InputMultiplexer.touchDown(SourceFile:93)
    at com.badlogic.gdx.backends.android.AndroidInput.a(SourceFile:380)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:437)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1470)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1224)
** Activity (main) Pause, UserClosed = true **
waiting for pause synchronization took too long; assuming deadlock and killing

I have disposed the Stage in the Hide (cq Dispose) event.
I've tried to first call stage.Clear but this does not have effect.
I've tried to call Clear on the table which holds the buttons. This should clear all , actions and eventlistener but without luck. I still receive above error when touching the screen, implying the listener is still active.

I've tried to loop through each button and call Clear on the buttons which should remove the childrens, actions and eventlistener from the actor, but this gives an error as shown below.

How should I remove the scene2d listeners??

B4X:
java.lang.IllegalStateException: Invalid between begin/end.


    at com.badlogic.gdx.utils.DelayedRemovalArray.clear(SourceFile:136)
    at com.badlogic.gdx.scenes.scene2d.Actor.clearListeners(SourceFile:373)
    at com.badlogic.gdx.scenes.scene2d.Actor.clear(SourceFile:380)
    at com.badlogic.gdx.scenes.scene2d.Group.clear(SourceFile:345)
    at flm.b4a.libgdxtest.main._start_hide(main.java:835)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.libgdx.lgScreenManager$lgScreen.hide(SourceFile:148)
    at anywheresoftware.b4a.libgdx.lgScreenManager.setCurrentScreen(SourceFile:58)
    at flm.b4a.libgdxtest.main._txtbtn_click(main.java:979)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.libgdx.scene2d.lgTextButton$1.changed(SourceFile:37)


    at com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.handle(SourceFile:31)
    at com.badlogic.gdx.scenes.scene2d.Actor.notify(SourceFile:258)
    at com.badlogic.gdx.scenes.scene2d.Actor.fire(SourceFile:221)
    at com.badlogic.gdx.scenes.scene2d.ui.Button.setChecked(SourceFile:129)
    at com.badlogic.gdx.scenes.scene2d.ui.Button$1.clicked(SourceFile:100)
    at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(SourceFile:149)
    at com.badlogic.gdx.scenes.scene2d.InputListener.handle(SourceFile:105)
    at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(SourceFile:401)
    at anywheresoftware.b4a.libgdx.scene2d.lgStage.touchUp(SourceFile:123)
    at com.badlogic.gdx.InputMultiplexer.touchUp(SourceFile:99)
    at com.badlogic.gdx.backends.android.AndroidInput.a(SourceFile:384)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:437)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1470)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1224)
java.lang.IllegalStateException: Invalid between begin/end.
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:121)
    at android.app.Dialog.<init>(Dialog.java:127)
    at android.app.AlertDialog.<init>(AlertDialog.java:114)
    at android.app.AlertDialog$Builder.create(AlertDialog.java:913)
    at anywheresoftware.b4a.BA.ShowErrorMsgbox(BA.java:222)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:202)
    at anywheresoftware.b4a.libgdx.lgScreenManager$lgScreen.hide(SourceFile:148)
    at anywheresoftware.b4a.libgdx.lgScreenManager.setCurrentScreen(SourceFile:58)
    at flm.b4a.libgdxtest.main._txtbtn_click(main.java:979)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.libgdx.scene2d.lgTextButton$1.changed(SourceFile:37)
    at com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.handle(SourceFile:31)
    at com.badlogic.gdx.scenes.scene2d.Actor.notify(SourceFile:258)
    at com.badlogic.gdx.scenes.scene2d.Actor.fire(SourceFile:221)
    at com.badlogic.gdx.scenes.scene2d.ui.Button.setChecked(SourceFile:129)
    at com.badlogic.gdx.scenes.scene2d.ui.Button$1.clicked(SourceFile:100)
    at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(SourceFile:149)
    at com.badlogic.gdx.scenes.scene2d.InputListener.handle(SourceFile:105)
    at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(SourceFile:401)
    at anywheresoftware.b4a.libgdx.scene2d.lgStage.touchUp(SourceFile:123)
    at com.badlogic.gdx.InputMultiplexer.touchUp(SourceFile:99)
    at com.badlogic.gdx.backends.android.AndroidInput.a(SourceFile:384)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:437)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1470)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1224)
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


    at android.os.Handler.<init>(Handler.java:121)
    at android.app.Dialog.<init>(Dialog.java:127)
    at android.app.AlertDialog.<init>(AlertDialog.java:114)
    at android.app.AlertDialog$Builder.create(AlertDialog.java:913)
    at anywheresoftware.b4a.BA.ShowErrorMsgbox(BA.java:222)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:202)
    at anywheresoftware.b4a.libgdx.scene2d.lgTextButton$1.changed(SourceFile:37)
    at com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.handle(SourceFile:31)
    at com.badlogic.gdx.scenes.scene2d.Actor.notify(SourceFile:258)
    at com.badlogic.gdx.scenes.scene2d.Actor.fire(SourceFile:221)
    at com.badlogic.gdx.scenes.scene2d.ui.Button.setChecked(SourceFile:129)
    at com.badlogic.gdx.scenes.scene2d.ui.Button$1.clicked(SourceFile:100)
    at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(SourceFile:149)
    at com.badlogic.gdx.scenes.scene2d.InputListener.handle(SourceFile:105)
    at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(SourceFile:401)
    at anywheresoftware.b4a.libgdx.scene2d.lgStage.touchUp(SourceFile:123)
    at com.badlogic.gdx.InputMultiplexer.touchUp(SourceFile:99)
    at com.badlogic.gdx.backends.android.AndroidInput.a(SourceFile:384)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:437)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1470)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1224)

B4X:
Sub LG_Create
   
    lGdx_ScrMgr.Initialize(lGdx)
    lGdx_Screen(0) = lGdx_ScrMgr.AddScreen("START")
    lGdx_Screen(1) = lGdx_ScrMgr.AddScreen("PLAY")
    lGdx_Screen(2) = lGdx_ScrMgr.AddScreen("GAME_OVER")
    lGdx_Screen(3) = lGdx_ScrMgr.AddScreen("SETTINGS")

    lGdx_ScrMgr.CurrentScreen = lGdx_Screen(0)

    camera.Initialize
    camera.SetToOrtho2(False, lGdx.Graphics.Width, lGdx.Graphics.Height)
    camera.Update

End Sub

B4X:
Sub START_Show
'Create Start screen

Stage.Initialize("ST")

Dim CL As lgColor
cl.SetAlpha(1)

Table.Initialize("")
Table.debugColor = CL.BLUE
Table.debugCellColor = CL.BLUE
Table.Defaults.pad(3dip)
Table.setPosition(lGdx.Graphics.Width/2, lGdx.Graphics.Height/2)
Stage.AddActor(Table)


Dim npBtnUp As lgScn2DNinePatchDrawable
Dim npBtnDown As lgScn2DNinePatchDrawable
Dim stylTextButton As lgScn2DTextButtonStyle

Font.Initialize

Atlas.InitializeWithFile("atlas/uiskin.pack")

npBtnUp.Initialize2(Atlas.Create9Patch("default-round"))
npBtnDown.Initialize2(Atlas.Create9Patch("default-round-down"))

stylTextButton.Initialize(npBtnUp, npBtnDown, Font)
stylTextButton.SetDrawableSize(80%x, 30%y)
stylTextButton.FontColor = Font.Color.WHITE
stylTextButton.CheckedFontColor = Font.Color.YELLOW
stylTextButton.DisabledFontColor = Font.Color.GRAY
stylTextButton.DownFontColor = Font.Color.ORANGE

TextButtons(0).Initialize("START", stylTextButton, "TxtBtn")
TextButtons(0).Name = "TxtBtn" & 0
TextButtons(0).Tag = 0
Table.AddActor(TextButtons(0))
Table.NewRow

TextButtons(1).Initialize("PLAY", stylTextButton, "TxtBtn")
TextButtons(1).Name = "TxtBtn" & 1
TextButtons(1).Tag = 1
Table.AddActor(TextButtons(1))
Table.NewRow

TextButtons(2).Initialize("SETTINGS", stylTextButton, "TxtBtn")
TextButtons(2).Name = "TxtBtn" & 2
TextButtons(2).Tag = 3
Table.AddActor(TextButtons(2))
Table.NewRow

Log("Table X-Y: " & Table.X & ":" & Table.Y)

End Sub
Sub START_Update
End Sub
Sub START_Resize(Width As Int, Height As Int)

    Stage.SetViewport(Width, Height, True)

End Sub
Sub START_Render(Delta As Float)
    GL.glClearColor(0, 0, 0, 1)
    GL.glClear(GL.GL10_COLOR_BUFFER_BIT)
  
    'Applies the actions to actors
    Stage.Act

    'Draws the buttons
    Stage.Draw
End Sub
Sub START_Pause
'save game data
End Sub
Sub START_Resume  
End Sub
Sub START_Hide

'For i=0 To TextButtons.Length-1
'    TextButtons(i).clearListeners
'Next

Stage.Clear
Stage.dispose
Font.dispose
Atlas.dispose

Log("Hide Start")

End Sub

Sub TxtBtn_Click(CheckedState As Boolean)

If lGdx_ScrMgr.CurrentScreen = lGdx_Screen(0) Then
    Dim Bt As lgScn2DTextButton = Sender
    lGdx_ScrMgr.CurrentScreen = lGdx_Screen(Bt.Tag)
End If

End Sub
 

Informatix

Expert
Licensed User
Longtime User
Hi,

I've implemented the LibGDX screen manager in my project.
It create 4 screens, Start, Play, Game_over and Settings.

On the Start screen i've created 3 buttons which link to the Start, Play and Settings screen.
These buttons have been created with Scene2d.

When I load the game and press the play button, the app goes to Play screen and loads as usual.
But when I touch the screen it triggers an Eventlistener for the Scene2d which was used on Screen Start (loading screen which holds the buttons)

My mistake. I forgot to unregister the input processor of the stage when disposed. I'm going to fix that.
 
Upvote 0
Top