20210117のJavaに関する記事は10件です。

複雑なfor文

複雑なfor文

❶初期化処理 ❷繰り返し条件 ❸繰り返し時処理の3つを工夫し、高度な繰り返しを実現

単に「◯◯回繰り返す」という単純な繰り返しではなく、下記のようにすれば少し高度な繰り返しが行える

//ループ変数を1からスタートする
for (int i = 1; i < 10; i++){...}

//ループ変数を2ずつ増やす
for (int i = 0; i < 10; i += 2){...}

//ループ変数を10から1ずつ1まで減らしていく
for (int i = 10; i > 0; i--){...}

//ループ変数を初期化しない
for (; i < 10; i++){...}

//繰り返し時の処理を行わない
for (int i = 0; i < 10;){...} 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

複雑なfor文(基礎)

複雑なfor文

❶初期化処理 ❷繰り返し条件 ❸繰り返し時処理の3つを工夫し、高度な繰り返しを実現

単に「◯◯回繰り返す」という単純な繰り返しではなく、下記のようにすれば少し高度な繰り返しが行える

//ループ変数を1からスタートする
for (int i = 1; i < 10; i++){...}

//ループ変数を2ずつ増やす
for (int i = 0; i < 10; i += 2){...}

//ループ変数を10から1ずつ1まで減らしていく
for (int i = 10; i > 0; i--){...}

//ループ変数を初期化しない
for (; i < 10; i++){...}

//繰り返し時の処理を行わない
for (int i = 0; i < 10;){...} 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

<java> awtで"EXCEPTION_ACCESS_VIOLATION"が出たとき

前書き

大学のjavaの課題でawtを使おうとしたところ,大量のエラーが出て小一時間格闘したので解決策を残しておきます。
初めての記事なのでご了承ください。

環境

OS : Windows10
JDK : 15.0.1
JRE : 15.0.1

後述のエラー文にこのような記述があったのでそれを参考にしています。
vm_info: OpenJDK 64-Bit Server VM (15.0.1+9-18) for windows-amd64 JRE (15.0.1+9-18)

筆者はInteliJIDEA Ultimateをエディタとして利用しており,インストール時点でjdkもjreもなかったのでIDEAの指示に従って一番新しいものをインストールした形です。

症状

ソースコード
AWTGraphics.java
import java.awt.*;

public class AWTGraphics extends Canvas
{
    static final int WORLD_W = 320;
    static final int WORLD_H = 240;

    public void paint(Graphics g)
    {
        g.setColor(Color.red);
        g.drawLine(0, 0, WORLD_W, WORLD_H);
        g.setFont(new Font("Dialog", Font.PLAIN, 20));
        g.drawString("Hello, awt!", 0, WORLD_H / 2);
    }
    public static void main(String[] args)
    {
        Frame frame = new Frame("AWTGraphics");
        frame.setBackground(Color.black);
        AWTGraphics canvas = new AWTGraphics();
        canvas.setPreferredSize(new Dimension(WORLD_W, WORLD_H));
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);
    }
}
正しく実行できたとき

スクリーンショット 2021-01-17 224536.png

エラー文(抜粋)
hs_err_pid4364.log
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff83d8902ae, pid=4364, tid=2572
#
# JRE version: OpenJDK Runtime Environment (15.0.1+9) (build 15.0.1+9-18)
# Java VM: OpenJDK 64-Bit Server VM (15.0.1+9-18, mixed mode, sharing, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [awt.dll+0x902ae]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

エラー文が長くてとても読めたものではないので先頭の数行分だけ載せています。
筆者もまともに読んでいません。

どうやらIDEAはとても優秀なようでスタックやメモリの状態まで詳細にエラーログとして出力してくれていますが,
ほとんど関係がないです。

注目すべきはここでしょうか

# C  [awt.dll+0x902ae]

どうやらこの"awt.dll+0x902ae"というJREにあるファイルが悪さをしている模様。
しかしJREの"/bin"ディレクトリにある.dllなのでこのファイルを直接書き換えたりはおそらくできません。

解決策①

実行するときにファイルエンコーディングで違う文字コードを指定してあげると治るみたいです。
筆者の環境ではデフォルトのファイルエンコーディングはUTF-8だったので,これをWindows-31j(Shift-JIS)に変えました。

