Error when disposing of OrthagonalTiledMapRenderer - java

Im running into a problem while disposing of a screen. I am getting this error message when I try to dispose of my OrthogonalTiledMapRenderer. I looked around online and didnt find see any other examples of this or situations where this happened.
Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: buffer not allocated with newUnsafeByteBuffer or already disposed
at com.badlogic.gdx.utils.BufferUtils.disposeUnsafeByteBuffer(BufferUtils.java:507)
at com.badlogic.gdx.graphics.glutils.VertexArray.dispose(VertexArray.java:67)
at com.badlogic.gdx.graphics.Mesh.dispose(Mesh.java:551)
at com.badlogic.gdx.graphics.g2d.SpriteBatch.dispose(SpriteBatch.java:944)
at com.badlogic.gdx.maps.tiled.renderers.BatchTiledMapRenderer.dispose(BatchTiledMapRenderer.java:152)
at org.shawnhenry.rollypauly.screens.GameScreen.dispose(GameScreen.java:264)
at org.shawnhenry.rollypauly.screens.GameScreen.hide(GameScreen.java:238)
at org.shawnhenry.rollypauly.InputHandler.doTap(InputHandler.java:147)
at org.shawnhenry.rollypauly.InputHandler.touchUp(InputHandler.java:117)
at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:305)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:199)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
My implementation is quite simple.
In my main method I initilize the renderer:
renderer = new OrthogonalTiledMapRenderer(world.getTiledMap());
The render method called the renderer to draw objects like:
renderer.render(backgroundLayers);
and
renderer.getSpriteBatch().draw(resume, world.getResumeButton().x, world.getResumeButton().y, world.getResumeButton().width, world.getResumeButton().height);
Here is the trace through my various classes/functions mentioned in the error message:
FROM "InputHandler"
if(mainMenu.contains(x, y)){//Tapped the mainMenu button.
//Gdx.app.log("InputHandler", "Hit menu button!");
gameScreen.getGame().setScreen(new LevelSelectScreen(gameScreen.getGame()));
gameScreen.hide();
}
FROM "GameScreen"
#Override
public void hide() {
dispose();
}
#Override
public void dispose() {
renderer.dispose();
//world.dispose();
}
Any help you can give me would be great. If I dispose of my world class, and not renderer I dont get an error. My concern is that I believe the renderer is a resource heavy object so when leaving the screen it needs to be disposed of.

I believe solved my problem. I figured I was calling dispose twice, but I looked through my entire code and the only place I called dispose() was the one time during the hide() and the hide() was only being called once during this:
if(mainMenu.contains(x, y)){//Tapped the mainMenu button.
//Gdx.app.log("InputHandler", "Hit menu button!");
gameScreen.getGame().setScreen(new LevelSelectScreen(gameScreen.getGame()));
gameScreen.hide();
}
My problem I believe is that when I set the new screen to the LevelSelectScreen() the hide() function is automatically called as the the LevelSelectScreen() gains focus...dispose() is called for the first time. Then it is called again in the very next line when I explicitly call it gameScreen.hide()'.

Related

JTextField in JFrame uneditable when using JCEF in JInternalFrame until JFrame loses focus

