Problème avec setItems() dans un TableView

java.lang.NullPointerException

a marqué ce sujet comme résolu.

Alors voilà, je suis bloqué sur ce message d’erreur que je n’arrive pas du tout à solutionner:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
java.lang.NullPointerException
    at ca.nutritix.nutrion.view.PrincipalLayoutController.initFull(PrincipalLayoutController.java:89)
    at ca.nutritix.nutrion.view.PrincipalLayoutController.<init>(PrincipalLayoutController.java:46)
    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 ca.nutritix.nutrion.MainApp.initPrincipalLayout(MainApp.java:30)
    at ca.nutritix.nutrion.MainApp.start(MainApp.java:23)
        ...

J’ai écris mon code en m’inspirant de plusieurs exemples sur le web, je ne saisie pas bien toutes les nuances de chacunes des étapes. L’erreur se produit à la ligne 89. Je soupçonne que ça se produise parce que je ne fait pas de setCellValueFactory sur mes gugus de colonne…

Je sais que j’en demande beaucoup mais si quelqu’un pouvait m’aider… Au besoin, je partagerai mon projet complet via mon GDrive… Edit: Il m’est venu à l’esprit qu’il ne serait peut-être pas judicieux de vous partager directement le dossier sur lequel je fais des modifications pour essayer de solutionner moi-même mon problème en attendant, alors je vous ai fait une archive de mon projet en l’état où je pose cette question que vous pouvez récupérer avec ce lien:20161217-03-59Nutrion.rar

Aussi, comment puis-je faire pour que le nom et le chemin de fichier de ma BDD fasse plus propre et pointe directement dans l’arborescence du projet sans que je parte de mon ~/?

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package ca.nutritix.nutrion.view;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.Button;

import java.sql.*;

import ca.nutritix.nutrion.MainApp;
import ca.nutritix.nutrion.model.Aliment;


public class PrincipalLayoutController {
    static final String JDBC_DRIVER = "org.h2.Driver";
    static final String DB_URL = "jdbc:h2:~/Google Drive/Java/Neon/Nutrion/resources/db/FCEN2015";

    static final String USER = "nutrion";
    static final String PASS = "";

    @FXML
    private TextField txtRecherche;
    @FXML 
    private Button btnRecherche;
    @FXML
    private TableView<Aliment> alimentTable;
    @FXML
    private TableColumn<Aliment, String> idColumn;  //Ici le String ne serait-il pas plutot Integer???
    @FXML
    private TableColumn<Aliment, String> foodDescColumn;
    @FXML
    private TableColumn<Aliment, String> sciNameColumn;

    private ObservableList<Aliment> rechercheData = FXCollections.observableArrayList();

    private ObservableList uneListe;

    private MainApp mainApp;

    public PrincipalLayoutController() {

        this.initFull();
    }

    @FXML
    private void doRecherche() {

    }

    private void initFull() {
/*      idColumn.setCellValueFactory(cellData -> cellData.getValue().idAlimentProperty());
        foodDescColumn.setCellValueFactory(cellData -> cellData.getValue().foodDescriptionProperty());
        sciNameColumn.setCellValueFactory(cellData -> cellData.getValue().sciNameProperty());
*/      
        Connection conn = null;
        Statement stmt = null;
        String sql = null;

        try{
            //Register JDBC driver
            Class.forName(JDBC_DRIVER);

            //Open a connection
            System.out.println("*** Connecting to database...");
            conn = DriverManager.getConnection(DB_URL,USER,PASS);
            System.out.println(conn.getMetaData());

            stmt = conn.createStatement();
            sql = "SELECT FOODID, FOODDESCRIPTIONF, SCIENTIFICNAME FROM FOOD_NAME";

            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()) {

                Aliment unAliment = null;
                for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                    unAliment = new Aliment(rs.getString(1), rs.getString(2), rs.getString(3));
                    System.out.println(unAliment.getIdAliment() + " | " + unAliment.getFoodDescription() + " | "
                                        + unAliment.getSciName());

                }
                rechercheData.add(unAliment);

            }

            alimentTable.setItems(rechercheData);

        }catch(SQLException se){
            //Handle errors for JDBC
            se.printStackTrace();
        }catch(Exception e){
            //Handle errors for Class.forName
            e.printStackTrace();
        }finally{
            try{
                if(conn!=null) {
                    conn.close();
                    System.out.println("*** Déconnexion.");
                }
            }catch(SQLException se){
                se.printStackTrace();
            }//end finally try
        }
    }


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

        // Add observable list data to the table
        //personTable.setItems(mainApp.getPersonData());
    }
}

