2

I'm making a game, and upon exporting the game to a .jar file, I stumbled upon a problem: I can't make the sound play.

I have made lot of research about this, and I'm starting to think this is some problem with JAVA. I also realized that I'm not the only one with this problem, but there was no answer provided to those people that could help me.

I studied the difference between getClass() and getClassLoader(), and tryed both cases, but still nothing. But The problem is not about loading the resources anyway, it is about the sound not playing, even though it loads.

The game plays nicely, loading all the sprites, but nothing of sound.

During my research about this, I learned the I could execute the game using "java -jar file.jar" on command, and the sound started to work. However this doesn't sound like a good option for me, since I have the intention of distributing the game.

Here is a test I made, that shows exactly what I'm talking about. You can add any image and sound, and test it by your selves.

package testando;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Testando extends JFrame {

    private final LineListener myLineListener;

    public Testando() { 
        super();
        setLayout( new BorderLayout() );

        setBounds( 200, 200, 500, 500 );
        myLineListener = new MyLineListener();
        MultiSound multiSoundPanel = new MultiSound();

        addWindowListener( new WindowAdapter() {
            @Override public void windowClosing( WindowEvent e ) {
                System.exit( 0 );
            }
        });

        add( multiSoundPanel );


    }

    private class MultiSound extends JPanel {

        final BufferedImage desertImage;

        MultiSound(){
            super( null, true );
            final AudioInfo audioInfos = new AudioInfo( "testando/Iron_Click.wav" );

            addMouseListener( new MouseListener() {
                final AudioInfo audioInfo = audioInfos;

                @Override
                public void mousePressed( MouseEvent e ) {

                    Sound sound = new Sound( audioInfo );
                    new Thread(sound).start();

                }

                @Override public void mouseClicked( MouseEvent e ) {}
                @Override public void mouseReleased( MouseEvent e ) {}
                @Override public void mouseEntered( MouseEvent e ) {}
                @Override public void mouseExited( MouseEvent e ) {}
            });

            java.net.URL streamURL = Thread.currentThread().getContextClassLoader().getResource( "testando/Desert.jpg" );

            BufferedImage desertImagebuff = null;
            try {
                desertImagebuff = ImageIO.read( streamURL );
            }
            catch ( IOException ex ) {
                StringBuilder sb = new StringBuilder(ex.toString());
                for (StackTraceElement ste : ex.getStackTrace()) {
                    sb.append("\n\tat ");
                    sb.append(ste);
                }
                String trace = sb.toString();

                JOptionPane.showMessageDialog( null, trace, "ERROR", JOptionPane.INFORMATION_MESSAGE);
                System.exit( -1 );
            }

            desertImage = desertImagebuff;
        }

        @Override
        protected void paintComponent( Graphics g ) {
            super.paintComponent( g ); //To change body of generated methods, choose Tools | Templates.

            Graphics2D g2 = (Graphics2D)g.create();

            Rectangle rect = getVisibleRect();
            double desSx = ((rect.width*1.0d)/desertImage.getWidth());
            double desSy = ((rect.height*1.0d)/desertImage.getHeight());

            //To keep the image scalled to the panel;
            AffineTransform scale = AffineTransform.getScaleInstance( desSx, desSy );
            AffineTransformOp transformer = new AffineTransformOp( scale, null );
            g2.drawImage( desertImage, transformer , rect.x, rect.y );
            g2.dispose();
        }

    }

    private class AudioInfo {

        final AudioFormat audioFormat;
        final int size;
        final byte[] audio;
        final DataLine.Info info;

        AudioInfo( String path ){

            java.net.URL streamURL = Thread.currentThread().getContextClassLoader().getResource( path );


            AudioFormat toAudioFormat = null;
            int toSize = -1;
            byte[] toByte = null;
            DataLine.Info toInfo = null;

            try {

                InputStream stream = new BufferedInputStream( streamURL.openStream() );

                AudioInputStream audioInputStream   = AudioSystem.getAudioInputStream( stream );
                toAudioFormat                       = audioInputStream.getFormat();
                toSize                              = (int) ( toAudioFormat.getFrameSize() * audioInputStream.getFrameLength() );
                toByte                              = new byte[toSize];
                toInfo                              = new DataLine.Info(Clip.class, toAudioFormat, toSize);

                audioInputStream.read(toByte, 0, toSize);

            }
            catch ( UnsupportedAudioFileException | IOException ex ) {
                StringBuilder sb = new StringBuilder(ex.toString());
                for (StackTraceElement ste : ex.getStackTrace()) {
                    sb.append("\n\tat ");
                    sb.append(ste);
                }
                String trace = sb.toString();

                JOptionPane.showMessageDialog( null, trace, "ERROR", JOptionPane.INFORMATION_MESSAGE);
                System.exit( -1 );
            }

            audioFormat = toAudioFormat;
            size = toSize;
            audio = toByte;
            info = toInfo;
        }
    }

    private class MyLineListener implements LineListener {

        @Override
        public void update( LineEvent event ) {

            if ( event.getType( ) == LineEvent.Type.STOP )
                event.getLine().close();

        }

    }

    private class Sound implements Runnable {

        private final Clip sound;

        Sound( AudioInfo audioInfo ){

            AudioFormat audioFormat = audioInfo.audioFormat;
            int size = audioInfo.size;
            byte[] audio = audioInfo.audio;
            DataLine.Info info = audioInfo.info;

            Clip clip = null;

            try {
                clip = (Clip) AudioSystem.getLine( info );
                clip.open( audioFormat, audio, 0, size );
                clip.addLineListener( myLineListener );
            }
            catch ( LineUnavailableException ex ) {
                clip = null;
            }

            sound = clip;
        }

        @Override
        public void run() {
            sound.start();
        }

    }

    public static void main( String[] args ) {

        Testando testando = new Testando();
        testando.setVisible( true );
    }

}

