コードジェネレータの統合のチュートリアル
このチュートリアルでは、新しい項目を NetBeans コード生成機能に統合するモジュールの記述方法について説明します。これは、エディタで Alt-Insert キーを押すと表示されます。
目次

このチュートリアルを行うには、次の表に示すソフトウェアおよびリソースが必要です。
| ソフトウェアまたはリソース | 必須バージョン |
|---|---|
| NetBeans IDE | version 6.7 以上 |
| Java Developer Kit (JDK) | version 6 または version 5 |
トラブルシューティングのために、完了したサンプルをダウンロードしてソースを調べることもできます (任意)。
コードジェネレータの統合入門
NetBeans IDE 6.5 で導入されたコードジェネレータ機能は、Alt-Insert キーを押すと表示される項目のリストで構成されます。各項目は、エディタ内にコードを生成します。

モジュールプロジェクトの作成
この節では、ウィザードを使用して、各 NetBeans モジュールが必要とするソースの構造を作成します。ソースの構造は、特定の場所にある特定のフォルダと、常に必要なファイルのセットで構成されます。たとえば、すべての NetBeans モジュールには、プロジェクトのメタデータを保存する nbproject フォルダと、ツールバーボタンやウィンドウなどの項目を宣言登録するための layer.xml ファイルが必要です。
- 「ファイル」>「新規プロジェクト」(Ctrl-Shift-N) を選択します。「カテゴリ」で「NetBeans モジュール」を選択します。「プロジェクト」で「モジュール」を選択し、「次へ」をクリックします。
- 「名前と場所」パネルで、「プロジェクト名」に「DemoCodeGenerator」と入力します。「プロジェクトの場所」を、c:\mymodules などのコンピュータ上の任意のディレクトリに変更します。「スタンドアロンモジュール」ラジオボタンは選択したままにしておきます。パネルは次のようになります。

「次へ」をクリックします。
- 「基本モジュール構成」パネルで、コード名ベースに「org.netbeans.modules.demo」と入力します。「XML レイヤーを生成」チェックボックスを選択し、「ローカライズ版バンドル」と「XML レイヤー」の場所はそのままにしておきます。これらは org/netbeans/modules/demo という名前のパッケージに格納されます。パネルは次のようになります。

- 「完了」をクリックします。
IDE によって DemoCodeGenerator プロジェクトが作成されます。このプロジェクトには、ソースや、プロジェクトの Ant 構築スクリプトなどのプロジェクトメタデータがすべて含まれます。IDE でプロジェクトが開きます。「プロジェクト」ウィンドウ (Ctrl-1) で、プロジェクトの論理構造を表示できます。また、「ファイル」ウィンドウ (Ctrl-2) で、プロジェクトのファイル構造を表示できます。
「コードジェネレータ」ウィザードの使用
この節では、ウィザードを使用して、コードジェネレータ機能との統合を開始するために必要となるスタブクラスとレイヤーのエントリを作成します。
- プロジェクトノードを右クリックし、「新規」>「その他」を選択します。次に示すように、「新規ファイル」ダイアログで、「モジュールの開発」>「コードジェネレータ」を選択します。

- 「新規コードジェネレータ」パネルで、次のとおりに設定します。
- クラス名。ウィザードで生成するスタブのクラス名を指定します。このフィールドには、「DemoCodeGenerator」と入力します。
- パッケージ。スタブクラスが生成されるパッケージを指定します。ドロップダウンから「org.netbeans.modules.demo」を選択します。
- MIME タイプ。コードジェネレータの統合が適用される MIME タイプを指定します。このフィールドには、「x-java」と入力します。
- CodeGeneratorContextProvider を生成。コードジェネレータのルックアップにほかのオブジェクトを追加します。このチェックボックスは、選択解除したままにします。
画面は次のようになります。

- 「完了」をクリックします。
「プロジェクト」ウィンドウは次のようになります。

layer.xml ファイルは、次のように表示されます。
<filesystem>
<folder name="Editors">
<folder name="text">
<folder name="x-java">
<folder name="CodeGenerators">
<file name="org-netbeans-modules-demo-DemoCodeGenerator$Factory.instance"/>
</folder>
</folder>
</folder>
</folder>
</filesystem>
生成されたクラスは、次のようになります。
public class DemoCodeGenerator implements CodeGenerator {
JTextComponent textComp;
/**
*
* @param context containing JTextComponent and possibly other items
* registered by {@link CodeGeneratorContextProvider}
*/
private DemoCodeGenerator(Lookup context) {
// Good practice is not to save Lookup outside ctor
textComp = context.lookup(JTextComponent.class);
}
public static class Factory implements CodeGenerator.Factory {
public List extends CodeGenerator> create(Lookup context) {
return Collections.singletonList(new DemoCodeGenerator(context));
}
}
/**
* The name which will be inserted inside Insert Code dialog
*/
public String getDisplayName() {
return "Sample Generator";
}
/**
* This will be invoked when user chooses this Generator from Insert Code
* dialog
*/
public void invoke() {
}
}
コードジェネレータの統合のコーディング
次に、API を実装します。API のクラスは、次のとおりです。
| クラス | 説明 |
|---|---|
| JavaSource | 後日記載 |
| CancellableTask | 後日記載 |
| WorkingCopy | 後日記載 |
| CompilationUnitTree | 後日記載 |
| TreeMaker | 後日記載 |
| ClassTree | 後日記載 |
| ModifiersTree | 後日記載 |
| VariableTree | 後日記載 |
| TypeElement | 後日記載 |
| ExpressionTree | 後日記載 |
| MethodTree | 後日記載 |
次では、必要なモジュールとの依存関係を設定し、その依存関係を独自のモジュールに実装します。
- プロジェクトを右クリックし、「プロパティー」を選択して「ライブラリ」パネルに次の 4 つの依存関係を設定します。