`
+0 -0

Et voici mon fichier fxml et mon model pour consultation rapide:

PrincipalLayout.fxml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Font?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ca.nutritix.nutrion.view.PrincipalLayoutController">
   <children>
      <TabPane layoutY="50.0" prefHeight="650.0" prefWidth="900.0" side="LEFT" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
        <tabs>
          <Tab text="Par aliment">
               <content>
                  <StackPane prefHeight="150.0" prefWidth="200.0">
                     <children>
                        <AnchorPane prefHeight="200.0" prefWidth="200.0" />
                        <AnchorPane prefHeight="200.0" prefWidth="200.0">
                           <children>
                              <Label layoutX="14.0" layoutY="14.0" text="Rechercher un aliment : " AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0">
                                 <font>
                                    <Font name="Arial" size="18.0" />
                                 </font>
                              </Label>
                              <TextField layoutX="211.0" layoutY="12.0" prefHeight="26.0" prefWidth="382.0" AnchorPane.leftAnchor="211.0" AnchorPane.topAnchor="12.0">
                                 <font>
                                    <Font name="Arial" size="14.0" />
                                 </font>
                              </TextField>
                              <TableView fx:id="alimentTable" layoutX="14.0" layoutY="61.0" prefHeight="575.0" prefWidth="843.0" AnchorPane.bottomAnchor="39.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="55.0">
                                <columns>
                                  <TableColumn fx:id="idColumn" minWidth="25.0" prefWidth="100.0" text="ID" />
                                  <TableColumn fx:id="foodDescColumn" minWidth="100.0" prefWidth="450.0" text="Description de l'aliment" />
                                    <TableColumn fx:id="sciNameColumn" minWidth="100.0" prefWidth="300.0" text="Nom scientifique" />
                                </columns>
                              </TableView>
                              <Button layoutX="601.0" layoutY="8.0" mnemonicParsing="false" text="Go!">
                                 <font>
                                    <Font name="Arial" size="18.0" />
                                 </font>
                              </Button>
                              <Label layoutX="14.0" layoutY="619.0" prefHeight="17.0" prefWidth="624.0" text="Double-cliquez sur la ligne d'un des aliments de la liste pour afficher ses propriétés nutritionnelles" textFill="RED" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0">
                                 <font>
                                    <Font name="Arial" size="14.0" />
                                 </font>
                              </Label>
                           </children>
                        </AnchorPane>
                     </children>
                  </StackPane>
               </content>
          </Tab>
          <Tab text="Par nutriment" />
        </tabs>
      </TabPane>
   </children>
</AnchorPane>

`

et Aliment.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package ca.nutritix.nutrion.model;

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

public class Aliment {

    private final StringProperty idAliment;
    private final StringProperty foodDescription;
    private final StringProperty sciName;

    public Aliment() {
        this(null, null, null);
    }

    public Aliment(String idAliment, String foodDescription, String sciName) {
        this.idAliment = new SimpleStringProperty(idAliment);
        this.foodDescription = new SimpleStringProperty(foodDescription);
        this.sciName = new SimpleStringProperty(sciName);
    }

    public String getIdAliment() {
        return this.idAliment.get();
    }

    public void setIdAliment(String idAliment) {
        this.idAliment.set(idAliment);
    }

    public StringProperty idAlimentProperty() {
        return idAliment;
    }

    public String getFoodDescription() {
        return this.foodDescription.get();
    }

    public void setFoodDescription(String foodDescription) {
        this.foodDescription.set(foodDescription);
    }

    public StringProperty foodDescriptionProperty() {
        return foodDescription;
    }

    public String getSciName() {
        return this.sciName.get();
    }

    public void setSciName(String sciName) {
        this.sciName.set(sciName);
    }

    public StringProperty sciNameProperty() {
        return sciName;
    }
}

`

Bon, j’ai résolu mon bug…

Premièrement, j’ai sorti l’appel de ma fonction initFull du constructeur pour en déléguer l’appel à mon MainApp à la suite de l’appel de:

1
2
3
Scene scene = new Scene(principalLayout);
primaryStage.setScene(scene);
primaryStage.show();

Ensuite, j’ai remis en fonction les lignes de codes suivantes que j’avais mises en commentaires ne sachant pas trop à quoi m’en tenir:

1
2
3
        idColumn.setCellValueFactory(cellData -> cellData.getValue().idAlimentProperty());
        foodDescColumn.setCellValueFactory(cellData -> cellData.getValue().foodDescriptionProperty());
        sciNameColumn.setCellValueFactory(cellData -> cellData.getValue().sciNameProperty());

C’est fou, j’ai l’impression de tout comprendre tout d’un coup alors que ce n’est pas le cas!!! :soleil:

Edit: J’ai également trouvé comment positionner le path du fichier de ma bdd dans mes resources en utilisant le .

1
String DB_URL = "jdbc:h2:./resources/db/FCEN2015";
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte