なぜ、テキストエディタじゃなくてIntelliJ IDEAを使うか

http://samuraism.jp/diary/2014/07/21/1405945860000.html

ネタエントリです。私はテキストエディタで済むのはテキストエディタを使います。もっぱら使うのは香り屋版gVimWindows)で、自宅ではMacVimだったのにOS X 10.9.4にしてから調子悪くなったのでSublime Textに浮気中。ええ、そうです。Vim指に呪われています。

1.Mac, Linux, Windowsのどれでも使える

Javaアプリですからね。インストールのしやすさはどれも同じだけれど、無事に初期起動できるかどうかで、これくらいの差があるんじゃないかな。

Windows >> Linux >>(越えられない壁)>> Mac

MacLinuxは起動用のJREが付いてない。Macはさらに初期設定でJava6を要求するとかで、地味にハードル上げてます(別にJava7でも動く)。あとプロジェクト用のJDKも付いてないので、はじめに設定しないとJavaプロジェクト作るのにも一苦労です。

2.起動が速い

どうゆう理由かわかりませんが、その日の初回起動は普通に遅いです。インデックスの再構築がとってもCPUパワーを食いつぶすので、コア数多ければ多いほど起動は速いです。インデックスの有効期間なのかキャッシュなのか、わかんないけど、それを乗り越えると起動は早くなります。

なので、他のIDEと比べて格段にちょ早って感じはしないです。隣の芝生は青く見えるものです。

3.キーマッピングが自由自在

