java gradle 资源访问,如何使用Gradle访问Java项目中的资源?

当使用Gradle构建包含JavaFX和资源文件的项目时,资源文件路径会发生改变,导致运行时MediaException。解决方法是利用类路径加载资源,如`SoundPlayer.class.getResource()`,而非直接使用文件路径。这允许在打包成jar后仍能正确加载音乐文件。
摘要由CSDN通过智能技术生成

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

public String toExternalForm()

Constructs a string representation of this URL. The string is created by calling the toExternalForm method of the stream protocol handler for this object.

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();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值