Modale Jobs

Status
Nicht offen für weitere Antworten.
G

Gast

Gast
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.
 
G

Gast

Gast
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

Top Contributor
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.
 
G

Gast

Gast
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

Top Contributor
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.
 
G

Gast

Gast
Habe das jetzt so gemacht:
Code:
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?
 
G

Guest

Gast
Code:
 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

Top Contributor
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"
 
G

Gast

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

Gast

Gast
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

Top Contributor
Registrier einen Adapter der Job auf IRunnableWithProgress adaptiert.
Danach machst du
Code:
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.
 

Wildcard

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

Gast

Gast
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

Top Contributor
Der Adapter würde etwa so aussehen:
Code:
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
 
G

Gast

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

Code:
  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.
Code:
 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

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

Code:
    public Object getAdapter(Object adaptableObject, Class adapterType)
    {
        if (adaptableObject instanceof Job)
        {
            return new RunnableJobAdapter((Job)adaptableObject);
               
        }
        return null;
    }
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben