简体   繁体   English

程序完全在Eclipse中运行,但是当导出为可运行的JAR文件时无法运行

[英]Program runs completely in Eclipse but does not run when exported as a Runnable JAR file

I have a main class that looks like this: 我有一个主班,看起来像这样:

package complete;

import java.io.File;
import java.io.*;
import javax.sound.sampled.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JFrame;

public class Main {

public static void main(String[] args) {
    JFrame frame = new JFrame("Presentation");
    frame.setSize(806, 506);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.add(new GameFrame());
    frame.setVisible(true);
sound = new File("Assets/BackgroundSound.wav"); // Write you own file location here and be aware that it need to be an .wav file

    new Thread(play).start();
}

static File sound;
static boolean muted = false; // This should explain itself
static float volume = 100.0f; // This is the volume that goes from 0 to 100
static float pan = 0.0f; // The balance between the speakers 0 is both sides and it goes from -1 to 1

static double seconds = 0.0d; // The amount of seconds to wait before the sound starts playing

static boolean looped_forever = true; // It will keep looping forever if this is true

static int loop_times = 0; // Set the amount of extra times you want the sound to loop (you don't need to have looped_forever set to true)
static int loops_done = 0; // When the program is running this is counting the times the sound has looped so it knows when to stop

final static Runnable play = new Runnable() // This Thread/Runnabe is for playing the sound
{
    public void run()
    {
        try
        {
            // Check if the audio file is a .wav file
            if (sound.getName().toLowerCase().contains(".wav"))
            {
                AudioInputStream stream = AudioSystem.getAudioInputStream(sound);

                AudioFormat format = stream.getFormat();

                if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED)
                {
                    format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                            format.getSampleRate(),
                            format.getSampleSizeInBits() * 2,
                            format.getChannels(),
                            format.getFrameSize() * 2,
                            format.getFrameRate(),
                            true);

                    stream = AudioSystem.getAudioInputStream(format, stream);
                }

                SourceDataLine.Info info = new DataLine.Info(
                        SourceDataLine.class,
                        stream.getFormat(),
                        (int) (stream.getFrameLength() * format.getFrameSize()));

                SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(stream.getFormat());
                line.start();

                // Set Volume
                FloatControl volume_control = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
                volume_control.setValue((float) (Math.log(volume / 100.0f) / Math.log(10.0f) * 20.0f));

                // Mute
                BooleanControl mute_control = (BooleanControl) line.getControl(BooleanControl.Type.MUTE);
                mute_control.setValue(muted);

                FloatControl pan_control = (FloatControl) line.getControl(FloatControl.Type.PAN);
                pan_control.setValue(pan);

                long last_update = System.currentTimeMillis();
                double since_last_update = (System.currentTimeMillis() - last_update) / 1000.0d;

                // Wait the amount of seconds set before continuing
                while (since_last_update < seconds)
                {
                    since_last_update = (System.currentTimeMillis() - last_update) / 1000.0d;
                }

                //System.out.println("Playing!");

                int num_read = 0;
                byte[] buf = new byte[line.getBufferSize()];

                while ((num_read = stream.read(buf, 0, buf.length)) >= 0)
                {
                    int offset = 0;

                    while (offset < num_read)
                    {
                        offset += line.write(buf, offset, num_read - offset);
                    }
                }

                line.drain();
                line.stop();

                if (looped_forever)
                {
                    new Thread(play).start();
                }
                else if (loops_done < loop_times)
                {
                    loops_done++;
                    new Thread(play).start();
                }
            }
        }
        catch (Exception ex) { ex.printStackTrace(); }
    }
};



}

When I run the runnable JAR, the frame opens with the correct size and title but with a blank screen. 当我运行可运行的JAR时,框架以正确的大小和标题打开,但屏幕空白。

When I run from the command line I get this error: 当我从命令行运行时,出现此错误:

java.io.FileNotFoundException: Assets\BackgroundSound.wav <The system cannot find the path specified> 

at java.io.FileInputStream.open<Native Method>

at java.io.FileInputStream.<init><Unknown Source>

at com.sun.media.sound.WaveFloatFileReader.getAudioInputStream<Unknown Source>

at javax.sound.sampled.AudioSystem.getAudioInputStream<Unknown Source>

at complete.Main$1.run<Main.Java:50>

at java.lang.Thread.run<Unknown Source>

I have extracted the files from the JAR and all the classes, images and the WAV file are there. 我已经从JAR中提取了文件,并且所有的类,图像和WAV文件都在那里。

