# RCP coolbar



## Guest (3. Sep 2008)

Hi zusammen,

wie kann ich von einem Editor aus einen Action in der coolbar aktivieren bzw. deaktivieren?

Danke


----------



## Wildcard (3. Sep 2008)

Du kannst im IWorkbenchWindowActionDelegate auf Selection reagieren. Genügt dir das nicht?


----------



## Guest (3. Sep 2008)

ich möchte so eine ähnliche funktion wie der speicher button...
wenn eine bestimmt methode true zurück gibt dann soll der button aktiv werden...
oder im notfall halt den button von dem editor aus setzen


----------



## foobar (3. Sep 2008)

Deine Actions sollten immer Selbstbefriedigung machen d.h. eine Action kümmert sich selber um ihren Zustand. Du kannst in deiner  IWorkbenchWindowActionDelegate in der selectionChanged-Methode auf die gesamte Workbench zugreifen und dir z.b. den aktiven Editor holen. Der Editor hat dann irgendwelche Flags, die der Action anzeigen was zu tun ist. Die Logik dafür gehört aber in die Action selber. Das macht das Leben einfacher


----------



## Guest (3. Sep 2008)

dann ich glaub igendwas falsch gemacht + verstanden...
wo finde ich die  IWorkbenchWindowActionDelegate bzw. wo muss die einbinden

hab meine coolbar


```
public class ApplicationActionBarAdvisor extends ActionBarAdvisor
{

  private SendMailAction senden;
  private IWorkbenchAction saveAction;

  protected void makeActions(IWorkbenchWindow window)
  {
    saveAction = ActionFactory.SAVE.create(window);
    register(saveAction);
    senden = new SendMailAction(window);
    register(senden);
  }
}
```

und mein action

```
public class SendMailAction extends Action
{

  private final IWorkbenchWindow mWindow;

  public SendMailAction(final IWorkbenchWindow window)
  {
    mWindow = window;
    setId(ID);
    setActionDefinitionId(ID);
    setImageDescriptor(Activator.getImageDescriptor("/icons/mail.ico"));
  }

  public void run()
  {

  }
}
```


----------



## foobar (3. Sep 2008)

Es gibt 2 Typen von Actions in Eclipse RCP. Einmal die programmatisch registrierten Actions, die du in deinem Beispiel verwendest und die  IWorkbenchWindowActionDelegate, die über die plugin.xml deklarativ registriert werden.
Nur die IWorkbenchWindowActionDelegate können ohne Umwege auf Selections reagieren. Ausserdem kannst du diese Delegates in ActionSets zusammen fassen und je nach Perspective eine anderes ActionSet anzeigen. 

http://help.eclipse.org/help21/inde...clipse/ui/IWorkbenchWindowActionDelegate.html

Lies dir auch das hier mal durch: http://help.eclipse.org/help21/topi...rence/api/org/eclipse/ui/IActionDelegate.html

und das hier: http://www.vogella.de/articles/RichClientPlatform/article.html#actions_s1c


----------



## Guest (4. Sep 2008)

ok thx jetzt habe ich den action angelegt

wie kann ich ihm jetzt sagen wo er in der coolbar und menu hinsoll er macht die mir jetzt ganz rechts hin...


----------



## Wildcard (4. Sep 2008)

Du gibst einen Toolbar Path an (zB Normal/additions). Die erscheinen dann am angegeben Pfad in der *umgekehrten* Reihenfolge in der sie definiert wurden.


----------



## Guest (4. Sep 2008)

ja okay und was ist wenn ich die coolbar von oben hab und den action jetzt zwischen reinsetzen möchte...


----------



## Wildcard (4. Sep 2008)

Ich weiß doch nicht welche Einträge du in deiner Bar hast. Der Toolbar Path muss dazu passen.


----------



## Guest (4. Sep 2008)

irgendwie check ich des grad nicht ich hab doch in dem oberen post eine coolbar... und da will ich den action jetzt an eine bestimmten stelle einfügen muss ich da jetzt noch einen command machen????
mein ziel ist es einen button wie den eclipse speicher button zu kreieren der bei einer bestimmten editor methode ob diese false oder true ist aktiv oder inaktiv wird...


----------



## Guest (4. Sep 2008)

in dem tutorial steht nur drin wie ich so ein action an anleg nicht wie ich diese mit den eclipse standard button z.B. verbinde und diese auch einfügen kann... verstehst was ich mein wo mein Problem ist bzw. was ich nicht versteh ???

Ich versuch mal ein Bespiel ich möchte als erstes in der coolbar den save button dann meine eigenen und dann den exit button wie mache ich das???


----------



## Wildcard (4. Sep 2008)

Die Eclipse Actions schließt du an in dem du auf die Commands reagierst. Einige der Actions lassen sich auch einfacher aktivieren. Zum Beispiel für Save sollte es genügen, wenn du ISaveablePart implementierst. 
Innerhalb eines ToolBar-Paths hast du AFAIK keinen Einfluß auf die Reihenfolge in der die Actions erscheinen.
Das ganze Toolbar/Actions/Command/Context/Handler Framework ist sehr komplziert, da musst du schon selbst die Dokumentation bemühen.


----------



## Guest (4. Sep 2008)

kannst du mir sagen nach was genau ich suchen soll?

ich versteh das grundprinzip eh noch nicht richtig
wenn ich eine toolbar erstellen will ...
erstell ich dann lauter commands die ich registiere 

und diese commands behinhalten dann meine Delegates oder ist er ansatz falsch ???


```
public class ApplicationActionBarAdvisor extends ActionBarAdvisor
{
  private SendCommand senden;
  private IWorkbenchAction saveAction;



  public ApplicationActionBarAdvisor(IActionBarConfigurer configurer)
  {
    super(configurer);
  }


  protected void makeActions(IWorkbenchWindow window)
  {


    saveAction = ActionFactory.SAVE.create(window);
    register(saveAction);


    senden = new SendCommand(window);
    register(senden);

  }

  protected void fillCoolBar(ICoolBarManager coolBar)
  {

    IToolBarManager toolbar1 = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
    coolBar.add(new ToolBarContributionItem(toolbar1, "toolbar1"));
    toolbar1.add(saveAction);
    toolbar1.add(senden);
 }
```



```
public class SendCommand extends Action
{
  private final IWorkbenchWindow mWindow;

  public SendCommand(final IWorkbenchWindow window)
  {
    mWindow = window;
  }

  public void run()
  {
    SendMailAction send = new SendMailAction();
    send.init(mWindow);
    send.run(this);
  }

  public void dispose()
  {
    // TODO Auto-generated method stub

  }
}
```



```
{

  private IWorkbenchWindow mWindow;
  public static final String ID="Tippspiel-RCP.SendMailAction";

  public void dispose()
  {
    // TODO Auto-generated method stub

  }
  public void init(IWorkbenchWindow window)
  {
    mWindow = window;

  }
  public void run(IAction action)
  {
   System.out.println("Action");

  }

  public void selectionChanged(IAction action, ISelection selection)
  {
    System.out.println("selectionChanged");

  }



}
```

??? mhm????


----------



## Guest (4. Sep 2008)

sry 
	
	
	
	





```
public class SendMailAction implements IWorkbenchWindowActionDelegate
{

  private IWorkbenchWindow mWindow;
  public static final String ID="Tippspiel-RCP.SendMailAction";

  public void dispose()
  {
    // TODO Auto-generated method stub

  }
  public void init(IWorkbenchWindow window)
  {
    mWindow = window;

  }
  public void run(IAction action)
  {
   System.out.println("Action");

  }

  public void selectionChanged(IAction action, ISelection selection)
  {
    System.out.println("selectionChanged");
  }
```


----------



## Guest (4. Sep 2008)

mhm okay iwie komm ich mit der sache nicht so ganz voran...
mich würde erst mal irgendwie interessieren wie der mechanismus mit dem save button funktioniert dass wenn bei einem editior isDirty() true/flase zurückliefert der Button der button je nachdem aktiv/inaktiv ist...
weil der save button muss ja irgenwie auf den zustand zugriff haben d.h. wenn die methode ausgeführt wird muss der button das ja mitbekommen ... versteh nicht ganz wie das klappt kann des jemand in groben zügen erklären vielleicht kleines cbsp ... würde mir echt helfen thx.......


----------



## foobar (4. Sep 2008)

Du brauchst eine Action:


