[Eclipse] GEF entry series (6. Add menus and toolbar)

Source: Internet
Author: User

I found that once I realized the beauty of GEF a little, it would naturally be attracted to it. It is not only because the graphic interface made with it looks good, but more importantly, the most complex and subtle issues in the UI are not carefully considered in the GEF design and solved in an appropriate mode, once you understand this, you can convert these solutions to solve design problems in other fields. After a GEF project was completed last year, Huang did not give up his continued research on it. Now he even used his spare time to develop the GEF-based SWT/jface enhancement software package, the charm of eclipse and GEF is evident. I believe that in the next two years, due to the maturity of RCP/GEF and other technologies, Java standalone applicationsProgramIt is bound to develop and play an important role in the areas where the B/S model is hard to implement.

The topic of this article is to implement the menu function. Due to eclipse's scalable design, adding menus to the GEF application requires more considerations. Therefore, I will first introduce some menu concepts in eclipse, then, you can use an instance to describe how to add menus, toolbar, and context menus to GEF.

We know that eclipse is only a platform, and users cannot use it directly. Its role is to provide a basic environment for components that provide practical functions, all components construct interfaces and use resources in the way specified by the platform. In eclipse, these components are called plug-ins. For example, Java Development Environment (jdt), ant support, CVS client, and help system are all plug-ins, the eclipse we downloaded from eclipse.org already contains these commonly used plug-ins, so no additional installation is required, as if windows already contains notepad, drawing, and other tools. If we need new features, we need to download and install them or install them online on the eclipse platform, common such as XML editor, properties file editor, and J2EE development support, this type of plug-ins includes the GEF Development Kit. The plug-ins are generally installed in the Plugins subdirectory of the eclipse installation directory, or you can install them in other locations using the link method.

An excellent part of the eclipse platform is that so many plug-ins can be perfectly integrated into the same environment, every plug-in may have complex elements such as editors, views, menus, tool bars, and file associations. It is not easy to make them coexist peacefully. Therefore, eclipse provides a series of mechanisms to solve various problems. Due to space limitations, you can only briefly describe the menu and toolbar. For more information, see the plug-in development help documentation provided by eclipse.

In most cases, developing an eclipse-based application means developing an Eclipse plug-in. Each plug-in eclipse has a plug-in named plug-in. XML files are used to define various elements in the plug-in, such as the editors and views of the plug-in. For more information about how to use menus and toolbar in a view, see the previous post. This article only describes the editor, because most GEF applications are editor-based.


Figure 1 components of the eclipse Platform

First, we should introduce the concept of retarget action. This is an action with a certain semantics but no actual function. Its only function is to occupy a position on the main menu bar or main toolbar, the editor can map actions with actual functions to a retarget action. When the editor is activated, the retarget action on the main menu/Toolbar will have that action function. For example, eclipse provides iworkbenchactionconstants. copy this retarget action. Its text and icons are pre-defined. Suppose our editor needs a "Copy node to clipboard" function, because the semantics of the two words "Copy node" and "copy" are very similar, you can create a copynodeaction (extends action) with actual functions, and then call the following at an appropriate location.CodeImplement the ing between the two:

 
Iactionbars. setglobalactionhandler (iworkbenchactionconstants. Copy, copynodeaction );

When the editor is activated, eclipse checks the ing to make the copy item available. When the user presses it, It executes the operation defined in copynodeaction, that is, run () code in the method. Eclipse introduces retarget action to minimize the consumption of rebuilding the main menu/toolbar and facilitate user consistency. In the GEF application, because there are likely to be multiple views (for example, editing a view and outline view, even if there is only one view, you must consider the possibility of extension in the future ), each view should be able to perform similar operations. For example, in the Outline View of the tree structure, you should be able to delete the selected node like editing the view, therefore, general operations should be established by ing to retarget action.

Main Menu/main toolbar

Unlike the View window, the editor does not have its own menu bar or toolbar, and its menu can only be added to the main menu. Since an editor can have multiple instances, and they should have the same menu and toolbar. when defining an editor in XML, the element has a contributorclass attribute. Its value is the full name of a class that implements the ieditexceptionbarcontributor interface. This class can be called the "menu toolbar loader ". You can add the required items to the main menu or main toolbar of eclipse in the adder. Take our project as an example. It requires that each operation can be undone/redone, and each element on the canvas can be deleted, you can set the priority of each node element to three levels: High, Medium, and low. Therefore, we need to add these six retarget actions. The following code is part of the diagramactionbarcontributor class:

 Public   Class Diagramactionbarcontributor Extends Actionbarcontributor {  Protected   Void  Buildactions () {addretargetaction (  New  Undoretargetaction (); addretargetaction (  New  Redoretargetaction (); addretargetaction (  New  Deleteretargetaction (); addretargetaction (  New  Priorityretargetaction (iconstants. priority_high); addretargetaction (  New Priorityretargetaction (iconstants. priority_medium); addretargetaction (  New  Priorityretargetaction (iconstants. priority_low ));}  Protected   Void  Declareglobalactionkeys (){}  Public   Void  Contributetotoolbar (itoolbarmanager toolbarmanager ){...... }  Public   Void  Contributetomenu (imenumanager menumanager) {imenumanager Mgr =New Menumanager ("& node", "Node" ); Menumanager. insertafter (iworkbenchactionconstants. m_edit, MGR); Mgr. add (getaction (iconstants. action_mark_priority_high); Mgr. add (getaction (iconstants. action_mark_priority_medium); Mgr. add (getaction (iconstants. action_mark_priority_low ));}} 

As you can see, the diagramactionbarcontributor class inherits from the actionbarcontributor class provided by GEF, which is an abstract class that implements the ieditexceptionbarcontributor interface. The buildactions () method is used to create retarget actions to be added to the main menu/toolbar, and register them into a dedicated registry. contributetomenu () the code in the method adds the retarget actions to the main menu bar and uses imenumanager. insertafter () is used to make the newly added menu appear behind the specified system menu, while contributetotoolbar () is the code added to the main toolbar.


Figure 2 Add the action to the main menu bar and the main toolbar

GEF maintains the retargetactions and globalactionkeys lists in actionbarcontributor. The latter is a retarget actions ID list, and the addretargetaction () method adds a retarget action to both, for existing retarget actions, we should call the addglobalactionkey () method in the declareglobalactionkeys () method to declare it. When an editor is activated, actions with the same ID value (with actual functions) as those in globalactionkeys will be associated with the retarget action corresponding to this ID, so you do not need to explicitly call setglobalactionhandler () method. You only need to ensure that the IDs of the two are the same.

GEF has built-in retarget actions for Undo, redo, and delete operations (because they are too common). Their IDs are iworkbenchactionconstants. undo, redo, and delete, so there is no problem. The priority setting action does not have a ready-made retarget action with similar semantics. Therefore, we must first define a priorityretargetaction with the following content (which has not been processed internationally ):

 Public   Class Priorityretargetaction Extends  Labelretargetaction {  Public Priorityretargetaction (Int  Priority ){  Super ( Null , Null  );  Switch  (Priority ){  Case  Iconstants. priority_high: setid (iconstants. action_mark_priority_high); settext ( "High Priority" );  Break  ;  Case Iconstants. priority_medium: setid (iconstants. action_mark_priority_medium); settext ( "Medium priority" );  Break  ;  Case  Iconstants. priority_low: setid (iconstants. action_mark_priority_low); settext ( "Low priority" );  Break  ;  Default  :  Break ;}}} 

Next we need to create actions with actual functions in createactions () of the Editor (cbmeditor). They should be subclasses of selectionaction (provided by GEF), because we need to get the selected node. The priorityaction code will be provided later. The code for the createactions () method of the editor is as follows:

 Protected   Void  Createactions (){  Super  . Createactions ();  //  High priority Iaction action = New Priorityaction ( This , Iconstants. priority_high); Action. setid (iconstants. action_mark_priority_high); getactionregistry (). registeraction (action); getselectionactions (). Add (action. GETID ());  //  Medium priority Action = New Priorityaction ( This  , Iconstants. priority_medium); Action. setid (iconstants. events); getactionregistry (). registeraction (action); getselectionactions (). Add (action. GETID ());  //  Low priority Action = New Priorityaction (This  , Iconstants. priority_low); Action. setid (iconstants. action_mark_priority_low); getactionregistry (). registeraction (action); getselectionactions (). Add (action. GETID ());} 

Note that in this method, the ID of each action corresponds to the ID of the previously created retarget action. Otherwise, it cannot correspond to the retarget actions in the main menu bar or the main toolbar. You may have discovered that, here we have created only three actions with the set priority, but not the actions for Undo, redo, and delete. In fact, GEF has created these common actions in graphicaleditor of this class, including Undo/Redo, select all, save, and print, so do not forget to call super. createactions.

The undo, redo, and delete actions provided by GEF automatically determine whether they are available based on the selected editpart (s). The action we define must be in the calculateenabled () method. In addition, to implement the Undo/Redo function, a command is usually created during action execution, the latter is added to the commandstack, and then the command object is executed, instead of writing the Execution Code directly in the action's run () method. The following is part of our code for setting the priorityaction priority. This class inherits from selectionaction:

 Public   Void Run () {execute (createcommand ());}  Private  Command createcommand () {List objects = Getselectedobjects ();  If  (Objects. isempty ())  Return   Null  ;  For (Iterator iter = Objects. iterator (); ITER. hasnext ();) {object OBJ = ITER. Next ();  If ((! (OBJInstanceof Nodepart ))&&(! (OBJ Instanceof  Nodetreeeditpart )))  Return   Null  ;} Compoundcommand compoundcmd = New  Compoundcommand (gefmessages. deleteaction_actiondeletecommandname );  For ( Int I = 0; I <objects. Size (); I ++ ) {Editpart object =(Editpart) objects. Get (I); changeprioritycommand cmd = New  Changeprioritycommand (); cmd. setnode (node) object. GetModel (); cmd. setnewpriority (priority); compoundcmd. Add (CMD );}  Return  Compoundcmd ;}  Protected   Boolean  Calculateenabled () {command cmd = Createcommand ();  If (Cmd = Null  ) Return   False  ;  Return  Cmd. canexecute ();} 

Because users can set priority for multiple selected nodes at a time, we create multiple command objects in this action and add them to a compoundcommand object, the advantage is that it can also be completed at one time during Undo/Redo, instead of a node or node.

Context Menu

In GEF, It is very convenient to right-click the context menu to pop up, as long as you write an inherited Org. eclipse. GEF. the custom class of contextmenuprovider. Compile the code for adding menu items in its buildcontextmenu () method, and then call graphicalviewer in the editor. setcontextmenu. GEF pre-defines some menu groups for us to differentiate menu items for different purposes. Each group is displayed as a separator in appearance, for example, there are undo groups, copy groups, and print groups. If your menu items are not suitable for any group, they can be placed in the others group. If you have many menu items, you can also define a new group for classification.


Figure 3 context menu

Suppose we want to implement the context menu shown in, and we have created and added these actions in the actionregistry (completed in the createactions () method of editor), The contextmenuprovider should be written as follows:

Public   Class Cbmeditorcontextmenuprovider Extends  Contextmenuprovider {  Private  Actionregistry;  Public  Cbmeditorcontextmenuprovider (editpartviewer viewer, actionregistry registry ){  Super  (Viewer); actionregistry = Registry ;}  Public   Void Buildcontextmenu (imenumanager menu ){  //  Add standard action groups to the menu  Gefactionconstants. addstandardactiongroups (menu );  //  Add actions to the menu Menu. appendtogroup (gefactionconstants. group_undo, getaction (actionfactory. undo. GETID (); menu. appendtogroup (gefactionconstants. group_undo, getaction (actionfactory. redo. GETID (); menu. appendtogroup (gefactionconstants. group_edit, getaction (actionfactory. delete. GETID (); menu. appendtogroup (gefactionconstants. group_rest, getaction (iconstants. action_mark_priority_high); menu. appendtogroup (gefactionconstants. group_rest, getaction (iconstants. action_mark_priority_medium); menu. appendtogroup (gefactionconstants. group_rest, getaction (iconstants. action_mark_priority_low ));}  Private  Iaction getaction (string actionid ){  Return  Actionregistry. getaction (actionid );}} 

Note that the first sentence in the buildcontextmenu () method is to create the default groups. If the statements after this step are not ignored, the system will prompt that the Group does not exist, you can also use this method to see how GEF creates a group and what groups are there. Let the editor use the code of this class in the configuregraphicalviewer () method.

By the way, I introduced some basic concepts of eclipse, and added a lot of code, so this post looks long, in fact, it is easy to understand how to use the menu by viewing the built-in Undo/Redo implementations of GEF.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.