![]() |
Javaソースファイルの編集 |
Meadow+JDEによるJavaソースファイルの編集機能について見ていきます。
新たにJavaのソースコードを編集するときに、雛形を生成する。生成する種類は次のとおり。
/**
* NewClassA.java
*
*
* Created: Mon Aug 14 02:58:01 2000
*
* @author <a href="mailto:torutk@alles.or.jp">Toru TAKAHASHI</a>
* @version
*/
public class NewClassA extends SuperClass
implements Interface {
public NewClassA () {
}
}// NewClassA
|
[*1] JDE 2.2.1以降のjde-gen.elには、@authorの後ろの展開と、クラス・メソッド定義の{の前の空白がうまく制御できていない(というか気に入らない)ので、修正しています。
JDE2.2.7beta3で@authorの後ろの展開は修正されました。{の前の空白は未のままです。
| patch用ファイル | jde-gen.el.patch | 各バージョン毎に修正するのが面倒なのでdiffでパッチ用差分ファイルを作ってみました。JDE
2.2.3 - 2.2.6について動作確認しています。実行方法は、jde-gen.elのあるディレクトリで $ patch -p1 <jde-gen.el.patch |
| jde-gen-1.32_space.patch | JDE2.2.7beta3以降用 |
JDE→Project→Options→Autocode で開かれるCustomize Aproposバッファ中で、Jde Gen Buffer Boilerplateの項目に記述する。
Jde Gen Buffer Boilerplate: [Hide] [INS] [DEL] Line: /** [INS] [DEL] Line: * Torutk jde mastering project. [INS] [DEL] Line: * Copyright (C) 2000 by Toru TAKAHASHI, all rights reserved. [INS] [DEL] Line: * [INS] [DEL] Line: */ [INS] [DEL] Line: [INS] [State]: you have edited the value as text, but you have not set the option. Lines of boilerplate text to put at the head of a buffer template. |
Javaでは、インスタンス変数はメソッドを介してアクセスすることがよいコーディングとされています。したがって、コーディング中はインスタンス変数の定義とそのアクセス用メソッドをひたすら記述していく、やや機械的な作業を強いられます。そんなときにこのコード生成機能を使います。JDEには2通りの生成方法があります。
String firstName;
/**
* Get the value of firstName.
* @return Value of firstName.
*/
public String getFirstName() {return firstName;}
/**
* Set the value of firstName.
* @param v Value to assign to firstName.
*/
public void setFirstName(String v) {this.firstName = v;}
|
JDEのGet/Set Pairテンプレートで不満な点が3つあります。1つ目は、引数がprivateでないこと、2つ目は、引数の名前が'v'と自動的になってしまうこと、最後の1つは、インスタンス変数の位置がカーソル位置になってしまうことです。本当はフィールドはクラス先頭付近、メソッドはその次にしたいところです。Emacsのよいところは、拡張、改良が細かくできることなので、どんどん解決していきましょう。まず1と2を解決してみました。Get/Set Pair生成テンプレートの改良を参照。
クラスに定義されているフィールドのGetメソッドとSetメソッドを自動生成します。既にGet/Setメソッドが存在していれば、二重に生成されないようになっています。
class Foo {
String firstName;
:
}
|
class Foo {
String firstName;
:
/**
* Gets the value of firstName
*
* @return the value of firstName
*/
public String getFirstName() {
return this.firstName;
}
/**
* Sets the value of firstName
*
* @param argFirstName Value to assign to this.firstName
*/
public void setFirstName(String argFirstName){
this.firstName = argFirstName;
}
}
|
Interfaceで定義したメソッドを実装するときに、実装クラスでそれらメソッドのシグネチャを1から打ち込むのは手間です。Meadow+JDEでは、この手間をコード生成機能で省いてくれます。実装したいInterfaceで定義されているメソッドがコメント付きで挿入されるほか、Interfaceで定義されているメソッドの引数・戻り値型がimport文として生成されます。実装したいインタフェースのクラスがクラスパスに含まれている必要があります。クラスパスは、JDEのプロジェクトで設定します。
スーパークラスで定義しているメソッドをオーバーライドするときに、サブクラス側でそのメソッドシグネチャを1から打ち込み、引数や戻り値に使うクラス型をimport文に記述するのはかなりの手間です。
スーパークラスで定義したメソッドをオーバーライドするときに、サブクラスでそのメソッドのシグネチャを1から打ち込むのは手間であるだけでなく、メソッド名に1文字でもスペルミスがあるとオーバーライドではなく新規メソッドとして定義されてしまうため、デバッグに非常に苦労します。Meadow+JDEでは、このオーバーライドしたいメソッドのシグネチャ記述を自動で行うことが出来ます。
/**
*
* @param param1 <description>
*/
public void paintComponent(Graphics param1) {
//TO DO: Implement this method.
}
|
Javaでは(というかオブジェクト指向プログラミングでは)、委譲を使うことがよくあります。委譲は機械的なコーディングをしなければならないので、かなり苦痛です。それをやわらげてくれる機能がJDEにあります。
コードを書いているときに、新しいクラスを使用するために、import文を書くのは面倒な作業です。JDEでは、コマンド1つでimport文を追加する機能があります。既にimport済みなら、2重にimport文を加えることはありません。
| 設定項目名 | デフォルト値 | 目的 | 設定する値(例) |
|---|---|---|---|
| Jde Import Auto Sort | off | import後自動的に整列し直す | on |
メソッドを書いた後に、Javadoc用コメントを記述するのは面倒な作業です。JDEEでは、コーディングしたメソッドのJavadoc用コメントを生成する機能があります。
System.out.println("..."); というコードを書くことは非常に多いですが、タイプするのは長くて面倒です。そこで、、、
JBuilderでは、オブジェクト名の後にピリオド'.'をキータイプすると、そのオブジェクトが持つフィールドおよびメソッド名の一覧がポップアップされる機能があります。こんなのに頼らずAPIドキュメントを見なきゃだめだという意見もありますが、人間便利な機能に慣れるとそれなしではいられなくなってしまいます。
ツリー構造でJavaソースファイルリストを表示する。クラス内のメソッド、フィールドまで展開され、該当ソースコード行をEmacsウィンドウ側に表示させることができます。
Speedbar画面例
現在のBufferに開いているクラスのソースのメンバ(フィールドおよびメソッド)を一覧し選択した個所へ移動することができます。

タグテーブルは、ファイル名・クラス名・メソッド名などとそれらのファイル内の位置の一覧です。これを使うと、あるメソッド名がどのファイルで定義されているかを見つけ出すことが容易になります。ファイルの数が多くなりがちなJavaではとても便利な機能です。
JDEには、Java文法に対応したjtagsコマンドが含まれていますが、Meadowに含まれるetagsの問題のため、機能しません。Meadowの次期リリースに含まれるetagsでは解消されるようです。(Meadow1.06b1ではOk)タグテーブルを作成するには、etagsコマンドを使います。etagsはMeadowのbinディレクトリに存在します。src以下の複数ディレクトリに格納されているソースファイル全体のタグテーブルを作成するには、次のようにGNUのfindコマンドと組み合わせると簡単です。
C:\home\torutk\work\src>find . -name *.java -print | etags -
すると、TAGSという名前のファイルが生成されます。
JDEに含まれるjtagsは、シェルスクリプトなため、Cygnus(GNU Win32)環境が必要です。jtagsを引数なしで実行すると、カレントディレクトリ以下のサブディレクトリを再帰的に検索し、TAGSファイルにタグテーブルを作成します。
タグテーブルを指定するには、M-x visit-tags-tableと打ち、ミニバッファ欄にタグテーブルのあるディレクトリ(1.の例では~/work/src)を入力する。
ソースコード上でクラス名やメソッド名にポイントを合わせ、M-. と打つと、その名前が定義されている場所をタグテーブルを使って探し、そのファイルを開いて該当個所を表示します。または、M-. name でnameを含むクラス名・メソッド名を検索します。
JDEは、Emacsのメジャーモードとしてjde-modeを提供しています。そこで、jde-mode-hookを使ってカスタマイズをすることができます。
JDEは、cc-modeをベースにしたjde-modeを提供しているので、cc-modeのインデント設定方法で変更することができます。例えば長い行があって、これをインデントを保って改行するとします。
SomeType mySomeType = new SomeType(SettingType a, ConfigurationType b); |
JDEではデフォルトでは次のようなインデント設定を行います。
SomeType mySomeType = new SomeType(SettingType a,
ConfigurationType b);
|
これでもまだ長いとき、(の直後に改行を入れると、JDEではこのような状態になってしまいます。
SomeType mySomeType = new SomeType(
SettingType a,
ConfigurationType b
);
|
これは、JDEのスタイル設定がそうなっているからで、例え手作業で(BSを打って)前へ移動させても、自動インデントをしたりその行に編集を加えてEnterを押したりすると、デフォルトの位置に戻ってしまいます。これでは不便なので、インデントを変更したいと思います。
SomeType mySomeType = new SomeType(
SettingType a, ConfigurationType b
);
|
この設定は次のようなElispコードを.emacsに追加します。
(add-hook 'jde-mode-hook
'(lambda ()
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close 0)))
|
arglist-introは、引数の開始が独立した行になる場合のインデント量を設定する変数です。+は、標準インデント量(JDEモードの場合は4スペース)を意味します。なお、++とすると、標準インデント量(JDEモードの場合は4)の2倍(つまり8スペース分)を意味します。
arglist-closeは、引数の指定の後にくる閉じ括弧が独立した行にある場合のインデント量を設定する変数です。0は、そのブロックのインデント位置となります。
Javaはマルチプラットフォーム対応なので、様々な環境でソースを閲覧・編集されることが多いです。そこで、インデントにはTABを使わず、スペースを用いることを推奨します。Emacsではインデント時にデフォルトではTABコードを割り当てますが、これをスペースにするよう設定を行います。設定は.emacsではなく、jde-modeに限定するために、上述のjde-mode-hookにadd-hookで追加している設定に下記を追加します。
(setq indent-tabs-mode nil) |