java.lang.StackOverflowError while using LWJGL's Keyboard class - java

I have been trying to implement a Keyboard class into my game and received the exception below. This is just a snippet. The full exception goes on for ages longer than this.
Exception in thread "main" java.lang.StackOverflowError
at org.lwjgl.opengl.DisplayMode.<init>(DisplayMode.java:63)
at oregon.client.Oregon.<init>(Oregon.java:10)
at oregon.src.Controller.<init>(Controller.java:9)
at oregon.client.Oregon.<init>(Oregon.java:12)
at oregon.src.Controller.<init>(Controller.java:9)
at oregon.client.Oregon.<init>(Oregon.java:12)
at oregon.src.Controller.<init>(Controller.java:9)
Here's the code for the main class (oregon.client.Oregon):
package oregon.client;
import oregon.src.Controller;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class Oregon {
public DisplayMode normal = new DisplayMode(640, 640);
public Controller controls = new Controller();
public boolean fullscreen = false;
public void start() {
try {
create();
} catch (LWJGLException e) {
stop(e);
}
while (!Display.isCloseRequested()) {
events();
Display.update();
}
Display.destroy();
}
public void events() {
try {
controls.getInput();
} catch (LWJGLException e) {
stop(e);
}
}
public void setFullscreen() {
try {
if (!fullscreen) {
Display.setFullscreen(true);
fullscreen = true;
} else if (fullscreen) {
Display.setDisplayMode(normal);
fullscreen = false;
}
} catch (LWJGLException e) {
stop(e);
}
}
public void create() throws LWJGLException {
if (fullscreen) {
Display.setFullscreen(true);
} else if (!fullscreen) {
Display.setDisplayMode(normal);
}
Display.create();
}
public void stop() {
System.exit(0);
Display.destroy();
}
public void stop(Exception e) {
e.printStackTrace();
System.exit(0);
Display.destroy();
}
public static void main(String args[]) {
Oregon oregon = new Oregon();
oregon.start();
}
}
And here's the code for my keyboard class:-
package oregon.src;
import oregon.client.Oregon;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
public class Controller {
public Oregon oregon = new Oregon();
public void getInput() throws LWJGLException {
while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
if (Keyboard.getEventKey() == Keyboard.KEY_F11) {
oregon.setFullscreen();
}
}
}
}
}
If there is an expert out the with LWJGL, could you please help me out? Thank you and I hope I do get some help. :D

Nothing to do with LWJGL. Stack overflows in simple code are always because of accidental infinite loops. You have one: Controller tries to create an Oregon (this line: public Oregon oregon = new Oregon();), which then tries to create a Controller, which tries to... (etc..)

When you create an Oregon instance, it creates a Controller instance, which creates an Oregon instance, which creates a Controller instance, which creates an...
What you should probably be doing is not creating an Oregon instance in your controller, but passing your existing instance as a parameter to the Controller constructor and storing that (or the other way around).
Pseudo code:
public Oregon() {
controller = new Controller(this);
...
}
public Controller(Oregon oregon) {
this.oregon = oregon;
...
}

Related

Java StackOverflowError when I try to use Multithreading

