3

I tried the samples given in github griffon-master, also I tried the samples of the guide.

I would like to use javafx and groovy.

I would like to use fxml - thought of a scenario as that: fxml to set the stage, and for changes, use the groovy (set adjustment)

It seems that is not possible. I can use ("make it run"): javafx-java, read an fxml (with loadFromFXML), and the bindings are working. If using javafx-groovy, I can read an fxml, but with the javafx-class Loader (load), and bindings are not working (or it seems so).

Is it not possible at this moment, to use javafx-groovy and read-in fxml (via loadfromfxml)?

halfer
  • 19,824
  • 17
  • 99
  • 186
Will
  • 43
  • 3

2 Answers2

1

Could you post some sample code? Here's one example that makes use of the fxml node form GroovyFX

package org.example

import griffon.core.artifact.GriffonView
import griffon.metadata.ArtifactProviderFor
import javafx.scene.control.Tab
import org.codehaus.griffon.runtime.javafx.artifact.AbstractJavaFXGriffonView

@ArtifactProviderFor(GriffonView)
class Tab4View extends AbstractJavaFXGriffonView {
    FactoryBuilderSupport builder
    SampleController controller
    SampleModel model
    private AppView parentView

    void initUI() {
        builder.with {
            content = builder.fxml(resource('/org/example/tab4.fxml')) {
                inputLabel.text = application.messageSource.getMessage('name.label')
                bean(input, text: bind(model.inputProperty()))
                bean(output, text: bind(model.outputProperty()))
            }
        }

        connectActions(builder.content, controller)

        Tab tab = new Tab('Hybrid')
        tab.content = builder.content
        parentView.tabPane.tabs.add(tab)
    }
}
Andres Almiray
  • 3,236
  • 18
  • 28
  • We just pushed a new tutorial that explains the different options for building JavaFX views http://new.griffon-framework.org/tutorials/4_javafx_views.html – Andres Almiray Mar 15 '15 at 20:15
0

This can be done. The trick is to make your Controller actions adhere to a stringent set of rules. The tldr is to make sure they return void.

Good:

    def void save() {

Bad:

    def save() {

The reason is found in the reflective analysis the Griffon framework uses to create its list of action targets. This list is generated in DefaultGriffonControllerClass.getActionNames(), which requires that:

Actions are subject to the following rules in order to be considered as such:

  • must have public (Java) or default (Groovy) visibility modifier.
  • name does not match an event handler, i.e, it does not begin with on.
  • must pass {code GriffonClassUtils.isPlainMethod()} if it's a method.
  • must have void as return type if it's a method.
  • value must be a closure (including curried method pointers) if it's a property.

The criteria defined in GriffonClassUtils.isPlainMethod() are as follows:

  • isInstanceMethod(method)
  • ! isBasicMethod(method)
  • ! isGroovyInjectedMethod(method)
  • ! isThreadingMethod(method)
  • ! isArtifactMethod(method)
  • ! isMvcMethod(method)
  • ! isServiceMethod(method)
  • ! isEventPublisherMethod(method)
  • ! isObservableMethod(method)
  • ! isResourceHandlerMethod(method)
  • ! isGetterMethod(method)
  • ! isSetterMethod(method)
  • ! isContributionMethod(method)

The list of action target names is subsequently used by AbstractActionManager:

@Nullable
private static Method findActionAsMethod(@Nonnull GriffonController controller, @Nonnull String actionName) {
    for (Method method : controller.getClass().getMethods()) {
        if (actionName.equals(method.getName()) &&
            isPublic(method.getModifiers()) &&
            !isStatic(method.getModifiers()) &&
            method.getReturnType() == Void.TYPE) {
            return method;
        }
    }
    return null;
}
MTippetts
  • 1
  • 1