20220114のJavaに関する記事は5件です。

Webで使えるJavaのUIフレームワークのVaadinをさわってみた

モチベーション(動機) この記事の執筆に至る経緯の発端は、Apache Wicket製プロジェクトを新システムに移行するのにどうするかという課題を筆者が持つ所以である。筆者は十数年Javaをメインにしている。最近はニューラルネットや機械学習でpythonをさわることが多くなっている。Webアプリを作るといえばReactやらVueやらでてくるのでReactを勉強しているがTypeScriptの型のサポート具合がどうにもしっくりこないやらバージョンアップのたびにばっさりと下位互換性をきりすてる具合にはついていけるかどうか一抹の不安が拭えないという印象がある。自身のできないことをできるようにすることは大事であるが、自身の強みを生かして伸ばすことも同様に大事だと気づいた。初心に立ち返ってJavaでがんばるには最近はどうしたらいいのだろうということで筆をとった次第である。 Vaadinとは JavaでWebのUIを作ることができるフレームワーク。Pure Javaで書けそう。同類としてはApache Wicket。最近はFlowとFusionという仕組みを用意してPure JavaだけでなくTypescript+Javaという選択肢が用意された。 Roadmap 2022/01/14執筆時点で、LTSは14。最新版は22。次期LTSは23。23のリリース時期はMarch 2022を予定されている。 (LTS: Long Term Support version) 「Release model > LTS(Long Term Support) versions」に記載があるように、2年ごとにLTSがリリースされるスケジュールが組まれる。通常サポートが5年間(14は2024まで)と拡張サポートがさらに10年間(LTSの初期からふまえると15年間)。non-LTSは3ヶ月ごとのリリース。次のLTSに向けた実装が行われている。アーリーアダプター向け。大半の開発者はLTSが適切であるような旨が記載されている。 詳細は https://vaadin.com/roadmap を参照されたい。 Quick Startをやってみる 公式サイトのQuick Start https://vaadin.com/docs/latest/flow/guide/quick-start を取り組んで見る。 Download a Vaadin Project Quick Startの案内に従ってVaadinのプロジェクトをダウンロードした。中身はmavenプロジェクト。IDEはすきなものを選べときているのでIntellij IDEAにインポートした。 MainView 公式の記載通りに最初にアクセスする画面のプログラムを記述した。htmlやcssの記述はしない。VerticalLayoutという名称からおそらく垂直方向にボタンやテキストフィールドといったコンポーネントを表示するという推測をする。 ボタンのクリックの動作はリスナーで登録する。リスナーはLambda式で記述できる。WicketでもReactでもよくみかける形式なのでドキュメントを読まなくともある程度直感的に頭に入ってくる。 場所は src/main/java/org/vaadin/example/MainView.java 出典:https://vaadin.com/docs/latest/flow/guide/quick-start/#step-2-add-your-code package org.vaadin.example; import com.vaadin.flow.component.Key; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.html.H1; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.Route; @Route("") public class MainView extends VerticalLayout { public MainView() { VerticalLayout todosList = new VerticalLayout(); TextField taskField = new TextField(); Button addButton = new Button("Add"); addButton.addClickListener(click -> { Checkbox checkbox = new Checkbox(taskField.getValue()); todosList.add(checkbox); }); addButton.addClickShortcut(Key.ENTER); add( new H1("Vaadin Todo"), todosList, new HorizontalLayout( taskField, addButton ) ); } } アプリケーションの起動 IDEからは Application.java をRunさせることでアプリケーションを起動する。コマンドラインからは付属の mvnw を叩いて起動する方法もある。 localhost:8080 にブラウザからアクセスする。 以下の画面が表示された。 テキストフィールドに文字を入力してエンターキーを押したら追加された。 起動ログをみるとSpringBootと組み込みTomcatが動いているのがわかる。pom.xmlにSpringBootの記述があるのVaadinはSpringBootを利用するのが標準なのだろう。 今回はここまで 今回は最初のエッセンスを体験するのに留める。これだけでは新システムに採用できるものかの判断がつかないが、検討に値することはわかった。 Now you have a taste of how Vaadin Flow empowers you to quickly build web apps in pure Java, without writing any HTML or JavaScript. Continue exploring Vaadin Flow in the documentation, tutorials, and video courses: - Flow framework overview - In-depth course: learn Vaadin Flow development in 4 hours - Free online video courses covering Vaadin basics
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaを通してPDFタイル画像の背景(透かし)を設定する方法