```
public class HelloAction implements IWorkbenchWindowActionDelegate
{
    public final static String ID = "RCPActionDemo.HelloAction"; //$NON-NLS-1$
    private IWorkbenchWindow window;
    
    
    @Override
    public void dispose()
    {
    }

    @Override
    public void init(IWorkbenchWindow window)
    {
        this.window = window;
    }

    @Override
    public void run(IAction action)
    {
        MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "Hallo", "Hallo Welt");
    }

    @Override
    public void selectionChanged(IAction action, ISelection selection)
    {
          IEditorPart edi = window.getActivePage().getActiveEditor();
          
          if (null != edi)
          {
              // wenn der Editor einen bestimmten Zustand hat action aktivieren
              //.....
              action.setEnabled(true);
          }
          action.setEnabled(false);
    }
}
```
Die Action kann jetzt selber bestimmten welchen zustand sie hat.



Die Action wird in der plugin.xml registriert:


```
<extension
         point="org.eclipse.ui.actionSets">
      <actionSet
            id="RCPActionDemo.myActionSet"
            label="My ActionSet">
         <action
               class="rcpactiondemo.HelloAction"
               definitionId="RCPActionDemo.HelloAction"
               id="RCPActionDemo.HelloAction"
               label="say Hello"
               style="push"
               menubarPath="file/slot1">
         </action>
      </actionSet>
   </extension>
```


Das ActionSet wird der perspektive zugeordnet:

```
public class Perspective implements IPerspectiveFactory {

	public void createInitialLayout(IPageLayout layout) {
		String editorArea = layout.getEditorArea();
		layout.setEditorAreaVisible(false);
		
		layout.addStandaloneView(NavigationView.ID,  false, IPageLayout.LEFT, 0.25f, editorArea);
		IFolderLayout folder = layout.createFolder("messages", IPageLayout.TOP, 0.5f, editorArea);
		folder.addPlaceholder(View.ID + ":*");
		folder.addView(View.ID);
		
		layout.getViewLayout(NavigationView.ID).setCloseable(false);
		layout.addActionSet("RCPActionDemo.myActionSet");
	}
}
```


----------



## Guest (4. Sep 2008)

cool danke schau ich mir übers we mal an... den ersten teil hatte ich habe es nur keiner perspektive zugewiesen...
dann war er in meinen beiden perspektiven verfügbar...

meine frage hierzu war ob ich bestimmen kann wo in der toolbar der action hingesetzt wird? sonst ist er immer ganz rechts,wenn ich es mit meinen anderen commands/actions mische. 
Also kann ich meine Actions(siehe post zu coolbar) und IDelegateAction mischen und bestimmen wie die anordnung in der coolbar ist 
ODER
muss ich alle meine Actions in IDelegateActions umschreiben???damit ich die reihenfolge in der coolbar und im menü bestimmen kann???
danke für eure mühe


----------



## foobar (5. Sep 2008)

Du kannst die Position bestimmt selber bestimmen. In den Menüs macht man das über den MenubarPath für die Coolbar gibts bestimmt auch sowas.


----------



## Gast2 (6. Sep 2008)

also das einfügen hat geklappt thx...
aber wann wird die methode 

```
public void selectionChanged(IAction action, ISelection selection)
```
ausgeführt?


----------



## foobar (6. Sep 2008)

Sobald sich die Selection in der Anwendung ändert. Dafür mußt du in irgendeiner View oder Editor einen SelectionProvider registrieren. Alle TableViewer sind bereits SelectionProvider und müssen nur noch über die Site registriert werden.

Wenn du z.b. deinen Editor nur dann aktivieren willst, wenn eine selektierte Bean einen bestimmten Status hat, machst du sowas:

```
getSite().setSelectionProvider(myTableViewer);
```

Damit wird ein ISelection gefeuert, wenn die Selektion der Table sich ändert.

http://help.eclipse.org/help32/inde...eclipse/jface/viewers/ISelectionProvider.html


----------



## Gast2 (6. Sep 2008)

okay das wird dann geworfen wenn ich eine neue Zeile auswähle oder???
aber was ist wenn ich noch texfelder oder sonstige komponenten habe???
das heißt bei jedem focuswechsel in eine andere komponente müsste das event gewrofen werden...


