Eclipseのプラグイン開発のPreference(設定の保存)について。
|
|
Eclipseでは、メニューバーの「Windows(W)」→「設定(P)」で設定(Preference)ダイアログを開き、各プラグインの設定を変更・保存する事が出来る。
これはPreferenceStore(設定保存)クラスで実現する。
→プロジェクト毎の設定はPropertyPageで行う。
メッセージを表示するアクションの例に対し、表示するダイアログのタイトルとメッセージを設定できるように改造してみる。
まず、設定のデフォルト値(初期値)を管理するクラスを作成する。
package com.example.eclipse.plugin.hello.preference; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; import org.eclipse.jface.preference.IPreferenceStore; import com.example.eclipse.plugin.Activator;
public class HelloPreferenceInitializer extends AbstractPreferenceInitializer { public static final String KEY_TITLE = "HELLO_TITLE"; public static final String KEY_MESSAGE = "HELLO_MESSAGE";
@Override public void initializeDefaultPreferences() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); store.setDefault(KEY_TITLE, "plugin-example1"); store.setDefault(KEY_MESSAGE, "Hello, Eclipse world"); } }
Activatorから設定ストアを取得し、setDefault()でデフォルト値を設定していく。
(キー名は自分で適当に付ける)
そして、plugin.xmlにイニシャライザーを呼び出す記述を追加する。
<plugin> 〜 <extension point="org.eclipse.core.runtime.preferences"> <initializer class="com.example.eclipse.plugin.hello.preference.HelloPreferenceInitializer" /> </extension> </plugin>
次に、設定ダイアログで表示されるページを作成する。
これには、EclipseのSWT(GUIの為のクラス群)を使う。
package com.example.eclipse.plugin.hello.preference; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import com.example.eclipse.plugin.Activator;
SWTのラベルやテキストフィールドのクラス名はAWTやSwingと似ているが、インポートするのはSWTのクラス。
public class HelloPreferencePage1 extends PreferencePage implements IWorkbenchPreferencePage { private Text titleText; private Text messageText;
@Override public void init(IWorkbench workbench) { }
@Override protected Control createContents(Composite parent) { setTitle("preference-title"); IPreferenceStore store = Activator.getDefault().getPreferenceStore(); Composite composite = new Composite(parent, SWT.NONE); { GridLayout layout = new GridLayout(); layout.numColumns = 2; // 列数 composite.setLayout(layout); } { // タイトルを入力する行 Label label = new Label(composite, SWT.NONE); label.setText("title"); titleText = new Text(composite, SWT.SINGLE | SWT.BORDER); titleText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); titleText.setText(store.getString(HelloPreferenceInitializer.KEY_TITLE)); } { // メッセージを入力する行 Label label = new Label(composite, SWT.NONE); label.setText("message"); messageText = new Text(composite, SWT.SINGLE | SWT.BORDER); messageText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); messageText.setText(store.getString(HelloPreferenceInitializer.KEY_MESSAGE)); } return composite; }
createContents()でSWTを使って入力フィールドを用意していく。
@Override protected void performDefaults() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); titleText. setText(store.getDefaultString(HelloPreferenceInitializer.KEY_TITLE)); messageText.setText(store.getDefaultString(HelloPreferenceInitializer.KEY_MESSAGE)); }
performDefaults()は「デフォルトの復元」ボタンが押されたときに実行される。
設定ストアからデフォルト値を取得してテキストフィールドに設定し直す。
@Override public boolean performOk() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); store.setValue(HelloPreferenceInitializer.KEY_TITLE, titleText.getText()); store.setValue(HelloPreferenceInitializer.KEY_MESSAGE, messageText.getText()); return true; } }
performOk()は「OK」ボタンが押されたときに実行される。
テキストフィールドに入力された値を設定ストアに保存する。
なお、設定内容の永続化(どこかのファイルに保存される)は自動的に行われる。
そして、plugin.xmlに設定ページの記述を追加する。
<plugin> 〜 <extension point="org.eclipse.ui.preferencePages"> <page class="com.example.eclipse.plugin.hello.preference.HelloPreferencePage1" id="com.example.eclipse.plugin.hello.preference.page" name="plugin-example1"> </page> </extension> </plugin>
pageタグのname属性が、設定ダイアログのツリーに表示される文言となる。
今回の例の対象であるアクションクラスを修正し、設定ストアから値を読み込むようにする。
@Override public void run(IAction action) { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); String title = store.getString(HelloPreferenceInitializer.KEY_TITLE); String message = store.getString(HelloPreferenceInitializer.KEY_MESSAGE); ILog log = Activator.getDefault().getLog(); log.log(new Status(IStatus.INFO, Activator.PLUGIN_ID, String.format("action title=[%s], message=[%s]", title, message))); MessageDialog.openInformation(window.getShell(), title, message); }
単純なグリッド(表形式)の設定ページなら、FieldEditorPreferencePageというクラスを使った方がSWTを直接使うよりも便利。
package com.example.eclipse.plugin.hello.preference; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import com.example.eclipse.plugin.hello.Activator;
public class HelloPreferencePage2 extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { /** * コンストラクター. */ public HelloPreferencePage2() { super(GRID); setPreferenceStore(Activator.getDefault().getPreferenceStore()); }
@Override public void init(IWorkbench workbench) { }
@Override protected void createFieldEditors() { Composite parent = getFieldEditorParent(); addField(new StringFieldEditor(HelloPreferenceInitializer.KEY_TITLE, "title", parent)); addField(new StringFieldEditor(HelloPreferenceInitializer.KEY_MESSAGE, "message", parent)); } }
createFieldEditors()の中で設定ページの定義を行う。
addField()でフィールド行を追加していく。
StringFieldEditorがString用で、他にもBooleanFieldEditorとかIntegerFieldEditorなど色々なクラスがある。
Eclise3.7のプラグイン開発のデフォルトでは、設定ストアのスコープはワークスペース単位となっている。
(設定値の保存の範囲がワークスペースということ。つまり別々のワークスペースでは設定を共有しない)
Eclipse単位(Eclipse全体で設定を共有する)のスコープにするには、以下のようにする。
(全般的にActivatorオブジェクトから設定ストアを取得するコーディングになっているので、ActivatorクラスのgetPreferenceStore()をオーバーライドする)
import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.ui.preferences.ScopedPreferenceStore;
/** * Storage for preferences. */ private ScopedPreferenceStore preferenceStore;
@Override public IPreferenceStore getPreferenceStore() { if (preferenceStore == null) { preferenceStore = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, PLUGIN_ID); } return preferenceStore; }
スコープ | スコープオブジェクト |
---|---|
Eclipse単位 | ConfigurationScope.INSTANCE |
ワークスペース単位 | InstanceScope.INSTANCE |
Preferenceでは、ツリー構造で複数の画面(ページ)を持つことが出来る。[2013-02-09]
各ページの定義において、カテゴリーで別ページのIDを指定すると、そのページの子ページとなる。
カテゴリーを指定しない場合は全体(親)の子ページとなる。
<extension point="org.eclipse.ui.preferencePages"> <page class="com.example.preference.TopPreferencePage" id="example.top-preference-page" name="example top page"> </page> <page category="example.top-preference-page" class="com.example.preference.SubPreferencePage" id="example.sub-preference-page" name="example sub page"> </page> </extension>
特に設定を行わないページ(カテゴリーで階層を作ったトップページ等)の場合、デフォルトボタンや適用ボタンは不要。[2013-02-09]
そういうページでは、コンストラクターでボタン非表示の指定をしておく。
public class TopPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
public TopPreferencePage() { super("TopPreferencePage"); noDefaultAndApplyButton(); //DefaultボタンとApplyボタンの非表示 }
@Override public void init(IWorkbench workbench) { }
@Override protected Control createContents(Composite parent) { setTitle("example blank page"); Composite composite = new Composite(parent, SWT.NONE); return composite; } }
Pleiadesプラグインで日本語化しているEclipseを使っている場合、テスト実行して起動されるEclipseも日本語化される。
なんと、自分で作った設定ページ(のラベルの内容)も自動的に日本語化される。
例えば上記の例だと「title」は「タイトル」、「message」は「メッセージ」と表示される。
問題は、この変換内容がキャッシュされてしまうということ。
一度テスト実行したら、設定ページのソースを変えてコンパイルし直しても、次回以降のテスト実行では反映されない。
Eclipseをインストールしたディレクトリーの下のconfiguration\jp.sourceforge.mergedoc.pleiadesの中にある「transformed-class.cache」というファイルを削除すると、キャッシュが無いので最新のクラスが使われる。
※このファイルを一度削除すると再生成はされない(キャッシュされなくなる)っぽい。
テスト実行用の実行構成にPleiadesの設定があるので、無効化してやる。
(当然、起動されるEclipseは英語版になる)
-Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m -javaagent:dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar ↓ -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m