InteliJIDEAで変えるとき

IDEAのSettings -> File Encodings
ここからGlobal Encoding をWindows-31jに変更しました。
スクリーンショット 2021-01-17 230753.png

しかしこれだとすべてのプロジェクト実行時にWindows-31jでエンコーディングすることになり,後々面倒なことになるかもしれません。
(詳しくはありませんが,特に理由がない限りはUTF-8でなるべくエンコーディングするのが好ましいと筆者は考えています)

その場合はProject Encodingだけ変更するのがいいかもしれません。

コマンドラインで変えるとき

ほとんどの場合こちらだと思います。bashやcmdでjavaコマンドを叩くときですね。
末尾にファイルエンコーディングオプションをつけてあげればいいです。

お好きなコマンドラインツールで
java -Dfile.encoding=windows-31j AWTGraphics 

ファイルエンコーディングを変える方法はいくつかあると思います。お好きなように。

解決策②


JREのバージョンを下げるのも方法の一つとして試されてる方がいました。
解決策①で治らない方は試してみるといいかもしれません。
しかし色々調べても,どこまでバージョンを下げれば治るのかがわからないので筆者は試していません。

参考資料

https://qiita.com/solabito331/items/fad5a1eea3176aadd9f7

https://teratail.com/questions/260615

https://stackoverflow.com/questions/6448163/a-fatal-error-has-been-detected-by-the-java-runtime-environment-sigsegv-libjvm

https://teratail.com/questions/297104
↑実際に試して筆者が解決した方法です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Azure Java開発用のサンプルコード集

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java O/Rマッパーの種類と選定方法について調べたことのメモ

O/Rマッパーとは

「O/Rマッパー」って名前、なんか小学生の必殺技的な響きしてますよね。
最近業務で色々なO/Rマッパーに触れる機会があったので、ついでに調べたことをざっくりまとめました。

O/Rマッピングとは、オブジェクト指向プログラミング言語におけるオブジェクトとリレーショナルデータベース(RDB)の間でデータ形式の相互変換を行うこと。
IT用語辞典 -O/Rマッパーとは

簡単に言うとJavaなどのプログラミング言語とRDBの橋渡しをしてくれるものです。

もっと詳しく知りたい方
オブジェクト関係マッピング
O/Rマッピングの役割とメリット

先に結論

それぞれメリット・デメリットがあるため、どのO/Rマッパーが良いかはプロジェクト次第。
色々調べるよりまずはこれ読んでください。Java ORマッパー選定のポイント

O/Rマッパーの分類

要約するとこんな感じ。
JDBCラッパー型   初心者にとって理解しやすい。冗長的になりやすい。
SQLマッパー型     ↑
クエリビルダー型    ↓
O/Rマッパー型   学習コストがかかる。自由度が高いが運用の難易度も極めて高い。
下記は代表的なO/Rマッパーをリストアップしました。

  • JDBCラッパー型
    • Spring JDBC
    • DbOom
    • Apache Commons DbUtils
    • sql2o
  • SQLマッパー型
    • MyBatis
    • DOMA
    • Migrate SQL
    • jdbi
  • クエリビルダー型
    • jOOQ
    • DBFlute
    • Reladomo
    • Querydsi
    • Ebean
    • Speedment
    • Jinq
    • requery
    • Cayenne
    • Torque
  • O/Rマッパー型
    • JPA
    • EclipseLink
    • Hibernate

各O/Rマッパーの特徴

Spring JDBC

Spring Framework内で使用できるJDBCラッパー。
⭕️ Connection、PreparedStatementを開発者が意識しなくて良い。
⭕️ ResultSetから詰め替えるところを記述するだけで良い。
⭕️ Java EE環境など他の環境でも使える。
⭕️ 初心者がプログラミング言語とRDBとの繋がりを理解しやすい。
❌ SQL部分をクラスファイルにベタ書きするため、同じようなデータを取得する際に使いまわすことができない。やや冗長。メンテナンス性が悪い。
❌ Javaのクラスファイルにベタ書きするため、コーディング中に文法等のエラーを検知しない。そのため、実行して初めて気づくことが多い。

iciql

