# Modale Jobs



## Gast (28. Jul 2008)

Hallo Leute,
ich schreibe gerade eine kleine RCP Anwendung.
In dieser laufen mehrer Jobs.
Dazu jetzt meine Frage:

Wie kann ich das ganze konfigurieren das alle Views geblockt werden sobald ein  Job ausgeführt wird?
Also das dieser Job modal ist.

Danke schonmal.


----------



## foobar (28. Jul 2008)

Also normalerweise laufen Jobs im Hintergrund. Warum willst du die GUI blockieren?


----------



## Gast (28. Jul 2008)

Das ist ein vom User initierter Job (setUser(true))
Also mit Ladebalken und so.

Der User soll aber während er warten muss keine anderen Aktionen ausführen.


----------



## Wildcard (28. Jul 2008)

Da hast du zwei Möglichkeiten:
Wenn keine Dateien verändert werden dürfen, setz den WorkspaceRoot als Scheduling Rule.
Wenn gar nichts mehr getan werden darf, dann ruf Job.getJobManager().join(jobFamily,null) im SWT-Thread auf.


----------



## Gast (28. Jul 2008)

Habe jetzt einfach mal Job.getJobManager().join(null,null)
aufgerufen nach der Job startet.
Die Views werden auch geblockt, aber es wird ein zusätzlicher Screen engezeigt und das wollte ich eigentlich nicht. Es sollte nur der Job(mit ProgressBar) auswählbar sein und der Rest geblockt werden.

Was mache ich da noch verkehrt?


----------



## Wildcard (28. Jul 2008)

Das maximum für einen Job sollte wirklich das blockieren des Workspace sein. Sonst ist ein Job (bzgw. das schedulen im Job Manager) falsch.
Ich denke die User Experience verschlechtert sich, wenn du mehr als unbedingt nötig sperrst, aber wenn du darauf bestehst:
Verwende einen ProgressMonitorDialog mit blockOnOpen und führe dort deine Operation aus.


----------



## Gast (29. Jul 2008)

Habe das jetzt so gemacht:

```
final ProgressMonitorDialog d = new ProgressMonitorDialog(checkParent().getShell());
        d.setBlockOnOpen(true);
        d.setCancelable(false);        
        if (job_runtime != null) {
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {                  
                    d.open();

    //Operationen

                    d.close();
}
            });
            job_runtime.setUser(true);           
            job_runtime.schedule();
```

ein Dialog öffnet sich die Oberfläche wird auch geblockt, aber der Dialog schließt sich nicht mehr.

Wo liegt da der Fehler?


----------



## Gast (29. Jul 2008)

Achso und die Oberfläche bleibt blockiert


----------



## Wildcard (29. Jul 2008)

Rufst du auch irgendwann monitor.done() auf?


----------



## Gast (29. Jul 2008)

Ja monitor.done wird ausgeführt.


----------



## Wildcard (29. Jul 2008)

Warum hast du immer noch einen Job? Zeig mal mehr Code


----------



## Guest (29. Jul 2008)

```
private static void jobRunner(final Job job_runtime, final Job second) {
 final ProgressMonitorDialog d = new ProgressMonitorDialog(checkParent().getShell());
        d.setBlockOnOpen(true);
        d.setCancelable(false);        
        if (job_runtime != null) {
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    Thread t = new Thread(new Runnable() {
                        public void run() {
                            d.open();
                            if (job_runtime != null) {
                                while (job_runtime.getState() == Job.RUNNING) {
                                    try {
                                        Thread.sleep(500);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                                d.close();

                                if (job_runtime.getResult() != null) {
                                    int status = job_runtime.getResult()
                                            .getSeverity();
                                    String message = job_runtime.getResult()
                                            .getMessage();

                                    switch (status) {
                                        case Status.WARNING:
                                            Dialogs
                                                    .displayWarningDialog(message);
                                            break;

                                        case Status.INFO:
                                            Dialogs.displayInfoDialog(message);
                                            break;

                                        default:
                                            break;
                                    }

                                }
                            }

                        }
                    });
                    t.setPriority(Thread.MIN_PRIORITY);
                    t.start();
                }
            });
            job_runtime.setUser(true);
            job_runtime.schedule();
         
        }
    }
```

Hoffe das hilft beim Verständniss.


----------



## Wildcard (29. Jul 2008)

Du rufst nirgends done auf.
Was soll es bringen einen ProgressMonitorDialog zu verwenden wenn du den Thread trotzdem im JobManager ausführst. "Entweder, oder", nicht "sowohl als auch"


----------



## Gast (29. Jul 2008)

Aber wie könnte ich das gescheit machen. Vllt. nen kleines Code Beispiel wäre hilfreich.


----------



## Wildcard (29. Jul 2008)

Damit:
http://www.capescience.com/7.5.1/he...clipse.jface.operation.IRunnableWithProgress)


----------



## Gast (29. Jul 2008)

Danke erstmal, aber ich habe verdammt viele verschiedene Jobs und die will ungerne alle umbauen. Gibt es denn wirklich keine Möglichkeit die Views zu blockieren sobald ein Job ausgeführt wird?


----------



## Wildcard (29. Jul 2008)

Registrier einen Adapter der Job auf IRunnableWithProgress adaptiert.
Danach machst du 

```
progressMonitorDialog.run((IRunnableWithProgress)job.getAdapter(IRunnableWithProgress.class));
```

Edit: ist auch durchaus möglich, das die Plattform bereits den Adapter stellt, als versuch einfach mal ob job.getAdapter(IRunnableWithProgress.class) dir ein IRunnableWithProgress liefert. 
Wenn nicht, ist der Adapter schnell geschrieben.


----------



## Gast (29. Jul 2008)

Sorry leider noch nie gemacht.


----------



## Wildcard (29. Jul 2008)

Ich kann hier weder eine Frage erkennen, noch ob du versucht hast ob die Plattform dir einen Adapter für Job bereitstellt


----------



## Gast (29. Jul 2008)

Ah Sorry, 
die Plattform stellt den Adapter nicht.
Wie würde denn der Adapter aussehen und wie hänge ich ihn an die Job?


----------



## Wildcard (29. Jul 2008)

Der Adapter würde etwa so aussehen:

```
class RunnableJobAdapter  implements IRunnableWithProgress
{

    private Job job;

    /**
     * @param job
     */
    public RunnableJobAdapter(Job job)
    {
        super();
        this.job = job;
    }



    public void run(IProgressMonitor monitor)
        throws InvocationTargetException, InterruptedException
    {
        try
        {
            Method method = Job.class.getMethod("run", new Class[]{IProgressMonitor.class});
            method.setAccessible(true);
            method.invoke(job, new Object[]{monitor});
            
        }
        catch (SecurityException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (NoSuchMethodException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
    
}
```
Leider sind die Signaturen inkompatibel, und run protected, daher der Umweg über Reflection.

Danach registrierst du eine Adapter Factory für Job mit dem Extension Point 
org.eclipse.core.runtime.adapters


----------



## Gast (30. Jul 2008)

Ich glaube jetzt wirds langsam nervig, aber wie funktioniert das mit der Factory?
Habe z.B. so einen Job


```
job_runtime = new Job("Load Key Store") {

                        @Override
                        protected IStatus run(IProgressMonitor monitor) {
                        for(int i=0; i<100; i++)
                        {
                              System.out.println(i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
                        }

                                                        return Status.OK_STATUS;
                        }
                    };
```

Starten tue ich den Job bisher mit.

```
job_runtime.setUser(true);
         
            job_runtime.schedule();
```

Davon habe ich ne ganz Menge Jobs.
Wie könnte ich das jetzt da mit der Factory machen damit ich nicht in jeden Job eine Menge ändern müsste?

Danke erstmal für deine Mühen.


----------



## Wildcard (30. Jul 2008)

Unter besagtem Extension Point eine AdapterFactory einhängen die Job auf IRunnableWithProgress adaptiert und dann eien ProgressMonitorDialog verwenden
Die Factory macht nichts weltbewegendes:


```
public Object getAdapter(Object adaptableObject, Class adapterType)
    {
        if (adaptableObject instanceof Job)
        {
            return new RunnableJobAdapter((Job)adaptableObject);
               
        }
        return null;
    }
```


----------

