Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2005
    Messaggi
    83

    [KeyListener] Restituire un INT da un KeyListener al metodo esterno

    Salve a tutti,
    ho un problemino con un KeyListener..

    Ho creato un JOptionPane personalizzato (ci ho inserito una JLabel, una JPasswordField, etc) che richiede in input una stringa e controlla che questa stringa sia identica a quella già memorizzata.
    Il metodo si chiama loopTheUserInputWindow() e restituisce un valore "int".

    - se Stringa1==Stringa2, restituisco 0
    - se Stringa1 != Stringa2, restituisco -1
    - altrimenti restituisco 1 (nel caso in cui l'utente chiuda il pannello)

    Questo funziona benissimo finché l'utente, dopo aver inserito la stringa, clicca sul tasto "OK" del JOptionPane.
    Io però vorrei anche implementare la possibilità di andare avanti cliccando ENTER sulla tastiera, per cui ho aggiunto un KeyListener alla JPasswordField (sono sempre all'interno del metodo loopTheUserInputWindow() ).
    Il problema é che, dall'interno del metodo eriditato keyPressed() non posso restituire un valore di tipo "int", perché questo metodo keyPressed é definito come "VOID".

    Il codice é in basso..qualcuno potrebbe aiutarmi ?

    codice:
    private int loopTheUserInputWindow(){             
    
                    /*** CREATING THE INPUT BOX TO REQUEST THE PASSWORD ***/
    
            Object[] messageInTheBox= {"Please enter your password",usersPasswordField};
            String cryptoPopUPTitle="Authentication Required";
            Object[] usersOptions= {"OK","CANCEL"};     
    
                    /* CREATE PASSWORD FIELD TO BE PUT LATER ON IN THE USER DIALOG BOX */
    
                    usersPasswordField.setText(""); // RESET THE FIELD
                    usersPasswordField.setEchoChar('*');                                       usersPasswordField.setColumns(14);                          // MAX LENGHT --> 14 characters
    
            usersPasswordField.addKeyListener(new KeyListener(){                    
                    // QUI C'É IL KEY LISTENER CHE VORREI IMPLEMENTARE
                    public void keyTyped(KeyEvent e) {}
                    public void keyReleased(KeyEvent e) {}
                    public void keyPressed(KeyEvent e) {
                         // QUI DOVREI FARE IL CONTROLLO E RESTITUIRE UN int 
                         // AL METODO loopTheUserInputWindow..
    
                    }
    
            });
    
            if (JOptionPane.showOptionDialog(index, messageInTheBox, cryptoPopUPTitle,
    
                                    JOptionPane.YES_NO_OPTION, 0, new ImageIcon("images\\crypto_icon_small.JPG"), usersOptions, 
    
                                    messageInTheBox) == JOptionPane.YES_OPTION)
    
                            // USER CLICKED THE YES BUTTON 
    
                    {       
    
                    if (continueWithPassword(new String(usersPasswordField.getPassword())))
                            // RIGHT PASSWORD !!!
                            return 0;
                    else {
                            // WRONG PASSWORD !!!
                            return -1;
                    }
                    }                       
            else {
                       // USER CLICKED "NO" BUTTON OR CLOSED THE POP-UP WINDOW
                    return 1;
            }               
            }

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [KeyListener] Restituire un INT da un KeyListener al metodo esterno

    Originariamente inviato da onieliv
    Questo funziona benissimo finché l'utente, dopo aver inserito la stringa, clicca sul tasto "OK" del JOptionPane.
    Io però vorrei anche implementare la possibilità di andare avanti cliccando ENTER sulla tastiera, per cui ho aggiunto un KeyListener alla JPasswordField (sono sempre all'interno del metodo loopTheUserInputWindow() ).
    Il problema é che, dall'interno del metodo eriditato keyPressed() non posso restituire un valore di tipo "int", perché questo metodo keyPressed é definito come "VOID".
    Innanzitutto non è questo l'obiettivo che devi cercare di raggiungere (keyPressed ha tipo di ritorno void per un motivo semplice e valido: ti informa solo di un evento ma non può fare/cambiare nulla).

    E comunque non c'è bisogno di tutto il malloppo che hai scritto: basta usare semplicemente showConfirmDialog con l'opzione JOptionPane.OK_CANCEL_OPTION e il tasto OK è già gestito come "predefinito" e reagisce al <invio> anche se il focus ce l'hai nel JPasswordField inserito nel "message".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2005
    Messaggi
    83
    Ciao andbin,
    innanzitutto grazie della risposta!

    Il problema del .showMessageDialog é che mette di default il FOCUS sul tasto ("YES")invece di metterlo sulla textfield.. Ho guardato un po' in giro e non sembra esserci un modo per spostare il focus sull'area di testo usando un MessageDialog..

    L'unico modo é usare il .showOptionDialog, ma lí ho un altro problema...
    Praticamente.. se come penultimo paramentro inserisco l'array di oggetti (new Object[]{"OK", "Cancel"}, come ho visto in un esempio), il focus viene automaticamente messo sull'ultimo parametro ('pf', la password field), ma in questo modo il tasto ENTER non funziona piú..

    codice:
    if (JOptionPane.showOptionDialog(index, obj, "Autentication Required",
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon("images\\crypto_icon_small.JPG"), new Object[]{"OK", "Cancel"}, pf) == JOptionPane.YES_OPTION)
                            System.out.println("it works");

    Se invece, come penultimo parametro metto 'null', il tasto ENTER funziona di nuovo come predefinito ma il focus si sposta di nuovo sul tasto "YES"..

    codice:
            if (JOptionPane.showOptionDialog(index, obj, "Autentication Required",
    
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon("images\\crypto_icon_small.JPG"), new Object[]{"OK", "Cancel"}, pf) == JOptionPane.YES_OPTION)
    
                            System.out.println("it works");

    Non capisco proprio perché si comporti cosi... puoi darmi una mano?

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2005
    Messaggi
    83

    [Risolto]

    Ok, ho risolto con una soluzione trovata su un forum inglese.

    Usando un JOptionPane.showConfirmDialog, posso dare il focus all'area di testo facendole chiamare un'estensione del metodo .addAncestorListener

    Per riferimenti futuri, metto a disposizione il codice del JOptionPane (qui) e quello della classe RequestFocusListener.java (in basso)

    codice:
          JPasswordField pf = new JPasswordField();
          pf.addAncestorListener( new RequestFocusListener() );  // METTO IL FOCUS
     
          Object[] obj = {"Enter your Password:", pf};
    
         JOptionPane.showConfirmDialog(null, obj, "Enter Password", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,null"));

    codice:
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class RequestFocusListener implements AncestorListener
    {
    	private boolean removeListener;
    
    	/*
    	 *  Convenience constructor. The listener is only used once and then it is
    	 *  removed from the component.
    	 */
    	public RequestFocusListener()
    	{
    		this(true);
    	}
    
    	/*
    	 *  Constructor that controls whether this listen can be used once or
    	 *  multiple times.
    	 *
    	 *  @param removeListener when true this listener is only invoked once
    	 *                        otherwise it can be invoked multiple times.
    	 */
    	public RequestFocusListener(boolean removeListener)
    	{
    		this.removeListener = removeListener;
    	}
    
    	@Override
    	public void ancestorAdded(AncestorEvent e)
    	{
    		JComponent component = e.getComponent();
    		component.requestFocusInWindow();
    
    		if (removeListener)
    			component.removeAncestorListener( this );
    	}
    
    	@Override
    	public void ancestorMoved(AncestorEvent e) {}
    
    	@Override
    	public void ancestorRemoved(AncestorEvent e) {}
    }

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Io ho provato a farlo. Inizialmente ho sviluppato questo:

    codice:
    public static char[] showPasswordDialog(Component parentComponent) {
        JPasswordField passwordField = new JPasswordField(20);
        
        Object[] message = { "Inserire password:", passwordField };
        
        int r = JOptionPane.showConfirmDialog(parentComponent, message,
            "Autenticazione", JOptionPane.OK_CANCEL_OPTION,
            JOptionPane.QUESTION_MESSAGE);
        
        if (r == JOptionPane.OK_OPTION) {
            return passwordField.getPassword();
        } else {
            return null;
        }
    }
    Funziona (compreso <invio> per confermare), l'unico "problema" è che appunto il focus è inizialmente sul pulsante OK, non sul password-field.

    Ma sapendo come funziona internamente JOptionPane, ho sviluppato poi questo:

    codice:
    public static char[] showPasswordDialog(Component parentComponent) {
        final JPasswordField passwordField = new JPasswordField(20);
        
        Object[] message = { "Inserire password:", passwordField };
        
        JOptionPane optionPane = new JOptionPane(message,
                JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
            public void selectInitialValue() {
                super.selectInitialValue();
                passwordField.requestFocusInWindow();
            }
        };
        
        JDialog dialog = optionPane.createDialog(parentComponent, "Autenticazione");
        dialog.setVisible(true);
        dialog.dispose();
        
        if (new Integer(JOptionPane.OK_OPTION).equals(optionPane.getValue())) {
            return passwordField.getPassword();
        } else {
            return null;
        }
    }
    Questo funziona e il focus è inizialmente sul password-field.
    Nota come le mie implementazioni siano semplici, pulite e ben incapsulate in un metodo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.