I have started implementing JCEF in a project of mine, and I am initializing the embedded browser in a JInternalFrame inside of a JFrame, alongside a series of form fields on a JPanel next to the JInternalFrame. The browser component doesn't fully initialize until the JFrame actually becomes visible, and I'm finding that my JTextFields are uneditable unless the JFrame loses and regains focus.
Any idea of what could be happening and how to fix it? This only happens when using a JInternalFrame with the JCEF component...
It also happens every time I call loadURL to load a new page in the browser: the JTextFields become uneditable again, until I lose/gain focus in the JFrame.
UPDATE:
I have found a hack which allows the JTextFields to become editable again, but I wouldn't call it a solution because it is not very elegant. I added a load handler to the CefClient instance ( client.addLoadHandler(new CefLoadHandlerAdapter()) ) with an #Ovveride on the onLoadingStateChange method, which in turn gives access to the current browser component. From there I can detect when loading in the browser is complete, and use SwingUtilities to get the Window that the browser component is in. Then I setVisible(false) and setVisible(true) on that Window. I say it's not a solution because every time the browser is done loading the Window disappears and reappears. Even though the JTextFields are editable again, it is quite ugly to see the window flashing. I've tried all kinds of revalidate() and repaint() methods to no avail, unless I didn't call them right...
client.addLoadHandler(new CefLoadHandlerAdapter() {
#Override
public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
boolean canGoBack, boolean canGoForward) {
if (!isLoading) {
//browser_ready = true;
System.out.println("Browser has finished loading!");
SwingUtilities.windowForComponent( browser.getUIComponent() ).setVisible(false);
SwingUtilities.windowForComponent( browser.getUIComponent() ).setVisible(true);
}
}
});
If anyone can suggest a better solution, please do!
I figured out the problem by studying the sample JCEF application a little better. I need to implement a FocusHandler in order to release the embedded browser's hold on keyboard input:
private boolean browserFocus_ = true;
---
jTextField1.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
if (!browserFocus_) return;
browserFocus_ = false;
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
jTextField1.requestFocus();
}
});

LibGDX logging not showing up in logcat

I cannot get LibGDX logging to work in Android Studio. First i thought I had the same problem as my previous question but made sure my app updated on debug.
playButton.addListener(new ChangeListener()
{
#Override
public void changed(ChangeEvent event, Actor actor) {
Gdx.app.debug("BUTTON", "playButton Pressed");
optionButton.addAction(Actions.moveBy(-200, 0, 2));
}
});
The test action on the option button is carried out but i cannot get the debug log to show up.
The default Log level is LOG_INFO. For the Gdx.app.debug call to work, you must first call Gdx.app.setLogLevel(Application.LOG_DEBUG); once (probably the first line in your Game's constructor so you can easily change it).
Use Gdx.app.log or even System.out.println (write sout (syso in eclipse) and enter );

How to clear libgdx listeners

So in menu i have 3 buttons and all are with the same code. For the topic only important thing is
button2.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
game.setGame();
dispose();
return true;
}
});
Then everything is going fine until:
button3.clearListeners(); // MainMenu.java:174 line in exeption
and then exeption pops out:
Exception in thread "LWJGL Application" java.lang.IllegalStateException: Invalid between begin/end.
at com.badlogic.gdx.utils.DelayedRemovalArray.clear(DelayedRemovalArray.java:125)
at com.badlogic.gdx.scenes.scene2d.Actor.clearListeners(Actor.java:261)
at com.racostyle.avdelux.MainMenu.dispose(MainMenu.java:174)
at com.racostyle.avdelux.MainMenu$3.touchDown(MainMenu.java:123)
at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:55)
at com.badlogic.gdx.scenes.scene2d.Actor.notify(Actor.java:165)
at com.badlogic.gdx.scenes.scene2d.Actor.fire(Actor.java:136)
at com.badlogic.gdx.scenes.scene2d.Stage.touchDown(Stage.java:277)
at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:300)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:200)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
EDIT: if i don't remove listeners they are still active and can be clickable, afc with exeptions.
It looks like you're calling MainMenu.dispose within an actor.touchdown listener. MainMenu.dispose clears all listeners on a button. LIBGX won't allow that.
Why? Because LIBGDX is in the process of calling touch events on a lot of actors. You really don't want your game functioning different depending on the order buttons were added to your stage.
So, call clear listeners somewhere else.
Since you're doing this within a dispose method anyway, I'd suggest NOT removing your button listeners at all, as the actor you've registered listeners for should not be used again.
Its not allowed to just call clearListeners() without event;
Will you post your codes in jsfiddle.. i will try to debug it and add some codes..
Thanks ..

Rendering Problem with Swing App and Modal Dialogs