JDBCのライブラリ集の一つ。
⭕️ 単一のjarファイルで提供されている
⭕️ 設定ファイル無しで使用可能(xmlで設定する必要なし)
⭕️ JDBCの記述を簡素化することができる。
❌ 自動生成されるSQLの日付関連の処理に課題があるらしい?
[Java]iciqlで簡単DBアクセス[ORマッパー]
ICIQL導入をしてみる
O/Rマッパー iciqlについて

DbOom

JDBCのライブラリ集の一つ。
⭕️ 単一のjarファイルで提供されている
⭕️ JDBCの記述を簡素化することができる。
❌ 日本語の文献が少ない
DbOom(公式)
以下下記サイトのコピペJavaのDBアクセスライブラリ比較

Joddは機能ごとに切出せて何かと使いやすそう。
実行されるSQLをパラメタ埋め込み状態で取得でき、デバッグに有利。
Modelをそのまま保存できるinsert()あり。updateにも補助スクリプトあり。
セッションとかの機能もついてるのはいいかも。
トランザクションは一通りのサポートあり。
Camel <-> snake 変換機能あり。
キャッシュもあるらしい。
初期設定は自分で細々積み上げる必要があるが、必要な道具は一通り揃ってる感じ。
余計なことしないのはいいけど、面倒かも。
JoddのJTXは他のライブラリ使うときも切り出して使えそう。

Apache Commons DbUtils

JDBCのライブラリ集の一つ。ライブラリ自体の記述量が少なく、高速に動かすことを目的としている。
⭕️ 単一のjarファイルで提供されている
⭕️ JDBCの記述を簡素化することができる。
❌ あまり高度な機能はない。
Apache Commons DbUtils(公式)

MyBatis

SQLマッパー型。
SQLをXMLファイルに記述する。
⭕️ 公式ドキュメントが超他言語対応しているため、オフショア開発や英語アレルギーの日本人にも優しい笑。(英語・日本語・中国語・スペイン語・・・)
⭕️ SQLの自由度が高い
❌ XMLのルールが面倒。不等号や条件分岐の記述の扱いをしっかり理解する必要がある。

DOMA

SQLマッパー型。
個人用のプロジェクトや複雑な処理がないシステムにピッタリのO/Rマッパー。エンティティ一つでCRUDできる処理が多い場合に用いられる。
⭕️ 2WaySQL。

2WaySQLとは、簡単に言うと、SQLをそのまま貼り付けても実行できるし、アプリケーションでパラメータを可変にしても実行できるというSQLのことです。

引用元【超初心者向け】MirageSQL超入門
⭕️ DBの1つのエンティティに対してのDMLを自動で用意してくれる。
❌ テーブル結合を要するSQLの場合はカスタムクエリを作成する必要がある。
❌ 一つのクラスファイルで二つのSQLを使用することはできない。一つ目のSQLだけしか実行されない。

jOOQ

クエリビルダー型。
⭕️ SQLが自動生成されるため、タイプミスの心配がない。
❌ 複雑なSQLを表現するのに限界がありそう?

JPA

O/Rマッパー型。
JPAは「仕様」に過ぎないため、単体で使うのではなくeclipseLinkやHibernateで実装する必要がる。
JPAは高度なことができる分、学習コストが桁違い。安易に導入すべきではない?
やはりこのサイト、最強。。。
Java ORマッパー選定のポイント(再掲)

①DBを新規に登録できる
② 集合演算やFROM句での副問合せなど、
 複雑なSQLは要件的に少ない
③ 「パーフェクトJava EE」を読破した⼈が
 プロジェクトに1⼈以上いる
1つでも当てはまらない項⽬があれば、 他のORマッパーを使った⽅がいいかも

⭕️ ベンダーサポートがある。標準技術になっている。
❌ JPAの仕様書は英語で600ページ以上学習コストが高い!ムリ!ヨミタクナイ!

eclipseLink

O/Rマッパー型。
JPAを実装するために用いる。
フレームワーク内部の処理によってSQLを自動生成してくれる。
Hibernateとやりたいことは同じだが、生成されるSQLに微妙な違いがあったりする。

Hibernate

O/Rマッパー型。
JPAを実装するために用いる。
フレームワーク内部の処理によってSQLを自動生成してくれる。
eclipseLinkとやりたいことは同じだが、生成されるSQLに微妙な違いがあったりする。

