[Java] 58 JavaFX 16 Eclipseの設定

EclipseでのJavaFXプロジェクト(非Maven)作成について設定画像をアップします。

追々説明文は付けていく予定です。

これまで扱った感じではMavenプロジェクトは相当な難物という印象です。VScodeでもEclipseでも未だまともなjar実行ファイルを作れていないという体たらくです。

VScodeでMavenプロジェクトを作成しlaunchを確認できたら、あとはEclipseにインポートしてファイルをあらかじめ作成しておいたJavaFXプロジェクトに移すという手法でしばらくやってみようと考えています。Eclipseを扱うのは最小限に留めたいので。

[Java] 57 JavaFX 15 文字コード変換ツール その8 続バージョン検証

[macOS Catalina 10.15.7]

VScodeによる検証の続編です。

Googleによるuniversalchardetライブラリのリリース年が2008年というのを知り、古い環境でしか動かないのではないかと考えてJavaのバージョンをOracle版の8にして試してみたところ、いい線まで行きましたが結局NGでした。

さらにJavaSE6までさかのぼったものの上手くいかずで私のスキルではギブアップです。

しばらくはEclipse依存から脱することができないようです。

よくよく考えると現行のほとんどおよび過去のJDK(Oracle版とOpen版)は当然Intel Mac向けに作られたものなのでAppleシリコンMacにしてしまうとRosettaの呪縛から逃れられないのではないでしょうか。

そうだとすれば古いコード資産も活用したい私の場合はIntel Macを使い続けるのが得策のようですが、新しい技術も体感したいのでサブ機として次世代MシリーズMacを購入する方向に傾いています。

[Java] 56 JavaFX 14 文字コード変換ツール その7 universalchardet

[macOS Catalina 10.15.7]

VScodeでnkfコマンドを使った文字コード変換ツールはうまく作れましたが、universalchardetを使ったコードはjar実行ファイルにすると正常に動作しません。

macOSの影響かもしれないと考え、Mojave搭載機で試してみたものの結果はNGでした。

どうイジってもダメなので、EclipseでMavenではなく普通のJavaプロジェクトを作成してみるとあっさり成功しました。VScodeの軽量環境が気に入っていただけに残念です。

ところで未だにEclipseでまともなMavenプロジェクトを作れないでいます。今後の課題です。

自分の開発環境を確立するまではARMアーキテクチャのAppleシリコンMacへの移行はしない方がいいと考えています。リーク情報ではM1XやM2の開発状況がはかばかしくない、というのもありますが大丈夫なんでしょうか。

開発環境の脱RosettaやUSBポート等の拡張性に進歩がないのであれば、今年の購入は見送ってIntel Macを当面使い続けるつもりです。

package application;

import java.io.IOException;
import org.mozilla.universalchardet.UniversalDetector;

public class FileCharDetector {

    // コンストラクタ
    public FileCharDetector(){
    }

    public String main(String path) throws IOException {
        byte[] buf = new byte[4096];
        java.io.FileInputStream fis = new java.io.FileInputStream(path);

        UniversalDetector detector = new UniversalDetector(null);

        // 判定開始
        int nread;
        while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
            detector.handleData(buf, 0, nread);
        }

        // 判定終了
        detector.dataEnd();

        // 判定結果取得
        final String detectedCharset = detector.getDetectedCharset();
 
        // 判定の初期化
        detector.reset();
        fis.close();

        return detectedCharset;
    }
}

[Java] 55 JavaFX 13 文字コード変換ツール その6 nkfコマンド

nkfコマンドを使って仕上げました。

jar実行ファイルではこれまでと同じく文字コード判定ができませんでしたが、標準エラー出力をチェックしたところ、nkfコマンドを見つけられないことが判明しました。

nkfファイルは/usr/binフォルダには入っておらず、絶対パスのコマンドにすると解決しました。jar実行ファイルではnkfファイルへのpathが通らなくなるようです。

Pythonのtkinterでもコンソールなしの実行ファイルではうまく動作しないケースがあるのですが、コマンドの書き方がおかしいのかもしれません。

とりあえずこれで完成です。UniversalDetectorを使ったJavaオリジナルのコードも書いてみたいです。

package com.example;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.TextArea;
import javafx.event.ActionEvent;
import java.util.regex.Pattern;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class GuiController {
    @FXML
    private Button button1;
    @FXML
    private Button button2;
    @FXML
    private TextField text1;
    @FXML
    private TextField text2;
    @FXML
    private TextArea text3;

    String path;
    String path2;
    String code;
    String code2;
    String str1;

    @FXML
    void onButton1Action(ActionEvent event) {
        code2 = text2.getText();
        path2 = text1.getText();

        if(code2.matches("UTF-8")){
            // 変換後のファイル名を作成
            StringBuffer buf = new StringBuffer();
            buf.append(path2.split(Pattern.quote("."))[0]);
            buf.append("_s.");
            buf.append(path2.split(Pattern.quote("."))[1]); // 拡張子
            String s = buf.toString();

            // ファイルの文字コードをUTF-8からシフトJISに変換
            File file = new File(path2);
            File file2 = new File(s);
            try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2),"Shift-JIS"))){
                String line;
                while ((line = br.readLine()) != null) {
                    bw.write(line);
                    bw.newLine();
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        else{
            if(code2.matches("SHIFT_JIS")){
                // 変換後のファイル名を作成
                StringBuffer buf = new StringBuffer();
                buf.append(path2.split(Pattern.quote("."))[0]);
                buf.append("_u.");
                buf.append(path2.split(Pattern.quote("."))[1]); // 拡張子
                String s = buf.toString();

                // ファイルの文字コードをUTF-8からシフトJISに変換
                File file = new File(path2);
                File file2 = new File(s);
                try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"Shift-JIS"));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2),"UTF-8"))){
                    String line;
                    while ((line = br.readLine()) != null) {
                        bw.write(line);
                        bw.newLine();
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else{
                text2.setText("このツールでは不可");
            }
        }
    }

    @FXML
    void onButton2Action(ActionEvent event) {
        path = text1.getText();

        try{
            Function fc = new Function();
            str1 = fc.main(path);
            text3.appendText(str1);
        }
        catch (Exception e){
            System.out.println(e);
            text3.appendText("Function失敗\n");
        }

        if (str1 != null){
            text2.appendText(str1 + "\n");
        }
        else{
            text3.appendText("判定不可\n");
        }
    }
}
package com.example;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

public class Function {
    StringBuffer buf = new StringBuffer();
    public String main(String path) throws IOException {
        ProcessBuilder p = new ProcessBuilder("/usr/local/Cellar/nkf/2.1.5/bin/nkf","-g",path);
        p.redirectErrorStream(true);

        try{
            Process process = p.start();
            process.waitFor();

            // 判定結果を受け取る
            try (BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.defaultCharset()))) {
                String line;
                int count = 1;
                while ((line = r.readLine()) != null) {
                    if(count == 1){
                        buf.append(line + "\n");
                    }
                    else{
                        break;
                    }
                    count = count + 1;
                }
            }
        }
        catch (Exception e) {
            buf.append(e + "\n");
        }
        String s = buf.toString();
    return s;
    }
}

[Java] 54 JavaFX 12 文字コード変換ツール その5 バージョン検証

このツールはサクッと仕上げるつもりでしたが、思いの外難航しています。

前回のjar化で最大の危機を脱したものの、出来上がったアプリが一部機能しません(文字コード判定)。

mavenコンパイラとターミナル のJavaバージョンを変えて検証してみました。前者はpom.xml、後者は.bash_profileを書き換えてバージョン変更しています。

検証の結果、maven JDK1.7・ターミナル Java13で最もマシでした。と言いますか、jarファイルが起動したのが最初のこの条件のみです。文字コード判定は不可のままです。

ネットからいただいた該当コードは2015年時点のものなので私なりに書き直してみます。

[Java] 53 JavaFX 11 文字コード変換ツール その4 jar作成でトラブル

最後の最後でまたハマりました。

pom.xmlにmaven-assembly-pluginを追記して”mvn package”コマンドでjarを作成するのですが、いつもの泥沼な試行錯誤に陥りました。原因はMavenプロジェクト作成時にありました。

groupID名を例示されるcom.exampleにすると階層は、[プロジェクト名]-src-main-java-com-exampleとなります。

