mvc/dci in netbeans by jaroslav tulach
DESCRIPTION
MVC/DCI in NetBeans by Jaroslav TulachTRANSCRIPT
- 1.MVC in NetBeans and other modular applications Jaroslav Tulach
2. Agenda
- MVC
- DCI
- NetBeans APIs
- Towards Future
- Q/A
3. MVC
- Architecture Pattern
- Separating Application
-
- Model knows nothing about the rest
-
- Better maintenance
- Separate Input/Output
-
- Mainframes
-
- Web
- Controller
-
- knows it all
http://zdrojak.root.cz/clanky/prezentacni-vzory-zrodiny-mvc/ 4. Model/View/Presenter
- Variation of MVC
- Merged Input/Output
-
- GUI
-
- AJAX & co.
- Presenter
-
- business
-
- logic
http://zdrojak.root.cz/clanky/prezentacni-vzory-zrodiny-mvc/ 5. Dialogs & Wizards API
- Descriptor is model
-
- Notify, Dialog, Wizard descriptors
- DialogDisplayer
-
- presenter
- Wizards
-
- Iterator, Panel
-
- Internal view
- No modularity
6. Actions
- Action is view
-
- enables/disables
-
- updates name
- Editor is model
-
- text
-
- selection
-
- history
- Action tight to editor
-
- works with the only model
7. Actions in NetBeans
- Single action
-
- knows nothing about components
-
- slightly different meaning in each
- Multiple Components
-
- from various modules
- Not really MVC
8. Critique of MVC
- OOP good for data modeling
- Where to put operations?
- BankAccount & money transfer
-
- operation on account?
-
- asymmetric
-
- all or nothing
-
- transactions
- Projection of user mind
9. DCI
- Scandinavian
-
- as different as Simula or Beta
- Interactions
-
- specify requiredcontext
- Data
-
- morphed
-
- fed to thecontext
-
- manipulated by
-
- operations
http://www.artima.com/articles/dci_vision.html 10. DCI Actions in NetBeans
- Action seeks in context
-
- usually some specific interface
-
- enables/disables on its presence
-
- operates on it
- TopComponents provide own context
-
- morph themselves to specific interfaces
- Selection
-
- system builds Menu, Toolbar
-
- binds actions to selected TopComponent's context
11. DCI in NetBeansAction Selection Morphs Selectionto Action's modelEditor ExplorerImageviewer 12. Lookup
- Magical Bag
-
- a place to fish for an interface
- Adaptable Pattern
-
- an object can morph to something else
- Supports changes
-
- swim in and out
-
- listeners
- Type safe
13. Exposing Window State class MyWindow extendsorg.openide.windows.TopComponent{ privateJEditorPane pane; public org.openide.util.Lookup getLookup() { returnLookups.singleton(pane.getDocument()); } } 14. Querying
- import org.openide.util.Utilities;
- class MyInsertAction extends AbstractAction {
- public void actionPerformed (ActionEvent ev) {
- Lookup lkp = Utilities.actionGlobalContext();
- Document doc = lkp.lookup (Document.class);
- if (doc != null) {
- doc.insertString ("Hello world!", null, 0);
- }
- }
- }
15. Listening
- Lookup.Result res;
- res = someLookup.lookupResult(SomeClass.class);
- res.allItems(); // initialize
- res.addLookupListener (new LookupListener() {
- public void resultChanged (LookupEvent e) {
- for (SomeClass : res.allInstances()) {
- //handler code here
- }
- });
16. Create Own Lookup
- AbstractLookup + InstanceContent
-
- Lookupwhose contents you can manage
- Lookups.singleton( Object ) -one item Lookup
- Lookups.fixed( Object... ) -unchanging Lookup
- Lookups.exclude ( Lookup, Class[] );
- ProxyLookup ( Lookup[] otherLookups ) -compose multiple lookups
17. Morphing
- class MyLazyLookup extends AbstractLookup {
- MyTopComponent tc;
- protected voidbeforeLookup (Template t) {
- if (t.getType() == OpenCookie.class) {
- ic.add(new MorphAsOpenCookie(tc));
- }
- }
- }
- classMorphAsOpenCookie implements OpenCookie {
- public void open() {
- // implement open on MyTopComponent
- }
- }
18. Actions MVC and Modularity Defined together as MVPTopComponent1module A An Action CommonInterface TopComponent2module B 19. Context Actions
- http://wiki.netbeans.org/wiki/view/DevFaqActionContextSensitive
public class FooAction extends AbstractAction implements LookupListener, ContextAwareAction { private Lookup context; Lookup.Result lkpInfo; public FooAction() { this( Utilities.actionsGlobalContext() ); } private FooAction(Lookup context) { this.context = context; } void init() { Lookup.Template tpl = new Lookup.Template( Whatever.class ); lkpInfo = context.lookup (tpl); lkpInfo.addLookupListener(this); resultChanged(null); } public boolean isEnabled() { init(); return super.isEnabled(); } public Action createContextAwareInstance(Lookup context) { returnnew FooAction(context); } } 20. Into the Future
- @ActionRegistration (
- displayName=Open Action,
- iconBase=org/.../Open.png
- )
- public class MyAction extends ActionListener {
- private OpenCookie oc;
- publicMyAction(OpenCookie oc){
- // or other ways to dodependency injection
- this.oc = oc;
- }
- public void actionPerformed(ActionEvent ev) {
- oc.open();
- }
- }
21. Into the Future II
- @ActionRegistration (
- displayName=Find Action,
- iconBase=org/.../Open.png,
- key=find
- )
- public class MyAction extends ActionListener {
- }
- key to complete control
-
- any TopComponent can provide own action
-
- system will delegate, if found
-
- tc. getActionMap(). put ( find , new MyOwnAction());
22. Conclusion
- MVC
-
- view and controller tied to model
- DCI
-
- morphing & adaptation
- Lookup
-
- the way to morph in NetBeans
- Actions
-
- define control interfaces
- Future is in @annotations
23. Q&A