せぐ のページ

Sorry, this page is Japanese only.
このページは(これを読んでいる人にはおわかりの通り)日本語で書かれたページです
このページはWindows11日本語版のFirefoxのみで表示を確認しています

ぼそっ(今日の独り言)

Androidアプリでlog4j2が使えない

自作javaアプリをAndroidアプリに作り替えようとしているのですけれど、使っているライブラリ、jsoupとlog4j2のうちjsoupはAndroidでも使えそうなのですけれどlog4j2の方はビルドすらできませんでした。
ちゃんとエラーメッセージを見たらlog4j2のパッケージのjarにMETA-INF/DEPENDENCIESというファイルがあるのがダメらしい。このファイルをjarから削除したらビルドだけは通るようになりました。
でも、Androidアプリで使おうとするとエラーになってダメなのは変わらないのですけれどね。ファイルに書き込もうとするときに何か制限があるのかしら。Androidアプリに関しては初心者未満だから手も足も出ない感じ。

2024年04月10日 プログラミング雑談

OpenJDKでJavaFXを使う

新しいバージョンのJavaが使えると限らないけれど、Java 8くらいならばどこでも使えそうな気がするので私が書いているJavaプログラムはターゲットをJava 8にしています。
OracleのJREはJava 8でもバージョンに気を付ければ使えるけれど、JDKはOracleのアカウント登録が必要で使いにくいのでOpenJDKを使っています。
今回買ってきたJavaの本はGUIアプリでJavaFXを使っているので本のチュートリアルに書いてあるHello World!をポチポチ入力。でもjavafx.application.Applicationがimportできない。この本はOracleのJDKをインストールしている前提なので、JavaFXなんて使えて当たり前でしょ? みたいなノリで全く説明なし。
いろいろググった結果、JavaFXを使うならばAmazon CorrettoにはJavaFXが入っているので簡単なようです。
adoptiumのOpenJDKをアンインストールしてCorrettoを入れてみました。とりあえずチュートリアルのJavaFXのHello World!はあっさりコンパイルできて動きました。

JavaのUI、Swingならばたいていどこでも使えるだろうと思ってちょっとHello Worldを動かしたことがありますが、Windowsのディスプレイの拡大/縮小はプログラマが意識してコードを書く必要がありそうで、私の200%拡大設定ではUIが小さくてなんだかなぁと思っていました。JavaFXはディスプレイの拡大/縮小の設定が効いているように見えますし、ファイル選択のコモンダイアログもWindowsのを使えているみたいなので良いかも。
ChromeBookでもJavaFXは使えるかな?
jarを作ってChromeBookに持って行ったけれど動かない。javaFxが入っていないのかな。

sudo apt-get insatll openjfx

しても"Package 'openjfx' has no installation candidate"って言われてインストールできませんでした。

2024年04月08日 プログラミング雑談

実行可能jarを作る

javaのCLIでの実行jarの作り方を覚えてられないのでメモ
マニフェストファイルを作ります。

Manifest-Version: 1.0
Class-Path: .
Main-Class: com.my.App

classフォルダで

jar cvf [作りたいjarファイル名] [classファイルが入っているフォルダ名。例えばcom]
jar uvfm [作ったjarファイル名] [マニフェストファイル名]

2024年04月08日 プログラミング雑談

Android StudioをJavaで使うときライブラリのjarはどこに置くの?

私のWebページのスタティックhtmlファイルを生成するjavaプログラムをAndroidアプリ化しようとトライ中。
ググっていると広告ばっかりでイライラしてくるので入門書を購入。
あら、でもAndroid Studioでjavaのライブラリjarをどうやったら使えるか書いていない本を買ってきてしまったみたい。
(1) プロジェクトのviewでappフォルダ右クリック → New → Directory でlibsフォルダを作成
(2) エクスプローラーアプリからjarファイルをドラッグしてきてAndroid Studioのプロジェクトのviewの今作ったばかりのlibsフォルダにドロップ
(3) Copyするファイル名とフォルダを確認するダイアログが出るのでOKで閉じる
(4) プロジェクトのviewでCopyしたjarファイルを右クリック → Add as Library → Addするモジュールの確認ダイアログがでるのでドロップダウンリストから選択。デフォルトで良いみたい。
するとbuild.gradle.ktsに「implementation(files("libs\\jsoup-1.17.2.jar"))」みたいな行が追加されて、ライブラリが使えるようになりました。

jsoupはこれで使えたけれど、log4j2が実行時にエラーになる。まだAndroid Studioの使い方が全然わかっていないのでどんなエラーか把握できていないしどうやってデバッグすればいいかも勉強中。そもそもlog4jの使い方もわかっていないのでlog4jの使い方をちゃんと読めばいいのかな。

2024年04月07日 プログラミング雑談

エレコムの安いキーボードの潤滑化メンテ手順

キーボードをいわゆる「ルブ」したいと思いながらしばらく踏み切れなかったので、同じように踏み切れない人の背中を押すつもりで、エレコムの安いキーボードTK-FDM105TXBKの潤滑化について書きます
キーボード外観

用意するもの

Y字型のドライバーはSUNFLAGのNo.17-Cが近所で安かったのでこれを使いました。
SUNFLAGのNo.17-C
ネジの溝部分のサイズが2.2mm向けのドライバーのようです。これでもエレコムのキーボードのネジは回せましたが、もっと大きなドライバーが好ましいと思います。多分3.0mmくらいあった方が良いと思います。

