私のプロジェクトはEclipseで正しく実行されていますが、このプロジェクトのjarファイルを作成してcmdで実行しようとすると、「場所が設定されていません」というエラーが表示されます。
私のプロジェクト構造は次のとおりです。
メソッドは(Eclipseで実行)です:
@FXML
private void RegularCustomer(ActionEvent event) throws Exception{
Stage stage = (Stage) dailySales.getScene().getWindow();
Scene scene = dailySales.getScene();
FXMLLoader loader = new FXMLLoader(getClass().getResource("../customer/CustomerHome.fxml"));
System.out.println(loader.getLocation());
scene.setRoot(loader.load());
stage.setScene(scene);
stage.show();
}
このコードの何が問題になっていますか?
いくつかの相対的な質問がありますが、それらはそれとは異なります。彼らのコードはIDEで実行されませんでしたが、私のコードはIDEで実行されました。
参考:フォルダ構造にいくつか変更を加えて、正常に実行できました。しかし、すべてのFXMLファイルとコントローラーを同じパッケージに入れたため、その構造はひどいものでした。
getClass().getResource(...)
を使用すると、ファイルへのパスを指定するのではなく、リソースをロードすることになります。クラスローダーがファイルシステムからクラスをロードする場合、これらは本質的に同じものと同等であり、実際に機能します(ただし、技術的な理由はありません)。クラスローダーが他のメカニズムによって(そしておそらくすべての場合に)クラスをロードしているときは、Java リソースの仕様 に注意を払うことが重要です。
特に、次の点に注意してください。
リソース、名前、コンテキスト
リソースは、スラッシュ(/)で区切られた一連の部分文字列と、それに続くリソース名で構成される文字列によって識別されます。 各部分文字列は有効である必要がありますJava識別子。リソースnameの形式はshortNameまたはshortName.extensionです。shortNameとextensionはどちらもJava識別子である必要があります。
(私の強調。)_..
_は有効なJava識別子ではないため、このリソースが解決可能であるという保証はありません。ファイルシステムクラスローダーがこれをあなたの方法で解決することがあります。期待します。これがIDEで機能する理由ですが、jarクラスローダーでのgetResource(...)
の実装は、期待した方法でこれを実装しません。
試してみてください
_FXMLLoader loader = new FXMLLoader(getClass().getResource("/sm/customer/CustomerHome.fxml"));
_
各FXMLが対応するコントローラーファイルと同じパッケージに含まれるようにコードを編成したので(これは物事を行うための賢明な方法だと思います)、FXMLのロードにこれを活用することもできます。そのコントローラー」:
_FXMLLoader loader = new FXMLLoader(CustomerHomeCtrl.class.getResource("CustomerHome.fxml"));
_
これはこのセットアップではかなり自然に思えます。コンパイラは、クラスをインポートする時点で、CustomerHomeCtrl
のパッケージ名が正しいことを確認します。また、リファクタリングも簡単になります。たとえば、_sm.admin
_を複数のサブパッケージに分割したいとします。 Eclipseでは、サブパッケージを作成し、FXMLとコントローラーを適切なサブパッケージにドラッグアンドドロップすると、インポートステートメントが自動的に更新されます。これ以上の変更は必要ありません。パスがgetResource(...)
で指定されている場合、それらはすべて手動で変更する必要があります。