How can I pass data from one view to another in gluon mobile? how to switch to view and set Value?

1.1k views Asked by At

I have a View1 with a Textfield1 and a Button. When i click a Button, i want to go to View 2 and set that Value to Textfield2 in View2. When i make it it go open a new Scene.

This is the Code to pass the Value:

charmListView.selectedItemProperty().addListener((obs, oldSelection,    
newSelection) -> {
        if (newSelection != null) {
            ModellList l = new ModellList();
            charmListView.selectedItemProperty().get().getName();
               l.setName(charmListView.selectedItemProperty()
  .get().getName());
            SucheFahrtPresenter s = new SucheFahrtPresenter();

              MobileApplication.getInstance()
.switchView(SUCHEFAHRT_VIEW);
s.setDP(l.getName());


        }
    });

I have this error:

 Exception in thread "JavaFX Application Thread"        
 java.lang.NullPointerException

 at com.gluonapplication.views.SucheFahrtPresenter.setDP(SucheFahrtPresenter.java:122)
at com.gluonapplication.views.BasicView$3.lambda$run$0(BasicView.java:119)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at com.gluonhq.charm.glisten.control.CharmListView.setSelectedItem(SourceFile:710)

I try the Second Solution like that:

That is the Second Presenter:

import javax.inject.Inject;

@Inject
private Model model; 

public void initialize() {
         ........
    second.showingProperty().addListener((obs, oldValue, newValue) -> {
        if (newValue) {
            DP.setText(model.getText());
        }
    });
}

That is for the First presenter:

import javax.inject.Inject;

@Inject
private Model model;

@FXML
public void test() {
    charmListView.selectedItemProperty().
    addListener((obs, oldSelection, newSelection) -> {
        if (newSelection != null) {
            ModellList l = new ModellList();
            charmListView.selectedItemProperty().get().getName();
            l.setName(charmListView.selectedItemProperty().
    get().getName());
            SucheFahrtPresenter s = new SucheFahrtPresenter();
            model.setText(l.getName());
            MobileApplication.getInstance().switchView(SUCHEFAHRT_VIEW);

        }
    });
}

These are my dependencies in Gradle:

dependencies {
    compile 'com.gluonhq:charm:4.2.0'
    compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.12'
    compile  'de.jensd:fontawesomefx:8.9'
    androidRuntime 'org.sqldroid:sqldroid:1.0.3'
    androidCompile 'org.glassfish:javax.json:1.0.4'
    compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.15.1'
    compile group: 'org.sqldroid', name: 'sqldroid', version: '1.0.3'   
    compile group: 'com.gluonhq', name: 'charm-down-desktop', version:    
   '0.0.2'
    compile group: 'com.gluonhq', name: 'charm-down-common', version: 
  '0.0.1'
    compile group: 'com.gluonhq', name: 'charm-down-android', version:  
  '0.0.1'
    compile group: 'com.airhacks', name: 'afterburner.fx', version: '1.7.0'   
 }

This is the issue I have:

After change the Code for Charmlistview . I have this Error

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException at com.gluonapplication.views.SucheFahrtPresenter.lambda$setDP$4(SucheFahrtPresenter.java:138) at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361) at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81) at javafx.beans.property.ReadOnlyBooleanPropertyBase.fireValueChangedEvent(ReadOnlyBooleanPropertyBase.java:72) at javafx.beans.property.ReadOnlyBooleanWrapper.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:103) at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110) at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144) at com.gluonhq.charm.glisten.mvc.View.c(SourceFile:1158)

1

There are 1 answers

16
José Pereda On BEST ANSWER

I suggest you use the Gluon templates Project MultiView with FXML and Afterburner, or the Glisten-Afterburner one. Either of them will allow you using injection and getting a valid instance of the presenters.

Solution 1. Glisten-Afterburner

Using the Glisten-Afterburner default template, I've added two TextField controls, one to each of the views.

The only thing you need is exposing a method to set the value on the second presenter:

public class SecondaryPresenter extends GluonPresenter<YourApp> {

    @FXML
    private View secondary;

    @FXML
    private TextField textField;

    public void initialize() {
        ...
    }

    public void setText(String value) {
        textField.setText(value);
    }
}

And in your first view, in the button event handler you can switch the view and set the text:

public class PrimaryPresenter extends GluonPresenter<YourApp> {

    @FXML
    private View primary;

    @FXML
    private CharmListView<String, String> charmListView;

    public void initialize() {
        charmListView.setItems(FXCollections.observableArrayList("One", "Two", "Three", "Four"));
        charmListView.selectedItemProperty().addListener((obs, ov, nv) -> {
            AppViewManager.SECONDARY_VIEW.switchView()
                .ifPresent(presenter -> 
            ((SecondaryPresenter) presenter).setText(nv));
        });
        ...
    }

}

This solution requires Gluon IDE plugin 2.5.0

Solution 2. MultiView

Alternatively you can use the MultiView with FXML and Afterburner template and create a Model class:

public class Model {

    private final StringProperty text = new SimpleStringProperty();
    public final void setText(String value) { text.set(value); }
    public final String getText() { return text.get(); }
    public final StringProperty textProperty() { return text; }

}

that you can inject in both presenters:

public class PrimaryPresenter {

    @FXML
    private View primary;

    @FXML
    private CharmListView<String, String> charmListView;

    @Inject
    private Model model;

    public void initialize() {
        charmListView.setItems(FXCollections.observableArrayList("One", "Two", "Three", "Four"));
        charmListView.selectedItemProperty().addListener((obs, ov, nv) -> {
            model.setText(nv);
            MobileApplication.getInstance().switchView(SECONDARY_VIEW);
        });
        ...
    }
}

and:

public class SecondaryPresenter {

    @FXML
    private View secondary;

    @FXML
    private TextField textField;

    @Inject
    private Model model;

    public void initialize() {
        secondary.showingProperty().addListener((obs, oldValue, newValue) -> {
            if (newValue) {
                ...
                textField.setText(model.getText());
            }
        });
    }

}