javajavafxjavafx-8mvvmfx

mvvmFX Throws Incompatible Type in ViewTuple for Implemented ViewModel


I've created a sample project as shown in getting started documentation of mvvmFX. My MainViewModel implements de.saxsys.mvvmfx.ViewModel as intended. The content is the same as in documentation except the class name.

Oddly, ViewTuple in the start method doesn't accept MainViewModel as compatible.

Error:(28, 102) java: incompatible types: de.saxsys.mvvmfx.ViewTuple<com.erayerdin.imageviewer.views.MainView,de.saxsys.mvvmfx.ViewModel> cannot be converted to de.saxsys.mvvmfx.ViewTuple<com.erayerdin.imageviewer.views.MainView,com.erayerdin.imageviewer.viewmodels.MainViewModel>

So, why MainViewModel implementing de.saxsys.mvvmfx.ViewModel is incompatible for ViewTuple?


Code

App.java

package com.erayerdin.imageviewer;

import com.erayerdin.imageviewer.viewmodels.MainViewModel;
import com.erayerdin.imageviewer.views.MainView;
import de.saxsys.mvvmfx.FluentViewLoader;
import de.saxsys.mvvmfx.ViewTuple;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.util.List;

public class App extends Application {
    public static List<String> PARAMS;

    public static void main( String[] args ) {
        launch(args);
    }

    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Reian ImageViewer");

        ViewTuple<MainView, MainViewModel> viewTuple = FluentViewLoader.fxmlView(MainView.class).load();
        Parent root = viewTuple.getView();
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

MainView.java

package com.erayerdin.imageviewer.views;

import com.erayerdin.imageviewer.viewmodels.MainViewModel;
import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.InjectViewModel;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

import java.net.URL;
import java.util.ResourceBundle;

public class MainView implements FxmlView<MainViewModel>, Initializable {
    @FXML private Label helloLabel;

    @InjectViewModel
    MainViewModel controller;

    public void initialize(URL location, ResourceBundle resources) {
        helloLabel.textProperty().bind(controller.helloMessageProperty());
    }
}

MainViewModel.java

package com.erayerdin.imageviewer.viewmodels;

import de.saxsys.mvvmfx.ViewModel;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class MainViewModel implements ViewModel {
    private StringProperty helloMessage = new SimpleStringProperty("Hello World!");

    public String getHelloMessage() {
        return helloMessage.get();
    }

    public StringProperty helloMessageProperty() {
        return helloMessage;
    }

    public void setHelloMessage(String helloMessage) {
        this.helloMessage.set(helloMessage);
    }
}

Environment


Solution

  • This problem is most likely due to a wrong Java version. Even though you are using Java 8 I assume that your IDE/Build system is configured with an older Java version.

    The type inference that is used in the FluentViewLoader wasn't possible in previous java versions.

    I've tested your classes with a standard maven project and got the same error because maven by default uses Java 1.5 (as far as I know). Then I changed the maven settings so that the compiler uses version 1.8 as source and target version like this:

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    

    With this settings it worked as expected.