ドットを含まない名前にすると階層が、[プロジェクト名]-src-main-java-[groupID名]といった構造になり1階層浅くなります。どうやらこれがまずかったようです。

groupID名にドットを入れないとjar作成がうまくいきませんでした。相対パスがズレるからなのか。こんな些末なことで何時間も足止めです。さすがに疲れました。

Java関連の記事はどうしても愚痴が多くなります。次回以降の記事でjarの作成方法をまとめます。

[Java] 52 JavaFX 10 文字コード変換ツール その3 完成

一応完成しました。

昨年2020年9月にGUIアプリではないですがPython&Bashで同じことができるコードを書いています。nkfコマンドを使えばファイルの文字コード変換は楽勝です。

こちらの方の難易度は桁違いに高かったです。

あとはjar実行ファイルに変換して普段使いできるようにします。

先月下旬にVScodeでのJavaツール開発を諦めてEclipseへ移行してから1ヶ月余り。ようやくVScodeでも開発できるようになりました。XcodeやEclipseのようなIDEはなにか窮屈で書かされている感もあり苦手です。

package javafx_conv;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.event.ActionEvent;
import java.util.regex.Pattern;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class GuiController {
    @FXML
    private Button button1;
    @FXML
    private Button button2;
    @FXML
    private TextField text1;
    @FXML
    private TextField text2;

    String path;
    String path2;
    String code;
    String code2;

    @FXML
    void onButton1Action(ActionEvent event) {
        code2 = text2.getText();
        System.out.println(code2);

        path2 = text1.getText();
        System.out.println(path2);

        if(code2.matches("UTF-8")){
            // 変換後のファイル名を作成
            StringBuffer buf = new StringBuffer();
            buf.append(path2.split(Pattern.quote("."))[0]);
            buf.append("_s.");
            buf.append(path2.split(Pattern.quote("."))[1]); // 拡張子
            String s = buf.toString();
            System.out.println(s);

            // ファイルの文字コードをUTF-8からシフトJISに変換
            File file = new File(path2);
            File file2 = new File(s);
            try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2),"Shift-JIS"))){
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);

                    bw.write(line);
                    bw.newLine();
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        else{
            if(code2.matches("SHIFT_JIS")){
                // 変換後のファイル名を作成
                StringBuffer buf = new StringBuffer();
                buf.append(path2.split(Pattern.quote("."))[0]);
                buf.append("_u.");
                buf.append(path2.split(Pattern.quote("."))[1]); // 拡張子
                String s = buf.toString();
                System.out.println(s);

                // ファイルの文字コードをシフトJISからUTF-8に変換
                File file = new File(path2);
                File file2 = new File(s);
                try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"Shift-JIS"));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2),"UTF-8"))){
                    String line;
                    while ((line = br.readLine()) != null) {
                        System.out.println(line);

                        bw.write(line);
                        bw.newLine();
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else{
                text2.setText("");
                text2.setText("このツールでは不可");
            }
        }
    }

    @FXML
    void onButton2Action(ActionEvent event) {
        path = text1.getText();
        FileCharDetector fd = new FileCharDetector(path);

        try{
            code = fd.detector();
        }
        catch (Exception e) {
            System.out.println(e);
        }

        if (code != null){
            text2.setText(code);
        }
        else{
            text2.setText("判定不可");
        }

    }
}

[Java] 51 JavaFX 09 文字コード変換ツール その2

前回の続きです。

文字コードの判定でもしんどかったですが、ファイルの文字コード変換は輪をかけて手ごわかったです。

区切り文字をドット(.)にして文字列をすんなり分割できないというのにはまいりました。まさかsplitで足止めを喰らうとは思いませんでした。

Pythonの感覚で取り組むとひどい目にあいますね。数行書いてビルドするのではなく、1行あるいは1箇所書き足す度に確認しないと今の私には手に負えないです。緻密さを養うには最適な言語ではないでしょうか。

これだけ苦労しても嫌いにならないのは、ドキュメントなりネットなりどこかに答えが必ずあるという安心感と泥臭く取り組んできた思い入れゆえでしょうか。情報の少ないSwiftだったらとっくに投げ出していたでしょう。