When I remove the sound section from the Main class and run in Eclipse, the program runs completely and without sound as expected. 当我从Main类中删除声音部分并在Eclipse中运行时,该程序将完全运行且没有预期的声音。

When I export this version as a Runnable JAR, the same thing happens as before when I attempted to run it, except this time there are no command line errors. 当我将此版本导出为可运行的JAR时,与尝试运行它时发生的事情相同,只是这次没有命令行错误。

要从jar中加载文件,您需要使用getResources或getResourceAsStream。

采用:

sound = new File(Main.class.getResource("Assets/BackgroundSound.wav").getPath());

The data for sound is not contained in a file on your disk directly; sound数据不直接包含在磁盘上的文件中; it is inside the jar file for your project. 它在您的项目的jar文件中。 So, using File to access it is incorrect. 因此,使用File访问它是不正确的。 Instead, use the overloaded AudioStream method: 而是使用重载的AudioStream方法:

public static AudioInputStream getAudioInputStream(InputStream stream)
                                        throws UnsupportedAudioFileException,
                                               IOException

Obtains an audio input stream from the provided input stream. 从提供的输入流中获取音频输入流。 The stream must point to valid audio file data. 流必须指向有效的音频文件数据。 The implementation of this method may require multiple parsers to examine the stream to determine whether they support it. 此方法的实现可能需要多个解析器来检查流,以确定它们是否支持该流。 These parsers must be able to mark the stream, read enough data to determine whether they support the stream, and, if not, reset the stream's read pointer to its original position. 这些解析器必须能够标记流,读取足够的数据以确定它们是否支持该流,如果不能,则将流的读取指针重置为其原始位置。 If the input stream does not support these operation, this method may fail with an IOException. 如果输入流不支持这些操作,则此方法可能会失败,并出现IOException。

You get the InputStream by using Class.getResourceAsStream(String name) . 您可以使用Class.getResourceAsStream(String name)获得InputStream That will look on the class path, and so can be set to work in both Eclipse and from a jar file. 这将在类路径上查找,因此可以设置为在Eclipse和jar文件中均可使用。 Easiest is to move the sound file to be alongside your class file, so you can just use: 最简单的方法是将声音文件移到类文件的旁边,因此您可以使用:

InputStream soundResource = Main.class.getResourceAsStream("BackgroundSound.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(soundResource);

Sorry--I needed to edit the last part--I forgot that this was all in main . 抱歉-我需要编辑最后一部分-我忘了这一切都是main Try not to do that for any but the most trivial programs. 尝试对最琐碎的程序不要这样做。 Instead, instantiate the class and have the instance do things. 而是实例化该类并让实例执行操作。 And rename the class from Main to something like SoundDemo . 并将Main的类重命名为SoundDemo Otherwise in three months you'll say to yourself, "Where did I do that exercise on learning how to have Java play sounds? What file was it in? It was in Main ? Really?" 否则,在三个月内您将对自己说:“我在哪里进行了该练习以学习如何播放Java声音?它在哪个文件中?它在Main吗?真的吗?”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 程序在Eclipse中运行,但是导出的可运行jar文件将无法打开? - Program runs in Eclipse, but exported runnable jar file will not open? Hadoop MapReduce程序在Eclipse中运行良好,但在导出到.jar文件时却无法正常运行 - Hadoop MapReduce program runs fine in Eclipse but not when exported to .jar file 程序在Eclipse中可以正常运行,但是在导出到.jar文件时却不能正常运行 - program runs fine in Eclipse but not when exported to .jar file 导出的日食可运行.jar将无法运行 - Exported eclipse runnable .jar will not run 项目在Eclipse中正常运行,但导出到可运行的jar时无法正常运行 - Project runs normal in Eclipse but doesn't when exported to a runnable jar 我在eclipse上有一个程序,并将其导出为可运行的JAR文件,如何双击运行它? - I have a program on eclipse and exported it as a runnable JAR file, how do I run it on a double click? Java-程序在eclipse中运行完美,但是在导出到可运行的jar时似乎没有完成其预期的任务 - Java - program works perfectly in eclipse but does not seem to do its intended task when exported to runnable jar Java项目在Eclipse上工作但在导出到runnable jar文件时不起作用 - Java project working on Eclipse but not working when exported to runnable jar file 程序在Eclipse中运行,但运行的jar无法运行 - Program runs in Eclipse but running jar does not run 带导出的可运行jar文件的Java Eclipse错误 - Java eclipse error with exported runnable jar file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM