Create  Edit  Diff  FrontPage  Index  Search  Changes  Login

The Backyard - ImplementConnectionWizard Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

!データベースエクスプローラの接続情報を利用する(続)

!!データベース接続選択処理の実装(続)

ImplementConnectionPanelでGUI側の実装をしましたが、この状態ではまだウィザードの機能としては不十分です。
*DatabaseConnectionを選択しなくてもNextをクリックできてしまう
*選択したDatabaseConnectionを保持することができない

パネルの移動の可否判定や、GUIでの選択をコンテキスト(WizardDescriptor)へ保持するのはVisualクラスに対応するWizardクラスの役割です。

次のステップとしてWizardクラスに上記の処理を実装しましょう。

!!!Wizardとのインターフェイスの実装

その前にEntityVisualPanel1を修正して以下の機能を実装します。

*Wizardが選択したDatabaseConnectionを取得可能とする
*Wizardに対してリストからDatabaseConnectionが選択されたことを通知可能にする

選択したDatabaseConnectionを参照できるように次のメソッドをEntityVisualPanel1に実装しましょう。

    DatabaseConnection selectedConnection() {
        DatabaseConnection[] dc = ConnectionManager.getDefault().getConnections();
        for (int i = 0; i < dc.length; i++) {
            if (dc[i].getName().equals(connectionList.getSelectedValue())) {
                return dc[i];
            }
        }
        return null;
    }

JList(connectionListフィールド)にはDatabaseConnectionのnameプロパティを与えているので、selectedConnectionメソッドではnameプロパティが一致するDatabaseConnectionのインスタンスを返します。

次に、connectionListのvalueChangedイベントハンドラを実装します。

その前に、EntityWizardPanel1に対してイベントを通知できるようにEntityVisualPanel1にEntityWizardPanel1の参照を与えられるようにフィールドの追加とコンストラクタの修正を行います。

    EntityWizardPanel1 wizard;

    /** Creates new form EntityVisualPanel1 */
    public EntityVisualPanel1(EntityWizardPanel1 initWizard) {
        wizard = initWizard;
        ConnectionManager.getDefault().addConnectionListener(this);
        initComponents();
        setupList();
    }

EntityVisualPanel1を生成するのはEntityWizardPanel1なのでコンストラクタ呼び出しにthisを与えれば済むのでこの方法が良いと思います。

次に、connectionListの''Events''タブでvalueChangedイベントハンドラを割り当てて、そこから今追加したEntityWizardPanel1の呼び出しを実装します。

[[イベントハンドラの設定|http://arton.no-ip.info/data/nb5/nb3-valuechanged.png]]

    private void connectionListValueChanged(javax.swing.event.ListSelectionEvent evt) {
        wizard.fireChangeEvent();
    }

これで、DatabaseConnectionが選択される都度、EntityWizardPanel1へイベントが通知されるようになります。

!!!Wizardの実装
!!!!importの追加

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// ここより上を追加
import java.awt.Component;
import javax.swing.event.ChangeListener;
// ここより下を追加
import javax.swing.event.ChangeEvent;
// 下は既存
import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;

WizardがNetBeansにイベントを通知するためのコードはあらかじめコメントとして生成されるソースに含まれています。このコードを有効にするために、java.util.HashSetなどをimportしましょう。

!!!!Componentの型を特化する

EntityWizardPanel1からEntityVisualPanel1のメソッド(上記selectedConnectionメソッド)を呼び出すので、単なるCompoenetクラスとなっているフィールドをEntityVisualPanel1に修正して利用時のキャストを不要にします。

    private EntityVisualPanel1 component;

同様に、EntityVisualPanel1のコンストラクタの修正に対応させます。

    public Component getComponent() {
        if (component == null) {
            component = new EntityVisualPanel1(this);
        }
        return component;
    }

!!!!NetBeansへ状態を通知可能にする。

最初に単にtrueを返すように実装しているisValidメソッドを修正して、DatabaseConnectionが設定されている場合にのみtrueを返すようにしましょう。この修正を行うと、connectionListが未選択だとNextボタンが無効化されるようになります。

    public boolean isValid() {
        return component.selectedConnection() != null;
    }

次に、有効状態の変更を通知できるように、addChangeListener、removeChangeListener、fireChangeEventの3つのメソッドのコメントアウトを外します。逆に最初に生成されたソースのaddChangeListener、removeChangeListenerメソッドの実装を削除します。

なお、EntityVisualPanel1のconnectionListValueChangedメソッドで直截fireChangeEventを呼び出すように実装しているため、ここについての修正は以上で完了です。

!!!!選択されたDatabaseConnectionを保持する

最後に選択されたDatabaseConnectionを保持して後続のパネルから利用可能にします。

このためには、コンテキスト(WizardDescriptor)を利用します。Wizardクラスがコンテキストを利用するためのインターフェイスとして読み込みのためのreadSettings、保存のためのstoreSetteingsの2つのメソッドがあらかじめ用意されています。

ここでは保存のためなのでstoreSettingsメソッドを修正することになります。

    public void storeSettings(Object settings) {
        ((WizardDescriptor)settings).putProperty("connection", component.selectedConnection());
    }

これによって、後続の処理はreadSettingsメソッドの呼び出しで与えられたsettingsオブジェクトに対して、((WizardDescriptor)settings).getProperty("connection")を呼び出すことで、このパネルで選択されたDatabaseConnectionを利用することが可能となります。

!!!!コネクションの後始末を実装しておく

なお、後続のパネルでウィザードをキャンセルした場合に、もしDatabaseConnectionが接続状態だと余分なリソースの利用となるので望ましくないかも知れません(もっとも、データベースエクスプローラを利用すればユーザーはコネクションを切断できます)。

DatabaseConnectionのようなオブジェクトをWizardDescriptorに保持した場合は、Iteratorクラスのクリーンアップ処理に廃棄処理を実装することができます。そのタイミングで切断処理を実装しましょう。

EntityWizardIterator.javaを開いて、最初にimport宣言を追加します。

import org.netbeans.api.db.explorer.ConnectionManager;
import org.netbeans.api.db.explorer.DatabaseConnection;


次にuninitializeメソッドを探してください。NetBeansは最後にuninitializeメソッドを呼び出すので、このメソッドに切断処理を実装します。

    public void uninitialize(WizardDescriptor wizard) {
        DatabaseConnection dc = (DatabaseConnection)wizard.getProperty("connection");
        if (dc != null) {
            ConnectionManager.getDefault().disconnect(dc);
        }
        panels = null;
    }

なおウィザードを起動直後にキャンセルした場合にはWizardDescriptorにDatabaseConnectionは設定されていないので、nullチェックが必須です。