Cant access variable that was initialized in try/catch statment - java

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!
}
}

Related

Java reference from static class

Sorry, this question has probably been asked before, but I couldn't find any with an answer in the context that applies specifically enough to my problem for me to apply the solution.
Anyways, I'm working on a program that uses a file. When that file is updated, I want it to replace the File variable with the current one. I set up a main class that will work with the file, then I set up another class with a different thread that listens for the file update. When the file is updated, I want the variable in the main class to be updated.
That means that the update listener class has to have the instance of the main class, but when I try to send it during initiation of the update listener class, a warning says the main class cannot be referenced from a static context.
Here's the code:
Main Class
package me.xeyler;
import com.sun.media.jfxmedia.logging.Logger;
import javax.swing.*;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
/**
* Created by Brigham on 10/19/2016.
*/
public class ViewerMain {
static FileHandler fileHandler;
static File skinFile;
public static void main(String[] args) {
boolean bool = false;
fileHandler = new FileHandler(this);
fileHandler.start();
while(true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(bool);
}
}
public void setSkinFile(File skinFile) {
this.skinFile = skinFile;
}
}
File Listener Class
package me.xeyler;
import com.sun.media.jfxmedia.logging.Logger;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
/**
* Created by Brigham on 10/19/2016.
*/
public class FileHandler implements Runnable {
private Thread fileThread;
private String threadName;
WatchService watcher = null;
private ViewerMain main;
public FileHandler(ViewerMain main) {
this.main = main;
this.threadName = "FileThread";
}
public void watchFile(Path path) {
}
public void watchFile(File file) {
watchFile(Paths.get(file.getPath()));
}
public void close() {
try {
watcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void start () {
if (fileThread == null) {
System.out.println("Starting new thread...");
fileThread = new Thread (this, threadName);
fileThread.start();
System.out.println("Started thread: " + threadName);
}
}
#Override
public void run() {
System.out.println("Running thread...");
Path dir = Paths.get(System.getProperty("user.home"),"documents");
try {
watcher = FileSystems.getDefault().newWatchService();
WatchKey key = dir.register(watcher,
ENTRY_MODIFY);
} catch (IOException x) {
x.printStackTrace();
}
for (;;) {
// wait for key to be signaled
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
// The filename is the
// context of the event.
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path filename = ev.context();
if (filename.endsWith("text.txt")) {
System.out.println("File has changed");
//TODO: Update File variable in ViewerMain
main.setSkinFile(filename.toFile());
}
}
// Reset the key -- this step is critical if you want to
// receive further watch events. If the key is no longer valid,
// the directory is inaccessible so exit the loop.
boolean valid = key.reset();
if (!valid) {
// TODO: Handle inaccessible directory
break;
}
}
}
}
I suspect the answer is really obvious, but thanks for the patience!
If I understand correctly, you need an instance of the ViewerMain class.
this cannot be applied in a static context.
public static void main(String[] args) {
ViewerMain viewer = new ViewerMain(); // an instance
fileHandler = new FileHandler(viewer);
Same for skinFile
public File skinFile; // Remove static
public void setSkinFile(File skinFile) {
this.skinFile = skinFile;
}
You can not do this:
public void setSkinFile(File skinFile) {
this.skinFile = skinFile;
}
since skinFile is static, it would be better if you set that property as public static File skinFile; and then you accesed the property directly from the FileHandler:
ViewerMain.skinFile = filename.toFile()
given that it is a static property you dont need an instance of the class to access it, you can use the class directly.

converting mp3 to byte in java

I found this code for playing mp3 in java and I want to stream this in a network using UDP so I want to convert the mp3 file to byte so I can send it using DatagramPacket. What should I convert to do this?
I will be needing to send 60Kbyte of buffer to the datagrampacket.
import javazoom.jl.player.advanced.*;
public class JLayerTest
{
public static void main(String[] args)
{
SoundJLayer soundToPlay = new SoundJLayer("Test.mp3");
soundToPlay.play();
}
}
class SoundJLayer extends PlaybackListener implements Runnable
{
private String filePath;
private AdvancedPlayer player;
private Thread playerThread;
public SoundJLayer(String filePath)
{
this.filePath = filePath;
}
public void play()
{
try
{
String urlAsString = "file:\\C:\\Users\\Lorenz Kyle\\Desktop\\CODES by Lo\\Case 4\\Server\\Mp3MulticastServer\\src\\test.mp3";
this.player = new AdvancedPlayer
(
new java.net.URL(urlAsString).openStream(),
javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice()
);
this.player.setPlayBackListener(this);
this.playerThread = new Thread(this, "AudioPlayerThread");
this.playerThread.start();
}
catch (Exception ex)
{
}
}
// PlaybackListener members
public void playbackStarted(PlaybackEvent playbackEvent)
{
System.out.println("playbackStarted");
}
public void playbackFinished(PlaybackEvent playbackEvent)
{
System.out.println("playbackEnded");
}
// Runnable members
public void run()
{
try
{
this.player.play();
}
catch (javazoom.jl.decoder.JavaLayerException ex)
{
ex.printStackTrace();
}
}
}

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

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;
...
}

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());
}
}

wake up a thread from its state using notify