潤滑用のスプレーは呉のドライファストルブを使いました。
ドライファストルブ

分解

ネジの場所は赤く丸をつけたところです。水抜きの穴もあるのですべての穴にネジが入っているわけではありません。

ネジの場所
ちゃんと力を入れてドライバーを押し込む感じでネジを回す必要がありました。サイズが合ったドライバーならそれほど気を使わなくても良いと思います。

裏ブタと表のキーボード側の分離はキーボード側に3箇所小さな爪がありますので、爪の場所は裏ブタ側を外に押し広げる感じで外すと良いでしょう。
爪の場所

ネジはこんな感じ
ネジ
Y字のネジを一般的な+ネジに付け替えたくて近所のホームセンターに行きましたが同じサイズのネジは置いていませんでした。タッピングネジで鍋タイプの3x8よりは1mm位短くて、3x8の先端1mm位を切り落とした感じに見えます。
(追記: B0型タッピング ナベ M3×7 になるみたい)

中の構造

キーボード部分を外した裏ブタ側はこんな感じ。
裏ブタ側
メンブレンの白いシートは有線タイプのTK-FDM103と同じものだと思います。メンブレンのシートと右上の基板は3つのネジで圧着させる構造。この基板を有線タイプ、無線タイプ、Bluetoothタイプで使い分けるのでしょう。ちょっと高価なBluetoothタイプでメンブレンのシートが接触不良を起こしたら安い有線タイプを買ってきてシートだけ入れ替えれば使えるのではないかな。購入時期が何年も違うと中身が微妙にバージョンアップして互換性が失われているかもしれませんので積極的におすすめはしませんが。そうでなくても5年使った私のキーボードは、今回買い足して気が付きましたが、キートップがツルツルになっていたり左手親指の腹があたるキーボード下部がすり減っていたりしましたので、数年使ったのならば修理とか考えずに買い替えた方が良さそうです。2万円超のRealforceだと10年位使いたいかも?

キーボードの裏側、キートップの取り付け部分
キーの裏側
キートップは筐体に爪ではまっている構造です。キートップを引っ張っても抜けないように作られているのですね。
キーを押し込むとこんな感じ
キーを押し込む

スプレー作業

キーを押し込むとキートップと筐体の接触部分が露出しますので、ここにドライファブのスプレー液を付着させる感じで作業しました。作業時はキーを押し込まなくても筐体をひっくり返して広げた新聞紙の上に置けば自然とキーが押された状態になります。スプレー付属のストローを溝のように見える隙間に差し込んで、スプレー液で濡れようにします。
ルブのターゲット
気にしなくても良いのかもしれませんが、液がちゃんとキートップと筐体の接触部分にまんべんなく付着するように、キー4つくらいずつまとめてスプレーして、乾く前に手でキーをカチャカチャ押し込んでました。キートップが気化熱でひんやりすると、キートップにも液がちゃんとついてるんだなと安心できる感じ。
どのくらいの量をスプレーするのが最適かわかりませんが、キーボードの引っ掛かり感が解消していれば目的は達成できているのでヨシとしています。

天候などの関係で可能ならば屋外、せめて窓を開け放った室内で作業することをお勧めしておきます。有害物質は使われていないと思いますが、ちょっと溶剤っぽいにおいが気になるので。

組み立て

スプレー液がちゃんと乾くのを待って、キーボードを組み立てます。
呉のドライファストルブは乾くと白くなります。ところどころ白い汚れが付着したかなって感じになります。まあ組み立ててしまえば見えないところですので気にしません。
あ、白くなった写真を撮り忘れました・・・。

効果

PCに接続して試し打ち。
気のせいかもしれませんが打鍵音のカチャカチャの高音部が少し静かになった気がします。
押下感は滑らか。わざと斜めに押し込もうとしてもキーの引っ掛かり感はありません。(昔、斜めに押し込んでも引っ掛かりが無いパンタグラフタイプのキーボードが好きだった時期がありました)。メンブレンのラバーカップの変形する感触なのだと思いますが、押し始めがクニュっとして一番重い感じ。このクニュっとした感触がいまいち好きになれなくて、メカニカルのキーボードの方が好みなんだと思います。とはいえ職場で支給されたキー配置レベルでダメダメなキーボードに比べれば、このキーボードは十分ハッピーです。
あと、これも気のせいかもしれませんが、スプレー前よりもキーが重くなった?
今回は1週間くらい使ったくらいのほぼ新品に潤滑スプレー処理をしましたので劇的な改善はありませんが、斜めに押し込もうとしても引っ掛かり感はありませんので私の変な打鍵癖でキーが引っかかって入力されない(特にshiftキー)は改善されると思いますし、これだけ滑らかな打鍵感ならば高価なrealforceは私にはいらないと思いました。キーボード欲しい病がほぼ治りました。少なくともrealforceは欲しいものリストから削除されました。(茶軸のメカニカルはまだちょっと魅力的なのですけれどね)

2024年04月06日 エレコム廉価版キーボード TK-FDM105

エレコムの安いキーボード(5年経過)の潤滑化メンテ

