Sous-classe dans un bloc try

Fermé
Fenlabise - 15 mars 2013 à 19:22
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 16 mars 2013 à 19:03
Bonjour,
mon problème est double :
je suis dans un bloc try {} : comment faire sortir les valeurs que j'ai mise dans une variable car en sortant du bloc try, cette variable devient "null". Inversement, ces mêmes variables que j'ai définies dans le bloc try, je veux les faire rentrer dans une sous-classe mais Java me demande de les déclarer "final" ; je le fais et me dit lors de la compilation :
Noms.java:115: variable tableNom might not have been initialized
AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);
^
Noms.java:115: variable titre might not have been initialized
AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);

Alors je tourne en rond.
Voici le code abrégé :

import .... etc...

public class Noms extends Connect implements ListSelectionListener {
	private boolean NP[] = {false, true};
	private int i = 0, j = 0;
	private Object tableNom[][] = {{1, "nom", new Boolean(false), 1}};
	private JTable modeleType;
	private Fenetre fenNoms;
	private String RNoms = "SELECT NomClef, Nom, NomPrenom FROM Noms ORDER BY Nom";
	private Statement state;
	private ResultSet resNom;
	private TableModel tmNoms;
	
	public Noms() {
		//on instancie la fenêtre qui va recevoir les données 
		Fenetre fenNoms = new Fenetre(3, 10, 25, 80, "Liste des Noms");
		ResultatNoms(fenNoms);
	}
	
	public void ResultatNoms(Fenetre fenNoms) {
		String titre[] = {"Clef", "Nom", "Nom ?", "j"}; //en-têtes de colonnes 
		try {
			Statement state = getInstance().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
			ResultSet resNom = state.executeQuery(RNoms);//on envoie la requête à la Base			
			resNom.afterLast();
			while(resNom.previous()) {j++;} //on compte le nombre de lignes du tableau 
			Object tableNom[][] = new Object [j][4]; //on réinitialise la table en mettant le bon nombre de lignes 
			i = 0;
			resNom.beforeFirst();
			while(resNom.next()) { //on remplit le tableau par les données 
				tableNom[i][0] = resNom.getInt("NomClef");
				tableNom[i][1] = resNom.getString("Nom");
				tableNom[i][2] = NP[resNom.getInt("NomPrenom")];
				tableNom[i][3] = i+1;
				i++;
			}
			//on instancie JTable
			JTable modeleType = new JTable(tableNom, titre);
			//on instancie un modèle avec le tableau ci-dessus 
			tmNoms = modeleType.getModel();
			fenNoms.getContentPane().add(new JScrollPane(modeleType));
			fenNoms.addKeyListener(new KeyListener() {
				public void keyReleased(KeyEvent touche) {
					final Object tableNom[][];
					final String titre[];
					if(touche.getKeyCode() == 113) { //touche F2 
						//on ajoute une nouvelle ligne dans tmNoms 
						Object NouvelleLigne[] = {j, " ", new Boolean(false), j};
						AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);
						TableAugment.addRow(NouvelleLigne);
						//on ajoute cette nouvelle ligne maintenant dans la Base 
						String RInsertionNoms = "INSERT INTO Noms (Nom, NomPrenom) VALUES (' ', 0)";
						try {
							Statement state1 = getInstance().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
							state1.executeUpdate(RInsertionNoms);//on envoie la requête à la Base			
							state1.close();
						} catch(SQLException e1) {
							e1.printStackTrace();
						}
					}
				}
				/*
				 *je dois rajouter les deux méthodes suivantes
				 *pour que Java ne me dise pas que la classe n'est pas abstraite
				 */
				public void keyPressed(KeyEvent touche) {
				}
				public void keyTyped(KeyEvent touche) {
				}
			});
			resNom.close();
			state.close();
		} catch(SQLException e) {
				e.printStackTrace();
		}
	}
}


et en résumé pour mieux comprendre :
dans la classe Noms, il y a la methode ResultatNoms
qui contient elle-même le bloc try {}
qui contient lui-même la sous-classe anonyme ; il y a peut-être une autre construction plus adaptée :

public class Noms extends Connect implements ListSelectionListener {
	public Noms() {
		//on instancie la fenêtre qui va recevoir les données 
		Fenetre fenNoms = new Fenetre(3, 10, 25, 80, "Liste des Noms");
		ResultatNoms(fenNoms);
	}
	
	public void ResultatNoms(Fenetre fenNoms) {
		String titre[] = {"Clef", "Nom", "Nom ?", "j"}; //en-têtes de colonnes 
		try {
			//Définition de tableNom
			fenNoms.getContentPane().add(new JScrollPane(modeleType));
			fenNoms.addKeyListener(new KeyListener() {
				public void keyReleased(KeyEvent touche) {
					final Object tableNom[][]; //variables qui posent problème
					final String titre[];
					if(touche.getKeyCode() == 113) { //touche F2 
						//on ajoute une nouvelle ligne dans tmNoms 
						Object NouvelleLigne[] = {j, " ", new Boolean(false), j};
						AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);
						TableAugment.addRow(NouvelleLigne);
					}
				}
			});
			resNom.close();
			state.close();
		} catch(SQLException e) {
				e.printStackTrace();
		}
	}
}