Macはもともとのいろんなショートカットが割り当てられているので、その辺の知識が無いとキーカスタマイズするのも一苦労です。キーカスタマイズのしやすさは、こんな感じ(Linuxは風評。

Windows >>(越えられない壁)>> Linux > Mac

あと、Vimに強い愛情がなければ、IdeaVIMというプラグインがあります。

4.他のテキストエディタテキストエディタに比べて、カーソルが速く移動できる

これは慣れの問題かな。昔は Goto -> Class とかIntelliJならではだったけど、今だと別に珍しくも何ともない。

5.ホームポジションをあんまり崩さないで操作ができる

え?そうなの??たぶん、キーマップの工夫次第ですね。あたしはマウスやトラックパッドに操作が移るのを苦にしないので、あんまり気にしたこと無いです。

6.検索、置換が強力(変態)

これは本当。ただ、検索/置換メニューがメニューバーの「Edit → Find」と奥まってるので、どこにあるのか慣れるまで戸惑う。
あと、IDEA13.1から追加されたマルチカーソルが地味に便利。

7.Postfix completionという機能が便利過ぎる

そうなんだけど、忘れる。覚えたら便利なんだろうなって感じ。

8.英語ドキュメントやヘルプが豊富

書籍の類いはとほんど無いので、インターネットの海を探そう。

9.日本のIntelliJ IDEAコミュニティがやばい

あたしがレスするのは、もはや嫌がらせのレベル。
ちなみに「IdeaVIM」ってつぶやくと、それが何語だろうとIdeaVIMのコミッタからレスが来るので気をつけろw

10.ある意味マルチプラットフォームIntelliJというプラットフォーム

パーソナルライセンスだったら、どのPCに入れてても良いってのもよかね。

11.設定ファイルを読む必要はない

そのかわり検索ワードは英語だし、ある程度あたりが付いてないと、いくらそれっぽいワードを入れてもヒットしないよ。

12.他言語サポート

Ultimate EditionはAppCode以外に相当するので、たしかにUltimateなんだけど、PHPRubyなどの多言語プラグインの追従性とか知ってないと「思ってたんとちゃう」って事になるので、これも注意が必要だ。

13.UIがどんどん改善されていく

UIはね、だいぶ主観がはいるから。EclipseSWTがイケてるとか、Visual Studioの見た目がサイコーだとか、人によってさまざま。確実に言えることは、

  • Windowsの高解像度(高DPI)ディスプレイには、まだ対応してない
  • MacのJava6とJava7でフォントレンダリングがビミョーに異なって、地味に違和感
  • 伝統的にLinuxのフォントが汚い

ってあたり。

終わり。

万能軽快快適IDEなんてあるわけないけど、その辺のダメなところを分かった上で「やっぱりIntelliJ最高だ!」と言っているので、共感できる人は共に行こう!だし、単にあこがれているなら、悪い面もちゃんと知っとこうね、というネタのようなホントの話。

JSF2.2試してみた - 管理ビーンの模索

前回とちょっと間があいたけど、その続き。今度は管理ビーンのあり方についての模索、というか悪あがき。
素直にlombok使えばいいのだけれど、どうしても getter/setter だらけになるのはイヤなので、なんか回避する方法は無いものかと模索した結果がこれ。

@Named
@ViewScoped
public class CalcCtrl implements Serializable {
    :

    public void doCalculation() {
        long l = Long.parseLong(requestMap("left").toString());
        long r = Long.parseLong(requestMap("right").toString());
        long a = l + r;

        if (l % 2 == 0) flash("left", "左辺 " + l + " は偶数です");
        if (r % 2 != 0) flash("right", "右辺 " + r + " は奇数です");

        List<Calc> results = (List<Calc>) viewMap("results");
        results.add(0, new Calc(l, r, a));
        reset();
    }

    :
}

ちゃんとしたソースコードはここ。
JSFSample/CalcCtrl.java at master · masanobuimai/JSFSample · GitHub


何がしたかったかというと、Grailsや(最近は知らないけど)RailsみたくViewに渡す値をコントローラのメンバ変数に持たすのではなく、リクエストに紛れ込ませてみた。それを取り出すView側のコードはこんな感じ。

<h:inputText id="left" label="左辺" value="#{requestScope.left}"
             style="#{faceUtils.valid(component.clientId)}" required="true">
  <f:validateLongRange maximum="99999"/>
</h:inputText>
  :
<h:dataTable value="#{viewScope.results}" var="calc">
  <h:column>
    <h:outputText value="#{calc.left}"/> +
    <h:outputText value="#{calc.right}"/> =
    <h:outputText value="#{calc.answer}"/>
  </h:column>
</h:dataTable>


入力値(左辺・右辺)の受け取り方がJavaBeans(Calc)経由ではなく、リクエスト(requestMap("left" or "right"))経由でString型の取り出しになるため、そのままだと型チェックが効かない。なんでまぁ、苦肉の策として範囲チェック(validateLongRange)をあてて型チェックも兼ねさせる。

やってみて一応できたけど「こりゃイケる」という感慨はなかった。むしろJSFとしてはかなりトリッキーな組み方になるんで、こんなの広めても良いこと何も無いなと思うのであった。
別の見方をすると「JSF、柔軟性ありすぎや」とも言える。この話はもちょっと続くのだけれど、今回はこれでおしまい。

Android Studio Beta v0.8の注意事項

出遅れた感がありますが、注意一秒ケガ一生の標語よろしく既存のAndroid Studioユーザ向けの注意事項をまとめてみました。v0.8からの新規ユーザは、まっさらな気持ちで臨めるので特に気にすること無いです。
#宗教上の理由で、Eclipse ADTユーザはよくわかりません。(´・ω・`)

地雷その1 アップデート版はありません

おそらく地雷その3の絡みから新規ダウンロードのみです。でもv0.8を起動すると速攻で「v0.8.1にしてね」って言われるので、素直にアップデートしておきましょう。

ご存じのとおり、Android StudioAndroid SDKを内蔵しているので、不用意に既存のアプリを上書きすると、もれなくAndroid SDKも上書きされます。こんな風にバージョン分けてるなら平気ですが、特にインストールが簡単なMac版は注意してね。

地雷その2 付属しているAndroid SDKがミニマム構成になってる

簡単にいうとこれしか入ってない。足りないのは、あとで追加しときましょう。

でもって、既存のAndroid SDKを流用したい場合は、Android SDK ToolsとかBuild-toolsを最新にしときましょう。

地雷その3 設定フォルダ名が変わりました

gihyo.jpの連載んときにAS_HOMEとか言ってたヤツが $HOME/.AndroidStudioPreviewから$HOME/.AndroidStudioBetaに変わりました。
第2回 Android Studioの導入と設定:Android Studio最速入門~効率的にコーディングするための使い方|gihyo.jp … 技術評論社


「設定が飛んだ!!」とビックリした人もいると思いますが大丈夫、v0.6.xまでの設定は $HOME/.AndroidStudioPreview に残ってます。たぶん、この次は $HOME/.AndroidStudioになるんだと思うのだけど、問題は何時になるんでしょうかね?(順当にいって次回のGoogle I/Oかな。(・ω<)☆

地雷その4 プロジェクトウィザードが作るbuild.gradleが変わりました

ざっと上げると、こんな感じ。

  • Gradle Wrapperのバージョンが 1.12 になった
  • Androidプラグインのバージョンが 0.12.+ になった(最新は 0.12.0 だったかな
  • Androidプラグインの名称が 'com.android.application' になった
  • buildscript{}やサブプロジェクトのリポジトリjcenter()になった

既存のAndroid Studioで作ったプロジェクトを開けなくなったのは、Android SDK(地雷その2)のせいだから。

だいたいこんな感じ。AS_HOMEAndroid SDKに注意してれば、既存のプロジェクトを活かすこともできると思います。あと、このヘンがまた役に立つかも(#ステマ
第4回 Android Studio v0.1.2登場:Android Studio最速入門~効率的にコーディングするための使い方|gihyo.jp … 技術評論社

JSF2.2試してみた - メッセージまわり

バリデータと、ユーザプログラムで設定するメッセージについて。JSFが用意しているバリデータのメッセージが変更可能なのは知ってて、とりあえずどんな感じになるのか掴んでおきたかった。

ちなみに、バリデータの有無にかかわらず、Faceletがバインドしているオブジェクト(例えば Calc.setRight(long))の型に合わせた、型チェックは勝手にやってくれてた。デフォルトのメッセージはアレな感じだけど、ちょっとだけ感心した。


それはそれとして、バリデータではなく、管理ビーンの処理(アクション)で、いわゆるギョーム的なメッセージを付与して画面に返したいなんてのは良くある話で、かつエラーになった項目の背景色を赤にして目立たせたいなんてのもよくある話だよねと。
その辺は、こちらを参考に実装してみた。
JSFでエラーのある項目の背景色を変える - じゃばらの手記


その結果が、管理ビーンからフラッシュメッセージを使う事と、Faceletから component.clientid でエラー(バリデータが invalid)かどうかを判定するアレなコード。

<table>
  <tr>
    <td>
      <h:inputText id="left" label="左辺" value="#{calcView.calc.left}"
                   style="#{faceUtils.valid(component.clientId)}" required="true">
        <f:validateLongRange maximum="99999"/>
      </h:inputText>
    </td>
    <td></td>
    <td>
      <h:inputText id="right" label="右辺" value="#{calcView.calc.right}"
                   style="#{faceUtils.valid(component.clientId)}" required="true">
        <f:validateLongRange maximum="99999"/>
      </h:inputText>
    </td>
  </tr>
  <tr>
    <td><h:message for="left"/>#{flash.left}</td>
    <td>&nbsp;</td>
    <td><h:message for="right"/>#{flash.right}</td>
  </tr>
</table>

clientIdが自動発行されるので、messageタグとフラッシュメッセージを別々に用意したり、HTML要素のID知ってるのに、わざわざ component.clientid とかやって面倒だなと思ってたら、単なる思い込みだったと、キクタローさんのサンプルで知った(実にありがたいw
#prependId属性ってのを false にするといいらしい。


実装のイケてなさはさておき、とりあえず、

  • アクションの処理中に、特定の項目に紐づけたメッセージを出力できる
  • エラーになった入力項目を目立たせる事ができる

ことはわかった。


あと知っておきたいのは、

  • アクションの結果に応じて、特定の入力項目の属性(入力不可、非表示)を切り替えられるかどうか
  • (できたら、動的に入力項目を増減・入れ替えできるかどうかも)

なんだけど、その前にちょっと寄り道した(つづく)。

JSF2.2試してみた - みんなの反応

説明が終わる前に、いろいろ反応があったので、ネットに埋もれる前に回収しとく。みなさま、ありがとうございました。こうして有識者からのコメントが釣れるのを期待してました。:-)

まずはキクタローさん。


平日の夜中なのにありがとうございました。スーパー力作!!


明け方に [twitter:@btnrouge]さんからも。


ELはやっぱりgetter/setterが要るんだと。JPAはいずれ試す。



王子([twitter:@yoshioterada])から、ありがたいコメントを頂く。


寺田さんからは、まだ説明してない部分も先回りしてコメントもらったので、その辺はあとでフォローします。
コメントもらっといて、こんな事いう不届き者がw



キクタローさん経由で [twitter:@megascus]さんも捕捉したった。


今回知った事はそのうちサンプルにフィードバックするとして、まずは今のサンプルの解説を続けよう。
#けど、力尽きたので今日はおしまい。:-)

Java7から中黒(U+30FB '・' KATAKANA MIDDLE DOT)が識別子に使えない

「何を今さら」 と言うなかれ、ようやく仕事でJava7使えるようになったので、今ごろ気づいた。ちょうど日本語テストメソッド名で中黒(・)使ってたんで。:-)

Java6でビルドすれば平気なんだけど、NetBeans8やIntelliJ IDEA13はプロジェクトのターゲットJavaバージョンがJava6でも、エディタ上では中黒(・)を不正な識別子と見なす(ちなみに、エディタ上エラーになってるだけで、コンパイラはJava6なのでビルドは通るよ)。

Eclipse(4.3)はターゲットがJava6ならエディタ上でもエラーにしない(偉いw


それ(Java7から中黒がダメ)がホントかどうか知りたくて、言語仕様を探ってみたけど、それっぽいところを見つけられなかった。(´・ω・`)


頑張ってググってみたけど、唯一見つけられたのは、java.netのatomのfeed。その元になったjava.netの掲示板はもう無いみたい。(´・ω・`)


ps.
AppCodeもアカンらしい。これは手抜きっていうかAppCodeのバグなんでないか?



んでもって、JavaじゃなくてUnicodeのせいなんだそうな。


JSF2.2試してみた - 基本編のつづき

管理ビーンのデータの持ち方については、何とでもできるんだけど、個人的にはこうするのはイヤだった。

public class CalcView {
  private long left;
  private long right;
  private long answer;
    :
    // あとはそれらの getter/setter が続く
}

イヤな理由は管理ビーンがgetter/setterだらけになること。これに尽きる。

そうは言っても、管理ビーン画面単位で用意するなら、そこに登場するgetter/setterも、その画面(xhtml)に必要な分だけなので、もしかしたら許容範囲なのかもしれない。まかり間違って、複数の画面を束ねる管理ビーンだったりしたら、その画面分のgetter/setterがわんさと集まって、目も当てられない。

そんなわけで、データはデータであることがわかるように独立したオブジェクトにしといた。おっさん風に言えばDTO(Data Transfer Object)とかVO(Value Object)の類い。

ついで言えば、それらも

public class CalcView {
  private Calc calc;
  private List<Calc> results;
}

...とかしないで、CDIからインジェクションしてもらえば良いのかな?なんても思ったんだけど、

public class CalcView {
  @Inject   // <- これはイケる
  private Calc calc;
  @Inject   // <- こっちがあやしい
  private List<Calc> results;
}

ListみたいなコンテナオブジェクトをCDIでインジェクションする方法がイマイチわからんかった。今思えば、Producerを用意すればいいのかな?とも思うのだけれど、なんか大げさだし、気軽にCDI管理ビーンを増やしたら、CDIの名前が枯れそうなので、控えてた。
よく考えたら、インジェクションするだけなら、CalcがCDI管理ビーンである必要もないのか...とも。

CDIインジェクションで貫くとしたら、

@Named @RequestScoped
public class CalcView {
  @Inject
  private Calc calc;            // <- これは @RequestScoped
  @Inject
  private List<Calc> results;   // <- こっちは @ViewScoped
}

...ってやりたかったんだけど、@RequestScopedの管理ビーンに@ViewScopedの管理ビーンを貼り付けられなかった(...ような覚えがある。この辺、うろ覚え。


何にしてもCDI管理ビーンがgetter/setterだらけになるのは、たとえlombokがあったとしても好きじゃ無い。これは単なる好みの話。

っていうわけで、CDI管理ビーンのあるべき姿を探ってさまよう事になるのだけど、その話はまた今度。