職場であてがわれたパソコンのキーボードが"X"の下にaltキーがあって"Z"の下にWindowsキーがある極悪なキー配置だったので苦情を言って変えてもらったのだけれど、それもなんかイマイチだったのでBYOD。
別にRealforceやメカニカルのキーボードにしてほしいと言っているわけではなくて、結局使っているのはエレコムの安いキーボードであるところのTK-FCM103XBK。今Amazonで見たら830円だった。安い。
さすがに5年も使っていると打鍵感にひっかかりが出てきて、しばらくキーボード欲しい病を発病していました。

自宅ではFILCOのメカニカル。茶軸の打鍵感が心地よくて15年位前だったかにヨドバシの店頭で一目惚れして購入。その後、今から5年前に今使っている茶軸のコンパクトタイプのキーボードに変えました。Realforceも何度も検討したのですが、どうも打鍵感にワクワクを感じなくて。店頭で触った感じはキーに引っ掛かりも感じず滑らかでいいのですが、なんだろう、メカニカルのCherryの茶軸と比べて押し始めのラバーカップ感とでも言えばいいのか、モニョっとした感じが、何万円も出して買うキーボードではない感じがしてしまっています。
ラバーカップの打鍵感も千円前後のキーボードならば許容範囲。でも冒頭に書いたように5年も使っていると打鍵感に引っ掛かりが出てきて、滑らかな打鍵感に憧れてRealforceやメカニカルのキーボードを家電量販店の店頭で感触を確かめながら、2万円とか3万円とかの値札を見て購入をためらっていました。キーボードは商売道具でもあるのでケチりたくはないのですけれど、値段分の価値を感じられなくて。
ってことで(前振りが長い)、結局またエレコムの安いのを買ってしまいました。TK-FDM105TXBK。ワイヤレスで1,280円だったので。うん。打鍵感に引っ掛かりもなく良い感じ。これで十分。
私のキーボードの嗜好は、必須の条件はシリンドリカルのキートップで左altキーが標準的な位置にあることだけかもしれません。テンキーがあるとマウスが遠くなるのでテンキーレスとかコンパクトタイプのものを最近は選択してしまっています。あったらいいな、くらいの条件が、打鍵感やなんちゃってでいいのでステップスカルプチャ。最近はHomeキーやEndキーもよく使うのであまり特殊なキー配置は敬遠してしまいます。

で、今まで使っていた打鍵感に引っ掛かりが出てきたキーボード、ググったところルブと呼ばれているらしい、グリス類で打鍵感を改善することにトライ。
ググって見かけたのがメカニカルキーボードのキースイッチを分解してグリスを塗ったり、メンブレンキーボードの可動部にシリコンスプレーする方法。私は電気接点があるメカニカルキーボードに絶縁性の何かを塗るとか怖くてできません。シリコンスプレーはメカニカルキーボードを使い始める前にメンブレンのキーボードで試したことがあります。その時の記憶は、打鍵感の引っ掛かりは解消するのですが動きに液体っぽい抵抗感が感じられてイマイチというもの。
今回は何年か前に鍵穴の潤滑用にフッ素樹脂スプレーを入手していますので、フッ素樹脂スプレーで打鍵感の潤滑化に挑戦。鍵穴があんなに滑らかになるのだもの。きっとキーボードにも効果があるに違いありません。シリコンスプレーよりずっと高価でしたが、スプレー後すぐに乾いてサラサラ感があるのでシリコンスプレーと違って液体っぽい抵抗感も無いに違いない。
ところがTK-FCM103XBKってキーキャップを引っ張ってもキーが抜けない。Y字型の特殊なネジが使われていて分解もままなりません。830円で買えるキーボードの打鍵感改善のために900円超のフッ素スプレーと500円弱のY字ドライバーか・・・と思わないでもありませんが、今回新規購入したのはY字ドライバーだけなので気にしない。これでもホームセンターを3件まわってやっと見つけた安価なY字ドライバーだったりします。地元のホームセンター、コメリで購入。ホームセンタームサシには確か千円超だったけれどもっと太いタイプのY字ドライバーがあったような気がします。どうも話がすぐにわき道にそれますが・・・。
キーボードの裏ブタのネジを外します。このキーボード、ラベルのシールの下にネジが隠されていないあたり構造が良心的。ACアダプターとかいくつか分解したことがありますがラベルのシールの下にネジが隠れているのがデフォルトだったので、少し覚悟をしていたのですが、ラベルをはがさなくてよくてちょっとうれしい。
裏ブタを外すとキーの部分とメンブレンのシートと裏ブタに分かれます。キーの部分はひっくり返してもキートップが外れない構造。新聞紙を広げてキーの部分をひっくり返して置き、可動部にフッ素樹脂スプレーを吹きかけました。しっとりした感じになり、気化熱でキーボードがひんやり。可動部にスプレー液がちゃんとつくようにキーをカチャカチャ動かして、乾燥するのを待ちます。少し白っぽくなるのはこのスプレーの特性。どうせ見えなくなる部分なので気にしない。
有機化合物っぽい異臭が室内にこもるので外は暴風雨の夜でしたがやむなく窓を開けて換気します。
キーボードを組み立てて打鍵感を確認。引っ掛かりが解消。液体っぽい抵抗感はなく、ラバーカップの特性がダイレクトに感じられる打鍵感。キーを押したときのモニョっとした感じがRealforceっぽい。830円のキーボードでこの打鍵感ならお値段以上の価値がありますよ、これ。
でもやっぱり私はメカニカルの柔らかいバネっぽい押し下げ感の方が好きだわ。
そういえばせっかくねじを外したんだから標準的な+ネジに付け替えれば良かった。どうせM3くらいの安いので大丈夫だろうし。
フッ素樹脂スプレーは呉のドライファストルブ、Y字型のドライバーはSUNFLAGのNo.17-Cでいけました。No.17-Cはネジに合わせてみるとちょっと細い感じなので、3mmくらいのサイズのがあると良いと思いました。

