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