Comme d'habitude, je suis sûr que la solution est simple, mais là je ne vois pas.
Merci de m'aider.
Fenlabise.
A voir également:

3 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
15 mars 2013 à 19:37
Le problème est pourtant écrit noir sur blanc, et tu l'as même mis en gras :

Noms.java:115: variable tableNom might not have been initialized
AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);

Noms.java:115: variable titre might not have been initialized
AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);


Ligne 115 tu donnes en paramètre les tableaux tableNom et title, mais tu ne leur donne jamais de valeurs ! Initialises les et ce problème sera réglé.

final Object tableNom[][];
final String titre[];
if(touche.getKeyCode() == 113) { //touche F2 
    //on ajoute une nouvelle ligne dans tmNoms 
    Object NouvelleLigne[] = {j, " ", new Boolean(false), j};
    AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);
0
KX,
merci pour ta réponse, mais ces deux variable, je les ai déclarées (initialisées) au début, je leur ai donné une valeur (voir le code) il est vrai non dans la sous-classe mais dans la classe. Que pouvais-je faire de plus; à moins de changer la structure de l'algorythme c'est-à-dire de leur redonner une nouvelle valeur dans la sous-classe.
Se pose encore pour moi la question du bloc try :
car pour une méthode, on peut faire rentrer une variable dans une méthode et faire ressortir une variable par le mot clef return mais pour le bloc try, je peux faire rentrer une variable avec sa valeur mais plus la faire ressortir car cette variable devient alors "null" . Y a-t-il un remède car pour moi c'est un véritable problème.
J'espère que tout est clair.
Merci beaucoup pour l'aide apporté.
Fenlabise.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
16 mars 2013 à 18:50
"ces deux variable, je les ai déclarées (initialisées) au début, je leur ai donné une valeur"
Oui, et non...
Tu as effectivement déclaré et initialisé deux tableaux tableNom et titre au début, mais ce ne sont pas ceux là qui sont utilisés dans le KeyListener ! En effet tu as créé deux autres tableaux de même noms déclarés à l'intérieur du KeyListener (ligne 110 et 111) et ce sont ceux qui sont appelés car ils sont le plus interne dans la hiérarchie, or ils ne sont pas initialisés donc ça plante.

Tu devrais enlever les deux tableaux lignes 110 et 111 et n'utiliser que ceux qui ont une valeur (mais il faudra les déclarer final).

public void resultatNoms(Fenetre fenNoms)
{
    final String titre[] = {"Clef", "Nom", "Nom ?", "j"};
    try 
    {
        //...
        final Object tableNom[][] = new Object[j][4];
        //...
        fenNoms.addKeyListener(new KeyListener()
        {
            public void keyReleased(KeyEvent touche)
            {
                if(touche.getKeyCode() == KeyEvent.VK_F2) 
                {
                    //...
                    AjoutLigne TableAugment = new AjoutLigne(tableNom, titre);
                    //...
                }
            }
            
            //...
        });
        
        //...
    }
    catch(SQLException e)
    {
        e.printStackTrace();
    }
}
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
16 mars 2013 à 19:03
Remarque : toute ta partie sur le dimensionnement du tableau est mal pensé, tu lis les résultats un par un pour savoir combien tu as de lignes avant de créer un tableau de cette taille là, et relire à nouveau les enregistrements pour remplir le tableau, et après tu créés un JTable qui va lire le tableau ligne par ligne pour faire son affichage... C'est vraiment très lourd comme opérations !

Il faudrait que tu regardes un peu mieux comment fonctionne les Model, ça permet de manipuler les données d'un JTable beaucoup plus efficacement.

public void ResultatNoms(Fenetre fenNoms) 
{
    DefaultTableModel model = new DefaultTableModel();
    
    String columnIdentifiers[] = {"Clef", "Nom", "Nom ?", "j"};
    model.setColumnIdentifiers(columnIdentifiers);
    
    try 
    {
        Statement state = getInstance().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
        ResultSet result = state.executeQuery(RNoms);
        
        for (int i=1; result.next(); i++)
        {
            Object[] row = 
            {
                result.getInt("NomClef"),
                result.getString("Nom"),
                NP[result.getInt("NomPrenom")],
                i
            };
            
            model.addRow(row);
        }
        
        result.close();
        state.close();
        
        JTable table = new JTable(model);
            
        fenNoms.add(new JScrollPane(table));
0