Why not try to use TreeNodeModel to define different kind of nodes? On each node you can redefine the way to get children, the icon, etc. Then you give these nodes as the tree roots. Le 18 juin 2015 à 10:10, Peter Uhnák a écrit :
I don't fully understand the TreeModel example, what would your tool do with all the men/displayBlock/childrenBlock ... - methods?
Ah, I should've explained what TreeModel is; it is a Spec UI widget to display tree-like structures:
â
So the way this works is that I give the TreeModel some root object (DCFsm) and then blocks that describes some behavior. So in childrenBlock: [ :parent | ... ] the block is expected to return child elements for the parent. In displayBlock: you pass a block that returns the label that you will see.. e.g. [ :anObject | anObject name , ' (' , anObject class name , ')' ] iconBlock: returns the icon for the object and so on and so forth.
So the way I have implemented it right now is something like
~~~~~~~~~~~~~~~~~ childrenFor: anObject | col name | name := anObject class asString asSymbol. col := OrderedCollection new. name = #DMMindMap ifTrue: [ ^ col ]. (anObject isKindOf: DCDiagram) ifTrue: [ col addAll: anObject elements ]. (anObject isKindOf: DCNamedElement) ifTrue: [ name = #BormParticipant ifTrue: [ col addAll: anObject nodes ]. name = #BormActivity | (name = #BormState) ifTrue: [ col addAll: anObject outgoing ]. name = #BormActivity ifTrue: [ col addAll: anObject sent ]. name = #BormCommunication ifTrue: [ col addAll: anObject dataFlows ]. name = #BormCommunication ifTrue: [ anObject hasConstraint ifTrue: [ col add: anObject constraint ] ]. name = #BormTransition ifTrue: [ anObject hasConstraint ifTrue: [ col add: anObject constraint ] ] ]. ^ col ~~~~~~~~~~~~~~~~~
Which is unreadable, unmaintainable and nonextensible. All the #Borm* symbols actually refer to classes of a completely independent package and repository which doesn't even need to be loaded in the system.
I think what Peter means is: the object oriented way to handle different types is by dispatching on each type (~ double dispatch, ~ visiting). You could need this for different aspects of your application. In the end, the same core mechanism will be implemented multiple times. Sadly, minor semantics/structural differences will make it hard to abstract this out.
Yes, double-dispatch seems like the apt solution, however it would lead to NxM number of classes (as mentioned before). But the more I think about it the more I feel that I will not get any better than that.
Peter