Applications generated by EMFProgramYou can undo each command. For example, if you change the product price, you can click the Undo button to restore the original price.
To return to the new price through redo. In order to implement this function, the application maintains a commandstack data structure for storing commands.
All the commands that have been run are stored there. You need to extract the most recent command to undo it. This data structure is maintained by the editingdomain object,
Editingdomain is equivalent to the environment when the model is edited.
In EMF, the command framework can be divided into two parts: one is a common command unrelated to the model, and the other is the. Edit command, which is based on the former. EMF
Any modification is done through commands. For example, when you modify the attributes of an object in the attribute view, a new setcommand instance is generated and Its Execute
() Method. This method modifies the model (actually through the doexecute () method). After successful execution, this command is placed in the Command Stack for revocation.
General commands can be used completely out of EMF. That is to say, this command framework can be applied to any application that requires the command framework, including non-EMF applications. It is located in
In the org. Eclipse. EMF. Common. Command package, the command interface defines what is a "command". A command has (),
Undo () and redo () methods, as well as canexecute () and canundo () methods are used to determine whether a command can be executed or revoked (considering resource consumption, some commands can
Can be designed to be irrevocable and more reasonable ). Another important interface is commandstack, which is used to save all commands.
The addcommandstacklistener () method registers the listener to observe the status changes of the commandstack. The compoundcommand interface is optional.
It encapsulates multiple commands into a combined command in order, which is atomic and similar to the transaction concept in the database. This combined command can be executed only when all commands can be executed,
This is also true for Undo.
EMF provides some commands required for EMF model editing in the. Edit framework (located in the org. Eclipse. EMF. Edit. Command package), such
Setcommand is used to modify the attributes of an object. createchildcommand is used to create a sub-element, including movecommand,
Copycommand and cuttoclipboardcommand. These commands all implement the command interface, and most of them inherit from
Abstractoverrideablecommand is an abstract class. The impact of this class is that a do is added before the method name in the command interface, for example
Execute () is changed to doexecute (), canundo () is changed to docanundo (), etc. We need to override the doxxx side when extending these. Edit commands.
.. The Edit command modifies the model through reflection.
EMF provides these commands to complete basic model editing functions. In most cases, you can directly use them, but sometimes you can use custom commands to achieve some special requirements. For example
In the online store example, if the product price is accurate to only two digits after the decimal point, we need to round the value immediately after the user enters the new price, this operation can be used
The custom command is complete. Because the class provided by. Edit is used, we should generally extend the. Edit command, specifically setcommand.
First, we will create our setpricecommand by inheriting setcommand. In this method, we will overwrite the doexecute () method, setcommand
There are many available environment variables. We need to use the owner and value items. The former is the object to be modified and the product object here, the latter is the new value of the property, which is the new price here.
Grid. Therefore, our setpricecommand can be written as follows (to makeCodeThe simplest way is to directly convert the eobject type to the product type.
Using Reflection ):
Public Class Setpricecommand Extends Setcommand {
Public Setpricecommand (editingdomain domain, eobject owner, estructuralfeature feature, object Value ){
Super (Domain, owner, feature, value );
}
Public Void Doexecute (){
Product = (Product) owner;
Double Newprice = (Double) value). doublevalue ();
Newprice = Math. Max ( 0 , Newprice ); // New price value must> = 0
Newprice = Math. Round (newprice * 100 ) / 100d; // Max fraction digits is 2
Product. setprice (newprice );
}
}
To make this custom command take effect, you must overwrite the createsetcommand () method in productitemprovider, because this method returns setcommand by default. here we need to make a judgment: if the price attribute is modified, the custom command is returned, as shown below:
Protected Command createsetcommand (editingdomain domain, eobject owner, estructuralfeature feature, object value,
Int Index ){
If (Feature = Shoppackage. einstance. getproduct_price ())
Return New Setpricecommand (domain, owner, feature, value );
Return Super . Createsetcommand (domain, owner, feature, value, index );
}
In this way, when you change the price attribute on the property page, our setpricecommand will be called. By the way, in GEF
There are also similar editdomain and command, but the command in GEF generally uses the createxxxcommand () side of editpolicy
Method. Because the two command mechanisms of GEF and EMF do not implement a unified interface, some problems are often encountered when combined with GEF and EMF, and additional code is required to help solve the problem. Please
Refer to the two discussions (discussion 1, discussion 2 ).
Finally, createchildcommand is a bit special. It is a. Edit command but does not inherit it.
Abstractoverrideablecommand, and if you want to automatically complete some work when creating a child element, you should not extend this class, but in
In the collectnewchilddescriptors () method of xxxitemprovider, this method determines which child elements can be created for each object. You can
To modify its code to process the newly created element.
References:
Eclipse modeling framework a developers Guide, section 3.3 and section 14.1.
Click to download source code