问题描述
我有一个使用Gradle文件构建的javafx项目,我正在编写Intellij中的所有东西。其中,我使用javafx.scene.media.Media和javafx.scene.media.MediaPlayer播放音乐。
public SoundPlayer(String filename){
String soundLocation =\\src\\main\\resources\\sound\\+ fileName;
字符串绝对=新文件()。getAbsolutePath()+ soundLocation;
System.out.println(绝对);
Media soundMedia = new Media(new File(absolute).toURI()。toString());
mediaPlayer =新MediaPlayer(soundMedia);
}
我一直在做的项目目录是:
src /
| --- main /
| - - | --- java /
| --- | --- | --- sound.SoundPlayer
| --- | ---资源/
| --- | --- | ---声音/
| --- | --- | --- | --- click.mp3
| --- | --- |但是,当我去编译并将它变成一个jar文件时,Gradle将目录改成了这个(在jar中文件,顶层):
声音/ b
$ b
| - SoundPlayer.class $ / $>
| --- click.mp3
| --- bgm.mp3
这使得它抛出了媒体异常:MEDIA UNAVAILABLE。我尝试将文件更改为以下两种:
Media soundMedia = new Media(new File(sound \ \+ fileName).toURI()。toString());
和
Media soundMedia = new Media(new File(fileName).toURI()。toString());
...但我总是得到相同的异常。发生了什么事?
Gradle做的是完全可以预料的。 src / main / java 和 src / main / resources 目录分别存储代码和资源。资源文件夹包含所有非java代码,如图像,声音等。
在创建jar文件时,resources目录的内容将被原样复制(维护封装结构)。请注意, click.mp3 和 bgm.mp3 是声音包的成员。
SoundPlayer 具有相同的包,即
声音
,所以您可以使用 SoundPlayer
类来加载如下资源: public SoundPlayer(String filename){
URL资源= SoundPlayer.class.getResource(filename);
Media soundMedia = new Media(resource.toExternalForm());
mediaPlayer =新MediaPlayer(soundMedia);
}
来自Javadocs
实际上,toExternalForm()函数会创建给定资源的适当URL。
这是一个完整的例子。
apply plugin:'application'
sourceCompatibility ='1.8'
[compileJava,compileTestJava] * .options * .encoding ='UTF-8'
mainClassName ='sound.Main'
储存库{
mavenCentral()
$ b $ dependencies {
testCompile group:'junit',name:'junit',version:'4.10'
}
jar { manifest {attributes'Main-Class':'sound.Main'}}
和修改过的SoundPlayer
// sound.SoundPlayer
封装声音;
import java.net.URL;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class SoundPlayer {
private MediaPlayer mediaPlayer;
public SoundPlayer(String filename){
URL resource = SoundPlayer.class.getResource(filename);
Media soundMedia = new Media(resource.toExternalForm());
mediaPlayer =新MediaPlayer(soundMedia);
}
public void play(){
mediaPlayer.play();
和使用SoundPlayer的Main类
// sound.Main
//这个类实际上并不创建JavaFX UI。相反,它是
//只创建一个JavaFX应用程序来使用Media
包装声音;
import javafx.application.Application;
import javafx.stage.Stage;
/ **
*
* @author aga53
* /
public class Main extends Application {
/ * *
* @param args命令行参数
* /
public static void main(String [] args){
launch(args);
}
@Override
public void start(Stage primaryStage)throws Exception {
SoundPlayer s = new SoundPlayer(test.mp3);
System.out.println(Hello World);
s.play();
}
}
I have a javafx project I'm building using a Gradle file, and I'm writing everything in Intellij. In it, I use javafx.scene.media.Media and javafx.scene.media.MediaPlayer to play some music.
public SoundPlayer(String filename) {
String soundLocation = "\\src\\main\\resources\\sound\\" + fileName;
String absolute = new File("").getAbsolutePath() + soundLocation;
System.out.println(absolute);
Media soundMedia = new Media(new File(absolute).toURI().toString());
mediaPlayer = new MediaPlayer(soundMedia);
}
The project directory I had been working out of was:
src/
|---main/
|---|---java/
|---|---|---sound.SoundPlayer
|---|---resources/
|---|---|---sound/
|---|---|---|---click.mp3
|---|---|---|---bgm.mp3
however, when I went to compile and turn it into a jar file, Gradle changed the directory into this (within the jar file, top level):
sound/
|---SoundPlayer.class
|---click.mp3
|---bgm.mp3
That made it throw a Media Exception: MEDIA UNAVAILABLE. I've tried changing the file to both of the following:
Media soundMedia = new Media(new File("sound\\" + fileName).toURI().toString());
and
Media soundMedia = new Media(new File(fileName).toURI().toString());
... but I always get the same exception. What's going on?
What Gradle did is completely expected. The src/main/java and src/main/resources directories store code and resources respectively. The resources folder contains all the non-java code like images,sound etc.
When creating the jar file, the contents of the resources directory will be copied as is (maintaining the package structure). Note that click.mp3 and bgm.mp3 are members of the sound package.
So, when you want to load a resource, it should (generally) not be done using file paths. Instead use, package structure to do so. Here, as the sounds and SoundPlayer
have the same package, i.e. sound
, you can use the SoundPlayer
class to load resources like following:
public SoundPlayer(String filename) {
URL resource = SoundPlayer.class.getResource(filename);
Media soundMedia = new Media(resource.toExternalForm());
mediaPlayer = new MediaPlayer(soundMedia);
}
From Javadocs
In essence, the toExternalForm() function creates the appropriate URL for a given resource.
Here is a complete example.
// build.gradle
apply plugin: 'java'
apply plugin: 'application'
sourceCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
mainClassName = 'sound.Main'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.10'
}
jar { manifest { attributes 'Main-Class': 'sound.Main' } }
and the modified SoundPlayer
//sound.SoundPlayer
package sound;
import java.net.URL;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class SoundPlayer {
private MediaPlayer mediaPlayer;
public SoundPlayer(String filename) {
URL resource = SoundPlayer.class.getResource(filename);
Media soundMedia = new Media(resource.toExternalForm());
mediaPlayer = new MediaPlayer(soundMedia);
}
public void play(){
mediaPlayer.play();
}
}
and the Main class to use SoundPlayer
// sound.Main
// This class does not actually create a JavaFX UI. Instead, it is
// only creating a JavaFX application to use Media
package sound;
import javafx.application.Application;
import javafx.stage.Stage;
/**
*
* @author aga53
*/
public class Main extends Application{
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
SoundPlayer s = new SoundPlayer("test.mp3");
System.out.println("Hello World");
s.play();
}
}
这篇关于如何使用Gradle访问Java项目中的资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!