機能 #15
完了JARファイルのマニフェスト定義参照プログラムを作成する
100%
説明
プログラムの実行条件は次のとおり。
- 管理者権限のないユーザーでもインストール、実行及びアンインストールできる
- ネットワークに接続されていないマシンでもインストール、実行及びアンインストールできる
- 実行環境(CPU、OS)はOracle Java SEが対応する範囲とする
- ユーザーインタフェースはCUI及びGUIとする
- GUI表示を基本とし、GUIが利用できない環境ではCUI表示とする
- 本プログラムの実行時にはJREが利用可能とする
ファイル
高橋 徹 さんがほぼ11年前に更新
- ステータス を 新規 から 進行中 に変更
- 進捗率 を 0 から 50 に変更
開発環境の定義を行います。
開発言語:Java SE 8開発環境:NetBeans IDE 8
使用するGUI:JavaFX
実行形態:実行可能JAR形式
- 配布を容易にするため、JARファイル1つに収める
リポジトリ:本Redmineプロジェクトのリポジトリを使用 - [[source:learn/java/javafx/JarManifestViewer]]
高橋 徹 さんがほぼ11年前に更新
- ファイル picture142-1.png picture142-1.png を追加
NetBeansで新規プロジェクト(アプリケーション種類はJavaFX FXMLアプリケーション)を作成、プロジェクト設定の画面を添付。
高橋 徹 さんがほぼ11年前に更新
- ファイル picture207-1.png を追加
- ファイル picture207-2.png を追加
- ファイル picture207-3.png を追加
画面の設計¶
NetBeansのJavaFX FXMLアプリケーションが生成する雛形のFXMLでは、画面全体のコンテナにAnchorPaneが使われています。AnchorPaneは、部品の配置に細かな調整ができるので汎用性が高いコンテナですが、その分配置が手間です。
今回は、BorderPaneを画面全体のコンテナに使うことにします。
BorderPaneは中央と上下左右の5つの配置領域を持ち、画面をリサイズすると5つの領域の配置関係を維持したまま広がり、あるいは狭まります。BorderPaneはちょっとしたアプリケーションの画面には重宝するコンテナです。
そこで、雛形が生成したFXMLファイルに配置されるコンテナ、コントロールを全部削除し、BorderPaneを配置します。
+------------------------------------------------+ | +------------------------+ +----+ | | JARファイル: | | |指定| | | +------------------------+ +----+ | +------------------------------------------------+ | +------------+-------------------------------+ | | | キー名 | 設定値 | | | +------------+-------------------------------+ | | |Main-Class |com.torutk.Main | | | +------------+-------------------------------+ | | | | | | | +------------+-------------------------------+ | | | +------------------------------------------------+
- BorderPaneのTOPに、JARファイル名を指定・表示する領域
- BorderPaneのCENTERに、表領域
- BorderPaneのLEFT, RIGHT, BOTTOMは未使用
TOPの部分の画面設計¶
ここには、Label、TextField、Buttonを横並びで配置します。画面のリサイズ時に、Labelは常に左端、Buttonは常に右端、TextFieldは許す限り大きくとりたいとします。
候補のコンテナは、横並びなので- FlowPane
- GridPane
- HBox
- AnchorPane
あたりでしょうか。
HBoxを使ったレイアウトで実現可能です。次のWikiページに記載しています。
JavaFXとレイアウトのHBox項
高橋 徹 さんがほぼ11年前に更新
Unix系のunzipコマンドでJARファイル内のマニフェストファイルを見る方法
~$ unzip -p slf4j-api-1.6.1.jar META-INF/MANIFEST.MF Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: ceki Build-Jdk: 1.6.0_16 Bundle-Description: The slf4j API Bundle-Version: 1.6.1 Implementation-Version: 1.6.1 Implementation-Title: slf4j-api Bundle-ManifestVersion: 2 Bundle-SymbolicName: slf4j.api Bundle-Name: slf4j-api Bundle-Vendor: SLF4J.ORG Bundle-RequiredExecutionEnvironment: J2SE-1.3 Export-Package: org.slf4j;version=1.6.1, org.slf4j.spi;version=1.6.1, org.slf4j.helpers;version=1.6.1 Import-Package: org.slf4j.impl;version=1.6.0
高橋 徹 さんがほぼ11年前に更新
JavaでJARファイルの中のMANIFEST.MFの内容を読む方法
java.util.jar
パッケージのJarFile
クラスを使います- JARファイルへのパス(String)またはFileオブジェクトを指定して生成
getManifest
メソッドでManifest
オブジェクトを取得
Manifest
オブジェクトのgetMainAttributes
メソッドでMANIFEST.MFのメインセクションに記述された属性群を持つAttributes
オブジェクトを取得Attributes
クラスはMap<Object,Object>を実装したコレクションですentrySet
メソッドで、MANIFEST.MFのヘッダーと値の組(Map.Entry<Object, Object>
)の一覧を取得します- entryのgetKeyメソッドでヘッダー名(Attributes.Name型)、getValueメソッドでその値が取得できます
- getKeyはObject型を戻り値型としますが、実際に戻り値はAttributes.Name型です
コード例は次です。(MANIFEST取得コード部分を抜粋)
try (JarFile jar = new JarFile(filePathField.getText())) {
List<ManifestAttribute> attrs = jar.getManifest().getMainAttributes().entrySet().stream()
.map(entry -> new ManifestAttribute((String) entry.getKey().toString(), (String) entry.getValue()))
.collect(toList());
} catch (IOException ex) {
logger.warning(() -> String.format("%s", ex.getLocalizedMessage()));
}
ManifestAttributeは、JavaFXのTableView表示用のモデルクラスです。
高橋 徹 さんが10年以上前に更新
最低限機能するプログラムとなりました。そこで、このRedmineプロジェクトのgitリポジトリにコミット・プッシュしようとしました。ローカルでのコミットはOKですが、その後のプッシュがエラーとなってしまいました。リモートとローカルが大分乖離している模様です。こうなるとgitは少々面倒になってきます。トピックブランチを作らずmasterのみでリモート、ローカルをやり取りしていたもあり、復旧が困難です。
こうなると、別なところにリモートからcloneして立て直しを図るのが通例ですが、一つのgitリポジトリに雑多なものを入れていると今の作業にとって余計なものが多くてちょっと扱い難くなっています。
こうなってくると、GitHubのように気軽にリポジトリを切って使うアプローチがよく感じてきます。
- NetBeans上でJarManifestViewerプロジェクトを右クリックし、[バージョン管理] > [Gitリポジトリの初期化]
ローカルのJarManifestViewerプロジェクトのディレクトリを指定 - NetBeansからJarManifestViewerプロジェクトを右クリックして[Git] > [コミット]
- NetBeansからJarManifestViewerプロジェクトを右クリックして[Git] > [リモート] > [プッシュ]
- [Gitリポジトリの場所を指定]にチェックを付け、リモート名は[origin]、リポジトリURLには[https://github.com/torutk/jarmanifestviewer.git]を記述、ユーザー名とパスワードをGitHubのものを入れて[次>]ボタンを押す
- [master -> master[C]]をチェックし[次>]ボタンを押す
- [master -> origin/master[A]]にチェックが付いているのを見て[終了]ボタンを押す
- エラーになってしまう。GitHubに.gitignoreとREADME.mdがあるため。
- NetBeansからJarManifestViewerプロジェクトを右クリックして[Git] > [リモート] > [プル]
- マージするかリベースするか聞かれたのでリベースを選択したらローカルのコミット済みファイル群が消失した!
$ git reset --hard ORIG_HEAD
で消失したものを戻しました。 - 今度は[プル]でマージを選択、それから[プッシュ]を実行
ひとまずコミットOK、以下のGitHubにコードがアップされました。
高橋 徹 さんが10年以上前に更新
画面をダークテーマに
背景白ではまぶしいので、ダークテーマにしてみます。
次の記事で紹介されたCSS設定をほぼそのまま書き写しました(.hbox定義を追加)。
http://code.makery.ch/java/javafx-2-tutorial-part4/
ソースファイルと同じディレクトリにdarktheme.cssを置きます。
source:github_jarmanifestviewer|src/com/torutk/jarmanifest/darktheme.css@c23d136a
SceneBuilderで画面の最もルートに近いシーンであるBorderPaneのプロパティStylesheetsにdarktheme.cssを設定しました。SceneBuilderでの設定方法を次のWikiに記載しました。
JavaFXとCSSでScheneBuilderで画面全体に適用するCSSファイルを指定
ここで、BorderPaneのTop領域に貼ったHBoxの背景が白いままなのが気に入りません。
.hbox {
-fx-background-color: #1d1d1d;
}
と定義しているにも関わらずです。
この理由は、ちょっと前にはてな日記に記載しました。
http://d.hatena.ne.jp/torutk/20140801/p1
解決方法は、画面全体を覆うレイアウトペイン(ここではBorderPane)の背景色を明示的に指定する方法です。
この方法を2つ、はてな日記に記載しました。
http://d.hatena.ne.jp/torutk/20140816/p1
この問題、実は昔はてな日記に記載していた事項でした。orz
http://d.hatena.ne.jp/torutk/20120505/p1
高橋 徹 さんが10年以上前に更新
JARファイルのマニフェスト表示時にエフェクトをかける
JARファイルを選択すると、すぐにマニフェストが表示されます。その状態で次のJARファイルを選択すると瞬時にマニフェストが更新されます。その際、同じ程度の文字数だと、ぱっとみて表示が更新されたのかが分かりにくいです。
そこで、JARファイルを指定してマニフェストを表示する際、フェードイン効果を入れることで表示が更新されたことをユーザーに分かりやすくします。
フェード効果も昔はてな日記に記載済みです。
http://d.hatena.ne.jp/torutk/20120323/p1
今回は、この日記の実装をほぼ同じに使ってみました。
source:github_jarmanifestviewer|src/com/torutk/jarmanifest/JarManifestViewController.java