2024年03月30日 エレコム廉価版キーボード TK-FDM105

ChromeBookってLinuxマシンだったんだな

AndroidでもiPadでもいいから電子書籍リーダーや動画プレイヤーとして使えるタブレット端末がほしいと思って購入したキーボード分離型のChromeBook。
購入前の下調べで開発者モードにするとLinuxが使えるとかVisual Studio Codeすら使えるとか知りましたが、Androidアプリが使えればそれで十分かなと思っていました。
ところが、物理キーボードが意外と打ちやすいし、かなキー入力が普通にできる事がわかって、これは携帯用のテキスト入力マシンとして使える! 私の予備のWebページ更新用端末にしたいという誘惑に囚われてしまいました。
ChromeBook購入とは関係なく、これまでC++(クラスと継承が使えるC言語のレベル)で作って使っていたhtml生成用のコマンドラインアプリをjavaで書き換えましたので、これをAndroidアプリにすれば・・・と考えて、PCにAndroid Studioを入れてjavaのコマンドラインアプリにAndroid用のUIでくるむことを検討してみました。多分一週間くらいちゃんと勉強すれば作れそうな気がしました。
でも今はちょっとAndroidアプリ作成の勉強をする時間が確保できない(今はjavaで自分で納得できるレベルのアプリが書けるようになりたいということで勉強中なので)ので、ChromeBookの開発者モードにjreを入れて、現時点のjavaアプリをそのまま使っちゃえばいいじゃんという発想に至りました。
前置きが長くなりましたが

で数分でLinuxの環境ができてしまいました。
前提知識を持っていなかったので、開発者モードってChromeBookの普通の環境を動かしている土台のLinuxを公開するモードなのかなと思っていましたがもしかしてChromeBookのOSの上で動く仮想OSとかコンテナなのかも。このあたりはおいおいググって調べてみようと思います。
Linuxのシェルが開きましたので、最初はlsコマンドなどが動くことを確認。ChromeBookのメニューに「vim」とか出てきたので起動してみると本当にvimっぽい。

java --version

と打ってみましたがjavaなんて知らないって言われてしまいました。
ググってみましたら

sudo apt-get install default-jre

でjreが入るようです。

$ java --version
openjdk 17.0.10 2024-01-16
OpenJDK Runtime Environment (build 17.0.10+7-Debian-1deb12u1)
OpenJDK 64-Bit Server VM (build 17.0.10+7-Debian-1deb12u1, mixed mode, sharing)

PCで動かしているhtml生成のコマンドラインアプリを持ってきて動かしてみましたら、無事動きました。

2024年03月29日 ChromeBook CZ1000DV

どこまでも文字コードが付きまとう

javaでgradle使ってプログラム作るの第2弾。poiでexcelファイルを作る。

cell.setCellValue("日本語文字列");

ってやったら文字化けした。
poi側で何か文字コード設定があるのかと思ってググるのだけれどあまりヒットしない。日本語フォントを設定すれば文字化けが直るとか書いてあるサイトもあったけれどフォントを指定しても直らない。
しばらく悩んで

System.out.println("日本語文字列");

したらこっちも文字化けした(笑)
そうだった、build.gradle.ktsに

tasks.withType<JavaCompile>().configureEach {
    options.encoding = "UTF-8"
}

って書いてUTF-8でビルドしなきゃならないんだった

引き続き、
Excelのxlsxファイルを読み込んで条件付きで文字色を変更して別ファイルに保存させるプログラムを書こうと四苦八苦。OPCPackageってなんだかわからないけれどpoiのサイトのサンプルのコピペで

OPCPackage pkg = OPCPackage.open(new File("indata.xlsx"));

って書いてファイルを読むと読み出ししたいだけなのにファイルが何か更新されてしまうみたい。結局

XSSFWorkbook wb_r = (XSSFWorkbook) WorkbookFactory.create(new File("indata.xlsx"), null, true);

って書いて解決。create()の3番目の引数がread onlyにするフラグらしい。
でもなんか別ファイルを作って保存ってpoiではセル一つ一つを別ファイルにコピーする必要があるみたいで面倒らしい。poiの新しめのバージョンではメソッド一つでシートごとコピーできたりしないのかな・・・。後で調べてみる。

2024年03月20日 プログラミング雑談

javaでifを使わずにnullじゃなかったら実行する

javaでもC++でも良いのですけれど、コードを書いているとnullチェックのif文が並んで、なんだかなぁ、と思うことが多いです。
例えばjavaで次のような感じ。クラスAaa、Bbbなどは省略します。

public class App {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            create(args[i]);
        }
    }

    private static void create(String devName) {
        Map<String, Supplier<Xxx>> factory = new HashMap<>();
        factory.put("A", Aaa::new);
        factory.put("B", Bbb::new);
        Supplier<Xxx> sup = factory.get(devName);
        if (sup != null) { // ★
            Xxx xxx = sup.get();
            System.out.println(xxx.getProduct());
        }
    }
}

factory.get()のところをgetOrDefault()使ってnullが返らないようにする手もありますが、このケースでは本来エラーになるケースでsup.get()で無駄なインスタンスを生成してしまうのでいやだなぁと。
もう20世紀じゃない。javaでNullじゃなければ実行する、みたいなスマートな方法があるはず。どう調べればよいかわからないのでたどり着くのに時間がかかりましたが、こんな方法があるようです

    private static void create(String devName) {
        Map<String, Supplier<Xxx>> factory = new HashMap<>();
        factory.put("A", Aaa::new);
        factory.put("B", Bbb::new);
        Optional<Supplier<Xxx>> optxxx = Optional.ofNullable(factory.get(devName));
        optxxx.ifPresent(sup -> System.out.println(sup.get().getProduct())); // supにoptxxxが入る
    }

java.util.Optionalを使ってofNullableで「この変数、nullかもしれない」と申告しておいて、ifPresentで「もしnullじゃなかったらヨロシク」ってことらしい。
このコードではifPresentで実行までしていますが、生成したインスタンスを返して戻り先で実行させるならこんな感じ。「nullかもしれない」値をOptionalに入れて処理して、最後にorElseでインスタンスを取り出すみたい。

        Optional<Supplier<GenHtml>> maker = Optional.ofNullable(factory.get(htmlMode.toLowerCase(Locale.getDefault())));
        Optional<GenHtml> makerMethod = maker.map(zz -> zz.get());
        return makerMethod.orElse(null);

最初の方の例はこのページに書くためにでっち上げたコードだったけれど、こっちは自分のコードからコピペ。
多分読み慣れればifでnullチェックするよりも読みやすくなるのでしょうね。

問題というほどの問題ではないのですが、ifPresentやmapの中でラムダ式を使うのでjacocoではサイクロマチック数を一つ使ってしまうのですよね。Optionalの処理をメソッドにして追い出してしまうとかいう使い方を想定しているのでしょうかねぇ。

2024年03月10日 プログラミング雑談

匍匐前進

今年作っていたjavaのプログラム、VSCodeでMavenを使っていましたが、gradleも使ってみたくて。

VSCodeなのでGradle for Javaのプラグインを入れて、コマンドパレットで"Create a Gradle Java Project"でKotlinでJUnit5だったかな、そんな感じで選んでプロジェクトを作成。
もう一歩進むたびにやり方をググって・・・
依存パッケージの設定はbuild.gradle.ktsに

dependencies {
    // This dependency is used by the application.
    implementation("org.jsoup:jsoup:1.17.2")
    implementation("org.apache.logging.log4j:log4j-api:2.22.0")
    implementation("org.apache.logging.log4j:log4j-core:2.22.0")
}

とか書いて、VSCodeの左の象のアイコン→Tasks→build→buildしたらエラー。
どうやらbuild.gradleを更新したらUpdateする必要があるみたい。Mavenの時はpom.xmlを更新すると更新しますかみたいなメッセージボックスか何かが出てUpdateされていたみたいですが、まだ私の環境はbuild.gradleを更新しますかみたいなメッセージボックスか何かが出ているのですが反映されていないみたい。(追記)JDKとJREをインストールしなおしたら解決しました
とりあえずVSCodeを終了して立ち上げなおせば反映される。

Javaのソースファイルとテスト用データファイルを一式コピーしてbuild。今度はコンパイルが通ったけれど今度はテストでエラー。Webページのhtmlファイルを作るプログラムなので、生成したファイルの中の文字をチェックするのだけれど、UTF-8の文字列にもかかわらずShift-jisのつもりで比較している模様。UTF-8のソースファイルなのにShift-JISとしてコンパイルされているみたい。文字コードが誤認識されていてもビルドが通るとは恐るべし
VSCodeのエクステンションの設定かしらと思ってEncodeとか頑張って探すけれど設定する箇所が見つからない。
いろいろググってたらbuild.gradleで設定するらしい。このサイトの記載をそのまま使わせていただきました。

tasks.withType<JavaCompile>().configureEach {
    options.encoding = "UTF-8"
}

すっかり忘れていたけれど、Mavenの時はpom.xmlに

  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

みたいなのを書いた気がします。

VSCodeのjavaのプラグイン(?)でCreate Java Project→Maven→archetype-quickstart-jdk8とかで入ってくるcheckstyleとかjacocoとかはまだどうやったら使えるのかわからないし、log4jもまだlog4j2.xmlにパスが通っていないみたいでログが出てこないし、しばらくは前途多難な匍匐前進なのだな
でもググれば何かわかるというのは実に助かります。良い時代ですね。

2024年03月02日 プログラミング雑談

安いChromeBookも割り切って使えば悪くない

電子書籍リーダーのつもりで買ったChromeBookですが、シリンドリカルでは無いキーボードですが意外と打ちやすいので、こりゃ私のWebページ更新用の環境として使うのも悪くないかも? と思い始めています。
私はローマ字入力ではなくかなキー入力派で、普通のAndroidタブレットで適当なブルートゥースキーボードをつけてもかな入力が満足にできずに困っていたのですが、このChromeBookは普通にかな刻印ありのキーボードが付いてまして、普通にかなキーが使えています。Windowsで言うところのIMEは標準の英数字(日本語)キーボードだと思います。
WindowsではIMEのON/OFF切り替えはデフォルトではTABキーの上の日英キーですけれど、このトグル動作がいまいち不便なので変換キーでIME ON、英数キーでIME OFFに設定していました。ChormeBookでは英数キーの位置にメニューボタンらしいものがありますのでこれをIME OFFとして使うことはできないのですが、Windowsの無変換キーの位置にある英数キーでIME OFFできるのでこれはこれで便利。Windowsでも無変換キーでIME OFFにする設定で使い始めました。何年もWindows使っていますけれど、無変換キーって押したことなかったかも。

エディタはJota+。Aキーの横がChromeBookはメニューボタンですし、薄っぺらいキーボードですのでctrlキーが押しにくいのであれですが、Jota+ってctrl-hやctrl-mといった昔懐かしいショートカットが使えるんですよね。ダイヤモンドカーソル(って言ったっけ?)は使えないみたいですけど。これ書きながら、もしかしたらと思ってヘルプを見たらショートカットキーは自分で設定できる模様。ダイヤモンドカーソルしたければ設定できますね。もっとも職場でWindowsを使わなくてはならないのでダイヤモンドカーソルに体が慣れてしまうと仕事にならないかも。
ってことで、ここまでChromeBookで書いてみました。

2024年02月24日 ChromeBook CZ1000DV

Java AutoValueの私的なメモ

Effective Javaで今更ながらJavaを勉強中
最初の方の章でdataクラスを作るならequalとかちゃんとやらなきゃだめだよとか書いてあるみたい。自分で定義した値クラスを比較してないなら問題ないんでしょ? と思いながら、ちょっとお試し。
githubのAutoValue
detailed documentationをまるっとコピーしてしまうと、コード側の使い方はこんな感じらしい。@AutoValueというアノテーションを書くこととabstractクラスにすることがポイントらしい。インスタンス生成するためにabstractじゃないクラス名が必要だからcreateメソッドも必要ってことかな。

import com.google.auto.value.AutoValue;

@AutoValue
abstract class Animal {
  static Animal create(String name, int numberOfLegs) {
    return new AutoValue_Animal(name, numberOfLegs);
  }

  abstract String name();
  abstract int numberOfLegs();
}

mavenの場合pom.xmlには次のように書くみたい。${auto-value.version}は適切なバージョンに置き換える。

<dependencies>
  <dependency>
    <groupId>com.google.auto.value</groupId>
    <artifactId>auto-value-annotations</artifactId>
    <version>${auto-value.version}</version>
  </dependency>
</dependencies>

これだけだとAutoValue_Animalなんてクラス知らないって言われるので次の記載も必要みたい

<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>com.google.auto.value</groupId>
            <artifactId>auto-value</artifactId>
            <version>${auto-value.version}</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
  </plugins>
</build>

これでビルドするとtarget/generated-sourcesの下にAutoValue_Animal.javaが作られる。
私はたいしてjavaのコードを書いていないからこれまでこういうことを知らなくても実害はなかったけれど、コンテナに自作クラス(のインスタンス)を入れて何かさせる場合はequalとかちゃんと作らなきゃならないようなので、今は実害が無くてもちゃんと作る習慣を今からつけていかないと将来発見が難しいエラーを作りこんでしまうって事だろうな。

2024年02月24日 プログラミング雑談

サイクロマチック数 max 5の世界

久しぶりにプログラムを書くといろいろ勉強になりますね。
今回の一番の収穫はメソッドのサイクロマチック数をmax 5で作るのも良いものだ、という事を実感したことかもしれません。
最初はmavenの環境をチュートリアル見ながら構築したらデフォルトでそのような設定になっていたというだけなのですが、これがデフォルトという事は何か意味があるに違いないと思ってmax 5縛りで作ってみました。
最初に影響が出たのがswitch文。こんなの使うとあっという間にサイクロマチック数5を超えてしまいます。ファクトリーメソッドで処理を切り分けるようにしました。ファクトリーメソッドでもファクトリー部分で分岐が出ないようにArrayListとかに選択肢を詰め込んでおいてget(key)で探したりforeachで探したり。
次にif文の使用。メソッドの責務をシンプルにして、メソッドの上から下まで条件分岐なしでいかに流しきるか考えるようになりました。今回作っていたプログラムは、テキストファイルを読み込んでhtmlに変換して書き出すというシンプルなコマンドラインプログラムでした。メソッドの入り口で「入力ファイルを確認する」みたいなメソッドでチェックして、NGならエラーリターンし、その後の処理は余計なことは考えずに上から下まで一気に流す、みたいなスタイルになっていきました。

そのうちメソッドのサイクロマチック数 max 5はまあ普通に守れるようになってきましたが、次にクラスでmax 20という条件で引っかかるようになりました。メソッドが1つあればサイクロマチック数も最低1あるという数え方ですので、クラスのメンバー変数がいくつかあってsetter、getterを書き始めるとたちまち超えます。setter、getterは今回はあまり書かないで作ってみました。これが正しい対処法かどうかわかりませんが、
それよりも「もし入力ファイルが無かったら」はFileReaderクラスの責務、「もし入力ファイルの記載が間違っていたら」は処理するクラスの責務、みたいにクラスの責務を整理して、一つのクラスで処理しなければならないメソッドを減らすことに注力してました。
テキストファイルを読み込んだり、htmlをファイルに書き込んだりするのはhtmlを生成するクラスの責務ではないよね、ということで、ファイル読み書きは別クラスに切り出したり。

