| Syntax | file_extension: "<your_desired_editor_file_extension>" |
| Description | Define the extension of project files for your editor |
| Example |
file_extension: "p4pn" Could be an extenstion for "Poseidon for Petri Net" files |
| Syntax | diagram_types: "diagram_type_name_1" "diagram_type_name_2" ... |
| Description | Define the type names of the diagrams which will be used in the editor. Poseidon doesn't generate any actions or menu items (except for the default diagram) to create the desired diagram types. So, if you want to add several diagram types in your editor, define the names of desired diagram types in the diagram model, generate the code and then follow instructions on how to add Poseidon menu items to create your diagrams |
| Example |
diagram_types: "class" "activity" "deployment" Could be names of the diagram types for UML editor. |
| Syntax |
node <name_of_the_node> { <node_attribute_1> ... <node_attribute_n> <property_1> ... <property_n> <compartments> } |
| Description | Define a node for the graphical editor |
| Example |
node Place { metamodel_element: Place default_size: 4 * 4 minimum_size: 3 * 3 can_contain: Token } Definition of a "Place" node with semantic element "Place", default and minimum sizes. The node can contain other nodes - Tokens. |
| Syntax | metamodel_element: <semantic_element_name_from_mapping_model> |
| Description | Define the semantic element for the node. You don't have to guess the name of the semantic element, as there will be code completion (invoked by Ctrl-Space). It will give you the list of the semantic elements from your metamodel. Usage of this attribute is recommended, because in this case the code which creates the semantic element, will be generated. If you do not specify "metamodel_element" attribute, you will have to write an implementation of the method creating the semantic element yourself. Which is not difficult, but why bother if you can generate it? |
| Example |
node Place { metamodel_element: Place } Definition of a "Place" node with semantic element "Place" |
| Syntax | default_name: "<your_desired_default_name>" |
| Description | Define the default name of the node. If this attribute is not specified, the name of the node is used as a default name. |
| Example |
node Place { default_name: "A Place" } |
| Syntax | default_size: <width>*<height> |
| Description | Define the default size of the node. Size is defined in terms of the grid size of the Poseidon editor. |
| Example |
node Place { default_size: 3*3 } |
| Syntax | minimum_size: <width>*<height> |
| Description | Define the minimum size of the node. Size is defined in terms of the grid size of the Poseidon editor. |
| Example |
node Place { minimum_size: 2*2 } |
| Syntax | shape: <shape_name_from_predefined_set_of_shapes> |
| Description | Define the shape for the node. There is a set of shapes you can choose from. You Ctrl-Space to see the choices |
| Example |
node Place { shape: RHOMBUS } |
| Syntax | name_position: <name_position> |
| Description |
Define the position of the name of the node. Possible choices are:
If this attribute is not specified, the name is placed under the node by default. |
| Example |
node Place { name_position: ABOVE } |
| Syntax | keep_proportions: true | false |
| Description | Defines if the node has to keep its' original proportions when resized. The default is false. |
| Example |
node Place { keep_proportions: true } See how this attribute is used in the tutorial |
| Syntax | icon: "<image_name>" |
| Description |
Defines the icon for the node. This icon will be used in Model Browser, Tools Palette, context menu. Poseidon will search the icon with the specified name in 2 locations, both in project "Resources":
IMPORTANT: only specify the name of the image, do not specify the file extension (see example) |
| Example |
node Place { icon: "artifact" } In this example the file "artifact.png" is resided in "lib/Resources.jar" |
| Syntax | metamodel_container: <ecore_reference_name_from_mapping_model> |
| Description | Has a meaning only for nodes which are used as compartments (see how compartments are used in tutorial). You don't have to guess the name of the reference, as there will be code completion (invoked by Ctrl-Space). It will give you the list of the available references from your metamodel. Knowing the name of the reference, poseidon generator will generate the code which will store Tokens in the "tokens" reference of the Place. |
| Example |
node Token { metamodel_element: Token metamodel_container: Place_tokens } |
| Syntax | allowed_diagram_types: [<diagram_type>] |
| Description |
The list of diagram types where it is allowed to create this node. This attribute could be only necessary if you specify any diagram_types in the model. By default, the node can be created on any diagram. |
| Example |
diagram_types: "petri" "bpmn" node Place { metamodel_element: Place allowed_diagram_types: petri } |
| Syntax | forbidden_diagram_types: [<diagram_type>] |
| Description |
The list of diagram types where it is forbidden to create this node. This attribute could be only necessary if you specify any diagram_types in the model. By default, the node can be created on any diagram. |
| Example |
diagram_types: "petri" "bpmn" node Place { metamodel_element: Place forbidden_diagram_types: bpmn } |
| Syntax | creation_mode: CLICK_CREATION | DRAG_CREATION |
| Description |
There are two possible creation modes. CLICK_CREATION and DRAG_CREATION. If you select CLICK_CREATION - the node will be created at the point on the diagram where you click the mouse, with the default size. Then you can resize the node. If you select DRAG_CREATION - you can define the size of the element in the moment of creation. You click the mouse on the diagram and then drag the mouse without releasing the mouse button. Poseidon shows the preview of the node to be created. When you are happy with the preview, you release the mouse button and Poseidon creates a node of a size defined by you via click-and-drag. The default creation mode is CLICK_CREATION. |
| Example |
node Place { creation_mode: DRAG_CREATION } |
| Syntax | can_contain: [<name_of_the_node | name_of_the_role>] |
| Description | Defines the list of nodes which can be created or dragged inside the given node. |
| Example |
node Place { can_contain: Token Place } node Token { } Such a definition means that node "Place" can contain other Places and Tokens inside, i.e you can create a node for a Token or a Place inside the Place. Or, you can drag existing Token or Place inside another Place |
| Syntax | property <name_of_the_property> : <value_of_the_property> |
| Description | Defines the value of the property for the node. |
| Example |
node Place{ property FillColor : DARK_GRAY } Such a definition means that the default fill color of the node "Place" will be dark gray. |
node Place{
property Color : DARK_GRAY
}
node Place {
property Color: COLOR_RGB(28,87,180)
}
| Syntax | compartments: [<name_of_the_node>] |
| Description | Defines the list of compartments for the node. The nodes from the compartments list must must have the metamodel_container attribute specified. |
| Example |
node Place{ metamodel_element: Place compartments: Token } node Token { metamodel_element: Token metamodel_container: Place_tokens } |
| Syntax |
edge <name_of_the_edge> { sources: [<name_of_the_node | name_of_the_role>] targets: [<name_of_the_node | name_of_the_role>] <edge_attribute_1> ... <edge_attribute_n> <property_1> ... <property_n> } |
| Description | Define an edge for the graphical editor. |
| Example |
edge Arc { sources: Place Transition targets: Place Transition } Definition of an edge "Arc". It states that possible sources of that edge are nodes "Place" and "Transition". Possible targets are the same. When you generate the code and start Poseidon - it will only allow you to create an edge "Arc" if the source and the target of the edge are either Place or Transition. It will not allow to create an edge from (for example) a Token to a Place |
| Syntax | at_source_draw: NOTHING | OPEN_ARROW | CLOSED_ARROW |
| Description | Defines the style of the source end of the edge. Depending on your choice at the beginning of the edge an open arrow, closed arrow or nothing will be drawn. The default value is NOTHING |
| Example |
edge Arc { sources: Place Transition targets: Place Transition at_source_draw: NOTHING } |
| Syntax | at_target_draw: NOTHING | OPEN_ARROW | CLOSED_ARROW |
| Description | Defines the style of the target end of the edge. Depending on your choice at the end of the edge an open arrow, closed arrow or nothing will be drawn. The default value is NOTHING |
| Example |
edge Arc { sources: Place Transition targets: Place Transition at_target_draw: CLOSED_ARROW } |
| Syntax | line_style: SOLID | DASHED |
| Description | Defines the appearance style of the edge. Solid line and dashed line options are available. The default value is SOLID |
| Example |
edge Arc { sources: Place Transition targets: Place Transition line_style: SOLID } |
| Syntax |
property <name_of_the_property> { type: datatype default_value: "<default_value_of_the_property>" variable_name: "<variable_name_for_that_property>" } |
| Description | Define a property which you want to store in your project file. |
| Example |
property FillColor { type: Color default_value: COLOR_RGB(255,255,255) variable_name: "fill" } This is a definition from default diagram model which is actually used by Poseidon. In Poseidon editor, you can define the fill color for an element and this property is used to store the value of the color in the project file. |
| Syntax | datatype <datatype_name> mappedto "<java_class_fully_qualified_name>" |
| Description | Defines a datatype which can be used in property definition. |
| Example | datatype Color mappedto "java.awt.Color" |
| Syntax |
role <role_name> { nodes: [<name_of_the_node>] } |
| Description | Defines a role, which is actually a group of nodes which can be then referenced by a role name. |
| Example |
You can define an edge Arc with sources Place and Transition like this (roles are not used): edge Arc { sources: Place Transition targets: Place Transition } Or like this (roles are used): edge Arc { sources: ArcSources targets: Place Transition } role ArcSources{ nodes: Place Transition } |
| Syntax |
category <name_of_the_category> { icon: "<image_name>" mode: maximized | minimized <node_tool_1> ... <node_tool_n> <edge_tool_1> ... <edge_tool_n> <node_tool_reference_1> ... <node_tool_reference_n> <edge_tool_reference_1> ... <edge_tool_reference_n> } |
| Description |
Defines a category on the Tools Palette. In the generated code, project "Poseidon", there will be a property file DslGenMainPaletteResourceBundle.properties in package com/gentleware/poseidon/gui/palette/main/impl, which is responsible for screen names in the Tools Palette. This file is generated if it doesn't yet exist, but it is not overwritten if it already exists. So, you can change the screen name of the desired item. To set your own name for the category, add the following line to that property file: <name_of_the_category>Category = <desired_category_screen_name> For example, if you defined category "Petri" in the tools model category Petri { } you should add the following line to the properties file: PetriCategory = Petri Net Tools and the screen name of this category in Poseidon UI will be "Petri Net Tools" |
| Example |
category Petri { icon: "petri_diagrams_icon" mode: maximized node_tool Place{ diagram_node: Place } edge_tool Arc{ diagram_edge: Arc } } |
| Syntax | icon: "<image_name>" |
| Description |
Defines the icon for the category. This icon will be used in the tools Palette. Poseidon will search the icon with the specified name in 2 locations, both in project "Resources":
IMPORTANT: only specify the name of the image, do not specify the file extension (see example) |
| Example |
category Petri { icon: "petri_diagrams_icon" } In this example you have to put icon "petri_diagrams_icon.png" to folder "icons". |
| Syntax | mode: maximized | minimized |
| Description | Defines if this category should be expanded or collapsed in the Tools Palette by default. The defualt value is maximized. |
| Example |
category Petri { mode: maximized } |
| Syntax |
node_tool <name_of_the_tool> { diagram_node icon shown_in_add_menu_of add_menu_role } |
| Description |
Defines a tool on the Tool Palette. This tool creates on the diagram the node which you specified in the diagram_node attribute. You don't have to keep in memory the names of the nodes in your diagram model, the list of the available nodes will be provided to you if you press Ctrl-Space. In the generated code, project "Poseidon", there will be a property file DslGenMainPaletteResourceBundle.properties in package com/gentleware/poseidon/gui/palette/main/impl, which is responsible for screen names in the Tools Palette. This file is generated if it doesn't yet exist, but it is not overwritten if it already exists. So, you can change the screen name of the desired item. To set your own name for the tool, add the following line to that property file: <tool_name_in_the_model> = <desired_tool_screen_name> For example, if you defined tool "Place" in the tools model node_tool Place { diagram_node: Place } you should add the following line to the properties file: Place = A Place and the screen name of this tool in Poseidon UI will be "A Place" |
| Example |
node_tool Place{ diagram_node: Place } |
| Syntax | diagram_node: <reference_to_diagram_node_definition> |
| Description | Defines the diagram node (from diagram model) which this tool has to create on the diagram. You don't have to keep in memory the names of the nodes in your diagram model, the list of the available nodes will be provided to you if you press Ctrl-Space. |
| Example |
node_tool Place{ diagram_node: Place } |
| Syntax | icon: "<image_name>" |
| Description |
Defines the icon for the tool in the Tools Palette. Poseidon will search the icon with the specified name in 2 locations, both in project "Resources":
IMPORTANT: only specify the name of the image, do not specify the file extension (see example) If this attribute is not specified for the tool, the icon from the diagram node definition (which is referenced from the mandatory diagram_node attribute) will be used. |
| Example |
node_tool Place{ diagram_node: Place icon: "circle" } In this example the file "circle.png" is resided in "lib/Resources.jar" |
| Syntax | shown_in_add_menu_of:[Diagram|element|namespace|"<existing_add_menu_role>"] |
| Description |
In Poseidon, in the context menu of the diagram, there is a menu item called "add" that allows to add new model elements in the given context. There is also a short cut for this. Just hit the space bar and the add context menu will appear in the position of the mouse. If you invoke it in the empty space of a diagram, it will allow you to create elements in that position. Here is how it looks:
By default this add menu is empty. To add new elements to this add menu, the attribute "shown_in_add_menu_of" is used. For exapmle, if we are designing an editor for Petri nets and we have a node Place, it should be in the add menu of the diagram. In this case we use the following definition for "shown_in_add_menu_of" attribute: shown_in_add_menu_of: Diagram There are 3 predefined choices for that attribute (press Ctrl-Space to see them):
shown_in_add_menu_of: Diagram namespace You can also add a name of the add menu role which you defined in some other tools' add_menu_role attribute (see description for add_menu_role) |
| Example |
node_tool Place { diagram_node: Place shown_in_add_menu_of: Diagram } |
| Syntax | add_menu_role: Diagram|element|namespace|"<add_menu_role_name>" |
| Description |
Defines the add menu role for this tool. Say, we are designing an editor for Petri Nets. We have nodes for Places and Tokens. We want the Token to be available only in the add menu of a Place (but not in the add menu of diagram or any other element). To do that, we first add an "add_menu_role" attribute to the definition of the tool for Place: node_tool Place { diagram_node: Place add_menu_role: "place" } So, now node Place has an add menu role named "place". Now we add a shown_in_add_menu_of attribute to the definition of the Token tool. node_tool Token { diagram_node: Token shown_in_add_menu_of: "place" } So, with such definitions for Place and Token tools, the add menu of Place (and only the add menu of Place) will have an item to add a Token
|
| Example | see Description |
| Syntax |
edge_tool <name_of_the_tool> { diagram_edge icon shown_in_add_menu_of add_menu_role } |
| Description |
Defines a tool on the Tool Palette. This tool creates on the diagram the edge which you specified in the diagram_edge attribute. You don't have to keep in memory the names of all edges in your diagram model, the list of the available ed will be provided to you if you press Ctrl-Space. In the generated code, project "Poseidon", there will be a property file DslGenMainPaletteResourceBundle.properties in package com/gentleware/poseidon/gui/palette/main/impl, which is responsible for screen names in the Tools Palette. This file is generated if it doesn't yet exist, but it is not overwritten if it already exists. So, you can change the screen name of the desired item. To set your own name for the tool, add the following line to that property file: <tool_name_in_the_model> = <desired_tool_screen_name> For example, if you defined tool "Arc" in the tools model edge_tool Arc { diagram_edge: Arc } you should add the following line to the properties file: Arc = An Arc and the screen name of this tool in Poseidon UI will be "An Arc" |
| Example |
edge_tool Arc { diagram_edge: Arc } |
| Syntax | diagram_edge: <reference_to_diagram_edge_definition> |
| Description | Defines the diagram edge (from diagram model) which this tool has to create on the diagram. You don't have to keep in memory the names of the edges in your diagram model, the list of the available edges will be provided to you if you press Ctrl-Space. |
| Example |
edge_tool Arc { diagram_edge: Arc } |
| Syntax | node_tool_reference: <reference_to_node_tool> |
| Description | Allows to use node tool definitions from another category. See example |
| Example |
Say, your editor has 3 tool categories: A, B and C. You defined tool T in category A. But you also want this tool to be present in category C. In this case, instead of creating exactly the same tool definition in category C, you can use the existing tool definition from category A. category A { node_tool T { diagram_node: T } } category B { } category C{ node_tool_reference T } And here is how it looks in Poseidon after the code generation:
Tool T exists in categories A and C, category B is empty |
| Syntax | edge_tool_reference: <reference_to_edge_tool> |
| Description | Allows to use edge tool definitions from another category. |
| Example | Usage is the same as for node_tool_reference. |
| Syntax |
button <name_of_the_button> { anchors: [<diagram_node_definition_reference>] edge: <diagram_edge_definition_reference> position:[BOTTOM|BOTTOM_LEFT|BOTTOM_RIGHT|LEFT|LEFT_BOTTOM|LEFT_TOP |RIGHT|RIGHT_BOTTOM|RIGHT_TOP|TOP|TOP_LEFT|TOP_RIGHT] icon: "<image_name>" direction: INCOMING | OUTGOING } |
| Description |
Defines the rapid button.
|
| Example |
button Arc { anchors: Place Transition edge: Arc position: RIGHT_TOP icon: "edge-default" direction: INCOMING } In this example the file "edge-default.png" resides in "lib/Resources.jar" |
| Syntax |
rules_for <reference_to_edge_definition> { from <reference_to_node_definition> create <reference_to_node_definition> from <reference_to_node_definition> create <reference_to_node_definition> ... } |
| Description | Defines the rules for the specified edge. A rule "from NodeA create NodeB" means that if you start creating the specified edge from NodeA and release the mouse on an empty space of the diagram, an instance of NodeB will be created on the target end of the edge. |
| Example |
We design an editor for Petri Nets. We have nodes Place and Transition and an edge Arc. Possible sources for the Arc are Place and Transition. Possible targets are Place and Transition as well. But in Petri Nets you never connect a Place to another Place or a Transition to another Transition. The Arc always goes from Place to Transition or from Transition to Place. So, to make our Petri Net editor create correct target of the Arc, we should add following rule definition: rules_for Arc { from Place create Transition from Transition create Place } This example is taken from tutorial. See more detailed description in the tutorial. |
| Syntax |
attribute { name: "<name_of_the_attribute>" hidden_elements: ALL | [<reference_to_node_or_edge_definition>] included_elements: [<reference_to_node_or_edge_definition>] read_only_elements: ALL | [<reference_to_node_or_edge_definition>] } |
| Description |
By default, Poseidon shows all attributes of the element in the Model Browser. hidden_elements For example, you have an element "Dummy" in your metamodel and this element has attribute "internalId".
Suppose, you are using this internalId somehow internally in the code, but you do not want to show this attribiute to users. In this case you can hide it, using "hidden_element" attribute in the properties model: attribute { name: "internalId" hidden_elements: Dummy } This definition "tells" Poseidon to hide attribute "internalId" for "Dummy" node.
You can also specify a list of elements (nodes and edges) for which the attribute has to be hidden: attribute { name: "internalId" hidden_elements: Dummy Place Token } Or, you can use "ALL" keyword if you want to hide "internalId" for all elements: attribute { name: "internalId" hidden_elements: ALL } included_elements Has the same meaning as "hidden_elements", but vice verca. I.e instead of specifying the list of elements for which the "internalId" must be hidden you specify the list of elements for which it must be shown. Only one of "hidden_elements" or "included_elements" attributes can be used simultaneously. Use the one which is more convenient (i.e the one with the shorter list of elements). read_only_elements Allows to make an attribute read-only. For example, you want to show the "internalId" to users, but you don't want the users to edit it. You can configure it as a read-only attribute: attribute { name: "internalId" read_only_elements: Dummy } In this case the "internalId" attribute will be visible in the Model Browser, but it will not be editable. |
| Example | See Description. |
|
// default constructor public TypeTableReferenceViewer(PoseidonCoreElement element, EStructuralFeature attribute, DSLAttributeModificationListener listener, boolean readOnly) { super(element, attribute, listener, readOnly); } // this method creates the swing component which is used as an editor for // your reference. We neew a combo-box. @Override public JComponent createEditor(String advancedModelValue) { return new JComboBox(); } // if you use a combo-box as an editor, than this method is responsible for // filling up the list of possible values @Override protected void initListModel(JComboBox comboBox) { final DefaultComboBoxModel model = (DefaultComboBoxModel) comboBox .getModel(); model.removeAllElements(); final List<EModelElement> availableTypes = new ArrayList<EModelElement>(); availableTypes.add(null); final SubjectRepositoryFacet repository=GlobalSubjectRepository.repository; if (element instanceof DummyNode) { final List<PoseidonCoreElement> dummyNodesFromModel = repository .findAllElementsOfType(DummyNode.class, false); availableTypes.addAll(dummyNodesFromModel); } // apply sorting Collections.sort(availableTypes, new NameElementComparator()); for (EModelElement type : availableTypes) { model.addElement(type); } final Object modelValue = getModelValue(); model.setSelectedItem(modelValue); } // this method installs the editor into the attribute panel @Override public JComponent installAttributeEditor( final ToolCoordinatorFacet coordinator, final JPanel insetPanel, GridBagConstraints gbcLeft, GridBagConstraints gbcRight) { // call super-method to do all the work JComponent referenceEditor = super.installAttributeEditor( coordinator, insetPanel, gbcLeft, gbcRight); // add the renderer we want ((JComboBox) getEditor()) .setRenderer(new NamedElementComboBoxRenderer()); return referenceEditor; } // this method is responsible for getting the current value of the reference // ("type" in our example) from the model @Override protected Object getModelValue() { DummyNode type = null; if (element instanceof DummyNode) { DummyNode dummyNode = (DummyNode) element; type = dummyNode.undeleted_getType(); } return type; } // this method returns the command which is executed when you apply the // changes @Override public com.gentleware.poseidon.idraw.foundation.Command formApplyCommand() { if (!isModified()) return null; return new com.gentleware.poseidon.idraw.foundation.AbstractCommand( "set new type", "reverted to previous type") { private static final long serialVersionUID = 1L; private final DummyNode oldValue = (DummyNode) getModelValue(); private final DummyNode newValue = (DummyNode) getCurrentValue(); // this method is executed when you apply changes public void execute(boolean isTop) { setNewType((DummyNode) element, newValue); } // this method is executed when you undo your changes via Ctrl-Z or // from the main menu public void unExecute() { setNewType((DummyNode) element, oldValue); } private void setNewType(DummyNode typedElement, DummyNode type) { typedElement.setType(type); } }; } |
|
@Override protected void setupMenus() { super.setupMenus(); ResourceId myMenuItemResourceId = CustomMainMenuResourceBundle.MyTools; factory.addMenu(myMenuItemResourceId, "e"); } |
| public static ResourceId MyTools = new ResourceId(MAIN_MENU_BUNDLE, "MyTools"); |
| MyTools = My Tools |
| factory.addMenu(myMenuItemResourceId, "e"); |
|
@Override protected void setupMenus() { super.setupMenus(); JMenuItem createFooItem = factory.addMenuItem(MainMenuResourceBundle.Create, MainMenuResourceBundle.Create, CustomMainMenuResourceBundle.CreateFoo, "b"); } |
| public static ResourceId CreateFoo = new ResourceId(MAIN_MENU_BUNDLE, "CreateFoo"); |
| CreateFoo = Create New Foo |
|
@Override protected void setupMenus() { super.setupMenus(); JMenuItem createFooItem = factory.addMenuItem(MainMenuResourceBundle.Create, MainMenuResourceBundle.Create, CustomMainMenuResourceBundle.CreateFoo, "b"); createFooItem.setIcon(com.gentleware.poseidon.util.IconLoader .getIconLoader().get("foo-icon")); createFooItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // create foo } }); } |
|
@Override protected String getAboutText() { return "Poseidon for Football Tactics"; } @Override protected ImageIcon getAboutIcon() { return Utilities.loadImageIcon("ball"); } |
|
@Override public void actionPerformed(ActionEvent e) { final JDialog frame = new JDialog(applicationWindow); frame.setSize(250, 70); int windowWidth = applicationWindow.getWidth(); int windowHeight = applicationWindow.getHeight(); frame.setLocation(windowWidth / 2 - frame.getWidth() / 2, windowHeight / 2 - frame.getHeight() / 2); JLabel label = new JLabel("My Text"); frame.add(label, BorderLayout.CENTER); frame.setVisible(true); } |
|
@Override protected void createPoseidonToolbar() { makeZoomTools(); addSeparator(); makeCopyPasteTools(); } |
|
@Override protected void createPoseidonToolbar() { makeZoomTools(); addSeparator(); makeCopyPasteTools(); makeFooTool(); } private void makeFooTool() { final ToolBarFactory factory = ToolBarFactory.getInstance(); final AbstractButton createFooButton = factory.createToolBarButton( CustomMainMenuResourceBundle.CreateFoo, this, IconLoader .getIconLoader().get("blank")); createFooButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // create foo } }); } |
com.gentleware.poseidon.custom.repobrowser.CustomModelBrowserNodeRenderer and override method setUpIcons():|
@Override protected void setUpIcons() { super.setUpIcons(); AbstractDSLIconDeterminer iconDeterminer = new AbstractDSLIconDeterminer() { public boolean isRelevant(PoseidonCoreElement element) { if (!element.get__incomingRelationships().isEmpty() && !element.get__outgoingRelationships().isEmpty()) { return true; } return false; } }; addIcon(DummyNodeImpl.class, null, ShortCutType.NONE, "node-with-edge", iconDeterminer); } |
DummyNodeImpl. We also pass an instance of DSLIconDeterminer class to the addIcon method which means that this icon will be applied only if method isRelevant returns true; The implementation of isRelevant method returns true only if the node has connected edges. Now the icon for the "Dummy" node in the Model Browser depends on context:
|
@Override protected void setUpIcons() { super.setUpIcons(); addIcon(DummyNodeImpl.class, null, ShortCutType.NONE, "node-with-edge", null); } |
|
@Override protected String getText(PoseidonCoreElement element, CustomDSLNodeText nodeText) { String text = super.getText(element, nodeText); if (element instanceof DummyNode && !element.get__outgoingRelationships().isEmpty()) { text = text + " with edges"; } return text; } |
|
@Override public JPopupMenu createMenu(ToolCoordinatorFacet coordinator, DefaultMutableTreeNode node) { JPopupMenu menu = super.createMenu(coordinator, node); DSLTreeUserObject treeUserObject = (DSLTreeUserObject) node.getUserObject(); PoseidonCoreElement element = treeUserObject.getElement(); if (element instanceof DummyNode) { String localizedMenuItemName = Localizer .localize(CustomRepositoryBrowserResourceBundle.CreateFoo); JMenuItem createFooMenuItem = new JMenuItem(localizedMenuItemName); menu.add(createFooMenuItem); } return menu; } |
| public static ResourceId CreateFoo = new ResourceId(BUNDLE, "CreateFoo"); |
| CreateFoo = Create New Foo |
|
@Override protected boolean rejectElementFromTree(PoseidonCoreElement parent, PoseidonCoreElement child) { boolean rejected = super.rejectElementFromTree(parent, child); if (!rejected && child instanceof DummyEdge) { rejected = true; } return rejected; } |
|
node Dummy { metamodel_element: DummyNode shape: ROUNDED_RECTANGLE } |
|
@Override public NodeAppearanceFacet createBasicNodeAppearanceFacet() { return new BasicSeparateNameNodeAppearanceFacet(initialFillColor, initialFillColor, figureFacet, figureName, textableFacet, subject, false) { public ShapeAppearanceFacet createShapeAppearanceFacet() { return new AbstractShapeAppearanceFacet() { @Override public ZVisualComponent[] drawShapes(UBounds bounds) { ZShape rect = new ZRectangle(bounds); UPoint topLeft = bounds.getTopLeftPoint(); UPoint bottomRight = bounds.getBottomRightPoint(); ZLine zLine = new ZLine(topLeft, bottomRight); UPoint bottomLeft = bounds.getBottomLeftPoint(); UPoint topRight = bounds.getTopRightPoint(); ZLine zLine2 = new ZLine(bottomLeft, topRight); return new ZShape[] { rect, zLine, zLine2 }; } }; } }; } |
|
@Override public NodeAppearanceFacet createBasicNodeAppearanceFacet() { return new BasicSeparateNameNodeAppearanceFacet(initialFillColor, initialFillColor, figureFacet, figureName, textableFacet, subject, false) { @Override public ZNode formView() { // draw the default node shape ZGroup zGroup = (ZGroup) super.formView(); // get bounds of the node on the diagram ClassifierSizes sizes = (ClassifierSizes) makeCurrentInfo() .makeSizes(); Rectangle bounds = sizes.getOuter().getBounds(); final double x = bounds.getX(); final double y = bounds.getY(); final double width = bounds.getWidth(); final double height = bounds.getHeight(); // load icon by name String imageName = "smile-face"; ImageIcon imageIcon = Utilities.loadImageIcon(imageName); Image image = imageIcon.getImage(); ZImage icon = new ZImage(image); // set coordinates for the icon double iconWidth = icon.getWidth(); double iconHeight = icon.getHeight(); double iconX = x + (width - iconWidth) / 2; double iconY = y + (height - iconHeight) / 2; icon.setTranslation(iconX, iconY); // add icon to view zGroup.addChild(new ZVisualLeaf(icon)); return zGroup; } }; } |
|
@Override protected BasicArcAppearanceGem createBasicEdgeAppearanceFacet() { return new CustomBasicArcAppearanceFacet(fillColor, lineColor, figureFacet, figureName, subject) { public ArcEndAppearanceFacet createTargetEndAppearanceFacet() { return new ClosedArrowArcEndAppearanceFacet(false); } @Override public ZNode formAppearance(ZShape mainArc, UPoint start, UPoint second, UPoint secondLast, UPoint last, CalculatedArcPoints calculated, boolean curved) { // create the default appearance ZNode formAppearance = super.formAppearance(mainArc, start, second, secondLast, last, calculated, curved); // create and add a circle to the starting point of the edge if (mainArc instanceof ZPolyline) { ZPolyline mainLine = (ZPolyline) mainArc; double radius = 6; double diameter = radius * 2; ZEllipse zEllipse = new ZEllipse(mainLine.getX(0) - radius, mainLine.getY(0) - radius, diameter, diameter); ((ZGroup) formAppearance).addChild(new ZVisualLeaf(zEllipse)); } return formAppearance; } }; } |
|
@Override protected DslGenDiagramType getDiagramType() { return DslGenDiagramType.MY_LITERAL; } |
|
@Override protected void createPoseidonCreateMenu() { super.createPoseidonCreateMenu(); ResourceId createMenuResourceId = CustomMainMenuResourceBundle.Create; JMenuItem myDiagramItem = factory.addMenuItem(createMenuResourceId, createMenuResourceId, CustomMainMenuResourceBundle.NewMyDiagram, "b"); NewMyDiagramActionListener actionListener = new NewMyDiagramActionListener( this.applicationWindow); myDiagramItem.addActionListener(actionListener); } |
| public static final ResourceId NewMyDiagram = new ResourceId(MAIN_MENU_BUNDLE, "NewMyDiagram"); |
| NewMyDiagram=My Diagram |
| ImageIcon imageIcon = Utilities.loadImageIcon("smile-face"); |
|
|