概要と環境への準備 この記事では、PDFライブラリの無料バージョン(Java用のFree Spire.PDFを使用して画像をロードし、タイル画像の透かしとしても使用できるPDFタイル画像の背景を設定する)の効果を紹介します。コードを編集する前に、 jarファイルをインポートする必要があります。2つのタイプがあります。メソッドはオプションでインポートされます。 1.手動でのダウンロードとインポート:公式Webサイトにアクセスしてjarパッケージをダウンロードし、解凍して、libフォルダー内のSpire.Pdf.jarファイルをJavaプログラムにインポートできます。 Mavenリポジトリーのインポート:Mavenプロジェクトを作成することにより、pom.xmlファイルでMavenリポジトリー・パスを構成し、次のようにFree Spire.PDF for JavaのMaven依存関係を指定します。 com.e-iceblue http://repo.e-iceblue.com/repository/maven-public/ e-iceblue spire.pdf.free 4.4.1 構成が完了したら、「変更のインポート」をクリックしてJarファイルをインポートします。 Jarのインポート効果は次のとおりです。 Javaコード一覧 import com.spire.pdf.*; import com.spire.pdf.graphics.PdfImage; import com.spire.pdf.graphics.PdfTilingBrush; import java.awt.*; import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; public class AddBackground { public static void main(String[] args) { //PdfDocumentオブジェクトを作成し、PDFテストドキュメントをロードする PdfDocument pdf = new PdfDocument(); pdf.loadFromFile("C:\\Users\\Administrator\\Desktop\\test.pdf"); //ドキュメントの各ページをトラバースし、画像をロードして、タイル状の背景(透かし)として設定する for (int i = 0; i < pdf.getPages().getCount();i++) { PdfPageBase page = pdf.getPages().get(i); Dimension2D dimension2D = new Dimension(); dimension2D.setSize(page.getCanvas().getSize().getWidth()/4, page.getCanvas().getSize().getHeight()/3); PdfTilingBrush brush = new PdfTilingBrush(dimension2D); brush.getGraphics().setTransparency(0.2f); brush.getGraphics().translateTransform(brush.getSize().getWidth()/10,brush.getSize().getHeight()/10); brush.getGraphics().rotateTransform(30); PdfImage image = PdfImage.fromImage("C:\\Users\\Administrator\\Desktop\\logo.png"); brush.getGraphics().drawImage(image,brush.getSize().getWidth()-image.getWidth()/2,(brush.getSize().getHeight())/2); Rectangle2D rectangle2D = new Rectangle2D.Float(); rectangle2D.setFrame(new Point(0,0),page.getCanvas().getClientSize()); page.getCanvas().drawRectangle(brush,rectangle2D); } //ドキュメントを保存する pdf.saveToFile("SetTiledBackground.pdf"); pdf.dispose(); } } タイル画像の背景(透かし)効果はこのように: 以上です、今回のPDFタイル画像の設定方法はここまで、最後まで読んでいただきありがとうございます!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Intellijで@slf4jでログ出力しようとするとcannot find symbol logのエラーが出る

概要 IntellijでSpring Bootで@slf4jを使って log.debug("Sample") のようにログを出力しようとすると、 cannot find symbol log というエラーが発生し、Compileが失敗する。その対処方法。 Versions Intellij Ultimate 2021.3.1 Spring Boot 2.5.6 Enable annotaion processing Preference > Build, Excecution, Deployment > Compiler > Annotation Processing 「Enable annotaion processing」にチェックを入れる。 Plugin Lombockをインストールする。 build.gradle 以下を追記してインストール。 compileOnly 'org.projectlombok:lombok:1.18.20' annotationProcessor 'org.projectlombok:lombok:1.18.20' 以上 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C++,C#のコメントアウトテクニック

概要 下記のような記載が出来る言語で使えるコメントアウトのTips 使える言語の参照 main.cpp // 1行コメント /* 複数行コメント 複数行コメント */ 内容 複数行コメントを1文字で切り替える 先頭のスラッシュ(/)を消すと切り替えれる main.cpp //* 現在の 複数行コメントは コメントアウトされない //*/ /* 現在の 複数行コメントは コメントアウトされる //*/ 機能の切り替えを1文字で切り替える 上記のIF版で 先頭のスラッシュ(/)を消すと切り替えれる main.cpp //* Active Block /*/ Disable Block //*/ /* Disable Block /*/ Active Block //*/ まとめ C++er には多少有名なのでN番煎じではあるもののいろいろな言語で使えるので書いてみました。 C++では#if #endifで切り替えたりしますが、プリプロセッサで簡単に切り替える機能がない言語だと使いみちはありそうです。 後1文字切り替えなので楽ですが、可読性が良いとは言えないので過度な利用は控えたほうが良さそうです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

assertEqualsやassert_equalの引数はなぜ expected, actual の順なのか、調べてみた

はじめに xUnit系のテスティングフレームワークでは、2つの値が等しいことを検証するメソッド(assertEqualsやassert_equalなど)の引数が expected, actual(期待する値、実際の値)の順に並びます。 // Java (JUnit) assertEquals(2, calculator.add(1, 1)); # Ruby (minitest または test-unit) assert_equal(2, calculator.add(1, 1)) しかし、この引数の順番は直感に反するので、逆に書きたい、と思う人も中にはおられるようです(というか、僕も昔そう思っていました)。 // actual、expectedの順がいい! assertEquals(calculator.add(1, 1), 2); # actual、expectedの順がいい! assert_equal(calculator.add(1, 1), 2) そこで、expected, actualの順で引数が並ぶのには何か理由があるのか、ちょっと調べてみました。 調査方法 "unit test assert equal argument order why" みたいなキーワードでググってみました。検索の上位に毎度お馴染みのStack Overflowのリンクが上がってきたので、いくつか回答を覗いてみました。 Kent Beck氏は何と言っているか? JavaのJUnitやRubyのtest-unit/minitestなど、いわゆるxUnit系のテスティングフレームワークはKent Beck氏が始祖の一人であると言われています。 1997年に、Smalltalk のためのユニットテストのフレームワークであるSUnitをもとにして、エーリヒ・ガンマと、SUnitの開発者のケント・ベックが中心となって開発された。 JUnit - Wikipedia そして、こちらのStack Overflowの中に、この疑問に対するKent Beck氏の回答(のリンク)が載っていました。その回答がこちらです。 Line a bunch of assertEquals in a row. Having expected first makes them read better. And yes, it's too late to change it. (筆者訳) 大量の assertEquals をひとまとめにして並べてみる。expectedを最初に持ってきた方が読みやすい。(1つ前のスレッドの意見に対して)そしておっしゃるとおり、今から変更するのはもう手遅れです。 JUnit / RE: [Junit-devel] why not assertEquals(actual, expected)? コメントが短く、サンプルコードもないのでちょっと意図がつかみにくいのですが、Stack Overflowの回答を見る限り、こういうことのようです。 actual, expected の順だと読みにくい(?) def test_bit_length assert_equal((-2**12-1).bit_length, 13) assert_equal((-2**12).bit_length, 12) assert_equal((-2**12+1).bit_length, 12) assert_equal(-0x101.bit_length, 9) assert_equal(-0x100.bit_length, 8) assert_equal(-0xff.bit_length, 8) assert_equal(-2.bit_length, 1) assert_equal(-1.bit_length, 0) assert_equal(0.bit_length, 0) assert_equal(1.bit_length, 1) assert_equal(0xff.bit_length, 8) assert_equal(0x100.bit_length, 9) assert_equal(0x101.bit_length, 9) assert_equal((2**12-1).bit_length, 12) assert_equal((2**12).bit_length, 13) assert_equal((2**12+1).bit_length, 13) assert_equal((-2**10000-1).bit_length, 10001) assert_equal((-2**10000).bit_length, 10000) assert_equal((-2**10000+1).bit_length, 10000) assert_equal((2**10000-1).bit_length, 10000) assert_equal((2**10000).bit_length, 10001) assert_equal((2**10000+1).bit_length, 10001) 2.upto(1000) {|i| n = 2**i assert_equal((-n-1).bit_length, "(#{-n-1}).bit_length", i+1) assert_equal((-n).bit_length, "(#{-n}).bit_length", i) assert_equal((-n+1).bit_length, "(#{-n+1}).bit_length", i) assert_equal((n-1).bit_length, "#{n-1}.bit_length", i) assert_equal((n).bit_length, "#{n}.bit_length", i+1) assert_equal((n+1).bit_length, "#{n+1}.bit_length", i+1) } end expected, actual の順だと読みやすい(?) def test_bit_length assert_equal(13, (-2**12-1).bit_length) assert_equal(12, (-2**12).bit_length) assert_equal(12, (-2**12+1).bit_length) assert_equal(9, -0x101.bit_length) assert_equal(8, -0x100.bit_length) assert_equal(8, -0xff.bit_length) assert_equal(1, -2.bit_length) assert_equal(0, -1.bit_length) assert_equal(0, 0.bit_length) assert_equal(1, 1.bit_length) assert_equal(8, 0xff.bit_length) assert_equal(9, 0x100.bit_length) assert_equal(9, 0x101.bit_length) assert_equal(12, (2**12-1).bit_length) assert_equal(13, (2**12).bit_length) assert_equal(13, (2**12+1).bit_length) assert_equal(10001, (-2**10000-1).bit_length) assert_equal(10000, (-2**10000).bit_length) assert_equal(10000, (-2**10000+1).bit_length) assert_equal(10000, (2**10000-1).bit_length) assert_equal(10001, (2**10000).bit_length) assert_equal(10001, (2**10000+1).bit_length) 2.upto(1000) {|i| n = 2**i assert_equal(i+1, (-n-1).bit_length, "(#{-n-1}).bit_length") assert_equal(i, (-n).bit_length, "(#{-n}).bit_length") assert_equal(i, (-n+1).bit_length, "(#{-n+1}).bit_length") assert_equal(i, (n-1).bit_length, "#{n-1}.bit_length") assert_equal(i+1, (n).bit_length, "#{n}.bit_length") assert_equal(i+1, (n+1).bit_length, "#{n+1}.bit_length") } end サンプルコードの引用元: https://github.com/ruby/ruby/blob/master/test/ruby/test_integer.rb 引数の位置が安定しやすいから、この順番? 上のサンプルコードを見ただけではまだピンと来ないかもしれません。 StackOverflowの回答にも書いてあるんですが、expectedは文字列や数値といった単純なリテラルを書くことが多く、actualは複雑なメソッド呼び出しや、さまざまな引数を与えることが多いです(もちろん状況によりますが)。 結果、「expectedは短くて長さも安定しやすい」「actualは長くて長さも変わりやすい」ということになります。 そのため、assertEqualsやassert_equalを大量に並べる場合は、expectedを最初に持ってきた方が、引数の位置を安定させやすい(そしてexpectedをさっと把握しやすい)、ということのようです。 もちろん、例外パターンもあると思うので、「見ろ、こういう場合はactualが最初に来た方が読みやすいぞ!」という反論はいくらでもできそうですが、Kent Beck氏に言わせるとexpectedが最初に来た方が読みやすくなることが多いのかもしれません。 他のツールはおそらくJUnitを踏襲しただけ JUnitはもともとSmalltalk用のSUnitをJavaに移植したものですが、assertEqualsが導入されたのはJUnitが最初のようです(参考)。それゆえ、assertEqualsの元祖はJUnitになると思われます。 Rubyのtest-unit/minitestやPythonのunittestライブラリがexpected, actualの順になっているのは、おそらくJUnitの引数の順番を踏襲しただけだと思います。 まとめ というわけで、この記事ではassertEqualsやassert_equalの引数はなぜ expected, actual の順なのか調査した結果を書いてみました。 StackOverflowの回答を読んでいると、回答者自身の「俺はこう思う」的な意見は多いのですが、原典にさかのぼって調査するような回答はほとんど見つけられませんでした。その中で唯一見つけられたのが、前述のKent Beck氏の回答です。 とはいえ、その回答も短く、僕個人も「わかるような、わからんような」という感が否めません。なんとなくの予想ですが、Kent Beck氏自身も「まあ、どっちでもいいんだけどね」ぐらいに考えているような気がします(確固たる理由があるなら、もっと詳しいコメントが見つかりそうなので)。 この件についてもし詳しい理由をご存じの方がいたら、コメント欄等で情報源を教えてもらえると幸いです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む