----------



## Gast2 (6. Sep 2008)

also da ich nicht richtig verstanden habe wie das event auslöse 
habe ich mit einen eigenen action gebaut


```
public class A extends ActiveEditorAction 
{

    private List<IWorkbenchPart> partsWithListeners = new ArrayList<IWorkbenchPart>(1);
	public final static String ID = "Tippspiel-RCP.SendMailAction"; 
    
    public A(String text, IWorkbenchWindow window) 
	{
		super("",window);
		setId(ID);
		setText("Send Mail");
		setToolTipText("Tips versenden");
		setImageDescriptor(Activator.getImageDescriptor("/icons/sample3.gif"));
		
	}

    private final IPropertyListener propListener = new IPropertyListener() {
        public void propertyChanged(Object source, int propId) {
            if (source == getActiveEditor()) {
                if (propId == ISendable.PROP_DIRTY) {
					updateState();
				}
            }
        }
    };
 
    protected void editorActivated(IEditorPart part) {
        if (part != null) {
            part.addPropertyListener(propListener);
            partsWithListeners.add(part);
        }
    }

    protected void editorDeactivated(IEditorPart part) {
        if (part != null) {
            part.removePropertyListener(propListener);
            partsWithListeners.remove(part);
        }
    }

    public void pageActivated(IWorkbenchPage page) {
        super.pageActivated(page);
        updateState();
    }


    public void pageClosed(IWorkbenchPage page) {
        super.pageClosed(page);
        updateState();
    }


    public void partActivated(IWorkbenchPart part) {
        super.partActivated(part);
        if (part instanceof IViewPart) {
            updateState();
        }
    }


    public void partClosed(IWorkbenchPart part) {
        super.partClosed(part);
        if (part instanceof IViewPart) {
            updateState();
        }
    }

    public void partDeactivated(IWorkbenchPart part) {
        super.partDeactivated(part);
        if (part instanceof IViewPart) {
            updateState();
        }
    }


    public void dispose() {
        super.dispose();
        for (IWorkbenchPart part : partsWithListeners) {
            part.removePropertyListener(propListener);
        }
        partsWithListeners.clear();
    }
    
    
    public void updateState() {
            IEditorPart edi = getActiveEditor();
            
            if (null != edi)
            {
            	if(edi instanceof ISendable)
            	{
            		ISendable send = (ISendable) edi;
            		if(send.isSendable()){
            			  setEnabled(true);
                          return;
            		}
            	}               
            }
        setEnabled(false);
    }


}
```

in der ApplicationActionBarAdvisor ganz normal registrieren


```
private IWorkbenchAction action;

    protected void makeActions(IWorkbenchWindow window) {


      action = new A("Test", window);
      register(action);
```


und das interface je nachdem ob true oder false geliefert wird wird der action aktiv...

```
public interface ISendable {

	public static final int PROP_DIRTY = 10000;
	
	public boolean isSendable();
}
```


----------



## foobar (6. Sep 2008)

SirWayne hat gesagt.:
			
		

> okay das wird dann geworfen wenn ich eine neue Zeile auswähle oder???


genau




			
				SirWayne hat gesagt.:
			
		

> aber was ist wenn ich noch texfelder oder sonstige komponenten habe???
> das heißt bei jedem focuswechsel in eine andere komponente müsste das event gewrofen werden...


Wenn bei jeder Änderung der Gui, der Event gefeuert werden soll, würde ich das über das dirtyFlag des Editors machen.

Was genau willst du denn machen? Was hast du für Editoren, Views und was soll die Action machen?

BTW A ist ja mal ein sprechender Name für eine Klasse ;-)


----------



## Gast2 (6. Sep 2008)

ja sry war zu faul es zu ändern A wie Action ....

Ja hab ich doch gesagt dass ich so ein mechanismus möchte wie bei dem dirtyFlag....
Am anfang hab ich also das dirtyFlag benutzt und jedes mal wenn ich das event gefeuert hat. hat sich der button akutalisiert 
aber ich hab das ganze von dem dirtyflag entkoppelt und mir jetzt ein eigens flag gesetzt und dass kann ich dann feuern wann ich will...

also mein action wir immer nur gefeuert wenn ich einmal auf speichern gedrückt habe.


----------

