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

2024-01-08

我有一个JavaFX https://en.wikipedia.org/wiki/JavaFX我正在使用 Gradle 文件构建项目,并且我正在 IntelliJ 中编写所有内容。在其中,我使用javafx.scene.media.Media and javafx.scene.media.MediaPlayer播放一些音乐。

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

我一直在工作的项目目录是:

src/

|---主/

|---|---java/

|---|---|---声音.SoundPlayer

|---|---资源/

|---|---|---声音/

|---|---|---|---click.mp3

|---|---|---|---bgm.mp3

然而,当我去编译并将其转换为 JAR 文件时,Gradle 将目录更改为以下内容(在 JAR 文件中,顶层):

sound/

|---SoundPlayer.class

|---点击.mp3

|---bgm.mp3

这使得它抛出一个媒体异常:媒体不可用。我尝试将文件更改为以下两个内容:

Media soundMedia = new Media(new File("sound\\" + fileName).toURI().toString());

and

Media soundMedia = new Media(new File(fileName).toURI().toString());

...但我总是遇到同样的例外。这是怎么回事?


Gradle 所做的一切完全在意料之中。这src/主/java and src/主/资源目录分别存放代码和资源。 resources 文件夹包含所有非 Java 代码,如图像、声音等。

创建 JAR 文件时,资源目录的内容将按原样复制(保持包结构)。注意点击.mp3 and bgm.mp3是成员sound包裹。

因此,当您想要加载资源时,(通常)不应该使用文件路径来完成。相反,使用包结构来执行此操作。在这里,随着声音和SoundPlayer有相同的包,即sound,您可以使用SoundPlayer类来加载资源,如下所示:

public SoundPlayer(String filename) {
    URL resource = SoundPlayer.class.getResource(filename);
    Media soundMedia = new Media(resource.toExternalForm());
    mediaPlayer = new MediaPlayer(soundMedia);
}

来自Java文档

公共字符串 toExternalForm() 构造此 URL 的字符串表示形式。该字符串是通过调用该对象的流协议处理程序的 toExternalForm 方法创建的。

本质上,toExternalForm() 函数为给定资源创建适当的 URL。

这是一个完整的例子。

// 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' } }

和修改后的 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();
    }
}

和使用 SoundPlayer 的 Main 类

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

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Gradle 访问 Java 项目中的资源? 的相关文章