おかげで単体テストコードも書きやすいです。まだあまり書けていませんが、これまでコードの構造のせいでテストが書きにくいといった事には出くわしていません。
まだ単体テストを一通り書いていないのにこんなことを言うのもなんですが、単体テストってプログラマーの意図通りコードが書けているかどうかのテストなのだなぁと実感していました。単体テストが通っているのに出力されたhtmlファイルが意図通りではないことが頻発しています。これはplaywrightみたいなツールで結合テストするしかないのかもしれないですね

そうそう、サイクロマチック数とは関係ないかもですが、今回は(今回こそ)設計書をちゃんと書くぞと(まだ)思っています。DoxygenとかplantUMLとか使ってちまちま書いています。
私が飽きるのが先か、テストや設計書を作り切るのが先か、どうなるんでしょうね?

2024年02月04日 プログラミング雑談

ページのレイアウトをいじってました

ページの見た目をマイナーチェンジしました。
パソコンで見たときに、中途半端なウインドウ幅にしたときにレイアウトが崩れるのを放置していましたが、私のところではちゃんと表示するようにしたのと、スマホで見たときに少し見やすい感じを狙ってみました。
今回いじったのはcssファイルが中心で、ブラウザのキャッシュをクリアしないと変更が反映されないかも。
PC(firefox、chrome)とChromeBook(chrome)ではまあ想定通りの表示になったけれど、スマホのchromeでなぜか右に余白ができて右スクロールができてしまうのがちょっと気になる。あとはスマホのchromeで縦スクロールがカクカクする感じ。私の今のスマホ、5年位経ってたっけ・・・
(追記)スマホで右スクロールになってしまう件、ログ出力の英文がブラウザからは一単語に見えて改行できず、長い長い1行で表示していたためだったようです。cssファイルに

word-break: break-all;

って書いたら直りました。

2024年02月03日 このページのリフォーム

javaで正規表現

このページをテキスト形式からhtmlに変換するプログラムはC++で2009年に書いたものです。
これをjavaでjsoupを使って書き換えようと思い始めて多分2週間。
機能実現検証用の試作が動きました・・・。
もう若くないので夜更かしはできないし、平日昼間は仕事だし、このwebページをjava版の変換プログラムで作るのは2月に入ってからかなぁ。
秀丸の置換とかsedとかgawkで正規表現を便利に使っていますがjavaの場合のやり方を少しメモ。