package javafx_conv;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.event.ActionEvent;
import java.util.regex.Pattern;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class GuiController {
    @FXML
    private Button button1;
    @FXML
    private Button button2;
    @FXML
    private TextField text1;
    @FXML
    private TextField text2;

    String path;
    String path2;
    String code;
    String code2;

    @FXML
    void onButton1Action(ActionEvent event) {
        code2 = text2.getText();
        System.out.println(code2);

        path2 = text1.getText();
        System.out.println(path2);

        if(code2.matches("UTF-8")){
            // 変換後のファイル名を作成
            StringBuffer buf = new StringBuffer();
            buf.append(path2.split(Pattern.quote("."))[0]);
            buf.append("_s.csv");
            String s = buf.toString();
            System.out.println(s);

            // ファイルの文字コードをUTF-8からシフトJISに変換
            File file = new File(path2);
            File file2 = new File(s);
            try (BufferedReader br = new BufferedReader(new InputStreamReader\
(new FileInputStream(file),"UTF-8"));BufferedWriter bw = new BufferedWriter\
(new OutputStreamWriter(new FileOutputStream(file2),"Shift-JIS"))){
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);

                    bw.write(line);
                    bw.newLine();
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        else{
            if(code2.matches("SHIFT_JIS")){
                System.out.println("省略");
            }
            else{
                System.out.println("該当なし");
            }
        }
    }

    @FXML
    void onButton2Action(ActionEvent event) {
        path = text1.getText();
        FileCharDetector fd = new FileCharDetector(path);

        try{
            code = fd.detector();
        }
        catch (Exception e) {
            System.out.println(e);
        }

        if (code != null){
            text2.setText(code);
        }
        else{
            text2.setText("判定不可");
        }

    }
}

[Java] 50 JavaFX 08 文字コード変換ツール

GUI作成についてはPythonのtkinterからJavaFXへの移行を目指しています。

やはりScene Builderを使ってGUIをデザインするのが楽ですから。

今は文字コード変換ツールを作成しています。

文字コード判定のところまで書きました。文字コード判定クラスFileCharDetectorはネットから拝借して私なりに手を入れました。

早速TextAreaの高さをTextFieldに合わせられない不具合が発生していますが後日サイズ調整します。

package javafx_conv;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.TextArea;
import javafx.event.ActionEvent;

public class GuiController {

    @FXML
    private Button button1;
    @FXML
    private Button button2;
    @FXML
    private TextField text1;
    @FXML
    private TextArea textarea1;

    String path;
    String code;

    @FXML
    void onButton1Action(ActionEvent event) {
        System.out.println("変換ボタンを押しました!");
        // 作成中
    }

    @FXML
    void onButton2Action(ActionEvent event) {
        path = text1.getText();
        FileCharDetector fd = new FileCharDetector(path);

        try{
            code = fd.detector();
        }
        catch (Exception e) {
            System.out.println(e);
        }

        if (code != null){
            textarea1.setText(code);
        }
        else{
            textarea1.setText("判定不可");
        }

    }
}

参考サイト

[Java] 49 JavaFX 07 JDK11.0.11で文字化け

[macOS 10.15.7 Catalina]

Javaがらみではちょっとしたことでトラブルに巻き込まれるので、都度記録しておきます。

今回はJDKのバージョンによるJavaFXの文字化けです。

VScodeのsettings.jsonでJDKのバージョンを以下のように設定していました。

"java.home": "/Library/Java/JavaVirtualMachines/jdk-11.0.8.jdk/Contents/Home"

jdk-11.0.8.jdkからjdk-11.0.11.jdkに変更したところ文字化けが発生しました。ちなみにjdk13ではこのようなトラブルはありません。

私の環境だけかもしれませんが、今後も似たようなトラブルになった時のためにメモしておきます。前にもあったmacOS 10.15 Catalinaの問題のような気もします。

Javaは開発環境構築とトラブル対応のコストがかかり過ぎるがつくづく残念です。この傾向はEclipseのようなIDEでも、VScodeのようなエディタでも変わりません。

以前も書きましたが、VScodeを使った軽量環境構築はJava用プロジェクト管理ツールのMavenに出会うまでは本当に泥沼でした。