もっとマニアックなやつ(古いですが)

オープンソースJava O/Rマッピングソフト一覧(2014年1月版)

O/Rマッパーの選定方法

自分の手で書こうと思ったけど、やはりこの記事がとてもわかりやすかったので。もうこれみてください。てかここまで書いてきたけど最初からこの記事だけ見ればいいんじゃ、、、スライド62以降がもう答えなんじゃ(ry
Java ORマッパー選定のポイント

最後に

間違った点があれば遠慮なくご指摘ください。また、補足等があればコメントくださると幸いです。

いや、むしろ補足してください。
てか、本件について詳しい人、自分に教えろください。
必殺・O/Rマッパー!!!

参考文献

Java ORマッパー選定のポイント(再掲)
オブジェクト関係マッピング
DOMA
DOMA バインド変数コメント
mybatis
DBFlute
外だしSQL(OutsideSql)について
jOOQ
JavaのDBアクセスライブラリ比較
JPA、Hibernate、EclipseLinkの違い - Codeflow
JPAの基礎1(eclipseLinkについての記載有り)
【超初心者向け】MirageSQL超入門(再掲)
若手Javaエンジニア必見。知っておきたいフレームワーク・ツール23選
IT用語辞典 -O/Rマッパーとは(再掲)
[Java]iciqlで簡単DBアクセス[ORマッパー]
ICIQL導入をしてみる
DbOom(公式)
Apache Commons DbUtils(公式)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaEEとJakartaEE、どう違うの?

 よく考えてみると、わかりやすい説明がほとんどないことに気づきました。戸惑っている人も多いのではないかと思ったので、あえて、誤解をおそれず、本当のところ(と思うこと)をやさしく書いてみました。(もしも勘違いや間違いなどがあれば、お知らせください。)

Java EEのままではいけなかったの?

 2017年に、Java EEがOaracle社からEclipse財団に移譲されるという記事を見て、最初に思ったことでした。今は、大分時間が経ったので、少しわかるような気がします。背景として、クラウドネイティブという大きな潮流があったことがあげられます。

 docker(2013年)やKubernetes(2015年)のようなシステムの登場が大きな契機でした。エンタープライズシステム開発の将来を予見するような、エポックメイキングなプロダクトです。ただ、Oracle社の動きは鈍く、意欲も見えなかったので、これに対して、コミュニティでは、 Java EE Guardiansを結成(2016年)し、Orcle社へ働きかけました。そして、Microprofile(2016年)が登場する一方、ようやく、Java EE8も公開されることになりました。

 Java界のエッジの部分で大きなパラダイムシフトが起きそうなのに、Oracle社はなかなか動かない、そういうジレンマがコミュニティの活動を巻き起こし、Jakarta EEの誕生へと向かっていくことになった大きな原因だったのでしょう。

Java EE 8、そしてJakarta EE 8

 Java EE は、バージョン5(2006年)、6(2009年)、7(2013年)とバージョンを重ね、最後がJava EE 8(2017年)でした。開発の容易さを標榜して大きな成果をあげていたJavaEEですが、EE 8は、それまでのバージョンに加えて、JSFやCDIの改良、JPAのjava8対応、HTTP2への対応、そしてセキュリティAPIの追加など小さい変更に終わりました。MVCの追加も見送りになりましたが、Eclipse財団への移譲を控えて、あえて、大きな変更を避けたということだったのでしょう。
 
 Eclipse財団に移譲されたあと、移行作業が膨大なあまり、なかなか次のバージョンが出ませんでしたが、2019年にようやくJakarta EE 8が公開されました。しかし、何か新機能が追加されたわけではなく、Java EE 8のJakartaバージョンという位置づけです。
 機能を追加するには、Oracle社との権利関係にカタを付ける必要があったので、次のEE 9は、昨年12月でした。この辺りは、コロナ禍のせいばかりではなく、Oracle社が権利に固執しすぎたように思います。ただ、なんといっても営利企業ですから、仕方のないことだったのかもしれません。

Jakarta EE 9の位置づけは?

 機能的には、Jakarta EE8と変わりません。つまり、2017年のJava EE8から3年、ほぼ何も変わっていません。本当に?
 いえいえ、Javax.から始まるライブラリ(Java EEのすべてのライブラリ)がなくなり、Jakarta.から始まるライブラリに置き換わっています。これが大きな変更です。jakarta EE 9はこのために作られたバージョンです。

 Oracle社が、javaxライブラリの改訂を認めなかったので、新機能を追加するには、最低限、名前を変える必要があったのです。ただ、すぐに理解できるように、ライブラリの名称を変更すると、過去のプロダクトとの互換性が失われます。Jakarta EE9 の依存関係の元では、Java EEはもとより、Jakart EE8のプロダクトもコンパイルできません。
 影響は、PrimeFacesやOmniFacesなど、サードパーティのミドルウェア製品にもおよび、Jakarta EE9に対応しないと、使えないことになります(2021年1月現在、PrimeFacesは未対応のまま)。サードパーティ製品を使っているプロダクトは、その方面にも目配りが必要です。

 このように、影響が大きく広範囲に及ぶので、新生Jakart EEの出発点として開発されたバージョンが、Jakarta EE 9であると言えるでしょう。ですから、失われた数年間を取り戻すJakarta EEの巻き返しは、これから始まるところです。実際、コミュニティの熱気は相当なもので、今年にもリリースされるJakarta EE 10から、怒涛の快進撃(?)が始まるのではないかと期待しています。

これからどこへ向かうのか?

 そうれは、もう、マイクロサービス化へ向かうというのが、常識的な見方です。ただ、現在、Java界に氾濫している様々な専門用語を見聞きして、驚いたりする必要はありません。まだ発展途上のジャングル状態ですが、いずれ、すっきりした体系にコモディティ化するはずです。そうでなければ、広範な活用は見込めないからです。

 基本的な考え方はシンプルです。システムを小さなサービスに分けて作り、それらをまとめ上げて、大きなサービスにするということです。ですから、Jakarta REST(RESTful ウェブサービス)が開発の基本単位になるでしょう。
 Jakarta RESTは、ユーザーインタフェースを持たないので、JSFアプリケーションのようなものは作れないのかというと、そうではありません。ユーザーインタフェースは、何で作ってもいいのです。もちろん、クライアントAPIというのがあるので、Javaでも作れます。JSFでも作れますし、時期バージョンでMVCシステムが入ってくると、それも大きな選択肢のひとつになるでしょう。

 これまでとの大きな違いは、メンテナンスの容易さです。ひとつのサービスの守備範囲は小さく、明快に役割分担を行います。ですから、改訂しようとすると、どこをどうすべきか、コードの迷路に迷い込むことはありません。また、使い勝手はUIにかかる部分ですが、これは、それぞれ独立しているので、どうにでも作り変えられます。別な言語で書き直すことすら可能です。

 いいことだらけなのですが、唯一難しいのは、サービス同士の連携で、マイクロプロファイルに含まれる部分です。この部分が、現在進行形でどんどん発展しているところです。また、最近、Jakarta EEへの統合を議論するコミュニティグループが立ち上がりました。その成果が公開される頃、次のフェーズが始まるのではないかと思います。
 

  

 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaでRSA公開鍵による暗号化と復号化の方法

RSAを使った暗号化と復号化のやり方を今日も忘れたので備忘録として残しておく。

マイクロサービスアーキテクチャにおいて、ユーザーの認証情報を引き渡していくための方法として、いろいろなやり方があるが、オーバーヘッドが小さく確実にサービス側、呼び出し元の相互に認証と認可が可能なので公開鍵を使った認証済みのユーザー情報の暗号化がいいと思う。

なお、RSAの場合、鍵長に1024ビットを指定すると128バイトとなり、パディングが11バイトなので暗号化可能な文字列の長さは117バイトまでとなる。

認証済みのユーザーのIDなどを送信するには十分であるが、このあたりは注意が必要だ。

RSA鍵ペアの作成

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024); // RSA鍵の長さを指定する
KeyPair keyPair = keyGen.generateKeyPair();

KeyPair には、秘密鍵と公開鍵の両方が含まれている。

秘密鍵のPEM形式での書き出し

"-----BEGIN RSA PRIVATE KEY-----\r\n" + 
encodeBase64(keyPair.getPrivate().getEncoded()) + "\r\n" +
"-----END RSA PRIVATE KEY-----\r\n";

encodeBase64(byte[]) は64文字ずつ改行を入れたBase64エンコードを行う関数。

公開鍵のPEM形式での書き出し

"-----BEGIN PUBLIC KEY-----\r\n" +
encodeBase64(keyPair.getPublic().getEncoded()) + "\r\n" +
"-----END PUBLIC KEY-----\r\n";

公開鍵での暗号化

RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);

String encrypted = Base64.getEncoder()
    .encodeToString(cipher.doFinal(plainText.getBytes("ISO-8859-1")));

暗号化モードとして ECB を利用しているので、平文が同じ場合は常に同じ暗号文になる。これが許容できない場合はデータの頭にでも乱数でIVの代わりとなるダミーデータを入れておくとよいだろう。

秘密鍵での複合化

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPublic());

String plainText = new String(
    cipher.doFinal(Base64.getDecoder().decode(encrypted)), "ISO-8859-1");

まとめ

JWTほど面倒ではなく、あらゆる言語環境で共通して利用可能なRSAによる暗号化はマイクロサービス間の認証と認可の現実解だ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Listについて【Java】