I am desperate...I'm working all the day on a program but I didn't resolve my issue about thread cuncurrency.Please help me.
I have this class which is a generic Item.My problem is when this object enters in wait() it doesn't wake up anymore even if I call on the same object the method putItemToWork().I would know if there is a mistake on the code about cuncurrency because really I don't understand where I make mistakes...
Item Class
import java.io.*;
public class Item implements Serializable
{
private String id;
private String category;
private String machine;
private boolean isWorked;
private String mchTemp = null;
public Item(String id,String category,String machine,boolean isWorked)
{
this.id = id;
this.category = category;
this.machine = machine;
this.isWorked = isWorked;
}
public synchronized void putItemToWork(String id_machine)
{
try
{
System.out.println("Working the item...");
Thread.sleep((long)(1+Math.random()*10000));
}
catch(InterruptedException ie) {ie.printStackTrace(); }
mchTemp = id_machine;
isWorked = true;
notify();
}
public synchronized String getWorkedItem()
{
if(mchTemp == null)
{
try
{
wait();
}
catch(InterruptedException ie) {ie.printStackTrace(); }
}
return mchTemp;
}
public String getId()
{
return this.id;
}
public String getCategory()
{
return this.category;
}
public String getMachine()
{
return this.machine;
}
public boolean isWorked()
{
return this.isWorked;
}
}
}
ServerMultiThread
import java.io.*;
import java.util.*;
import java.net.*;
import javax.swing.SwingUtilities;
import javax.swing.JTextArea;
public class ServerMultiThread implements Runnable
{
Socket socket;
private ServerSocket serverSocket;
private LinkedList<Item> itemsList;
private LinkedList<Machine> machinesList;
private static final boolean listening = true;
private JTextArea output;
public ServerMultiThread(LinkedList<Item> itemsList,LinkedList<Machine> machinesList,JTextArea output)
{
this.itemsList = itemsList;
this.machinesList = machinesList;
this.output = output;
try
{
this.serverSocket = new ServerSocket(8090);
}
catch(IOException ioe){ioe.printStackTrace(); }
new Thread(this, "Server").start();
}
#Override
public void run()
{
Item itemTemp = null;
SwingUtilities.invokeLater(new Runnable(){#Override public void run(){output.append("Server in run!\n");}});
while(listening)
{
try
{
SwingUtilities.invokeLater(new Runnable(){public void run(){output.append("Waiting for incoming connection...\n");}});
socket = serverSocket.accept();
SwingUtilities.invokeLater(new Runnable(){#Override public void run(){output.append("Connected to: "+socket.getInetAddress()+":"+socket.getPort()+"!\n");}});
ObjectOutputStream ous = new ObjectOutputStream(socket.getOutputStream());
synchronized(itemsList)
{
for(Item item : itemsList)
{
if(!item.isWorked())
{
itemTemp = item;
break;
}
}
new ItemHandler(itemTemp,ous,output);
}
}
catch(IOException ioe) {ioe.printStackTrace(); }
}
}
}
ItemHandler
import java.io.*;
import java.util.LinkedList;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class ItemHandler implements Runnable
{
String id_machine;
private Item item;
private ObjectOutputStream ous;
//private ObjectInputStream ois;
private JTextArea output;
public ItemHandler(Item item,ObjectOutputStream ous,JTextArea output)
{
this.item = item;
this.ous = ous;
//this.ois = ois;
this.output = output;
new Thread(this).start();
}
#Override
public void run()
{
try
{
ous.writeObject(item);
SwingUtilities.invokeLater(new Runnable(){public void run(){output.append("Item Handler "+item.getId()+ " in run!\n");}});
id_machine = item.getWorkedItem();
SwingUtilities.invokeLater(new Runnable(){public void run(){output.append("The item "+item.getId()+" was correctly worked by "+id_machine);}});
//System.out.println("The item "+workedItem.getId()+" was correctly worked by "+workedItem.getMachine());
}
catch(IOException ioe){ioe.printStackTrace();}
}
}
MachineApp
import java.io.*;
import java.net.*;
public class MachineApp
{
private Socket socket;
private String id_machine;
public MachineApp(String id_machine)
{
this.id_machine = id_machine;
try
{
this.socket = new Socket("localhost",8090);
System.out.println("Estabilished connection to main server!");
}
catch(UnknownHostException uhe) {uhe.printStackTrace();}
catch(IOException ioe) {ioe.printStackTrace(); }
execution();
}
private void execution()
{
try
{
//ObjectOutputStream ous = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Item item = (Item) ois.readObject();
item.putItemToWork(id_machine);
System.out.println("Item Worked!");
}
catch(ClassNotFoundException cnfe) {cnfe.printStackTrace(); }
catch(IOException ioe) {ioe.printStackTrace(); }
}
public static void main(String[] args)
{
MachineApp machineApp = new MachineApp(args[0]);
}
}
For me your code works just fine. Are you calling wait/notify from different threads:
public static void main(String[] args) {
final Item item = new Item("id", "cat", "mach", false);
Thread retrievalThread = new Thread(new Runnable() {
#Override
public void run() {
item.getWorkedItem();
}
});
Thread puttingThread = new Thread(new Runnable() {
#Override
public void run() {
item.putItemToWork("id");
}
});
retrievalThread.start();
puttingThread.start();
}
EDIT: after client code was added to question:
I could be wrong but you're sending item object via socket and then trying to call getWorkedItem on it. It doesn't work this way because once you've send item thru network object on the other side (even if it's happening in one JVM) that will be different object. Therefore calling notify on it won't trigger wake up from wait.
How to solve it? Well, you can add some kind of query interface to your server code so you could query which items were worked.
If it's no homework, or learning exercise I think that Hadoop can be good fit for your needs
For starters, you're going to need to make mchTemp volatile, because you're writing to this field in one thread, and reading it from another. Without volatile, changes made in one thread may not be visible in another tread.
private volatile String mchTemp = null;

Categories

Resources