I have a Java/Swing desktop application (Java 6u16 on Windows XP) which occasionally appears to the users to hang. I say appears to because in reality what is happening is that the application is showing a modal dialog but this dialog is not being rendered. If the user uses Alt-Tab to switch away from the application and then subsequently returns to it, the dialog gets rendered correctly. Additionally, if a remote user connects to the session via NetOp (a VNC/Remote Desktop workalike) this also causes the GUI to be redrawn correctly.
The app runs via JavaWebstart. Since I've heard of rendering issues being caused by DirectDraw, I added the following to the JNLP
<property name="sun.java2d.noddraw" value="true"/>
but the problem still occurs (If I have understood correctly, this will switch off DirectDraw and Direct3d completely: see http://download.oracle.com/javase/1.5.0/docs/guide/2d/flags.html#noddraw)
I'm out of ideas on this one, any suggestions would be greatly appreciated.
Thanks,
Phil
Edit...
I have an abstract dialog class which extends JDialog and which all other dialogs extend. It contains the following method:
public void showDialog() {
initKeyBindings();
Application.getApplication().deactivateScannerListener();
setVisible(true);
}
Whenever I want to display a dialog, I call showDialog(). The initKeyBindings method sets up an ActionMap while the second line is application specific (Application is a singleton, I'm disabling the JPOS scanner listener while the dialog is displaying).
There is a corresponding hideDialog() method as follows:
public void hideDialog() {
setVisible(false);
Application.getApplication().activateScannerListener();
dispose();
}
Thanks,
Phil
Edit...
Sorry about this, one more edit: all of the dialogs have a parent. The AbstractDialog class will default to the main application frame if no other parent is specified.
FYI
For anyone following this, I've added the following to my code:
if (SwingUtilities.isEventDispatchThread()) {
initialiseAndShowDialog();
} else {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
initialiseAndShowDialog();
}
});
}
This ensures that the dialog is only opened from the EDT.
Which thread are you calling showDialog() from? Swing components should be accessed on the Event Dispatch Thread only.
You could try SwingUtilities.invokeAndWait()
and the Runnable argument passed to it should call showDialog().
Let us know if it fixed the problem.

Applet with JDialog not hiding correctly in Mac OSX

I have an applet that calls a JDialog that contains a JProgressBar component. I subclass the JDialog to expose a method to update the JProgressBar, something like:
public class ProgressDialog extends javax.swing.JDialog {
public void setProgress(double progress) {
jProgressBar1.setValue(jProgressBar1.getMinimum() + (int) (progress * jProgressBar1.getMaximum()));
}
...
}
I use this dialog in the following manner:
public void test() throws Exception {
progressDialog = new ProgressDialog(null, true);
try {
progressDialog.setLocationRelativeTo(null);
// show the dialog
EventQueue.invokeLater(new Runnable() {
public void run() {
progressDialog.setVisible(true);
}
});
// business logic code that calls progressDialog.setProgress along the way
doStuff();
} finally {
progressDialog.setVisible(false);
progressDialog.dispose();
}
}
It works fine on Windows/any browser. However, when invoking the above function on Firefox 2/3/3.5 on a Mac, the progressDialog is displayed indefinitely, i.e. it doesn't close.
I suspected that calling setVisible(true) inside the EventQueue was causing the problem, since it's a blocking call and might block the queue completely, so I tried changing it to:
// show the dialog
new Thread() {
public void run() {
progressDialog.setVisible(true);
}
}.start();
With this change, the progressDialog now closes correctly, but a new problem emerged - the contents of the dialog (which included the progressbar, an icon and a JLabel used to show a message string) were no longer shown inside the dialog. It was still a problem only on Mac Firefox.
Any ideas? I realize it's probably some AWT threading issue, but I've been at this for a couple of days and can't find a good solution. Wrapping the doStuff() business logic in a separate new Thread seems to work, but it's not easy to refactor the actual business logic code into a separate thread, so I'm hoping there's a simpler solution.
The envt is:
Mac OSX 10.5
Java 1.5
Firefox 2/3/3.5
Found out that the problem was that the applet function was executing inside the AWT dispatcher thread, therefore the thread blocks and no events are processed until the applet function finishes execution.
Solution was to move the processing logic into a separate thread spawned by the ProgressDialog object before calling setVisible(true). setVisible(true) would block the main thread but still allow the event dispatcher to continue processing, hence rendering the contents of the dialog until the spawned thread calls setVisible(false) to hide the dialog.

Categories