初期化① add

Main.java
package com.test;

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> animals = new ArrayList<>();
        animals.add("dog");
        animals.add("cat");
        animals.add("pig");
        System.out.println(animals); // [dog, cat, pig]
    }
}

初期化② Arrays.asList

※固定サイズのリストになるので注意
参考:Java - Arrays.asList の注意点

Main.java
package com.test;

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> animals = Arrays.asList("dog", "cat", "pig");
        System.out.println(animals); // [dog, cat, pig]
    }
}

現在要素数を返す size

System.out.println(animals.size()); // 3

indexを指定して要素の参照 get(index)

0→1番目の要素を参照
1→2番目の要素を参照
2→3番目の要素を参照
...etc

 for (int i = 0; i < animals.size(); i++) {
     System.out.print(animals.get(i) + ","); // dog,cat,pig,
 }

indexを指定して削除 remove(index)

0→1番目を削除
1→2番目を削除
2→3番目を削除
...etc

animals.remove(1);
System.out.println(animals); // [dog, pig]

全ての要素を削除 clear

animals.clear();
System.out.println(animals); // []
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Processing ライブラリ "ControlP5", "Fisica" を使って遊ぼう

こんにちは。最近は趣味でProcessingにハマっています(予定)
Processingオリジナルのライブラリとして"ControlP5"と"Fisica"があります。
実際に作ってみたものを例に、どのようなことに使えるのか、注意点も混じえて解説出来ればと思っております。

実物

My-Movie-5.gif
※2倍速です。

コード

ライブラリの追加

「スケッチ」→「ライブラリをインポート..」→「ライブラリを追加..」から検索してください。
スクリーンショット 2021-01-15 8.57.49.png

あとはコードの初めに以下を書きます。

sketch.pde
import controlP5.*;
import fisica.*;

これでどちらのライブラリのモジュールも利用することが出来ます。

setup()

ControlP5

一言で言うとGUIコントローラーを簡単に作成できるライブラリです。

Accordion, Background, Bang, Button, ButtonBar, Chart, CheckBox, ColorPicker, ColorWheel, ControlGroup, Controller, ControllerGroup, DropdownList, FrameRate, Group, Icon, Knob, ListBox, Matrix, MultiList, MultiListButton, Numberbox, Radio, RadioButton, Range, ScrollableList, Slider, Slider2D, Spacer, Tab, Textarea, Textfield, Textlabel, Toggle リファレンス

様々なものがあることが分かりますね。

sketch.pde
ControlP5 slider;
ControlP5 button;
ControlP5 toggle;
int sliderValue;