随机推荐

  • 减少包含超过 500 个事务的数据表页面的加载时间

    有没有办法仅通过使用数据表来减少 IE 中页面的加载时间 如果我们使用服务器端分页和排序 我们是否也可以在服务器端进行快速搜索 并且仅呈现特定选项卡而不是整个页面
  • 反序列化嵌套 JSON

    我需要一些帮助 我正在尝试反序列化 Json 文件 然后将其添加到列表中 以便我可以将其放入 C 应用程序中的表中 我生成了部分代码 但没有生成嵌套区域 我想计算属性的总数 在 json 中显示为 features 然后我想列出每个属性的
  • 使无边框窗体可移动?

    有没有办法使没有边框 FormBorderStyle 设置为 none 的窗体在鼠标在窗体上单击时可移动 就像有边框一样 This http www codeproject com KB cs csharpmovewindow aspxCo
  • XML 中的 HTML。我应该使用 CDATA 还是编码 HTML [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在使用 XML 来共享 HTML 内容 AFAIK 我可以通过以下方式嵌入 HTML 对其进行编码 我不知道使用它是否完全安全 我必须再次解
  • 为什么允许对角线移动会使 A* 和曼哈顿距离不可接受?

    我对使用 A 和曼哈顿距离度量的网格中的对角线移动有点困惑 有人可以解释为什么使用对角线移动会使其不可接受吗 进行对角线运动不会找到更好的最佳解决方案 因为比上下左右移动更少的步骤即可达到目标状态 还是我错过了一些东西 正如烧杯的评论所指出
  • 使用 jQuery 在 Firefox 中获取自动计算边距

    通过下面的标记和 CSS 我尝试获取计算出的 shell 左边距 section class page title div class shell h5 class title Welcome h5 div section shell zo
  • 为什么案例类仅扩展 Product 而不是 Product1、Product2、...、ProductN?

    当我了解到案例类扩展了 Product 后 我 想知道为什么它们不扩展 ProductN 例如 给出如下代码 case class Foo a Int 我预计Foo 1 asInstanceOf Product1 Int 工作 但它没有 用
  • Bash,检查变量

    好的 所以我正在尝试运行一个脚本 如果用户输入y or Y 那么输出是YES但如果用户输入n or N那么输出是NO 这是我到目前为止所拥有的 read character if character y character Y then e
  • 使用 XSLT 从 XML 获取值并存储在变量中

  • 实体框架中的“喜欢”查询

    如何使用 edo 实体框架在 ASP net MVC 中进行通配符文本搜索 如 SQL like 语句 我以为这会起作用 var elig from e in documentDataModel Protocol Eligibility V
  • 使用 PowerShell 同步文件夹

    我尝试这个脚本来同步 2 个文件夹 Folder1Path C test1 Folder2Path C test2 folder1Files Get ChildItem Recurse path Folder1Path folder2Fil
  • 如何阻止选项卡在 webNavigation.onBeforeNavigate 事件上打开页面?

    作为学习练习 我正在尝试构建一个示例 Chrome 扩展程序 以确保 灰名单 上的网站始终在隐身窗口中打开 这是我已经取得的进展 使用当灰色列表页面即将导航时触发的 webNavigation onBeforeNavigate 事件 我在隐
  • Cython - 实现回调

    我一直在使用 Cython 尝试与用 C 编写的库进行交互 到目前为止 一切进展顺利 我可以有效地使用库中的大部分函数 我唯一的问题在于实现回调 该库有 4 个函数定义 看起来有点像这样 typedef void Function1 con
  • 在bigquery脚本中将数组的列设置为变量值

    我试图获取数组中多列的值 并将它们设置为可在循环中用于执行其他操作的变量 谢谢 DECLARE the array ARRAY
  • 在静态变量初始化中使用 cout 时出现 C++ 分段错误

    我有一个程序 我使用 cout 来发出调试信息 该代码在静态全局变量的初始化中执行 即在程序执行的早期执行 当我使用自己的构建脚本构建程序时 它在第一次使用 cout 时出现段错误 仅将字符串文字移入 cout 因此它不能是值 我使用 va
  • 如何在ag-grid中动态添加自定义列

    我堆积在 ag grid 中动态添加自定义列 我尝试过以下方法 additionalCol field SOME RANDOM headerName SOME RANDOM scope gridOptions columnApi addVa
  • Smartgwt RestDataSource 与 SpringMVC 和跨客户端

    经过大量工作后 我有了一个现有的后端 Web 服务应用程序 该应用程序由 Sp ring RS Spring MVC Spring 控制器提供支持 这些控制器在 Spring 框架内使用 Jackson 将响应转换为 JSON 这是 WEB
  • 如何在Java中解码http POST数据?

    我正在使用 Netty 并且必须接受并解析 http POST 请求 据我所知 Netty 没有内置对 POST 的支持 只有 GET 的支持 这是一个相当低级的库 处理原始网络操作 使用 servlet 容器 开箱即用地完成所有这些工作
  • 如何将数组转换为数学计算表达式? [复制]

    这个问题在这里已经有答案了 我尝试编写一个计算数学表达式并将每个符号存储到一个数组中 例如 我想转换数组 let arr 10 2 1 3 对于以下表达式 let result 10 2 1 3 1 关于如何实现这一目标有什么建议吗 它不会
  • 如何使用 Gradle 访问 Java 项目中的资源?

    我有一个JavaFX https en wikipedia org wiki JavaFX我正在使用 Gradle 文件构建项目 并且我正在 IntelliJ 中编写所有内容 在其中 我使用javafx scene media Media