简体   繁体   English

在.jar导出中使用.mid文件

[英]Use a .mid file in a .jar export

I'm working on a text-based RPG with some friends using Netbeans. 我正在和一些使用Netbeans的朋友一起开发基于文本的RPG。 It works all fine and dandy in Netbeans but when I export it to a .jar file I get this error. 它在Netbeans中都可以正常工作,但是当我将其导出到.jar文件时,出现此错误。

Jan 28, 2019 2:27:15 PM Operator.DragonsHead startActionPerformed SEVERE: null java.io.FileNotFoundException: File "src\\Operator\\files\\Opening.mid" does not exist! 2019年1月28日2:27:15 PM Operator.DragonsHead startActionPerformed严重:null java.io.FileNotFoundException:文件“ src \\ Operator \\ files \\ Opening.mid”不存在!

This happens when the game starts, as we have a "theme" that plays at boot up. 游戏开始时会发生这种情况,因为我们在启动时会播放一个“主题”。 The song plays on Netbeans but not when exported. 这首歌在Netbeans上播放,但在导出时不播放。

I'm relatively new to Java programming, I took a course on it last year. 我是Java编程的新手,去年我参加了课程。

I've tried looking around the web for people having the same issue, but I can't quite get it to duplicate with my code. 我曾尝试在网上寻找同样问题的人,但是我无法完全将其与我的代码重复。

Here's the midi class: 这是Midi类:

import javax.sound.midi.*;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;

public class MIDI {

private File file = null;
private Sequencer sequencer = null;

public MIDI (String midiFile) throws FileNotFoundException {
    this.file = new File(midiFile);
    if (!file.isFile()) {
        throw new FileNotFoundException("File \"" + midiFile + "\" does not exist!");
    }
            try{
        sequencer = MidiSystem.getSequencer();
        if (sequencer == null){
            System.err.println("Error: Sequencer not supported");
            return;
        }
        sequencer.open();
        Sequence sequence = MidiSystem.getSequence(file);
        sequencer.setSequence(sequence);
    }
    catch (MidiUnavailableException | InvalidMidiDataException | IOException ex){
    }
}

public void play(){
        sequencer.start();
}

public void stop() {
    sequencer.stop();
}

public void waitAndStop(int millis) {
    Runnable song = () -> {
        try {
            Thread.sleep(millis);
        }
        catch (InterruptedException e) {
            System.err.println("MIDI playback interrupted");
        }
        stop();
    };
    Thread t = new Thread(song);
    t.start();
}

public long songLengthMicroseconds() {
    return sequencer.getMicrosecondLength();
}
public Sequence getSequence(String resource) {
    try {
        return MidiSystem.getSequence(new File(resource));
    }
    catch (InvalidMidiDataException | IOException ex) {
        return null;
    }
}

} }

Here's the lines that initialize it and call the song to play: 这是初始化它并调用歌曲播放的行:

    MIDI midiTest;
    midiTest = new MIDI("src\\Operator\\files\\Opening.mid");
    midiTest.play();

I'm not sure what the API is of 'MIDI', but unless you want to go through the rigamarole of writing an installer, you cannot use direct file access for resources like icons, pictures, music, and datafiles. 我不确定“ MIDI”的API是什么,但是除非您想通过编写安装程序的繁琐工作,否则无法对图标,图片,音乐和数据文件等资源使用直接文件访问。

Instead, use the getResource/getResourceAsStream mechanism, which returns URLs/InputStreams. 而是使用getResource / getResourceAsStream机制,该机制返回URL / InputStreams。 Well written libraries take these just as well as files. 编写良好的库会像处理文件一样处理这些。

Basic format: 基本格式:

try (InputStream resource = MyClassName.class.getResourceAsStream("Opening.mid")) {
    // do something with resource here.
}

where Opening.mid is in the exact same place that MyClassName.class is (so, if you are shipping as a jar, it's in the jar, in the same folder structure as myClassName.class. If you prefer to have a root dir 'music' in your jar, you can pass for example: /music/Opening.mid , with the leading slash to indicate you're going off of the jar root. 其中Opening.mid与MyClassName.class的位置完全相同(因此,如果您以jar形式运送,则它位于jar中,与myClassName.class处于同一文件夹结构。如果您希望使用root dir'音乐”在您的jar中,您可以传递例如: /music/Opening.mid ,并使用反斜杠/music/Opening.mid ,以表示您离开了jar根目录。

secondary observation, if you don't know what to do with an exception, best solution is to add the exception(s) you cannot handle to your method's 'throws' line. 次要观察,如果您不知道如何处理异常,最好的解决方案是将无法处理的异常添加到方法的“ throws”行中。 If that is somehow not possible, the proper body for a catch block is: 如果某种不可能,则挡块的合适主体是:

throw new RuntimeException("unhandled checked exception", e);

because right now if an error occurs, your code will silently just keep going. 因为现在如果发生错误,您的代码将默默地继续前进。 If that was your intent (because, hey, music is optional I guess), I'd still log it SOMEWHERE , right now if an error occurs, you just won't know about it. 如果这是你的意图(因为,嘿嘿,音乐是可选的我猜的),我还是会记录它的地方 ,如果发生错误,现在,你是不会知道这一点。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM