VMOptionsをハックして,オプションセットを複数持てるようにした。

毎回々々,大量にメモリを持ってかれるのもアレなんで,複数の起動オプションを切り替えできるようにしてみた。


そして,こいつ(Settingsダイアログ)の作り方。


IDE Settingsに登場するには,OpenAPIのConfigurableを実装しなければならない。それと,application-componentにしてあるんで,IDE Settingsに分類されてるんだと思う(project-componentだったら,Project Settingsに出るんじゃないかな。多分)。
さらに設定した内容を永続化したい場合は,JDOMExternalizableも実装する必要があるそうだ(これは後で補足する)。



とりあえず,コードで説明。

public class VMOptionsPlugin implements ApplicationComponent,
                                        JDOMExternalizable,
                                        Configurable,
                                        ActionListener {

※ActionListenerは,VMOptions本体が利用するために付けただけで,OpenAPIとは関係ない。


Configurableに関係するのは,以下のメソッド。

public String getDisplayName();
public Icon getIcon();
public String getHelpTopic();

// Settingsダイアログに貼り付けるSwingコンポーネント
public JComponent createComponent();

// APPLYボタンを有効にするかどうか
public boolean isModified();
// OK/APPLYボタンを押したときの処理
public void apply();
// CANCELボタンを押したときの処理
public void reset();

// Settingsダイアログを閉じたときの処理
public void disposeUIResources();

Settingsダイアログは,元々「OK/Cancel/Apply」の3つボタンを持っているので,createComponent()で返すコンポーネントは,それら(ダイアログの閉じ方)のことを気にしなくてよい。その代わり,それぞれのイベントに対応する処理(apply()/reset())を実装しておく。


あと,JDOMExternalizableを実装することで,そのSettingsダイアログに設定した内容を永続化することができるようだ。ちなみに,こんなコードで永続化と,その復元が可能。

public void readExternal(Element element) throws InvalidDataException {
  // 読み込んだElementの内容を自分自身に貼り付ける
  // ※ここで言う「自分自身」とは,「publicなフィールド変数」を指すみたい。
  //   更に言えば,その型はStringとかじゃないとダメっぽい(intやlongは試してないが,
  //   Mapはダメだった)。
  XmlSerializer.deserializeInto(this, element);
}

public void writeExternal(Element element) throws WriteExternalException {
  // 自身自分をElementに書き出す。
  DefaultJDOMExternalizer.writeExternal(this, element);
  // これ以外にも,Elementを操作して,自分が望むNodeを作り出してもいいみたい。
}

んで,その永続化先は,

  • application-componentの場合
    • ${idea.config.path}/options/other.xml(多分,ファイル名は変えられる)
  • project-componentの場合
    • $PROJECT_HOMEの*.ipr*.iws

だそうな。
http://www.intellij.net/forums/thread.jspa?messageID=5176257&#5176257
http://www.intellij.net/forums/thread.jspa?messageID=845855󎠟


ややこしいことに,IDEA7のOpenAPIではJDOMExternalizableやDefaultJDOMExternalizerはdeprecatedになっており,正しい永続化方法ではなくなるらしい。どうやら,変わりにPersistentStateComponent ってのを使えとあるが,やり方よくわからんので,しばらくは放っておく。
http://www.intellij.net/forums/thread.jspa?messageID=5186012&#5186012


最後に,ApplicationComponent,JDOMExternalizable,Configurableのイベント順を示して今回はおしまいにする。
まずIDEA起動時。

  1. ApplicationComponentのコンストラク
  2. JDOMExternalizable#readExternal()
  3. ApplicationComponent#initComponent

Settingsダイアログを開いて,閉じる時。

  1. Configurable#createComponent()
  1. Configurable#apply()/reset()
  2. Configurable#disposeUIResources()

IDEAを終了する時。

  1. JDOMExternalizable#writeExternal()
  2. ApplicationComponent#disposeComponent()