IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Java Discussion :

Toute première application


Sujet :

Java

  1. #61
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Merci JonathanTC, je vais essayer ça.

    Une autre question (je suis intarissable, mdr).
    Eclipse me dit que je peux sérialiser mes classes avec serialVersionUID. ça sert à quoi de sérialiser ?

  2. #62
    Membre régulier Avatar de JonathanTC
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2015
    Messages : 90
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par Vahia Voir le message
    Merci JonathanTC, je vais essayer ça.

    Une autre question (je suis intarissable, mdr).
    Eclipse me dit que je peux sérialiser mes classes avec serialVersionUID. ça sert à quoi de sérialiser ?
    pour sauvegarder un objet, vous devez rendre votre classe sérialisable à l'aide de l'interface Serializable.
    Vous pouvez enregistrer directement votre objet avec ses données dans un fichier par exemple.

    le serialVersionUID permet de vérifier si l'objet utiliser pour récupération est le même que celui utiliser pour l'enregistrement.

  3. #63
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Merci !
    Donc si j'ai bien compris, vu que je ne souhaite absolument rien sauvegarder en quittant le programme, je n'ai aucun intérêt à utiliser cette fonction.

    Et merci aussi pour la solution pour "tuer un vieux JPanel". ça fonctionne à merveille.

    Là je bosse sur une nouvelle caractéristique. Dans un de mes JPanel j'ai ajouté un bouton qui me fait des calculs et m'affiche un JLabel contenant le résultat. ça fonctionne. Mais maintenant je cherche à faire en sorte que quand j'appuie sur la touche "Entrée" j'ai le même comportement que si je cliquais sur le bouton.
    Pour ce faire j'ai commencé par sortir les instructions de l'ActionListener vers une méthode à part que je pourrait appeler autant avec un ActionListener qu'avec un KeyListener.
    Avec l'ActionListener ça fonctionne toujours mais pas moyen de faire fonctionner le KeyListener. J'ai trouvé pas mal de sujet identiques sur des furums mais aucune des solutions ne fonctionne pour moi. Je continue à creuser...

  4. #64
    Membre régulier Avatar de JonathanTC
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2015
    Messages : 90
    Points : 112
    Points
    112
    Par défaut
    Pour faire simple vous devez implémenter l'interface KeyListener à la JPanel en question.

    voici un exemple de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class PanHS6151 extends JPanel implements KeyListener{
     
    	public PanHS6151() {
    		this.setFocusable(true);
    		this.addKeyListener(this);
    	}
     
    	public void paintComponent (Graphics g) {
    		g.setColor(Color.RED);
    		g.fillRect(0, 0, this.getWidth(), this.getHeight());
    	}
     
    	@Override
    	public void keyTyped(KeyEvent e) {}
     
    	@Override
    	public void keyPressed(KeyEvent e) {
    		// TODO Auto-generated method stub
    		System.out.println(e.getKeyChar()); // <- ici vous pouvez tester la touche puis lancer votre méthode de calcule
    	}
     
    	@Override
    	public void keyReleased(KeyEvent e) {}
    }
    par contre il faudra obligatoirement donner le focus à votre Panel quand vous cliquez sur le bouton pour y accéder.

    voici un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    boutHS6151.addActionListener(new ActionListener() {
    	public void actionPerformed(ActionEvent b) {
    		choixPan = 1;
     
    		panHS6151 = new PanHS6151();
    		panHS6151.add(boutRet);
    		setContentPane(panHS6151);
     
    		panHS6151.requestFocus(); // <- pour donner le focus au JPanel
    		revalidate();
    	}
    });

  5. #65
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,
    Citation Envoyé par Vahia Voir le message
    Eclipse me dit que je peux sérialiser mes classes avec serialVersionUID. ça sert à quoi de sérialiser ?
    Eclipse ne te dit pas que tu epeux sérialiser, mais que comme la classe est sérialisable (elle implémente l'interface Serializable, ou elle étend une classe qui le fait, directement ou indirectement par l'une de ses super classes), alors il est préférable d'indiquer une version de classe.

    Citation Envoyé par JonathanTC Voir le message
    pour sauvegarder un objet, vous devez rendre votre classe sérialisable à l'aide de l'interface Serializable.
    Vous pouvez enregistrer directement votre objet avec ses données dans un fichier par exemple.

    le serialVersionUID permet de vérifier si l'objet utiliser pour récupération est le même que celui utiliser pour l'enregistrement.
    ça ne sert pas qu'à la sauvegarde. Plus généralement, ça introduit un mécanisme de conversion vers texte ou depuis texte. Cela peut être utilisé par la sauvegarde/restauration, mais c'est également utiliser pour le transport sur le réseau, par exemple via RMI, un protocole de partage réseau d'instances d'objet.
    A noter que ce mécanisme plus ou moins générique/automatique est exploité par des hackers pour injecter du code dans des systèmes distants, et que donc, Oracle envisage de supprimer cette possibilité en standard du moins.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #66
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par JonathanTC Voir le message

    par contre il faudra obligatoirement donner le focus à votre Panel quand vous cliquez sur le bouton pour y accéder.
    C'est bien le souci avec un KeyListener, c'est que le composant d'écoute doit avoir le focus. Pas le panel qui le contient : dans ce cas, ça ne fonctionne que si le composant est le seul focusable dans le panel... par défaut.

    Dans le cas général, on peut écouter de manière globale, en traitant le focus ou pas, en utilisant un KeyboardFocusManager par exemple. Voir exemple ici.
    A noter qu'il existe une méthode fait pour gérer la notion de touche entrée frame.getRootPane().setDefaultButton(button);, mais elle pose un souci qui la rend peu praticable (lorsqu'on saisi dans un champ, il faut valider une fois la saisie dans le champ d'abord, donc appuyer deux fois sur entrée).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #67
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    par contre il faudra obligatoirement donner le focus à votre Panel quand vous cliquez sur le bouton pour y accéder.
    Merci beaucoup à tous les deux pour tous ces renseignements.
    JonathanTC, votre code fonctionne mais partiellement. Si je clique sur le bouton qui m'amène sur mon nouveau JPanel et que là j'appuie sur Entrée, ça fonctionne (puisque désormais grâce à vous mon nouveau JPanel a le focus). Cependant, si je rempli le ou les JTextFields que j'ai mis dans ce JPanel, mon JPanel perd le focus et le KeyListener devient inopérant.
    En fait il faudrait trouver un moyen de faire en sorte que quoi qu'il arrive le JPanel conserve le focus...

    J'ai un bouton sur ce JPanel. Quand je clique dessus il lance une méthode qui récupère les valeurs des 2 JTextFields, fait des calculs et me renvoit le résultat dans un JLabel. En fin de méthode j'ai remis l'instruction "this.requestFocus();". Du coup, même si je clique sur le bouton je garde le focus sur le JPanel. Par contre il reste le problème des JTextFields. Quand on clique dedans pour modifier la valeur on perd forcément le focus et vu qu'aucune action n'est réalisée dans le programme, on ne peut pas renvoyer la commande "this.requestFocus();"...

  8. #68
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    C'est ce que je disais : un panel ne peut pas avoir le focus, seul un composant focusable le peut, comme un JButton ou un JTextField. S'il y a plusieurs composants focusable dans un JPanel, un seul composant peut avoir le focus et si ce n'est pas celui qui écoute le KeyListener ça ne peut pas fonctionner.

    Utilise un default button comme j'ai indiqué dans mon précédent message (ou un KeyboardFocusManager pour une gestion centralisée et plus fine) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class Demo {
     
    	public static void main(String[] args) {
     
    		JFrame frame =  new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.setContentPane(new JPanel(new GridBagLayout()));
    		JPanel panel = new JPanel(new GridBagLayout());
    		frame.getContentPane().add(panel);
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.gridx=GridBagConstraints.RELATIVE;
    		gbc.fill = GridBagConstraints.BOTH;
    		gbc.anchor = GridBagConstraints.EAST;
    		gbc.insets = new Insets(5, 5, 5, 5);
     
    		// ligne 1
    		gbc.gridy = 0;
    		JTextField textfield1 = new JTextField(20);
    		textfield1.setHorizontalAlignment(JTextField.RIGHT);
    		panel.add(textfield1, gbc); 
     
    		// ligne 2
    		gbc.gridy = 1;
    		JTextField textfield2 = new JTextField(20);
    		textfield2.setHorizontalAlignment(JTextField.RIGHT);
    		panel.add(textfield2, gbc);
     
    		// ligne 3
    		gbc.gridy = 2;
    		JLabel resultat = new JLabel(calculer(textfield1, textfield2), JLabel.RIGHT); 
    		resultat.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
    		panel.add(resultat, gbc);
    		JButton button = new JButton("Calculer");
    		panel.add(button, gbc);
     
    		button.addActionListener(e->{
    			resultat.setText(calculer(textfield1, textfield2));
    		}); 
     
                    frame.getRootPane().setDefaultButton(button);
     
    		frame.setSize(600,400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static String calculer(JTextField textfield1, JTextField textfield2) {
    		try {
    			int value1 = Integer.parseInt(textfield1.getText());
    			int value2 = Integer.parseInt(textfield2.getText());
    			return String.valueOf(value1+value2);
    		}
    		catch (NumberFormatException e) {
    			return "?";
    		}
    	}
     
    }
    Sinon, pour un JTextField, tu pourrais ajouter un ActionListener qui actionne ton bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    textfield.addActionListener(e-> {
    			button.doClick();
    		});
    Mais pour un JButton, la touche d'action est "espace", pas "entrée". Tu peux régler ça avec un KeyListener.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class Demo2{
     
    	public static void main(String[] args) {
     
    		JFrame frame =  new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.setContentPane(new JPanel(new GridBagLayout()));
    		JPanel panel = new JPanel(new GridBagLayout());
    		frame.getContentPane().add(panel);
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.gridx=GridBagConstraints.RELATIVE;
    		gbc.fill = GridBagConstraints.BOTH;
    		gbc.anchor = GridBagConstraints.EAST;
    		gbc.insets = new Insets(5, 5, 5, 5);
     
    		// ligne 1
    		gbc.gridy = 0;
    		JTextField textfield1 = new JTextField(20);
    		textfield1.setHorizontalAlignment(JTextField.RIGHT);
    		panel.add(textfield1, gbc); 
     
    		// ligne 2
    		gbc.gridy = 1;
    		JTextField textfield2 = new JTextField(20);
    		textfield2.setHorizontalAlignment(JTextField.RIGHT);
    		panel.add(textfield2, gbc);
     
    		// ligne 3
    		gbc.gridy = 2;
    		JLabel resultat = new JLabel(calculer(textfield1, textfield2), JLabel.RIGHT); 
    		resultat.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
    		panel.add(resultat, gbc);
    		JButton button = new JButton("Calculer");
    		panel.add(button, gbc);
     
    		textfield1.addActionListener(e-> {
    			button.doClick();
    		});
    		textfield2.addActionListener(e-> {
    			button.doClick();
    		});
    		button.addActionListener(e->{
    			resultat.setText(calculer(textfield1, textfield2));
    		});
    		button.addKeyListener(new KeyAdapter() {
    			@Override
    			public void keyTyped(KeyEvent e) { 
    				switch(e.getKeyChar()) {
    				case KeyEvent.VK_ENTER:
    					button.doClick();
    				}
    			}
    		}); 
     
    		frame.setSize(600,400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static String calculer(JTextField textfield1, JTextField textfield2) {
    		try {
    			int value1 = Integer.parseInt(textfield1.getText());
    			int value2 = Integer.parseInt(textfield2.getText());
    			return String.valueOf(value1+value2);
    		}
    		catch (NumberFormatException e) {
    			return "?";
    		}
    	}
     
    }
    ;
    Mais la première solution est plus simple !
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #69
    Membre régulier Avatar de JonathanTC
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2015
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2015
    Messages : 90
    Points : 112
    Points
    112
    Par défaut
    Désoler mais je n'avais pas imaginer votre Panel de cette façon. Effectivement si vous avez des champs de texte à l'intérieur et si à un moment donner vous devez les modifier cette solution pose un problème. Peut être que la solution de joel résoudrait votre problème.

  10. #70
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Merci joel.drigo !
    J'ai testé le code de la première solution dans eclipse, effectivement c'est pile ce qu'il me faut. Mais en l'état je ne peux pas l'intégrer à mon projet car ma JFrame et mon JPanel sont dans 2 classes distinctes. Il faut que je regarde comment adapter tout ça. (Je précise que dans mon projet j'ai 1 seule JFrame pour 11 JPanel différents. On passe d'un JPanel à l'autre en cliquant sur des boutons dédiés.)

    J'ai appris pas mal de choses dans ton code. Déjà je ne savais pas qu'on pouvait appeler une méthode dans la déclaration d'un élement ("new JLabel(calculer(textfield1, textfield2)").
    Et puis je suis surpris de la façon de déclarer l'ActionListener. Personnellement je suis plus habitué à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
              resultat.setText(calculer(textfield1, textfield2));
    	  }});

  11. #71
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Vahia Voir le message
    J'ai testé le code de la première solution dans eclipse, effectivement c'est pile ce qu'il me faut. Mais en l'état je ne peux pas l'intégrer à mon projet car ma JFrame et mon JPanel sont dans 2 classes distinctes.
    On peut procéder par un accesseur éventuellement (si tu as fait une classe qui étend JPanel) pour récupérer l'instance de JButton, ou en passant l'instance de JFrame au constructeur de cette classe, ou encore en faisant une méthode de construction de JPanel.

    Un autre moyen très simple est d'utilser SwingUtilities.getWindowAncestor(c). En revanche, il faut appeler cette méthode lorsque le panel est en place dans la JFrame. Ce qu'on peut faire avec un AncestorListener. L'exemple suivant fonctionne parce que j'ajoute bien l'instance de MyPanel dans son container alors que celui-ci est déjà bien dans la JFrame (en tant que content pane). Pour gérer un cas général qui fonctionne tout le temps, il faudrait regarder si le panel est bien dans une frame et enregistrer un écouteur sur chaque panneau parent, et gérer le "remove" également. Ici, j'ai simplifié pour éviter que l'exemple soit trop complexe : il suffit de se conformer à respecter l'ordre d'ajout dans ton cas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class Demo {
     
    	public static void main(String[] args) {
     
    		JFrame frame =  new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.setContentPane(new JPanel(new GridBagLayout()));
    		JPanel panel = new MyPanel();
     
    		frame.getContentPane().add(panel);
     
    		frame.setSize(600,400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static String calculer(JTextField textfield1, JTextField textfield2) {
    		try {
    			int value1 = Integer.parseInt(textfield1.getText());
    			int value2 = Integer.parseInt(textfield2.getText());
    			return String.valueOf(value1+value2);
    		}
    		catch (NumberFormatException e) {
    			return "?";
    		}
    	}
     
    	public static class MyPanel extends JPanel {
     
    		public MyPanel() {
    			super(new GridBagLayout());
    			GridBagConstraints gbc = new GridBagConstraints();
    			gbc.gridx=GridBagConstraints.RELATIVE;
    			gbc.fill = GridBagConstraints.BOTH;
    			gbc.anchor = GridBagConstraints.EAST;
    			gbc.insets = new Insets(5, 5, 5, 5);
     
    			// ligne 1
    			gbc.gridy = 0;
    			JTextField textfield1 = new JTextField(20);
    			textfield1.setHorizontalAlignment(JTextField.RIGHT);
    			add(textfield1, gbc); 
     
    			// ligne 2
    			gbc.gridy = 1;
    			JTextField textfield2 = new JTextField(20);
    			textfield2.setHorizontalAlignment(JTextField.RIGHT);
    			add(textfield2, gbc);
     
    			// ligne 3
    			gbc.gridy = 2;
    			JLabel resultat = new JLabel(calculer(textfield1, textfield2), JLabel.RIGHT); 
    			resultat.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
    			add(resultat, gbc);
    			JButton button = new JButton("Calculer");
    			add(button, gbc);
     
    			button.addActionListener(e->{
    				resultat.setText(calculer(textfield1, textfield2));
    			});
     
    			addAncestorListener(new AncestorListener() {
     
    				@Override
    				public void ancestorRemoved(AncestorEvent event) {
     
     
    				}
     
    				@Override
    				public void ancestorMoved(AncestorEvent event) { 
    				}
     
    				@Override
    				public void ancestorAdded(AncestorEvent event) {
     
                                            // ceci est invoqué lorsque l'instance de MyPanel est ajouté dans un contenant
     
    					JFrame frame = (JFrame)SwingUtilities.getWindowAncestor(MyPanel.this); // on récupère la fenêtre qui contient l'instance de MyPanel
    					frame.getRootPane().setDefaultButton(button);
     
    				}
    			});
     
    		}
     
    	}
     
    }
    Citation Envoyé par Vahia Voir le message
    J'ai appris pas mal de choses dans ton code. Déjà je ne savais pas qu'on pouvait appeler une méthode dans la déclaration d'un élement ("new JLabel(calculer(textfield1, textfield2)").
    On ne déclare pas ici, on crée une nouvelle instance, et on peut passer en paramètre, comme pour un appel de méthode aussi, une valeur littérale, une variable, ou une expression, un calcul par exemple, comme n'importe quel appel de méthode, pourvu que son retour soit compatible avec le paramètre.

    Citation Envoyé par Vahia Voir le message

    Et puis je suis surpris de la façon de déclarer l'ActionListener. Personnellement je suis plus habitué à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
              resultat.setText(calculer(textfield1, textfield2));
    	  }});
    La notation que j'utilise est ce qu'on appelle une expression lambda. Lorsqu'on crée une instance de classe anonyme (le new ActionListener() { de ton exemple) à partir d'une interface qui n'a qu'une seule méthode (on parle alors d'interface fonctionnelle), on peut écrire l'équivalent de la création d'instance de classe anonyme par une expression lambda.

    Sa forme générale est du type (des paramètres)-> { du code }. Ici, pour ActionListener, on a une méthode actionPerformed(ActionEvent e) avec un seul paramètre. Dans ce cas, on peut omettre les parenthèses dans la partie paramètre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    button.addActionListener(e-> {
              resultat.setText(calculer(textfield1, textfield2));
    	  });
    On peut même omettre les accolades dans ce cas, et le point-virgule, parce qu'il y a qu'une "ligne" de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    button.addActionListener(e-> resultat.setText(calculer(textfield1, textfield2)));
    C'est une façon d'écrire moins de code et de simplifier donc. Mais si tu préfères, tu peux faire comme tu fais d'habitude. Dans d'autres cas, en particulier dans l'usage de streams, ce genre de simplification apparaît beaucoup plus nécessaire.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  12. #72
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    J'ai oublié de préciser que si tu as plusieurs panels alternatifs qui doivent avoir ce comportement, comme une JFrame ne peut avoir qu'un seul bouton par défaut, il te faudra appeler setDefaultButton() sur le bon bouton à chaque fois que tu rends visible un JPanel.

    J'ai adapté un de mes exemples précédents pour exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class DemoFrameMultiPanel {
     
    	public static void main(String[] args) {
     
    		JFrame frame = createFrame("Démo");
     
    	    Object[][] configs = {
    	    		{
    	    			Color.RED,
    	    			"rouge",
    	    			createDefaultButton("rouge")
    	    		},
    	    		{
    	    			Color.YELLOW,
    	    			"jaune",
    	    			createDefaultButton("jaune")
    	    		},
    	    		{
    	    			Color.CYAN,
    	    			"bleu",
    	    			createDefaultButton("bleu")
    	    		}
    	    };
     
    		CardLayout cardLayout = new CardLayout();
    		frame.getContentPane().setLayout(cardLayout);
     
    		for(int i=0; i<configs.length; i++) {
    			createPanel(frame, cardLayout, i, configs);
    		}
    		frame.setTitle("Panneau "+ (String)configs[0][1]);
    		frame.getRootPane().setDefaultButton((JButton)configs[0][2]);
    		frame.setVisible(true);
     
    	}
     
    	private static void createPanel(JFrame frame, CardLayout cardLayout, int i, Object[][] configs) {
     
    		Color color = (Color) configs[i][0];
    		String id = (String) configs[i][1];
    		JButton defaultButton = (JButton) configs[i][2];
     
    		JPanel panel = new JPanel(new GridBagLayout());
    		panel.setBackground(color);
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.gridx=0;
    		gbc.gridy=GridBagConstraints.RELATIVE;
    		gbc.insets = new Insets(5, 5, 5, 5); 
    		Arrays.stream(configs)
    		      .filter(config-> config!=configs[i])
    		      .map(config-> createButton(frame, cardLayout, (String) config[1], (JButton) config[2]))
    		      .forEach(button-> panel.add(button, gbc));
     
    		panel.add(defaultButton, gbc);
    		frame.add(panel, id); 
     
    	}
     
    	private static JButton createButton(JFrame frame, CardLayout cardLayout, String id, JButton defaultButton) {
    		JButton button = new JButton("Afficher panneau "+id);
    		button.addActionListener(e-> {
    			cardLayout.show(frame.getContentPane(), id);  
    		    frame.getRootPane().setDefaultButton(defaultButton);
    		});
    		return button;
    	}  
     
    	private static JButton createDefaultButton(String id) {
    		JButton defaultButton = new JButton("Default");
    		defaultButton.addActionListener(e-> {
    			JOptionPane.showMessageDialog(SwingUtilities.getAncestorOfClass(java.awt.Container.class, defaultButton), "Ceci est le panneau " + id);
    		});
    		return defaultButton;
    	} 
     
    	private static JFrame createFrame(String name) {
     
    		JFrame frame = new JFrame(name);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.setSize(400, 400);
    		frame.setLocationRelativeTo(null);
    		return frame;
     
    	}
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  13. #73
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Je n'ai pas tout compris à ton dernier message.
    Il y aura effectivement 2 Panels au total qui devront avoir ce comportement. Mais bon, si y'en a déjà un qui fonctionne ce serait un bon point.

    J'ai essayé d'adapter ton code et ça ne fonctionne pas. J'ai entré ton code dans un nouveau projet dans eclipse et c'est parfait et quand je l'adapte à mon projet ça ne fonctionne plus. Je ne comprends pas pourquoi...

    Au cas où, voici la classe de la JFrame :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    // J'ai retiré tout le code inutile à notre cas mais il peut y avoir des reliquats oubliés.
    package d5;
     
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JTextField;
     
    public class FenetreMainD5 extends JFrame {
    	private PanneauMainD5 panMainD5 = new PanneauMainD5();
     
    	Font fontbout = new Font("Courrier", Font.PLAIN, 30);
     
    	private JButton boutTrack = new JButton();
     
    	public FenetreMainD5() {
    		this.setTitle("Outils D5-Isom");
    		this.setSize(1700, 1000);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.setResizable(false);
     
    		Color mongray = new Color(100, 100, 100);
     
    			this.setContentPane(panMainD5);
    			this.setBackground(Color.DARK_GRAY);
    			this.getContentPane().setLayout(null);
     
    			boutTrack.setText("<html><center>Heure de<br>Changement de Bac</center></html>");
    			boutTrack.setBounds(35, 490, 295, 200);
    			boutTrack.setBackground(mongray);
    			boutTrack.setBorder(BorderFactory.createLineBorder(mongray));
    			boutTrack.setFont(fontbout);
    			boutTrack.setFocusPainted(false);
    			this.getContentPane().add(boutTrack);
     
    			try {back = ImageIO.read(this.getClass().getResource("/d5/retour.png"));}
    			catch (IOException e) {e.printStackTrace();}
    			JButton boutRet = new JButton (new ImageIcon(back));
    			boutRet.setBounds(10, 10, 75, 50);
    			boutRet.setBackground(mongray);
    			boutRet.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
     
    			boutTrack.addActionListener(new ActionListener() {
    				public void actionPerformed(ActionEvent a) {
    					PanHCB panHCB = new PanHCB();
    					setContentPane(panHCB);
    					panHCB.setLayout(null);
    					panHCB.add(boutRet);
    					boutRet.setVisible(true);
    					panHCB.requestFocus();
    					revalidate();
    				}
    			});
     
    			boutRet.addActionListener(new ActionListener() {
    				public void actionPerformed(ActionEvent c) {
    					setContentPane(panMainD5);
    					boutTrack.setVisible(true);
    					boutRet.setVisible(false);
    					revalidate();
    				}
    			});
     
    			this.setBackground(Color.DARK_GRAY);
    			this.getContentPane().setLayout(null);
    		}
    	}
    et la classe du JPanel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    package d5;
     
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
     
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    import javax.swing.event.AncestorEvent;
    import javax.swing.event.AncestorListener;
     
    public class PanHCB extends JPanel {
     
    	public PanHCB() {
    		this.setFocusable(true);
    	}
     
    Font ftitre = new Font("Courrier", Font.BOLD, 60);
    Font fontLabel1 = new Font("Courrier", Font.PLAIN, 40);
    Font fontLabel2 = new Font("Courrier", Font.PLAIN, 30);
    Font fontLabel3 = new Font("Courrier", Font.ITALIC, 40);
    Font font4 = new Font("Courrier", Font.BOLD, 15);
     
    private String masseString = "0", allureString = "0", newStopTime;
     
    JLabel newStopTimeLabel = new JLabel();
     
    private int c1 = 535, c2 = 885, c3 = 1100, l1 = 350, l2 = 450;
     
    JTextField masseT = new JTextField();
    JTextField allureText = new JTextField();
     
    JLabel masse = new JLabel();
    JLabel masseU = new JLabel();
    JLabel allureT = new JLabel();
    JLabel allureU = new JLabel();
     
    JButton calcHCB = new JButton();
     
     
    	public void paintComponent (Graphics g) {
    		g.setColor(Color.DARK_GRAY);
    		g.fillRect(0, 0, this.getWidth(), this.getHeight());
     
    		g.setColor(Color.GRAY);
    		g.setFont(ftitre);
    		g.drawString("Calcul de l'heure de changement de bac", 270, 150);
     
    		masse.setText("Masse pompable :");
    		masse.setFont(fontLabel1);
    		masse.setForeground(Color.GRAY);
    		masse.setBounds(c1, l1, 400, 75);
    		masse.setVisible(true);
    		this.add(masse);
    		masseT.setFont(fontLabel1);
    		masseT.setForeground(Color.GRAY);
    		masseT.setBounds(c2, l1, 200, 75);
    		masseT.setHorizontalAlignment(JTextField.CENTER);
    		masseT.setText(masseString);
    		this.add(masseT);
    		masseU.setText("t");
    		masseU.setFont(fontLabel1);
    		masseU.setForeground(Color.GRAY);
    		masseU.setBounds(c3, l1, 25, 75);
    		this.add(masseU);
     
    		allureT.setText("Allure :");
    		allureT.setFont(fontLabel1);
    		allureT.setForeground(Color.GRAY);
    		allureT.setBounds(c1, l2, 400, 75);
    		this.add(allureT);
    		allureText.setFont(fontLabel1);
    		allureText.setForeground(Color.GRAY);
    		allureText.setBounds(c2, l2, 200, 75);
    		allureText.setHorizontalAlignment(JTextField.CENTER);
    		allureText.setText(allureString);
    		this.add(allureText);
    		allureU.setText("t/j");
    		allureU.setFont(fontLabel1);
    		allureU.setForeground(Color.GRAY);
    		allureU.setBounds(c3, l2, 35, 75);
    		this.add(allureU);
     
    		calcHCB.setText("Calcul");
    		calcHCB.setBounds(745, 575, 200, 50);
    		calcHCB.setFont(fontLabel2);
    		calcHCB.setBackground(Color.GRAY);
    		calcHCB.setBorder(BorderFactory.createLineBorder(Color.GRAY));
    		calcHCB.setFocusPainted(false);
    		this.add(calcHCB);
     
     
    		calcHCB.addActionListener(e->{
    			whatToDo();
    		});
     
    		addAncestorListener(new AncestorListener() {
    			@Override
    			public void ancestorRemoved(AncestorEvent event) {}
    			@Override
    			public void ancestorMoved(AncestorEvent event) {}
    			@Override
    			public void ancestorAdded(AncestorEvent event) {
    				JFrame FenetreMainD5 = (JFrame)SwingUtilities.getWindowAncestor(PanHCB.this);
    				FenetreMainD5.getRootPane().setDefaultButton(calcHCB);
    			}
    		});
     
    		}
     
     
    	public void whatToDo() {
    		this.add(newStopTimeLabel);
    		masseString = masseT.getText();
    		double masse = Double.parseDouble(masseString);
    		allureString = allureText.getText();
    		double allure = Double.parseDouble(allureString);
    		double allureMinute = allure/1440;
    		double minutesToAdd = masse/allureMinute;
    		int minutasToAdd = (int) minutesToAdd;
    		SimpleDateFormat sdfStopTime = new SimpleDateFormat ("HH:mm");
    		Calendar calend = Calendar.getInstance();
    		calend.add(Calendar.MINUTE, minutasToAdd);
    		Date d = calend.getTime();
    		newStopTime = sdfStopTime.format(d);
    		newStopTimeLabel.setFont(fontLabel3);
    		newStopTimeLabel.setForeground(Color.GRAY);
    		if (masse <= 0.0 && allure > 0.0) {
    			newStopTimeLabel.setText("Veuillez saisir une valeur correcte pour la masse pompable.");
    			newStopTimeLabel.setBounds(320, 650, 1100, 150);}
    		else if (masse > 0.0 && allure <= 0.0) {
    			newStopTimeLabel.setText("Veuillez saisir une valeur correcte pour l'allure.");
    			newStopTimeLabel.setBounds(440, 650, 900, 150);}
    		else if (masse <= 0.0 && allure <= 0.0) {
    			newStopTimeLabel.setText("Veuillez saisir des valeurs correctes.");
    			newStopTimeLabel.setBounds(520, 650, 800, 150);}
    		else {
    			newStopTimeLabel.setText("Le changement de bac est prévu à " + newStopTime);
    			newStopTimeLabel.setBounds(480, 650, 800, 150);}
    		newStopTimeLabel.setVisible(true);
    		this.requestFocus();
    		revalidate();
    	}
    }
    J'ai foiré un truc ?

  14. #74
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Vahia Voir le message
    Je n'ai pas tout compris à ton dernier message.
    ON ne peut pas avoir deux boutons par défaut en même temps. Si ces boutons sont dans un panel différent, qui ne sont pas affichés en même temps, à un moment donné le bouton d'un panel pourra être bouton par défaut. Mais le bouton par défaut va changer, au moment où le panneau qui le contient va être affiché. Si tu procèdes avec l'AncestorListener, comme tu as fait avec PanHCB, ça va fonctionner fonctionner parce que tu crées un nouveau PanHCB et tu l'ajoutes. Et donc l'AncestorLIstener va se déclencher à ce moment là.

    Tu peux aussi te passer de l'AncestorListener :
    1. il n'y a qu'une seule JFrame
    2. Tu crées une nouvelle instance de panel
    3. tu contrôles le moment exact où tu ajoutes le panel
    4. tu as une classe dédiée

    Donc
    1. tu supprimes l'AncestorListener (la partie addAncestorListener(new AncestorListener...)
    2. Tu ajoutes à ta classe PanHCB une méthode qui permet de récupérer le bouton :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      	public JButton getDefaultButton() {
      		return calcHCB;
      	}
    3. Puis dans le code qui "affiche" le PanHCB, tu fais le "setDefaultButton" :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public void actionPerformed(ActionEvent a) { 
      				PanHCB panHCB = new PanHCB();
      				setContentPane(panHCB); 
      				panHCB.setLayout(null);
      				panHCB.add(boutRet);
      				boutRet.setVisible(true);
      				panHCB.requestFocus();
      				FenetreMainD5.this.getRootPane().setDefaultButton(panHCB.getDefaultBUtton());
      				revalidate();
      			}


    Citation Envoyé par Vahia Voir le message
    J'ai foiré un truc ?
    Tu as mis le code de construction de l'UI de PanHCB dans sa méthode paintComponent, donc il ne s'exécute pas au bon moment, et il risque même de s'exécuter plusieurs fois.

    1. la méthode paintComponent sert à dessiner dans le fond du JPanel quand aucunes des classes de Swing ne conviennent. Quand c'est le cas, il vaut mieux les utiliser, parce qu'elles sont optimisées. Sans parler des méthodes qui risquent de provoquer des boucles ou des dysfonctionnement parce que pas dans le bon contexte.
      En tout cas, pour l'ajout de composants (JLabel, JButton...) au JPanel, les valdate (la plupart ne sont pas utile d'autant plus que tu contourne le boutot du layout manager, donc pourquoi lui demander le boulot), setVisible etc, fais ça dans le constructeur de PanHCB ;

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      public PanHCB() {
      		this.setFocusable(true);
      		calcHCB.setText("Calcul");
      		calcHCB.setBounds(745, 575, 200, 50);
      		calcHCB.setFont(fontLabel2);
      		calcHCB.setBackground(Color.GRAY);
      		calcHCB.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      		calcHCB.setFocusPainted(false);
      		this.add(calcHCB);
       
      		calcHCB.addActionListener(e -> {
      			whatToDo();
      		});
                      /* etc */
      Si tu as vraiment besoin de layouter à la main (c'est plutôt une mauvaise idée dans un contexte responsive mais bon), supprime le layout manager, sinon vire tous ces setBound, revalidate/validate/invalidate, ça va retirer beaucoup code inutile, et laisse un LayoutManager faire le job, en lui donnant les contraintes adéquates.



      Et par ailleurs, je ne vois rien dans ta méthode paintComponent qui justifie de redéfinir paintComponent.

    2. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      g.setColor(Color.DARK_GRAY);
      		g.fillRect(0, 0, this.getWidth(), this.getHeight());
      ne sert à rien.
      Dans le constructeur :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      this.setBackground(Color.DARK_GRAY);
    3. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
       
      g.setColor(Color.GRAY);
      		g.setFont(ftitre);
      		g.drawString("Calcul de l'heure de changement de bac", 270, 150);
      ne sert à rien : ça se fait tout seul avec un JLabel.


    Et enfin, au lieu de t'enquiquiner avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    try {back = ImageIO.read(this.getClass().getResource("/d5/retour.png"));}
    		catch (IOException e) {e.printStackTrace();}
    		JButton boutRet = new JButton (new ImageIcon(back));
    ça fait la même chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JButton boutRet = new JButton(new ImageIcon(this.getClass().getResource("/d5/retour.png")));
    Plus simple, plus concis, et pas de variable back inutile...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  15. #75
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Un énorme merci à toi !!!

    ça fonctionne à la perfection. Je vais tenter de l'appliquer aux 2e JPanel mais je pense que ça va rouler.

    Tu as raison, mon code n'est pas très beau (vive les newbies...). J'ai recréé ma classe PanHCB en déclarant les choses au bon endroit et au passage ça a réglé quelques petits bugs d'affichage.
    En fait, au début, dans le premier JPanel que j'ai créé j'avais juste besoin d'afficher une image. Donc la méthode paintComponent était ce qu'il y avait de plus pratique. Et du coup je suis resté sur ce modèle et ce n'était pas spécialement une bonne idée.

    Citation Envoyé par joel.drigo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    g.setColor(Color.DARK_GRAY);
    g.fillRect(0, 0, this.getWidth(), this.getHeight());
    ça, ça servait à résoudre un problème de surimpression. Quand je cliquais plusieurs fois sur le bouton calcul, les résultats se superposaient et devenaient donc illisibles. Mais en déclarant au bon endroit et en n'utilisant plus la méthode paintComponent, ce souci a disparu dont effectivement ces lignes sont inutiles.

    Tu as raison aussi sur le fait que je devrais utiliser un LayoutManager au lieu de tout faire à la main. Mais à ce jour je ne maîtrise pas les LayoutManager. J'apprends le Java avec le livre "Apprenez à programmer en Java" de Cyrille Herby (que je trouve vraiment super) et la partie sur les LayoutManager n'est pas super détaillée à mon goût. Du coup j'ai opté pour le mode bourrin. Mais je reconnaîs qu'à l'avenir il faudra que je m'y colle si je veux progresser.

    Encore une fois merci à vous deux @joel.drigo et @JonathanTC, vous m'avez appris beaucoup de choses et j'espère que ce topic sera utile à plein de débutants comme moi !

    Je m'en vais de ce pas assainir mon code et finaliser mon projet. Je vous tiendrais au courant quand j'aurais fini, en espérant ne plus avoir de questions à vous poser.

  16. #76
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Vahia Voir le message
    En fait, au début, dans le premier JPanel que j'ai créé j'avais juste besoin d'afficher une image. Donc la méthode paintComponent était ce qu'il y avait de plus pratique. Et du coup je suis resté sur ce modèle et ce n'était pas spécialement une bonne idée.
    C'est le plus simple en effet pour afficher une image de fond, en particulier si elle doit s'adapter à la taille de la fenêtre, mais ça peut aussi poser certains soucis. Voir ce sujet pour en savoir plus.
    Une autre solution est d'utiliser un javax.swing.OverlayLayout.
    Afficher un dessin original, ou une animation (encore que ça peut être un peu compliqué à cause du multi-buffering si nécessaire). Ou afficher une texture en le fond du panel en répétant un motif nécessite de passer par une rédéfinition d'une méthode du type paintxxx, setBackground ne prenant pas du Paint en paramètre mais du Color. D'autres cas aussi comme le code que je propose ici pour montrer la grille d'un GridBagLayout à fin de déboguage. Mais en général, ce n'est pas nécessaire, surtout pour des UI de type formulaires.

    Citation Envoyé par Vahia Voir le message
    ça, ça servait à résoudre un problème de surimpression. Quand je cliquais plusieurs fois sur le bouton calcul, les résultats se superposaient et devenaient donc illisibles.
    Pour ce problème, il me semble bien avoir indiqué que c'était dû au recyclage du contexte graphique et qu'il suffisait d'appeler super.paintComponent(g) pour l'éviter.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  17. #77
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Un petit retour sur ma première application.
    Grâce à votre aide tout fonctionne à merveille. J'ai recréé un projet tout neuf pour corriger certaines erreurs de nommage (respect des usages java) et pour nettoyer le code. J'ai ajouté pas mal de commentaires pour m'en servir de support pour la suite.

    Il me reste juste un petit point à régler.
    J'ai exécuté mon programme sous Linux et je me suis aperçu que le rendu diffère. Et ce à cause des polices. Sous Windows j'ai pourtant utilisé une police "de base" (je n'en ai pas ajouté après l'installation de l'OS) mais elle n'est pas présente sous Linux. Alors je pourrais paramétrer Linux pour qu'il utilise aussi les polices Windows mais mon programme est fait pour être partagé notamment à des gens qui ne connaissent rien en informatique. Donc si je commence à indiquer des manips à faire pour profiter pleinement de mon programme, je ne vais pas avoir un grand succès, mdr.
    C'est pourquoi, l'idéal serait de pouvoir embarquer la ou les polices utilisées dans mon fichier .jar exécutable. C'est possible ça ?
    J'ai cherché sur le net, je n'ai rien trouvé de probant...

    Quand j'aurais réglé ce point, je me pencherais sur l'utilisation des Layouts car j'ai bien compris qu'ils sont incontournables.

    Encore merci à JonathanTC et joel.drigo !

  18. #78
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Je viens de trouver une solution qui fonctionne, je la partage ici au cas où ça pourrait aider quelqu'un :

    Tout d'abord on copie le fichier de la police dans le projet (moi je l'ai mis à la racine).
    Ensuite, au début de la classe on ajoute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    private InputStream is = null;
    private Font onboardFont;
    Dans la méthode, avant toute utilisation de la police :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try {
    is = this.getClass().getResourceAsStream("/d5/ERASLGHT.TTF");
    onboardFont = Font.createFont(Font.TRUETYPE_FONT, is);}
    catch (FontFormatException ffe) {}
    catch (IOException e) {}
    Et enfin, au moment d'utiliser la police (sur un bouton par exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monbouton.setFont(onboardFont.deriveFont(Font.PLAIN, 27));

    Voilà, j'espère que aidera...

  19. #79
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    [edit]tu as fini par trouver par toi-même...

    Je le laisse, parce que plutôt que de faire setFont sur chaque bouton, l'exemple que je montre te permettra de changer la police par défaut des boutons (avec l'id "Button.font")

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class FontEras {
     
    	public static Font ERASLIGHT = createErasLightFont();
     
    	public static void main(String[] args) {  
     		setAllUIFont(FontEras.ERASLIGHT.deriveFont(Font.PLAIN, 24));
     		//setUIFont("Label.font", FontEras.ERASLIGHT.deriveFont(Font.PLAIN, 24));
    		JFrame frame = new JFrame("Démo");
    		JLabel label = new JLabel("Démo");
    		JPanel panel = new JPanel(new GridBagLayout());
    		panel.add(label);
    		frame.getContentPane().add(panel);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setSize(300,300);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    	}
     
    	/**
             * Crée la police à partir du fichier se trouvant dans le classpath (dans le dossier d5)
             * @return
             */
    	public static Font createErasLightFont() {
    		try(InputStream is = FontEras.class.getResourceAsStream("/d5/ERASLGHT.TTF")) {
    			return Font.createFont(Font.TRUETYPE_FONT,is);
    		} catch (FontFormatException | IOException e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
     
    	/**
             * Set la police au type de composant d'id spécifié (par exemple Label pour les JLabel)
             * @param componentId
             * @param font
             */
    	public static void setUIFont (String componentId, Font font) {
    		setUIFont(componentId, new FontUIResource(font));
    	}
    	public static void setUIFont (String componentId, javax.swing.plaf.FontUIResource fontui) {
    		Collections.list(UIManager.getDefaults().keys())
    	    .stream()
    	    .filter(key-> Objects.equals(key, componentId))
    	    .forEach(key-> {
    	      Object value = UIManager.get (key);
    	      if (value instanceof javax.swing.plaf.FontUIResource ) {
    	        UIManager.put (key, fontui);
    	      }
    	    });
     
    	}
    	/**
             * Set la police pour tous les types de composant
             * @param componentId
             * @param font
             */
    	public static void setAllUIFont (Font font) {
    		setAllUIFont(new FontUIResource(font));
    	}
    	public static void setAllUIFont (javax.swing.plaf.FontUIResource fontui) {
    	    Collections.list(UIManager.getDefaults().keys())
    	    .forEach(key-> {
    	      Object value = UIManager.get (key);
    	      if (value instanceof javax.swing.plaf.FontUIResource) {
    	        UIManager.put (key, fontui);
    	      }
    	    });
    	}
     
    	/**
             * Affiche tous les types de composants
             */
    	public static void outAllFontKeys () {
    	    Collections.list(UIManager.getDefaults().keys())
    	    .forEach(key-> {
    	      Object value = UIManager.get (key);
    	      if (value instanceof javax.swing.plaf.FontUIResource) {
    	    	  System.out.println(key);
    	      }
    	    });
    	}
     
    }
    Si tu veux affecter tes polices directement, tu peux bien sûr faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    JLabel label = new JLabel("machintruc");
    label.setFont(FontEras.ERASLIGHT);
    ou utiliser deriveFont, pour changer le style et/ou la taille
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    JLabel label = new JLabel("machintruc");
    label.setFont(FontEras.ERASLIGHT.deriveFont(Font.BOLD, 24));
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  20. #80
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Points : 54
    Points
    54
    Par défaut
    Oui j'ai fini par trouver mais il a fallut que je combine plusieurs sujets trouvé sur des forums parce que tous ceux qui ont posé la même question que moi n'ont eu aucune réponse.
    Mais bon, le principal c'est que j'ai pu synthétiser une solution ici.

    Merci joel.drigo pour ton complément d'information. Je t'avoue que je vais devoir creuser ton code pour tout comprendre...

Discussions similaires

  1. [hibernate][spring] première application
    Par iftolotfi dans le forum Hibernate
    Réponses: 2
    Dernier message: 01/06/2006, 07h03
  2. [Debutant(e)] Lancement de ma première application J2EE
    Par thomas_le_debutant dans le forum Java EE
    Réponses: 14
    Dernier message: 15/03/2006, 09h12
  3. [ActionPerformed] Fermer toute l'application
    Par Invité dans le forum AWT/Swing
    Réponses: 13
    Dernier message: 14/03/2006, 11h53
  4. Récupérer les composants visuels de toute l'application
    Par sessime dans le forum Composants VCL
    Réponses: 4
    Dernier message: 27/02/2006, 09h18
  5. [DEBUTANT]Première application avec XML
    Par mlallem dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 17/11/2005, 15h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo