MenuItemFactory.groovy
001 /*
002  * Copyright 2008-2016 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package griffon.builder.javafx.factory
017 
018 import griffon.javafx.support.JavaFXAction
019 import groovyx.javafx.factory.AbstractNodeFactory
020 import javafx.scene.Node
021 import javafx.scene.control.CustomMenuItem
022 import javafx.scene.control.Menu
023 import javafx.scene.control.MenuItem
024 
025 import static griffon.builder.javafx.factory.ActionFactory.applyAction
026 import static griffon.builder.javafx.factory.ActionFactory.extractActionParams
027 
028 /**
029  *
030  @author jimclarke
031  */
032 class MenuItemFactory extends AbstractNodeFactory {
033     MenuItemFactory(Class beanClass) {
034         super(beanClass)
035     }
036 
037     MenuItemFactory(Class beanClass, Closure instantiator) {
038         super(beanClass, instantiator)
039     }
040 
041     Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map attributesthrows InstantiationException, IllegalAccessException {
042         JavaFXAction action = null
043         Map actionParams = [:]
044         if (value instanceof JavaFXAction) {
045             action = value
046             value = null
047             actionParams = extractActionParams(attributes)
048         }
049 
050         Object menuItem = instantiate(builder, name, value, attributes)
051 
052         if (action) {
053             applyAction(menuItem, action, actionParams)
054         }
055 
056         menuItem
057     }
058 
059     private Object instantiate(FactoryBuilderSupport builder, Object name, Object value, Map attributesthrows InstantiationException, IllegalAccessException {
060         if (Menu.isAssignableFrom(beanClass)) {
061             return handleMenuNode(builder, name, value, attributes)
062         }
063 
064         if (value == null) {
065             return super.newInstance(builder, name, value, attributes)
066         }
067 
068         MenuItem mi = null
069         switch (value) {
070             case CharSequence:
071                 mi = super.newInstance(builder, name, value, attributes)
072                 mi.text = value.toString()
073                 break
074             case MenuItem:
075                 mi = super.newInstance(builder, name, value, attributes)
076                 mi.items.add(value);
077                 break
078             case Node:
079                 mi = super.newInstance(builder, name, null, attributes)
080                 if (mi instanceof CustomMenuItem) {
081                     mi.content = node
082                 else {
083                     mi.graphic = node
084                 }
085                 break
086             default:
087                 throw new Exception("In $name value must be an instanceof MenuItem or one of its subclass, a String or a Node to be used as embedded content.")
088         }
089         mi
090     }
091 
092     protected Menu handleMenuNode(FactoryBuilderSupport builder, Object name, Object value, Map attributes) {
093         if (value == null)
094             return beanClass.newInstance("")
095 
096         Menu menu = null
097         switch (value) {
098             case Menu:
099                 menu = value
100                 break
101             case CharSequence:
102                 menu = beanClass.newInstance(value.toString())
103                 break
104             case Node:
105                 menu = beanClass.newInstance("")
106                 menu.graphic = value
107                 break
108             default:
109                 throw new Exception("In $name value must be an instanceof Menu or one of its subclasses, a String or a Node to be used as graphic content.")
110         }
111         menu
112     }
113 
114     void setChild(FactoryBuilderSupport builder, Object parent, Object child) {
115         if (parent instanceof Menu && child instanceof MenuItem) {
116             parent.items.add(child);
117         else if (child instanceof Node) {
118             if (parent instanceof CustomMenuItem)
119                 parent.content = child
120             else
121                 parent.graphic = child;
122         else if (child instanceof NodeBuilder) {
123             parent.graphic = child.build();
124         else {
125             super.setChild(builder, parent, child);
126         }
127     }
128 }