Eduardo Abreu
Eduardo Abreu

Reputation: 155

java.lang.reflect.InvocationTargetException JavaFX TableView

I've encountered this problem while trying to use cellData -> cellData.getValue() to add an attribute from an object, the attribute is a StringProperty and i have a method to return it, and i'm using it in the cellData -> cellData.getValue().methodtoreturnproperty, but it's still giving me java.lang.reflect.InvocationTargetException, does anyone know what i'm doing wrong? Here's the code:

   package projeto.resources;

import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import projeto.Filmes;
import projeto.MainApp;
import projeto.Sala;

public class FilmeOverviewController {

    @FXML
    private TableView<Filmes> filmeTable;
    @FXML
    private TableColumn<Filmes, String> nomeColumn;
    @FXML
    private TableColumn<Filmes, String> categoriaColumn;
    @FXML
    private TableColumn<Filmes, String> salaColumn;

    @FXML
    private Label nomeLabel;
    @FXML
    private Label salaLabel;
    @FXML
    private Label categoriaLabel;
    @FXML
    private Label diretorLabel;
    @FXML
    private Label duracaoLabel;
    @FXML
    private Label protagonistaLabel;
    @FXML
    private Label classificacaoLabel;

    // Reference to the main application.
    private MainApp mainApp;

    public FilmeOverviewController() {
    }

    @FXML
    private void initialize() {
        //Inicia a tableview com tres colunas.
        nomeColumn.setCellValueFactory(cellData -> cellData.getValue().nomeProperty());
        categoriaColumn.setCellValueFactory(cellData -> cellData.getValue().categoriaProperty());
        salaColumn.setCellValueFactory(cellData -> cellData.getValue().numeroProperty());
        // limpando os detalhes
        showFilmeDetails(null);
        // adicionando funcao
        filmeTable.getSelectionModel().selectedItemProperty()
                .addListener((observable, oldValue, newValue) -> showFilmeDetails(newValue));

    }

    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;

        //adiciona uma observable list
        filmeTable.setItems(mainApp.getfilmeDados());
    }

    private void showFilmeDetails(Filmes filme) {
        if (filme != null) {
            nomeLabel.setText(filme.getNome());
            categoriaLabel.setText(filme.getCategoria());
            duracaoLabel.setText(filme.getDuracao());
            protagonistaLabel.setText(filme.getProtagonista());
            classificacaoLabel.setText(filme.getClassificacao());
            diretorLabel.setText(filme.getDiretor());
            salaLabel.setText(filme.getSalaN());
        } else {
            nomeLabel.setText("");
            categoriaLabel.setText("");
            duracaoLabel.setText("");
            protagonistaLabel.setText("");
            classificacaoLabel.setText("");
            diretorLabel.setText("");
            salaLabel.setText("");
        }
    }

    @FXML
    private void handleDeletarFilme() {
        int selectedIndex = filmeTable.getSelectionModel().getSelectedIndex();
        if (selectedIndex >= 0) {
            filmeTable.getItems().remove(selectedIndex);
        } else {
            Alert alerta = new Alert(AlertType.WARNING);
            alerta.setTitle("Nenhum filme selecionado");
            alerta.setHeaderText("Nenhuma Selecao");
            alerta.setContentText("Por favor selecione um filme para deletar");
            alerta.showAndWait();
        }

    }

    @FXML
    private void handleNovoFilme() {
        Filmes tempFilme = new Filmes("Nome","Categoria");
        boolean clicado = mainApp.showEditarFilmeDialog(tempFilme);
        if (clicado) {
            mainApp.getfilmeDados().add(tempFilme);
        }

    }

    @FXML
    private void handleEditarFilme() {
        Filmes filmeSelecionado = filmeTable.getSelectionModel().getSelectedItem();
            if(filmeSelecionado != null) {
                boolean clicado = mainApp.showEditarFilmeDialog(filmeSelecionado);
                if(clicado) {
                    showFilmeDetails(filmeSelecionado);
                }
            }else {
                //se nada for selecionado
                Alert alerta = new Alert(AlertType.WARNING);
                alerta.initOwner(mainApp.getPrimaryStage());
                alerta.setTitle("Nenhuma selecao");
                alerta.setHeaderText("Nenhum filme selecionado");
                alerta.setContentText("Por favor selecione algum filme.");
                alerta.showAndWait();
            }
    }
}

There's a class called Sala, that's being imported into this controller, i could make it work with another class called Filmes, i don't know exactly why it's not working with the class Sala, here's the code in the class:

package projeto;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Sala {
    private boolean e3d;
    private int assentosMax;
    private int assentosDisp;
    private final StringProperty numeroProperty = new SimpleStringProperty();


    public Sala(boolean e3d, int assentosMax, int assentosDisp, String numero) {
        setNumero(numero);
        e3d = this.e3d;
        assentosMax = this.assentosMax;
        assentosDisp = this.assentosDisp;
    }
    public boolean isE3d() {
        return e3d;
    }
    public void setE3d(boolean e3d) {
        this.e3d = e3d;
    }
    public int getAssentosMax() {
        return assentosMax;
    }
    public void setAssentosMax(int assentosMax) {
        this.assentosMax = assentosMax;
    }
    public int getAssentosDisp() {
        return assentosDisp;
    }
    public void setAssentosDisp(int assentosDisp) {
        this.assentosDisp = assentosDisp;
    }
    public StringProperty numeroProperty() {
        return numeroProperty;
    }
    public final String getNumero() {
        return numeroProperty.get();
    }
    public final void setNumero(String numero) {
        numeroProperty().set(numero);
    }



}

Edit: Here's the error:

jun 07, 2018 3:18:37 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 9.0.1 by JavaFX runtime of version 8.0.171
Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.Error: Unresolved compilation problem: 
    The method numeroProperty() is undefined for the type Filmes

    at projeto.resources.FilmeOverviewController.<init>(FilmeOverviewController.java:50)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at projeto.MainApp.showFilmeOverview(MainApp.java:59)
    at projeto.MainApp.start(MainApp.java:50)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    ... 1 more
Exception running application projeto.MainApp

Thanks in advance!

Upvotes: 0

Views: 730

Answers (1)

purring pigeon
purring pigeon

Reputation: 4209

This looks like you are expecting one type of object in the table but providing another.

You define your table like this:

@FXML
private TableColumn<Filmes, String> salaColumn;

Your cell value factory is trying to get the following:

salaColumn.setCellValueFactory(cellData -> cellData.getValue().numeroProperty());

The numeroProperty is on the Sala object, not the Filmes Object.

Try the following (Though I am not 100% sure, since your definition of Filmes is not in the question):

salaColumn.setCellValueFactory(cellData -> cellData.getValue().getSala().numeroProperty());

Also - if there is a chance that the Sala object could be null, you'll want to check for that before trying to access the numeroProperty().

Upvotes: 1

Related Questions