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

Agents de placement/Fenêtres Java Discussion :

leaking this in constructor actionlistener


Sujet :

Agents de placement/Fenêtres Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur logiciel en formation
    Inscrit en
    Février 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur logiciel en formation
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2016
    Messages : 13
    Points : 11
    Points
    11
    Par défaut leaking this in constructor actionlistener
    Bonjour à tous,

    Comme indiqué dans une précédente discussion, j'essaie de réaliser un convertisseur "Km/Miles", afin de m'exercer sur les interfaces graphiques, mais aussi les Listener.

    Voici mon probleme :

    J'ai réussi à faire changer en temps réel la valeur de la distance en km en fonction du curseur du JSlider, grace à un ChangeListener.

    Nom : KmMiles.JPG
Affichages : 258
Taille : 21,5 Ko

    Mais lorsque j'utilise un ActionEvent pour que la valeur en miles apparaisse aussi en temps réel (avec la conversion qui va bien !!!), ça ne fonctionne pas.

    Voici le 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
    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
     
    package com.mycompany.convertisseurkmmilesv2;
     
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JSlider;
    import javax.swing.JTextField;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
     
     
    public class Fenetre extends JFrame implements ChangeListener, ActionListener{
     
        private JPanel panPrinc;
        private JPanel panKm;
        private JPanel panMiles;
     
        private JSlider sliderKm;
     
        private JTextField valeurKm;
     
        private JLabel labelKm;
        private JLabel conversionMiles;
        private JLabel labelMiles;
     
        int valeur = 0;
     
        public Fenetre()
        {
            // JFrame
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setTitle("Convertisseur Km en Miles");
            this.setLocationRelativeTo(null);
     
            // Panel principal
            panPrinc = new JPanel(new GridLayout(2,1));
     
            // Panel Km
            panKm = new JPanel();
            panKm.setBorder(BorderFactory.createTitledBorder("Distance en kilomètres"));
            valeurKm = new JTextField();
            valeurKm.setPreferredSize(new Dimension(50,30));
            labelKm = new JLabel("km");
            sliderKm = new JSlider(JSlider.HORIZONTAL,0,100,0);
            sliderKm.setMajorTickSpacing(10);
            sliderKm.setMinorTickSpacing(1);
            sliderKm.setPaintLabels(true);
            sliderKm.setPaintTicks(true);
            panKm.add(valeurKm);
            panKm.add(labelKm);
            panKm.add(sliderKm);
     
            // panel Miles
            panMiles = new JPanel();
            panMiles.setBorder(BorderFactory.createTitledBorder("conversion en miles"));
            conversionMiles = new JLabel();
            labelMiles = new JLabel("miles");
            labelMiles.setOpaque(true);
            panMiles.add(conversionMiles);
            panMiles.add(labelMiles);
     
            // ChangeListener du slider
            sliderKm.addChangeListener(this);
            conversionMiles.addActionListener(this);
     
            // les panels
            panPrinc.add(panKm);
            panPrinc.add(panMiles);
     
            // JFrame
            this.setContentPane(panPrinc);
            this.setVisible(true);
        }
     
        @Override
        public void stateChanged(ChangeEvent e) {
            double value = sliderKm.getValue();
            valeurKm.setText(""+value);
        }
     
        @Override
        public void actionPerformed(ActionEvent e) {
     
            double conversion = sliderKm.getValue() * 0.6215;
            if(e.getSource() == conversionMiles)
            {
                conversionMiles.setText("" + conversion);
            }
        }
    }
    Le probleme est là dessus, avec le message indiqué en titre ("leaking this in constructor"):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    conversionMiles.addActionListener(this);
    la valeur en miles apparait dans un JLabel à côté du JLabel "mile".

    Qu'en pensez-vous ?

  2. #2
    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
    Je ne sais pas trop pourquoi NetBeans te donne cette erreur peu claire. Le problème est simplement que la méthode addActionListener(ActionListener) n'existe pas pour JLabel.

    Si tu veux faire la mise à jour lors de la modification du JSlider, il suffit de mettre le code dans stateChanged, tout simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        @Override
        public void stateChanged(ChangeEvent e) {
            double value = sliderKm.getValue();
            valeurKm.setText(""+value);
            double conversion = value * 0.6215;
             conversionMiles.setText("" + conversion);
        ]
    Par ailleurs, si on saisie une valeur directement dans le champ valeurKm (JTextField), le traitement ne se fait pas, et en plus le slider ne se met pas à jour. Il faut également écouter les modifications faites sur le JTextField (cela pose d'ailleurs un petit souci : un JTextField est fait pour saisir n'importe quelle chaine, donc la valeur peut ne pas être un nombre, et en plus, elle pourra être en dehors de l'intervalle possible du JSlider). Il faudra juste mettre en place un traitement particulier. Ou on gère l'erreur, ou on empêche la saisie d'autre chose qu'un nombre (voir classe InputVerifier, ou DocumentListener (à ce sujet voir ci-après)). Pour mettre à jour le JSlider, utilise la méthode sliderKm.setValue(value).

    Pour détecter la saisie dans un JTextField, on peut utiliser un ActionListener. Mais celui se déclenche uniquement en cas de validation (soit touche entrée appuyée, soit sortie du champ, fermeture de la fenêtre, etc.). On peut également écouter les changements au cours de la frappe :

    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
     
            valeurKm.getDocument().addDocumentListener(new DocumentListener() {
     
    			@Override
    			public void removeUpdate(DocumentEvent e) {
    				update(valeurKm);
    			}
     
    			@Override
    			public void insertUpdate(DocumentEvent e) {
    				update(valeurKm);
    			}
     
    			@Override
    			public void changedUpdate(DocumentEvent e) {
    				update(valeurKm);
    			}
     
     
    			private void update(JTextField valeurKm) {
    				// là tu mets le code de vérification et mise à jour du slider
     
    			}
     
    		});
    Une autre solution assez simple serait d'utiliser un JSpinner au lieu d'un JTextField.


    Enfin, plutôt que de faire la bidouille ""+conversion, tu peux utiliser String.valueOf(conversion), soit, mieux encore, formater la valeur :
    • soit par la méthode String.format()
    • soit par la classe DecimalFormat (ou NumberFormat pour un format plus général)
    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.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur logiciel en formation
    Inscrit en
    Février 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur logiciel en formation
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2016
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup d'avoir pris du temps pour me répondre avec autant de détails

    beaucoup d'éléments m'ont été extrement utiles, et j'ai beaucoup appris par vos explications.

    J'ai essayé de faire avec une autre manière. Non pas que j'en avais pas envie, au contraire, mais j'ai essayé les quelques connaissances que j'ai actuellement pour essayer de boucler ce mini-projet.

    je ne voulais pas "pomper" la réponse sans en comprendre le fonctionnement. c'est pour ça que je mets toutes vos infos de côté, et je les réutiliserai pour optimiser mon code (disons que ça beaucoup d'information d'un coup, et il faut que j'arrive à les assimiler).

    Voici mon nouveau code (je ne mets que la partie sur les Listener):

    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
     
    @Override
        public void stateChanged(ChangeEvent e) {
            double value = sliderKm.getValue();
            valeurKm.setText(String.valueOf(value));
            double conversion = sliderKm.getValue() * 0.6215;
            conversionMiles.setText(String.valueOf(conversion));
     
        }
     
        @Override
        public void actionPerformed(ActionEvent e) {
     
            if(valeurKm.getText().equals(""))
                {
                    JOptionPane.showMessageDialog(this,"Veuillez saisir une valeur numérique.");
                }
                else if(!valeurKm.getText().matches("^[0-9]*.[0-9]*$"))
                {
                    JOptionPane.showMessageDialog(this,"Veuillez saisir une valeur numérique.");
                    valeurKm.setText("");
                }
            else
                {
                    String valeurJText = valeurKm.getText();
                    sliderKm.setValue(Integer.parseInt(valeurJText));
                }
        }
    Le ChangeEvent fonctionne très bien et la conversion se fait bien dans la partie "Miles". En revanche, pour optimiser la partie visuelle, il faudrait que je réduise le nombre de chiffres après la virgule. Je pensais essayer de passer sur du BigDecimal et et faire un setscale à 2. Qu'en pensez-vous ?

    Pour l'ActionListener, je suis partie sur les expressions régulières pour éviter les caractères non numériques et éviter les saisies étranges, comme mettre des caractères spéciaux, ou mettre plusieurs virgules après les décimales, ou bien de taper Entrée si le JTextField est vide.
    les messages apparaissent très bien dans tous les cas.
    En revanche, dès que le nombre est saisie, et que je tape deux fois sur Entrée, je vois dans la console qu'une erreur survient. Pour l'erreur qui va suivre, j'ai juste tapé 56 (au hasard) dans le JTextField et j'ai appuyé deux fois sur Entrée. La 1ère fois, le JSlider s'est bien déplacé, et j'ai eu la conversion. La 2ème fois, rien ne se passe sur l'appli, mais je vois ce message dans la console NetBeans :
    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
     
    Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "56.0"
    	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    	at java.lang.Integer.parseInt(Integer.java:580)
    	at java.lang.Integer.parseInt(Integer.java:615)
    	at com.mycompany.convertisseurkmmilesv2.Fenetre.actionPerformed(Fenetre.java:106)
    	at javax.swing.JTextField.fireActionPerformed(JTextField.java:508)
    	at javax.swing.JTextField.postActionEvent(JTextField.java:721)
    	at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:836)
    	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1663)
    	at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
    	at javax.swing.JComponent.processKeyBindings(JComponent.java:2929)
    	at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
    	at java.awt.Component.processEvent(Component.java:6310)
    	at java.awt.Container.processEvent(Container.java:2236)
    	at java.awt.Component.dispatchEventImpl(Component.java:4889)
    	at java.awt.Container.dispatchEventImpl(Container.java:2294)
    	at java.awt.Component.dispatchEvent(Component.java:4711)
    	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
    	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806)
    	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074)
    	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945)
    	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771)
    	at java.awt.Component.dispatchEventImpl(Component.java:4760)
    	at java.awt.Container.dispatchEventImpl(Container.java:2294)
    	at java.awt.Window.dispatchEventImpl(Window.java:2746)
    	at java.awt.Component.dispatchEvent(Component.java:4711)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    	at java.awt.EventQueue.access$500(EventQueue.java:97)
    	at java.awt.EventQueue$3.run(EventQueue.java:709)
    	at java.awt.EventQueue$3.run(EventQueue.java:703)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    	at java.awt.EventQueue$4.run(EventQueue.java:731)
    	at java.awt.EventQueue$4.run(EventQueue.java:729)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    une petite idée ?

    Merci encore pour tout

  4. #4
    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 Senjinsama Voir le message
    Le ChangeEvent fonctionne très bien et la conversion se fait bien dans la partie "Miles". En revanche, pour optimiser la partie visuelle, il faudrait que je réduise le nombre de chiffres après la virgule. Je pensais essayer de passer sur du BigDecimal et et faire un setscale à 2. Qu'en pensez-vous ?
    Attention : ne pas confondre une valeur et la façon de l'afficher (on ne converti pas une valeur en une autre juste pour l'afficher). On peut avoir besoin de modifier la précision décimale d'une valeur (ce qu'on peut faire par multiplication et division simplement), mais si le but est seulement d'afficher un nombre avec 2 décimales, on utilise un formateur.

    On peut utiliser par exemple un DecimalFormat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DecimalFormat format = new DecimalFormat("#,##0.00"); // 2 chiffres après la virgule, séparateur de milliers
    String stringValue = format.format( value );
    On peut utiliser aussi String.format() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String stringValue = String.format("%1$,.2f",value);
    Citation Envoyé par Senjinsama Voir le message
    La 2ème fois, rien ne se passe sur l'appli, mais je vois ce message dans la console NetBeans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "56.0"
    Ici, le souci est l'inverse du formatage : passer d'une chaîne à une valeur. Tu utilises Integer.parseInt(), qui permet de passer d'une String à un int. Mais il faut que la chaîne contienne un int. Or si tu tapes 56.0, ce n'est pas un int, puisqu'il y a un . dans le texte.

    1. Première possibilité : utiliser Double.parseDouble() (pour obtenir un double), ou Float.parseFloat() (pour obtenir un float). Seulement JSlider.setValue() prend un int en paramètre, donc il faut convertir le nombre en int (par cast par exemple, ou en utilisant Double.valueOf(), ou Float.valueOf(), qui te donneront un Double ou un Float (respectivement), et par la méthode intValue() tu auras un int).
    2. Deuxième possibilité, utiliser un DecimalFormat avec un format compatible avec un int. Parce que cette classe sait s'arrêter au bon endroit pour ne pas traiter ce qui pourrait causer une erreur, comme un point, ou une virgule.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      	DecimalFormat format = new DecimalFormat("0");int value = ((Number) format.parse(stringValue)).intValue();


    Dans les deux cas, il y aura toujours possibilité d'exception (par exemple si on tape "xxx" dans le champ). Dans le cas du Double.parseDouble() ou Integer.parseInt(), ce sera une NumberFormatException. Dans le cas du DecimalFormat, une ParseException. Exception que tu peux attraper et réagir en fonction.

    Il y a également :

    1. La soluton de l'InputVerifier, mais cette solution, très simple, est plutôt très limitée, car elle n'empêche que la perte de focus par tabulation. Elle n'empêche par un actionListener de se déclencher, de cliquer sur un bouton, etc... et surtout de récupérer une valeur valide.
      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
      public static void main(String[] args) throws ParseException {
       
      	JFrame frame = new JFrame("Démo");
      	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      	JTextField field = new JTextField();
      	field.setInputVerifier(new InputVerifier() {
       
      		@Override
      		public boolean verify(JComponent input) {
      			try {
      				Integer.parseInt(((JTextField)input).getText());
      				return true; // valide
      			}
      			catch(NumberFormatException e) {
      				return false; // invalide
      			}
      		}
      	});
      	field.addActionListener(e->JOptionPane.showMessageDialog(frame, "Saisie : "+field.getText()));
       
       
      	JPanel panel = new JPanel(new GridBagLayout());
      	GridBagConstraints gbc = new GridBagConstraints();
      	gbc.insets=new Insets(3,3,3,3);
      	panel.add(new JLabel("Saisie :"), gbc);
      	gbc.weightx=1;
      	gbc.fill=GridBagConstraints.HORIZONTAL;
      	panel.add(field, gbc);
       
      	gbc.gridy=1;
      	gbc.weightx=0;
      	gbc.gridwidth=2;
      	gbc.anchor=GridBagConstraints.CENTER;
      	gbc.fill=GridBagConstraints.NONE;
      	JButton button = new JButton("Valider");
      	panel.add(button, gbc);
      	button.addActionListener(e-> JOptionPane.showMessageDialog(frame, "Saisie : "+field.getText()));
       
      	frame.add(panel);
       
      	frame.pack();
      	frame.setLocationRelativeTo(null);
      	frame.setVisible(true);
       
      }
    2. Il y a le JFormattedTextField, mais il sert surtout à formater, pas à valider, et finalement, il faut faire la même chose pour la validation qu'on ferait avec un JTextField. Il y a également, comme je te le disais, le JSpinner qui te permettra également de saisir un int, directement, en mettant en place un intervalle de saisie. Il ajoute certes 2 contrôles supplémentaires, pour incrémenter ou décrémenter, mais il est le plus en adéquation avec un JSlider et est très simple à mettre en place.
    3. Enfin, il y a le DocumentFilter qui permet de filtrer les caractères qu'on ne veut pas, ou de reformater éventuellement la saisie. Tu verras avec l'exemple suivant qu'on ne peut pas saisir autre chose qu'un nombre entier dans le champ. Limiter le nombre à un intervalle sera plus compliqué.


      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 static void main(String[] args) throws ParseException {
       
      	JFrame frame = new JFrame("Démo");
      	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      	JTextField field = new JTextField();
      	field.setText("0");
      	((AbstractDocument)field.getDocument()).setDocumentFilter(new DocumentFilter() {
      		@Override
      		public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
      				throws BadLocationException {
      			string = string.replaceAll("\\D", ""); // on supprime tout ce qui n'est pas chiffre
      			super.insertString(fb, offset, string, attr);
      		}
      		@Override
      		public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
      				throws BadLocationException {
      			text = text.replaceAll("\\D", ""); // on supprime tout ce qui n'est pas chiffre
      			if ( offset==0 && length==field.getText().length() && text.length()==0 ) { // si on remplace le contenu complet du champ par unue chaîne vide
      				text = "0"; // on remet un 0 dans le champ
      			}
      			super.replace(fb, offset, length, text, attrs);
      		}
      		@Override
      		public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
      			if ( offset==0 && length==field.getText().length() ) { // si on supprime tous les caractères
      				super.replace(fb, 0, field.getText().length(), "0", null); // on remet un 0 dans le champ
      			}
      			else {
      				super.remove(fb, offset, length);
      			}
      		}
      	});
      	field.addActionListener(e->JOptionPane.showMessageDialog(frame, "Saisie : "+field.getText()));
       
       
      	JPanel panel = new JPanel(new GridBagLayout());
      	GridBagConstraints gbc = new GridBagConstraints();
      	gbc.insets=new Insets(3,3,3,3);
      	panel.add(new JLabel("Saisie :"), gbc);
      	gbc.weightx=1;
      	gbc.fill=GridBagConstraints.HORIZONTAL;
      	panel.add(field, gbc);
       
      	gbc.gridy=1;
      	gbc.weightx=0;
      	gbc.gridwidth=2;
      	gbc.anchor=GridBagConstraints.CENTER;
      	gbc.fill=GridBagConstraints.NONE;
      	JButton button = new JButton("Valider");
      	panel.add(button, gbc);
      	button.addActionListener(e-> JOptionPane.showMessageDialog(frame, "Saisie : "+field.getText()));
       
      	frame.add(panel);
       
      	frame.pack();
      	frame.setLocationRelativeTo(null);
      	frame.setVisible(true);
       
      }
    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.

Discussions similaires

  1. Implémentation de ActionListener : récupérer this
    Par AceSir dans le forum Général Java
    Réponses: 11
    Dernier message: 01/03/2013, 15h56
  2. cannot reference this before supertype constructor has been called
    Par renlel dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 26/11/2009, 14h25
  3. TypeError: this constructor takes no arguments
    Par mfaty dans le forum Général Python
    Réponses: 5
    Dernier message: 26/08/2009, 23h17
  4. Réponses: 7
    Dernier message: 26/02/2004, 09h32
  5. Copy constructor ?
    Par Keyser dans le forum MFC
    Réponses: 4
    Dernier message: 17/02/2004, 15h33

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