I Wanted to print the 2 statements from the payFees class while the getReceipt class waits for the execution of the payFees class and vice versa with the getReceipt class and admissionCompleted class using Multithreading
It shows the java.lang.StackOverflowError.
But when I try to Initalise all the objects of these classes and call the start() and join(), It works perfectly.
Please Help.
package codes;
class payFees extends Thread
{
public payFees()
{
this.start();
getReceipt g= new getReceipt();
g.start();
}
public void run()
{
try
{
System.out.println("Withdraw Amount");
Thread.sleep(1000);
System.out.println("Fees Paid");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
class getReceipt extends Thread
{
payFees p=new payFees();
public void run()
{
try
{
p.join();
System.out.println("Ask for Receipt");
Thread.sleep(1000);
System.out.println("Receipt collected");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
class admissionCompleted extends Thread
{
public static void main(String args[])
{
new payFees();
getReceipt g=new getReceipt();
try
{
g.join();
System.out.println("Wait for confirmation");
Thread.sleep(1000);
System.out.println("Successfully completed admission process");
}
catch(Exception e)
{
System.out.println(e);
}
}
}

While loop not working when running it in thread

So basically i tried to get this while loop to run inside this thread, it should activate when "activate" evaluates to true but for some reason it is not working.
"activate" is boolean value which activates when user presses mouse button (i setted up listener for that). If anyone wonders im using jnativehook library for this project. Any help or explanation would be greatly appreciated.
private boolean activate;
private Robot robot;
#Override
public void run() {
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
while(true) {
if (activate == true) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(100);
}
}
}
activate is never set to true.
If you don't believe me then add this line at the bottom of your while loop:
System.out.println("activate = " + activate);
One possibility is that the compiler (either the Java compiler, or the JIT compiler) has decided that it does not need to test activate because it can prove that nothing inside the while loop ever changes it. In most compiled programming languages, the compiler is allowed to assume that the code will be single threaded unless you do something special to tell it otherwise. That assumption is justified because it enables the compiler to generate much more efficient code most of the time.
Accessing the variable from within a synchronized block, or declaring the variable to be volatile would prevent the compiler from making that assumption.
Better still would be to use a private final AtomicBoolean activate;.
// Here is the sample program which should run your method correctly. All the changes
// are commented upon. Don't judge harshly, not a professional with java
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.Scanner;
class Processor extends Thread {
// Have to initialize the variable here
private boolean activate = true;
private Robot robot;
public void run() {
try {
robot = new Robot();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// No need for while (true) here
while (activate) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(100);
}
}
// method to stop the program
public void shutdown() {
activate = false;
}
}
public class App {
public static void main(String[] args) throws AWTException, InterruptedException, NullPointerException {
// activates the process
Processor p = new Processor();
p.start();
// Press any key to stop the process
// program will run endlessly until scanner value (key input) is provided
Scanner key_input = new Scanner(System.in);
key_input.nextLine();
p.shutdown();
}
}
Thanks for all suggestion fixed the problem by passing class instance to my MouseListener class.
For anyone that gets same problem:
public boolean activate;
public boolean toggled;
private Robot robot;
public MouseListener mouseListener = new MouseListener();
public KeyboardListener keyListener = new KeyboardListener();
public static Game instance;
public Game() {
this.activate = false;
// this.toggled = false;
try {
GlobalScreen.registerNativeHook();
GlobalScreen.isNativeHookRegistered();
GlobalScreen.addNativeMouseListener(mouseListener);
GlobalScreen.addNativeKeyListener(keyListener);
} catch (NativeHookException e) {
e.printStackTrace();
}
}
public void run() {
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
while(true) {
try {
Thread.sleep(1L);
if(Game.this.isActivate()) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public boolean isActivate() {
return activate;
}
public void setActivate(boolean activate) {
this.activate = activate;
}
public boolean isToggled() {
return toggled;
}
public void setToggled(boolean toggled) {
this.toggled = toggled;
}
**public static Game getGame() {
if(Game.instance == null) {
Game.instance = new Game();
}
return Game.instance;
}**
Here is the class that changes "activate" to "true".
public void nativeMouseClicked(NativeMouseEvent e) {
// nothing
}
public void nativeMousePressed(NativeMouseEvent e) {
if(e.getButton() == NativeMouseEvent.BUTTON1) {
Game.getGame().setActivate(true);
}
}
public void nativeMouseReleased(NativeMouseEvent e) {
if(e.getButton() == NativeMouseEvent.BUTTON1) {
Game.getGame().setActivate(false);
}
}
}

why the first compiles but second doesn't

import static java.lang.System.*;
import java.io.*;
public class ExceptionDemo {
public static void main(String args[]) {
try {
int x = 5/0;
}finally {
System.out.print("exception ");
}
}
}
import static java.lang.System.*;
import java.io.*;
public class ExceptionDemo {
public static void main(String args[]) {
try {
throw new Exception();
} finally {
System.out.print("exception ");
}
}
}
You have two choices here :
Either catch the exception you're throwing :
public static void main(String args[]) {
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.print("exception ");
}
}
Either make your method throw it :
public static void main(String args[]) throws Exception {
try {
throw new Exception();
} finally {
System.out.print("exception ");
}
}
But you have to handle it anyway. My own preference being catching it and handling it directly.

Cant access variable that was initialized in try/catch statment

I am making a sound class for my game and after trying and trying i cant seem to get rid of the NullPointerException. This is happening because I cant access a variable in a try/catch statement.
Here is the code:
package util;
import java.applet.*;
import java.net.URL;
public class Sound
{
private AudioClip audio;
private URL file;
public Sound(String srcfile)
{
try
{
this.file = new URL(srcfile);
}
catch(Exception e){}
this.audio = Applet.newAudioClip(file);
}
public void Play()
{
this.audio.play();
}
public void Loop()
{
this.audio.loop();
}
public void Stop()
{
this.audio.stop();
}
public AudioClip getAudio()
{
return audio;
}
public void setAudio(AudioClip audio)
{
this.audio = audio;
}
}
Here is the error(no longer getting):
Exception in thread "main" java.lang.NullPointerException
at sun.applet.AppletAudioClip.<init>(Unknown Source)
at java.applet.Applet.newAudioClip(Unknown Source)
at util.Sound.<init>(Sound.java:19)
at main.Blocks.run(Blocks.java:38)
at main.Blocks.main(Blocks.java:26)
After revising the old code her is the new code:
package util;
import java.applet.*;
import java.net.URL;
public class Sound
{
private AudioClip audio;
public Sound(String srcfile)
{
try
{
this.audio = Applet.newAudioClip(new URL("file://" + srcfile));
}
catch(Exception e)
{
Log.log(e.getMessage(), Log.ERROR);
e.printStackTrace();
System.exit(1);
}
}
public void Play()
{
this.audio.play();
}
public void Loop()
{
this.audio.loop();
}
public void Stop()
{
this.audio.stop();
}
public AudioClip getAudio()
{
return audio;
}
public void setAudio(AudioClip audio)
{
this.audio = audio;
}
}
I am calling
Play();
but nothings happening
Here is how I'm calling the method:
Sound snd = new Sound("res/dev/sound.wav");
snd.Play();
Any help would be appreciated.
It doesn't look like from the way your class is designed that there's any need for the file variable to exist outside the constructor. Something like this would probably serve well:
public Sound(String srcfile) {
try {
this.audio = Applet.newAudioClip(new URL(srcfile));
}
catch(Exception e){
//at least print the stack trace
e.printStackTrace();
//do some proper exception handling that makes sense for you app!
}
}

javazoom Player wont work on Windows with SHOUTcast stream (says invalid Https Request)

I'm writing a small app to play a shoutcast stream, and I am using javazoom.jl.player.Player to do this. Here is my code:
package music;
import java.io.InputStream;
import java.net.URL;
import javazoom.jl.player.Player;
class audiostream extends Thread {
private Player mediafilePlayer;
private volatile boolean shouldPlay = true;
#Override
public void run() {
while (true) {
if (shouldPlay) {
player();
}
}
}
public void player() {
try {
URL mediafile = new URL("http://hi1.streamingsoundtracks.com:8000/;");
InputStream stream = mediafile.openStream();
mediafilePlayer = new Player(stream);
mediafilePlayer.play();
} catch (Exception e) {
System.out.println(e);
}
}
public void pause() {
shouldPlay = false;
mediafilePlayer.close();
}
public void play() {
shouldPlay = true;
}
}
This works perfectly fine on my Mac and I can hear the stream. However on Windows when I try to run this I get the error "java.io.IOException: Invalid Http response". I believe this is because SHOUTcast returns icy 200 ok headers wherein something on Windows must want it to return http headers. I can't seem to find how to make it accept these different headers on windows using javazoom Player.
I ended up solving this issue by using BasicPlayerListener instead. I replaced the code in my question with the following:
package music;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jlgui.basicplayer.BasicController;
import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerEvent;
import javazoom.jlgui.basicplayer.BasicPlayerException;
import javazoom.jlgui.basicplayer.BasicPlayerListener;
public class audiostream implements BasicPlayerListener, Runnable {
public String streamurl;
public BasicController playerControl;
private volatile boolean shouldPlay = true;
#Override
public void run() {
while (true) {
if (shouldPlay) {
player();
}
}
}
// ** RUN ONCE TO START THREAD
public void start() {
new Thread(this).start();
}
// ** RUN TO PAUSE/STOP THE PLAYER
public void pause() {
// set play bool to false
shouldPlay = false;
// stop player
try {
playerControl.stop();
} catch (BasicPlayerException ex) {
Logger.getLogger(audiostream.class.getName()).log(Level.SEVERE, null, ex);
}
}
// ** RUN TO PLAY
public void play() {
shouldPlay = true;
}
// construct
public audiostream(String givenStreamurl) {
// assign the radio url
streamurl = givenStreamurl;
}
// OPENS UP THE SHOUTCAST STREAM
public void player() {
// dont allow multiple runnings of this
shouldPlay = false;
// start stream
try {
BasicPlayer player = new BasicPlayer();
playerControl = (BasicController) player;
player.addBasicPlayerListener(this);
try {
playerControl.open(new URL(streamurl));
} catch (MalformedURLException ex) { }
playerControl.play();
} catch (BasicPlayerException ex) { }
}
#Override
public void opened(Object o, Map map) {
//System.out.println("opened : "+map.toString());
}
#Override
public void progress(int i, long l, byte[] bytes, Map map) {
//System.out.println("opened : "+map.toString());
}
#Override
public void stateUpdated(BasicPlayerEvent bpe) {
//System.out.println("opened : "+bpe.toString());
}
#Override
public void setController(BasicController bc) {
//System.out.println("opened : "+bc.toString());
}
}

Categories

Resources