Java のプロジェクトを作りたいっ その 3

あの宮本さんからトラバしていただきました。そして、JavaCapabilityConfigurationPage クラスを調べてていただいてもらいました。宮本さんありがとうございます。宮本さんに手助けしてもらったら勇気 100 倍、胸一杯です。

http://d.hatena.ne.jp/muimy/20050905/p1

昨日は調べるところで時間を使ってしまったので、今日からコードを書いて試してみます。

ということで、さっそく LG3DProjectWizard クラスの init メソッドを次のように書きかえてみました。

    public void init(IWorkbench workbench, IStructuredSelection selection) {
        setWindowTitle("New Project Looking Glass Project");
        
        creationPage = new WizardNewProjectCreationPage("LG3D Project");
        creationPage.setTitle("Configuration of New LG3D Project");
        creationPage.setDescription("Input project name and location."); 
        addPage(creationPage);
        
        IJavaProject javaProject = JavaCore.create(creationPage.getProjectHandle());
        IPath path = creationPage.getLocationPath();
        
        JavaCapabilityConfigurationPage javaPage = new JavaCapabilityConfigurationPage();
        javaPage.init(javaProject, path, null, false);
        addPage(javaPage);
    }

これで完璧だ、と思って実行したのですが...

Unhandled event loop exception
Reason:
java.lang.NullPointerException

がっくし orz

ここまでは宮本さんの blog を見る前に作ってみたのですが... ダメですね。で、宮本さんの blog を見てみると init は内部的に呼ばれるメソッドのようですね。

そうか、JavaCapabilityConfigurationPage は派生させることを前提に使うのか。勉強になります。それに、上の例で LG3DProjectWizard#init に書いていたことは addPages に書くらしいということも分かりました。

昨日、[Next >] を押されたときのイベントがとれないと書きましたけど、派生させていいなら話は別です。setVisible メソッドがページが表示されたときに呼ばれるメソッドなのだそうです。

で、宮本さんのサンプルをベースにして addPages を次のように書きかえてみました。

    public void addPages() {
        setWindowTitle("New Project Looking Glass Project");
        
        creationPage = new WizardNewProjectCreationPage("LG3D Project");
        creationPage.setTitle("Configuration of New LG3D Project");
        creationPage.setDescription("Input project name and location."); 
        addPage(creationPage);
        
        javaPage = new JavaCapabilityConfigurationPage(){
            public void setVisible(boolean visible) {
                if (visible) {
                    project = creationPage.getProjectHandle();
                    IJavaProject javaProject= JavaCore.create(project);
                    init(javaProject, null, null, true);
                } else {
                }
                super.setVisible(visible);
            }
        };
        addPage(javaPage);
    }

後は終わらせるときですね。宮本さんのサンプルだと JavaCapabilityConfigurationPage の派生クラスにプロジェクトを生成させるためのメソッドが追加されていましたが、LG3DProjectWizard#performFinish メソッドで同じ処理をk記述するようにしました。

    public boolean performFinish() {
        IRunnableWithProgress op = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {              
                try {
                    project.create(monitor);
                    project.open(monitor);
                    javaPage.configureJavaProject(monitor);
                } catch (CoreException ex) {
                    throw new InvocationTargetException(ex);
                } finally {
                    monitor.done();
                }
            }
        };
        
        try {
            getContainer().run(true, false, op);
        } catch (InterruptedException ex) {
            return false;
        } catch (InvocationTargetException ex) {
            Throwable realException = ex.getTargetException();
            MessageDialog.openError(getShell(), "Error", realException.getMessage());
            return false;
        }

        return true;
    }

そうか IRunnableWithProgress インタフェースなんてものがあるんだ。全然知りませんでした。

後は canFinish メソッドは project オブジェクトが生成されているかどうかで、チェックするようにしました。

    public boolean canFinish() {
        if (project == null) {
            return false;
        } else {
            return true;
        }
    }

で、実行っ!

Project Creation Wizard Page

何も入力していないと [Next >] も [Finish] も押せないようになってます。

Project Creation Wizard Page

プロジェクト名を入力すると次にいけます。

Project Creation Wizard Page

Java Project の設定ページまでいくと、[Finish] もできるようになりました。

[Finish] させると

Project

プロジェクトが生成できましたっ!