void setup(){
  size(500,500);
  int r = color(255,0,0);

  //スライダー
  slider = new ControlP5(this);
  slider.addSlider("sliderValue") // スライダーの追加
    .setRange(2,180) // 値の範囲
    .setValue(25) // 値の初期値
    .setPosition(50,40) // スライダーの座標
    .setColorValue(r) // キャプションラベルの色
    .setSize(300,20); // スライダーの大きさ

  // Display the current value of the slider
  slider.getController("sliderValue")
    .getValueLabel()
    .align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE)
    .setPaddingX(-20);

  // ボタン  
  button = new ControlP5(this);
  button.addButton("drop_circle") // 実行する関数
      .setLabel("Drop")  // 表示するテキスト
      .setPosition(25, 400)
      .setSize(100,40);

  // トグルスイッチ
  toggle = new ControlP5(this);
  toggle.addToggle("appear_slope") 
      .setLabel("") // 記述しないとID名が付与されてしまう。
      .setMode(ControlP5.SWITCH) // スイッチのデザイン
      .setPosition(25,450)
      .setSize(100,40)
      .setValue(false);
  ...
//

@akspectさんの記事のものを参考にさせていただきました。インスタントメソッドに関しては、より網羅されているかと思います。

Fisica

こちらも一言で言うと物理シミュレーションライブラリです。
球体から多角形まで幅広いラインナップです。

sketch.pde
FWorld world;
FBox box, slope;
FCircle ball;

void setup(){
  ...
  Fisica.init(this); // 初期化(おまじない
  world = new FWorld(); // これにオブジェクトを追加していきます(おまじない

  // 
  box = new FBox(100,40);
  box.setPosition(75,420);
  box.setStatic(true); // 物体を静止させる
  world.add(box); // 追加

  slope = new FBox(500,2);
  slope.setStroke(255);
  slope.setPosition(width*2/3, height*2/5);
  slope.setRotation(-PI/5); // 角度の設定
  slope.setStatic(true);

}

setup()は以上となります。

draw()

sketch.pde
void draw(){
  background(sliderValue*1.38);

  ball = new FCircle(sliderValue);
  ball.setNoStroke(); // 輪郭無し
  ball.setPosition(width*3/4, -sliderValue/2);
  ball.setFill(120, 200, random(255));
  ball.setRestitution(0.6); // 反発係数の設定

  world.step();
  world.draw();
}

スライダーによって,sliderValueの値が変わるので, 背景も黒⇔白に変わる仕組みです。
また、それと同時にsliderValueの値によって生成されるボールの大きさが異なります。
蛇足ですが、setRestitutionを1以上に設定すると、物体が跳び続けます。
ラスト2行はおまじないです。

sketch.pde
void drop_circle(){
  world.add(ball);
}

void appear_slope(boolean value){
  if (value == true){
    world.add(slope);
  } else{
    world.remove(slope);
  }
}

最後はボタンとトグルスイッチによって実行される関数です。
1つ注意点として.addToggle()にboolean型を入れないようにしてください。
私はそれをしてしまい、さらに

sketch.pde
void draw(){
  ...
  if (toggleValue == true){
    world.add(slope);
  }else {
    world.remove(slope);
  }
  ...

と記述していたのですが、draw()関数は無限にループしてしまう為, 無限にスロープを生成してしまい、処理落ちを繰り返していました。

終わりに

いかがだったでしょうか?
私も学びたてですので、至らぬ点, 分かりづらい点などあったとは思いますが、あなたのクリエイティブ・コーディングライフに華を添えられたら幸いです。
質問、文句、雑談、お待ちしております。

Twitterアカウント : @A9qoxC

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】「エスケープ文字が不正です」「エンコーディングMS932にマップできません」の対処メモ

こんばんは。

今、自分の中で一大プロジェクトを進行中です。
(頓挫するかも知れないので内容は伏せます・・いつかここで公開できたら!)

その中のごく一部のプログラムを作るために、Javaでテキストの読み込み・出力ができるプログラムを作っています。
windows10になってから、デフォルトの文字コードがUTF-8になりました。
VbscriptでUTF-8のファイルの入出力を組もうと思ったのですが、従来のShift-Jis専用の処理だと文字化けしてしまいます。
Vbscript使いの皆さんは、コーディング方法を変えた感じでしょうか?
例)テキストファイルのレコードを読み込む処理
dataline = inStream.readline
      ↓
dataline = inStream.readtext(-2)
自分の会社のPCには、Vbscriptのツールが大量に保存してあるので、どうやって対応していこうかなあと悩み中です。
まあそんな事もあり、せっかくなので勉強中のJavaで組もうと思った次第です。
そこで発生したコンパイルエラーについて、対処しましたのでメモとして投稿します。

先に結論