Pattern pattern = Pattern.compile("^[ \t]*&([^:]+):") ;
Matcher matcher = pattern.matcher(inLine);
if(matcher.find()) {
    if(matcher.group(1).equals("end")) {

とかすると、"&end:"が検出できる模様。Patternの行からfindの行までは1行で書けるので、それなりにすっきり書くこともできるのですね。
はまったポイントは数字とマッチする"\d"は"\"自身がエスケープ文字なので"\\d"と書かねばならないとか、find()まで実行しないとgroupが使えないところですかね。

2024年01月21日 プログラミング雑談 このページのリフォーム

VSCodeでmavenでJUnitとかjacocoとか

割と最近までVisualStudioでC++の人だったのでjavaとかVSCodeとか、何かしようとするたびに壁にぶつかる今日この頃。
ググりまくりなのだけれど、右も左もわからない初心者なのでググるキーワードが多分不適切なのでしょう。全然情報が見つかりません・・・(涙)
VSCodeでExtension Pack for JavaとかMaven for Javaを入れて、簡単なコードを書いて、JUnitのテストコードを書いて実行してみてます。
コマンドパレットで"Maven Execute Commands..."で"install"を実行すると多分実行jarを作ってくれて、JUnitのテストを実行してくれて、カバレッジまで測ってくれるようです。ステキ。
そしたら間もなく
[WARNING] Rule violated for method com.segu.Index.addText(org.jsoup.nodes.Element, java.lang.String): complexity total count is 7, but expected maximum is 5
とか言われ始めました。
悪かったね! どうせ私のコードはスパゲッティだよ! とか思いながら、とりあえずcomplexityのmaximumを8とかにすれば良いんでしょ?ってことで、VSCodeのsettings.jsonとかに何か書けばいいんだろうなと思いながらググること何時間?。結局解決策がわからず、
[ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.4:check
で"install"がエラーになってから手動でJUnitのテストを実行してました。
pom.xmlを見ると

<maximum>${jacoco.unit-tests.limit.method-complexity}</maximum>

という行があったので、method-complexityというパラメタ名でググったけれどわからず。
あきらめてcomlexityのチェック行をpom.xmlから全削除するという暴挙に出てERRORを回避して何日か過ごしました。
で、
別件でpom.xmlを見てたら

<jacoco.unit-tests.limit.method-complexity>5</jacoco.unit-tests.limit.method-complexity>

なんて行があるではないですか。なんだ、pom.xmlの中で上限値を設定してたのかよ!ってことで、ここで上限値を8とかにしたらWARNINGもERRORも消えてすっきり

で、さらに私の前に(多分客観的には低い)壁が出現するわけですよ
JUnitのテストはlog4jで何のテストを実行したかログを出力したいので、log4j2.xmlが見えるようにクラスパスを設定したいのだけれど、どうやったら設定できるかわからずに半日ググった結果、このサイトを見つけました。
いや、見つけたってなんだよ。VSCodeのMavenプラグインが設定してくれたpom.xmlにmaven-surefire-pluginって書いてあんだから、surefireのオフィシャル見に行くのは当然だろ!って気もしますが、わかんないことばかりでどこを見に行って何を読めばいいかわかんないんですよ....と言い訳しておきます。
私はプロジェクトのルートにlog4j2.xmlを置いているのでpom.xmlに次のように書けばよいみたいです。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>${maven-surefire-plugin.version}</version>
  <configuration>
    <additionalClasspathElements>
      <additionalClasspathElement>./</additionalClasspathElement>
    </additionalClasspathElements>
  </configuration>
</plugin>

数日経つと忘れちゃうんだろうなという事で記録を残してみます。備忘録かよっ

2024年01月20日 プログラミング雑談

Jsoupの使い方がよくわかんない

このWebページを生成するプログラムをC++11以前の古いC++で作っていたのをjavaでjsoupを使って書き換えようという気分になって書き換え始めたのだけれど、jsoup自体初心者なので細かい問題にぶつかってばかり。
最初はjsoupでnodeとかdocumentとかelementとかの使い分けがわからないところからスタートしているのでjavadocっぽいドキュメントを頑張って読んでいました。
その後はxmlヘッダーやドキュメントヘッダーの付け方に悩み、今は改行の付け方に悩んでいます。
一応このページはXHTML 1.0 Strictで作っているので、改行は<br />なのですが、appendElement("br /")だと閉じタグが生成されて<br /></br />になってしまうんですよね。
appendElement("br")ならばならば閉じタグが作られず<br>だけが生成されるのに。
もしかしてjsoupでこれはxhtmlだとかhtml5だとか教えることができて、その辺の設定ができるとうまいことやってくれるのかしら?
(追記)やっとわかった。XHTMLだから、jsoupをhtmlモードではなくxmlモードで動かさなければならない模様。

doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml);

してからdoc.outerHtml();すれば良いんだ!
とりあえずXHTMLの骨組みはこんな感じで生成できそう

doc = new Document("");
XmlDeclaration xmlDecl = new XmlDeclaration("xml", false);
 
xmlDecl.attr("version", "1.0");
xmlDecl.attr("encoding", doc.charset().displayName());
DocumentType docType = new DocumentType("html", 
"-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
 
doc.appendChild(xmlDecl);
doc.appendChild(docType);
 
Element html = doc.appendElement("html");
html.attr("xmlns","http://www.w3.org/1999/xhtml");
html.attr("xml:lang","ja");
html.attr("lang","ja");
Element head = html.appendElement("head");
head.append("<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />");
head.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
head.append("<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />");
doc.title("MyPage");
Element body = html.appendElement("body");
 
Element ddd = body.appendElement("div");
ddd.appendChild(new Comment("Comment Node"));
ddd.appendChild(new TextNode("TextNode"));
ddd.appendElement("br");
ddd.appendText("&");
 
doc.outputSettings().indentAmount(0);
doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
 
doc.outerHtml();

誰かのお役に立てれば。

2024年01月13日 プログラミング雑談 このページのリフォーム

短波ラジオPL-330メモ

マニュアルを見ないとわかりにくい使い方をメモ
PL-330

スリープタイマー設定

電源OFF状態でPOWER長押し → チューニングダイヤルでタイマー時間設定
次から電源ONでスリープタイマーになる
スリープタイマーをOFFにするには再び電源OFF状態でPOWER長押ししてタイマー時間をOFFに設定する。

自動電源ON設定(アラーム)

電源OFF状態でALARM長押し → チューニングダイヤル(時)と音量ダイヤル(分)でON時刻設定 → ALRAM → チューニングダイヤルでONし続ける時間(分)を設定 → ALRAM

自動電源ON状態から操作可能な状態にする

POWER を押す = 操作を受け付けるようになる

自動電源ON状態(アラーム)を一時的に止めてスヌーズ

DISPLAYを押す = 自動電源ONを一時的に止めて、5分後に再び自動電源ON

自動電源ON時の放送局設定

聞きたい放送局に合わせ、"M" → ALARM → Enter(リターン);

中波放送のアンテナ切り替え(マニュアル非掲載)

中波放送受信中に "3"ボタン長押し → CH-S と表示される。バンド表示が"SW"も表示される。
この状態で、アンテナが内蔵バーアンテナから短波・FM用のロッドアンテナ(またはアンテナ端子に接続された外部アンテナ)に切り替わっている。受信周波数を変更するなど、何か操作すると表示は変わらないけれどアンテナが内蔵バーアンテナに戻ってしまう模様
再び "3"ボタン長押し → CH-A と表示され、バンド表示の"SW"も消える。アンテナが内蔵バーアンテナに戻る。

SSB受信時の周波数のキャリブレーション(マニュアル非掲載)

SSB受信中 チューニングステップを10Hzにしてゼロビートを取って "LSB"長押し するとその周波数がKHz単位に丸められる。(上手に表現できなくて申し訳ない)

ファームウェアバージョン表示(マニュアル非掲載)

電源OFF時にVF/VM長押し
ディスプレイがすべて表示され、次に右上に3306等と表示される。おそらく上2桁が機種を表し、下2桁がファームバージョン。
ファームバージョン 3305 は、SSB受信時に10Hzステップでチューニングしていてもチューニングダイヤルを早めに回すと50Hzに自動で切り替わる模様。
ファームバージョン 3306 は、チューニングステップが自動で切り替わらなくなっている模様。

2022年04月23日 短波ラジオ PL-330

Valid XHTML 1.0!Valid CSS!