I also compiled the executable version with the source code with it if you wish to analize it better. https://www.dropbox.com/s/328dr47i39vbart/testando_dist.zip

I don't know if it is usefull, but I'm using NetBeans 7.4.

Can somebody help me please?

Thank you in advance, saclyr.

saclyr
  • 161
  • 5
  • "*During my research about this, I learned the I could execute the game using `java -jar file.jar` on command, and the sound started to work*" I also used something like `java -cp testando.jar testando.Testando` and it also works (after few seconds where sound needs to be loaded). Can we know how are you running your application when sound doesn't work? – Pshemo Jun 07 '14 at 11:18
  • The sound doesn't run when I just execute the jar file by double-clicking (normal execution). – saclyr Jun 07 '14 at 11:26
  • That is indeed strange, it works fine for me. Maybe you need to reinstall your JRE? Also take a look at http://stackoverflow.com/questions/394616/running-jar-file-in-windows (accepted answer seems to be about WindowsXP so take a look at other answers if you have other OS). – Pshemo Jun 07 '14 at 12:09
  • My OS is Windows 7 Home Premium (64bits), and for the JRE, I desinstalled the old one and I reinstalled a more recent one (JRE 7u60-windows-x64), but still no sound. It's weird, maybe if I install the 32bits version. I'm also thinking in reinstalling the JDK. I will something later. – saclyr Jun 07 '14 at 20:33
  • This is weird indeed. I asked my father to try it on his computer and the sound works. Is it because I'm using JRE of 64bits? – saclyr Jun 07 '14 at 20:43

1 Answers1

0

I just found out why there is no sound.

I tryed lots of tings, including updating both the JDK and JRE, but still nothing. I tryed to install the JRE of 32bits, but still nothing, but after unistalling the 64bits version, I started to get the sound.

The game is fine now, but for some reason it does not work with 64bits.

The problem is with the 64bits version.

saclyr
  • 161
  • 5