発生したエラーは2つ。それぞれ対処を→で記載します。

・エラー: この文字は、エンコーディングMS932にマップできません
 →①コンパイル時に「-encoding UTF-8」などの指定をして、コーディングした
  ソースファイルのエンコーディングに合わせてコンパイルする
 →②ソースファイル保存時に、デフォルトエンコーディング(今回の場合はMS932ですが
  これはShift-Jisの拡張版のイメージなので、'ANSI’)で保存する
・エラー: エスケープ文字が不正です
 →エスケープすべき文字列を、エスケープシーケンスを使う等して
  対応する('\'→'\'等)

作ったプログラム

さて、以下のようなプログラムを組みました。
処理としては非常に単純で、テキストファイルを読み込んで画面に出力する処理です。
(某サイトのサンプルプログラムを拝借させていただきました)

readtest.java
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;

public class readtest{
public static void main(String args[]){
try{
//err1  File file = new File("C:\Users\ドキュメント\Java1\sinki\K0040d.txt");
//err2  File file = new File("C:\\Users\\ドキュメント\\Java1\\sinki\\K00401.txt");
  File file = new File("K0040d.txt");
  BufferedReader br = new BufferedReader(new FileReader(file));

  String str = br.readLine();
  while(str != null){
    System.out.println(str);

    str = br.readLine();
  }

  br.close();
}catch(FileNotFoundException e){
  System.out.println(e);
}catch(IOException e){
  System.out.println(e);
}

}
}

まず、'err1'となっているところです。
//err1 File file = new File("C:\Users\ドキュメント\Java1\sinki\K0040d.txt");
ここを有効にしてコンパイルすると、以下のエラーが出力されまくります。

readtest.java:13: エラー: この文字は、エンコーディングMS932にマップできません
//  File file = new File("C:\\Users\\繝峨く繝・繝。繝ウ繝?\\Java1\\sinki\\K0040d.txt");
                                               ^
readtest.java:10: エラー: エスケープ文字が不正です
  File file = new File("C:\Users\繝峨く繝・繝。繝ウ繝?\Java1\sinki\K0040d.txt");
                           ^

理由は簡単で、パスを指定するときは'\'をエスケープしてあげないといけないためです。なので、'\'→'\'にします。

これを対応したのがerr2。
//err2 File file = new File("C:\\Users\\ドキュメント\\Java1\\sinki\\K00401.txt");

(ちなみに最終的には絶対パスを指定するのはやめ、ファイル名のみにしました。
 読み込みたいテキストファイルは同じフォルダに格納されていたので、これでも大丈夫でした)

その後、コンパイルするとエスケープ文字のエラーだけが解決したみたいですが以下のエラーは残ってしまいます。

readtest.java:13: エラー: この文字は、エンコーディングMS932にマップできません
//  File file = new File("C:\\Users\\繝峨く繝・繝。繝ウ繝?\\Java1\\sinki\\K0040d.txt");
                                              ^

まず自分の開発する環境のデフォルトエンコーディングを認識しておく必要があります。それと異なる文字コードでソースファイルを扱ってしまうと、上記のエラーになります。

以下のサイトに記載のあったプログラムでデフォルトエンコーディングを確認すると、MS932になっていました。
https://www.javadrive.jp/start/encoding/index2.html

対して、今回組んだJavaのプログラムのファイルは、テキストファイルの保存時に
「UTF-8」を選択しています。
その場合は、MS932の文字コードで読み込むことができずエラーになります。

対策は2つ。
・ファイル保存時に「ANSI」で保存する。
・コンパイル時に、以下の指定をしてコンパイルする。
 javac -encoding UTF-8 readtest.java
 「-encoding xxx」のxxxに使用している文字コード
 (エンコードしたい文字コード)を指定する。
 
これで実行したところ、テキストファイルの内容が出た出た!わーいわーい。
2020/03/20 xxx -100
2020/04/20 xxx -100
2020/05/18 xxx -100
2020/06/20 xxx -100
2020/07/20 xxx -100
2020/08/20 xxx -100
2020/09/20 xxx -100

(テキストファイルの中身に意味はありません)

という事で、テキストファイルの読み込み・画面出力ができたところで今日はここまで。
こんな感じでコツコツとアウトプットしていきたいと思います。

ではまた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む