Question

In a Java application, how is it possible to output audio in a paint function? I've tried this code:

public static void Player(String audioname){ //For audio
    InputStream in = null;
    try{
        in = new FileInputStream (new File (audioname));
    }
    catch (FileNotFoundException e){
        System.err.print("Audio file not found!");
    }
    try{
        as = new AudioStream (in);
    }
    catch (IOException e){
        System.err.print("AudioStream couldn't be created!");
    }
}
////////////////////////////////////////////////////////////////
try{
    Player(name);
    AudioPlayer.player.start(as);
} catch(Exception f){
    System.err.print("Audio couldn't be played!");
}

...however the player gets caught in the Exception f catch statement. I've also tried placing it in a different place (as a separate method that the paint calls but it still doesn't work. Any help?

Edit:

class playAudio implements Runnable{
    public void run(){
        try{
            Player("countdown.wav");
            AudioPlayer.player.start(as);
        } catch(Exception f){
            System.err.print("Audio couldn't be played!");
        }
    }
}
///////////////////////////////////////
public void paint(Graphics g){ //Draw function
    Graphics2D g2d = (Graphics2D) g;
    ///////////////////////////////////
    Thread audioThrd = new Thread(new playAudio());
    audioThrd.start();
}

Here, I added a thread to play the audio file, but "Audio couldn't be played!" still shows. What am I doing wrong here?

Was it helpful?

Solution

No, never do audio inside of paint. Painting methods are for drawing and drawing only and should be blindingly fast. The slower your paint methods, the less responsive your program will seem to the users. Running audio will create a long-running process, and if this occurred within a paint method, your program's GUI would grind to a halt, not something you want to have happen.

Instead you want to play audio in a background thread off of the Swing event thread. A SwingWorker could work well, but so could any old garden variety thread.


Edit
Regarding this code:

public void paint(Graphics g){ //Draw function
    Graphics2D g2d = (Graphics2D) g;
    ///////////////////////////////////
    Thread audioThrd = new Thread(new playAudio());
    audioThrd.start();
}

Again, don't do this. Please understand that you do not have control over when or even if* paint gets called since this is controlled by the JVM. You can suggest that it be called by calling repaint(), but this is not guaranteed to work, especially if repaint requests "stack" up. Note also that the JVM can call paint when you don't request it such as when the operating system notifies it that one of its windows is "dirty" and needs to be repainted.

So the bottom line is:

DON'T TRY TO PLAY MUSIC FROM WITHIN PAINT OR PAINTCOMPONENT

As for why your code is not playing music, have you implement my printStackTrace() recommendation yet?


Next we'll talk about why you should not do drawing inside of paint(Graphics g) but instead should do your drawing inside of your JComponent's paintComponent(Graphics g) method instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top