注: 「コードジェネレータ」ウィザードによって、「エディタライブラリ 2」と「ユーティリティー API」がすでに自動的に設定されていることがわかります。ほかの 2 つの依存関係は、「Javac API ラッパー」と「Java ソース」です。新しいコードジェネレータの統合を使用して、新しい Java コードスニペットを生成できる必要があります。
- 生成されたクラスを開いて、invoke() メソッドを次のように変更します。
public void invoke() { try { Document doc = textComp.getDocument(); JavaSource javaSource = JavaSource.forDocument(doc); CancellableTask task = new CancellableTask<WorkingCopy>() { public void run(WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); CompilationUnitTree cut = workingCopy.getCompilationUnit(); TreeMaker make = workingCopy.getTreeMaker(); for (Tree typeDecl : cut.getTypeDecls()) { if (Tree.Kind.CLASS == typeDecl.getKind()) { ClassTree clazz = (ClassTree) typeDecl; ModifiersTree methodModifiers = make.Modifiers(Collections.<Modifier>singleton(Modifier.PUBLIC), Collections.<AnnotationTree>emptyList()); VariableTree parameter = make.Variable(make.Modifiers(Collections.<Modifier>singleton(Modifier.FINAL), Collections.<AnnotationTree>emptyList()), "arg0", make.Identifier("Object"), null); TypeElement element = workingCopy.getElements().getTypeElement("java.io.IOException"); ExpressionTree throwsClause = make.QualIdent(element); MethodTree newMethod = make.Method(methodModifiers, "writeExternal", make.PrimitiveType(TypeKind.VOID), Collections.<TypeParameterTree>emptyList(), Collections.singletonList(parameter), Collections.<ExpressionTree>singletonList(throwsClause), "{ throw new UnsupportedOperationException(\"Not supported yet.\") }", null); ClassTree modifiedClazz = make.addClassMember(clazz, newMethod); workingCopy.rewrite(clazz, modifiedClazz); } } } public void cancel() { } }; ModificationResult result = javaSource.runModificationTask(task); result.commit(); } catch (Exception ex) { Exceptions.printStackTrace(ex); } } - 次のインポート文が宣言されていることを確認します。
import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.Tree; import com.sun.source.tree.TypeParameterTree; import com.sun.source.tree.VariableTree; import java.io.IOException; import java.util.Collections; import java.util.List; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeKind; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import org.netbeans.api.java.source.CancellableTask; import org.netbeans.api.java.source.JavaSource; import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.ModificationResult; import org.netbeans.api.java.source.TreeMaker; import org.netbeans.api.java.source.WorkingCopy; import org.netbeans.spi.editor.codegen.CodeGenerator; import org.netbeans.spi.editor.codegen.CodeGeneratorContextProvider; import org.openide.util.Exceptions; import org.openide.util.Lookup;
インストールおよび機能の動作確認
次に、モジュールをインストールし、コードジェネレータ機能の統合を使用します。IDE は、Ant 構築スクリプトを使用してモジュールを構築およびインストールします。構築スクリプトは、プロジェクトを作成するときに作成されます。
- 「プロジェクト」ウィンドウでプロジェクトを右クリックし、「実行」を選択します。
IDE の新しいインスタンスが開始され、コードジェネレータの統合モジュールがインストールされます。
- Alt-Insert キーを押すと、新しい項目が含まれていることがわかります。

- 項目をクリックすると、コードが挿入されます。
共有可能なモジュールバイナリの作成
モジュールが完了したので、ほかの人にそのモジュールを使用させることができます。そのためには、バイナリの「NBM」 (NetBeans モジュール) ファイルを作成し、それを配布する必要があります。
- 「プロジェクト」ウィンドウでプロジェクトを右クリックし、「NBM を作成」を選択します。
NBM ファイルが作成されます。これは「ファイル」ウィンドウ (Ctrl-2) で確認できます。
- たとえば、NetBeans プラグインポータルを通じて、ほかの人がそのファイルを使用できるようにします。受信者は「プラグインマネージャー」(「ツール」>「プラグイン」) を使用して、それをインストールします。
次の手順
NetBeans モジュールの作成と開発の詳細については、次のリソースを参照してください。
