Collegare listeners a pulsante

di il
11 risposte

Collegare listeners a pulsante

Ciao ragazzi..sto provando a fare un programma in java che una volta inserita una stringa dall'utente, venga eseguito un hash MD5. Il metodo c'è e funziona. Ora sto provando a implementare un interfaccia. Premetto che non sono molto pratico con interfacce e listeners..e anche Java lo studio da solo un anno. In ogni caso, non riesco a capire come collegare il pulsante "encrypt" al metodo che appunto cripti la stringa.
Vi metto qua sotto il codice delle 3 classi.
Classe con l'interfaccia(metto solo l instanza del bottone, ma forse non serve nemmeno:
private JButton encrypt = new JButton("Encrypt");
Classe con il metodo:
public class Converter {

    private String inputString;

    public Converter(String inputString) {
        this.inputString = inputString;
    }

    public static String encrypt(String string) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(string.getBytes());
            return String.format("%032x", new BigInteger(1, md.digest()));
        } catch (NoSuchAlgorithmException e) {
            return null;
        }

    }

}
Qui ho istanziato una stringa "inputString" che dovrebbe collegarsi al listener(penso)

Classe listener:
public class Listener implements ActionListener{
    
    private JTextField insertedString;
    private JTextField encryptedString;
    private String encrypt = "Encrypt";
    private Converter c;
   
    
    public Listener(JTextField insertedString, JTextField encryptedString){
        this.insertedString = insertedString;
        this.encryptedString = encryptedString;
        
    }
    
    @Override
    public void actionPerformed(ActionEvent ae){
        if(ae.getActionCommand().equalsIgnoreCase(encrypt)){
            c = new Converter(encrypt);
        }
    
    }
    
}
Ovviamente non fa nulla quando schiaccio il pulsante..quindi è proprio da sistemare. Più che altro è la prima volta che uso un metodo che ritorna un String.format . Onestamente non l'ho manco capito più di tanto(l'ho preso da un sito), e infatti non so come collegarlo al listener.
Grazie in anticipo a chiunque mi darà una mano

11 Risposte

  • Re: Collegare listeners a pulsante

    Se hai detto che il metodo c'è e funziona la classe Converter non è molto importante adesso, però non ha molto senso che il metodo encrypt sia un metodo statico e che contemporaneamente ci sia un campo d'istanza inputString e un costruttore.
    Se non hai bisogno di mantenere dello stato nell'oggetto (che so, l'elenco di tutte le stringhe inserite o altro) Converter potrebbe anche essere solo una classe che offre metodi di utilità statici, e non avresti bisogno di un oggetto Converter (ti basta richiamare Converter.encrypt (stringa)).
    Anche String.format c'entra poco o nulla, stai solo ottenendo una stringa formattata a partire da un'altra stringa.

    L'importante è capire come utilizzare i componenti e aggiungere l'ascoltatore, che può essere anche una classe esterna o interna al pannello, ma sarebbe meglio non contenesse textfield o altri componenti.
    Io ti suggerirei di utilizzare una classe anonima come ascoltatore del pulsante, mantenendo i textfield come variabili d'istanza nella "classe con l'interfaccia", alla pressione del bottone richiamerai poi il metodo encrypt () passando come input il testo del primo textfield, e settando il risultato come testo all'altro textfield. In modo molto abbozzato:
    
    public class MainPanel extends JPanel
    {
    	private JTextField inputField;
    	private JTextField outputField;
    	
    	public MainPanel (/* ... */) {
    	
    		// ... Crei tutto ciò che ti serve e i due textfield
    		
    		// Se aggiungi un listener anonimo al bottone non hai bisogno di salvarti il reference del bottone come variabile ...
    		
    		JButton encrypt = new JButton ("Encrypt"); 
    		
    		encrypt.addActionListener (new ActionListener () {
    			@public void actionPerformed (ActionEvent e) {
    				encryptString ();
    			}
    		});
    		
    		/* 
    			Potresti anche creare bottone e listener in una sola istruzione:
    			
    			JButton encrypt = new JButton (new AbstractAction ("Encrypt") {
    				@public void actionPerformed (ActionEvent e) {
    					encryptString ();
    				}
    			});
    		*/
    	}
    	private void encryptString () {
    		String input = inputField.getText ();
    		// eventuali controlli ...
    		String output = Converter.encrypt (input);
    		// altro ... ?
    		outputField.setText (output);
    	}
    }
    
    In caso tu voglia usare più pulsanti e un unico ascoltatore (io preferisco scrivere un po' di più e avere ascoltatori singoli, senza dover controllare la "sorgente" dell'evento) puoi anche salvarti il reference del pulsante e usare quello per il controllo:
    
    // ... all'interno dell' actionPerformed (ActionEvent e) ...
    Object source = e.getSource ();
    if (source == encryptButton) {
    // ...
    }
    else if (source == ...) 
    
    Ma sarebbe comunque meglio che l'ascoltatore fosse una classe privata interna alla classe con l'interfaccia, in modo da poter accedere alle variabili senza passare pulsanti e textfield da una classe all'altra.

    Nota che se aggiungi l'ascoltatore al bottone nello stesso metodo in cui crei i textfield (ad esempio nel costruttore del tuo pannello) non avresti nemmeno bisogno di salvarti alcun reference come variabile di istanza, ma potresti fare anche tutto nell'ascoltatore del pulsante.
  • Re: Collegare listeners a pulsante

    Ansharja ha scritto:


    Se hai detto che il metodo c'è e funziona la classe Converter non è molto importante adesso, però non ha molto senso che il metodo encrypt sia un metodo statico e che contemporaneamente ci sia un campo d'istanza inputString e un costruttore.
    Se non hai bisogno di mantenere dello stato nell'oggetto (che so, l'elenco di tutte le stringhe inserite o altro) Converter potrebbe anche essere solo una classe che offre metodi di utilità statici, e non avresti bisogno di un oggetto Converter (ti basta richiamare Converter.encrypt (stringa)).
    Anche String.format c'entra poco o nulla, stai solo ottenendo una stringa formattata a partire da un'altra stringa.

    L'importante è capire come utilizzare i componenti e aggiungere l'ascoltatore, che può essere anche una classe esterna o interna al pannello, ma sarebbe meglio non contenesse textfield o altri componenti.
    Io ti suggerirei di utilizzare una classe anonima come ascoltatore del pulsante, mantenendo i textfield come variabili d'istanza nella "classe con l'interfaccia", alla pressione del bottone richiamerai poi il metodo encrypt () passando come input il testo del primo textfield, e settando il risultato come testo all'altro textfield. In modo molto abbozzato:
    
    public class MainPanel extends JPanel
    {
    	private JTextField inputField;
    	private JTextField outputField;
    	
    	public MainPanel (/* ... */) {
    	
    		// ... Crei tutto ciò che ti serve e i due textfield
    		
    		// Se aggiungi un listener anonimo al bottone non hai bisogno di salvarti il reference del bottone come variabile ...
    		
    		JButton encrypt = new JButton ("Encrypt"); 
    		
    		encrypt.addActionListener (new ActionListener () {
    			@public void actionPerformed (ActionEvent e) {
    				encryptString ();
    			}
    		});
    		
    		/* 
    			Potresti anche creare bottone e listener in una sola istruzione:
    			
    			JButton encrypt = new JButton (new AbstractAction ("Encrypt") {
    				@public void actionPerformed (ActionEvent e) {
    					encryptString ();
    				}
    			});
    		*/
    	}
    	private void encryptString () {
    		String input = inputField.getText ();
    		// eventuali controlli ...
    		String output = Converter.encrypt (input);
    		// altro ... ?
    		outputField.setText (output);
    	}
    }
    
    In caso tu voglia usare più pulsanti e un unico ascoltatore (io preferisco scrivere un po' di più e avere ascoltatori singoli, senza dover controllare la "sorgente" dell'evento) puoi anche salvarti il reference del pulsante e usare quello per il controllo:
    
    // ... all'interno dell' actionPerformed (ActionEvent e) ...
    Object source = e.getSource ();
    if (source == encryptButton) {
    // ...
    }
    else if (source == ...) 
    
    Ma sarebbe comunque meglio che l'ascoltatore fosse una classe privata interna alla classe con l'interfaccia, in modo da poter accedere alle variabili senza passare pulsanti e textfield da una classe all'altra.

    Nota che se aggiungi l'ascoltatore al bottone nello stesso metodo in cui crei i textfield (ad esempio nel costruttore del tuo pannello) non avresti nemmeno bisogno di salvarti alcun reference come variabile di istanza, ma potresti fare anche tutto nell'ascoltatore del pulsante.
    Hei ciao Ansharja! Che piacere ritrovarti. Non so se ti ricordi di me...mesi fa mi avevi aiutato con quel programmino per la gestione di un aeroporto. Mi ero trovato veramente bene con te.
    Comunque, tornando al mio problema:
    Hai ragione, quel istanza e quel costruttore sono inutili..gli levo subito.
    Quindi tu consigli di togliere la classe ascoltatore e aggiungere il listeners solamene al pulsante "Encrypt" giusto? Si, forse è meglio.
    Volevo capire una cosa. All'interno di quel metodo nella classe converter, viene passata una stringa. Infatti se io poi nel listener scrivo ad esempio
     c.encrypt(); 
    e basta, mi da errore..sicuro perchè all'interno del metodo richiede una stringa. Ma non so cosa passarli in realtà.
    Comunque adesso faccio un po' di prove e vedo se riesco a mettere l'ascoltatore subito sul pulsante. Vediamo un po' cosa ne esce
    non ho capito solo una cosa:
    JButton encrypt = new JButton (new AbstractAction ("Encrypt") {
                @public void actionPerformed (ActionEvent e) {
                   encryptString ();
                }
                
    quel public void va sotto così? Perchè c'è una chiocciola? Poi "encryptString()" sarebbe il metodo della classe converter? Mi chiede comunque all'interno una stringa e se scrivo "string"(quella passata nel metodo) non me la accetta. Ci lavoro un po' nel frattempo magari..cerco anche qualcosa online.
    Grazie intanto per la tua risposta!
  • Re: Collegare listeners a pulsante

    EDIT: ho messo i pulsanti dentro il costruttore della classe GUI togliendo i private e ora già mi fa il completamento automatico e non da errore. Solo che non riesco proprio a capire come richiamare il risultato del metodo..quel return stringFormat(e tutta la roba dentro) mi confonde troppo. In più non ho capito come farlo stampare nella jtext di ouput.
    Comunque ho scritto una roba del genere:
    
    JButton encrypt = new JButton("Encrypt);
    encrypt.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
    Converter c = new Converter();
    String string = null // me lo suggeriva il compilatore..dice che la devo inizializzare per forza
    c.encrypt(String.format(string, encryptedString)); // qui ho scritto cose a caso LOL
    }}
    );
    
    Suggerimenti? Lo so, sono scarsissimo
  • Re: Collegare listeners a pulsante

    xXNicolaXx ha scritto:


    Hei ciao Ansharja! Che piacere ritrovarti. Non so se ti ricordi di me...mesi fa mi avevi aiutato con quel programmino per la gestione di un aeroporto. Mi ero trovato veramente bene con te.
    Comunque, tornando al mio problema:
    Hai ragione, quel istanza e quel costruttore sono inutili..gli levo subito.
    Quindi tu consigli di togliere la classe ascoltatore e aggiungere il listeners solamene al pulsante "Encrypt" giusto? Si, forse è meglio.
    Volevo capire una cosa. All'interno di quel metodo nella classe converter, viene passata una stringa. Infatti se io poi nel listener scrivo ad esempio
     c.encrypt(); 
    e basta, mi da errore..sicuro perchè all'interno del metodo richiede una stringa. Ma non so cosa passarli in realtà.
    Ciao! Ora sì ricordo, ma ho dovuto sbirciare la discussione perché era passato un po' di tempo

    Anche quell'oggetto "c" della classe Converter non serve più, se encrypt è un metodo statico lo richiami semplicemente con:
    
    Converter.encrypt (stringaDaCriptare);
    
    Ovvio che devi passare una stringa al metodo se l'hai definito in quel modo, per ora non vedo motivo di fare in altro modo.
    Per passare la stringa da criptare basta prendere il testo del textfield corrispondente con il metodo getText ().

    xXNicolaXx ha scritto:


    [...] non ho capito solo una cosa:
    JButton encrypt = new JButton (new AbstractAction ("Encrypt") {
                @public void actionPerformed (ActionEvent e) {
                   encryptString ();
                }
                
    quel public void va sotto così? Perchè c'è una chiocciola?
    Errore mio, l'ho dimenticata facendo copia incolla!
    Stava per @Override comunque, è una notazione che puoi mettere prima di un metodo di cui fai l'override e serve sia per chiarezza sia per evitare alcuni errori (il compilatore infatti controllerà che il metodo sia effettivamente l'override di un metodo di una superclasse, e darà errore se così non è, perché hai scritto male il nome o i parametri/tipo di ritorno non sono corretti, o se il metodo nella superclasse è private etc.). Diciamo che metterlo non fa male, ma non è affatto obbligatorio.

    xXNicolaXx ha scritto:


    Poi "encryptString()" sarebbe il metodo della classe converter? Mi chiede comunque all'interno una stringa e se scrivo "string"(quella passata nel metodo) non me la accetta.
    No encryptString è il metodo che ho scritto in quello schemetto della classe con l'interfaccia, viene richiamato dal listener, legge il testo del textfield e lo passa all'encrypt della classe Converter, per poi settare la stringa ricevuta dal metodo come testo nell'altro textfield.
    L'avevo scritto solo per non scrivere tutto il codice nel listener, ma non serve un metodo separato (a meno che non sia possibile richiamarlo anche in un altro modo), se ti fa confusione togli pure!

    Per quanto riguarda il tuo edit, riguardati questa parte del codice che avevo inserito:
    
    String input = inputField.getText ();
    // eventuali controlli ...
    String output = Converter.encrypt (input);
    // altro ... ?
    outputField.setText (output);
    
    E' tutto qui quello che devi fare per criptare la stringa: leggere il testo dal primo textfield, richiamare il metodo della classe Converter (non serve l'oggetto "c" come dicevo, non istanziare un oggetto per richiamare un metodo statico, ha [molto] poco senso), e settare il risultato del metodo all'altro textfield.
    Non deve confonderti lo String.format, viene solo usato nell'altro metodo in Converter, ma è solo un modo per restituire una stringa formattata con il BigInteger dentro, non ne hai bisogno per richiamare il metodo.
  • Re: Collegare listeners a pulsante

    Dunque..forse ora ho capito la logica. Però ancora non funziona. Sicuramente colpa mia e non tua.
    Posto di nuovo il codice per farti capire cosa ho combinato:
    Questa è la classe interfaccia:
    
    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    package md5converter;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javafx.scene.layout.Border;
    import javax.swing.AbstractAction;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    /**
     *
     * @author Nicola
     */
    public class GUI extends JFrame {
    
        private JTextField inputField;
        private JTextField outputField;
    
        private void encryptString() {
            String input = inputField.getText();
            String output = Converter.encrypt(input);
            outputField.setText(output);
        }
    
        public GUI() {
            super();
    
            JLabel stringToConvert = new JLabel("String to convert");
            JTextField inputString = new JTextField(10);
            JLabel encryptedString = new JLabel("Encrypted String");
            JTextField outputString = new JTextField(10);
            JButton encrypt = new JButton("Encrypt");
            JButton reset = new JButton("Reset");
    
            encrypt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    Converter.encrypt(outputField.getText());
                }
            }
           );
            JPanel mainPanelInput = new JPanel();
            mainPanelInput.setLayout(new FlowLayout());
            mainPanelInput.add(stringToConvert);
            mainPanelInput.add(inputString);
    
            JPanel mainPanelOutput = new JPanel();
            mainPanelOutput.setLayout(new FlowLayout());
            mainPanelOutput.add(encryptedString);
            mainPanelOutput.add(outputString);
    
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(encrypt);
            buttonPanel.add(reset);
    
            JPanel northPanel = new JPanel();
            northPanel.setLayout(new GridLayout(3, 1, 0, 20));
            northPanel.add(mainPanelInput);
            northPanel.add(mainPanelOutput);
            northPanel.add(buttonPanel);
            this.add(northPanel, BorderLayout.NORTH);
    
        }
    
        public void setDefault() {
            setTitle("MD5 Encrypter");
            setSize(500, 200);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setVisible(true);
    
        }
    
    }
    
    Ho messo tutto perchè magari manca una cavolata..però penso che la seconda metà non serva a risolvere il problema.
    Ti posto anche l'errore che riporta:
    run:
    Inserisci una stringa da convertire :
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at md5converter.GUI$1.actionPerformed(GUI.java:51)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6533)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6298)
    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.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    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)

    GUI:java51 sarebbe questa riga: Converter.encrypt(outputField.getText());
    Dove sbaglio?
    ps. ho provato con outputString.getText()) invece che outputField e non da errori..però non visualizza comunque niente dove dovrebbe uscire la stringa criptata
  • Re: Collegare listeners a pulsante

    Ci sei molto vicino, l'errore sta nel fatto che "outputField", la variabile di istanza della classe, non viene mai inizializzata, quindi quando richiami su di essa il metodo getText () ottieni una NullPointerException (non puoi invocare alcun metodo su un reference che punta a null).

    Va benissimo usare il textfield che crei nel costruttore, come dicevo in precedenza se accedi al testo direttamente nel luogo in cui crei il textfield non è necessario salvarlo come variabile d'istanza, in questo puoi quindi rimuovere quelle variabili:
    
    private JTextField inputField;
    private JTextField outputField;
    
    Ma deve esserti chiaro il fatto che inputString e outputString sono dichiarate internamente al costruttore, quindi non potresti accederci in un altro metodo della classe (è però più chiaro il nome inputField riferito a un JTextField, se il codice si allunga chi legge inputString si aspetta una variabile di tipo String ...).

    Un'altra cosa che ti deve essere chiara è che il comando:
    
    Converter.encrypt(outputField.getText());
    
    usato in questo modo non modifica in alcun modo i tuoi componenti, stai prendendo il risultato del metodo encrypt e non ne fai nulla.
    Devi usare tu il setText () sul textfield corrispondente (tra l'altro a rigor di logica il textfield che deve contenere la stringa da criptare dovrebbe essere quello di input, tu stai prendendo il testo di quello di output ...)
  • Re: Collegare listeners a pulsante

    Ansharja ha scritto:


    Ci sei molto vicino, l'errore sta nel fatto che "outputField", la variabile di istanza della classe, non viene mai inizializzata, quindi quando richiami su di essa il metodo getText () ottieni una NullPointerException (non puoi invocare alcun metodo su un reference che punta a null).

    Va benissimo usare il textfield che crei nel costruttore, come dicevo in precedenza se accedi al testo direttamente nel luogo in cui crei il textfield non è necessario salvarlo come variabile d'istanza, in questo puoi quindi rimuovere quelle variabili:
    
    private JTextField inputField;
    private JTextField outputField;
    
    Ma deve esserti chiaro il fatto che inputString e outputString sono dichiarate internamente al costruttore, quindi non potresti accederci in un altro metodo della classe (è però più chiaro il nome inputField riferito a un JTextField, se il codice si allunga chi legge inputString si aspetta una variabile di tipo String ...).

    Un'altra cosa che ti deve essere chiara è che il comando:
    
    Converter.encrypt(outputField.getText());
    
    usato in questo modo non modifica in alcun modo i tuoi componenti, stai prendendo il risultato del metodo encrypt e non ne fai nulla.
    Devi usare tu il setText () sul textfield corrispondente (tra l'altro a rigor di logica il textfield che deve contenere la stringa da criptare dovrebbe essere quello di input, tu stai prendendo il testo di quello di output ...)
    Sto impazzendo ahah
    Prima di tutto, non ho capito se nell'actionListener devo richiamare il metodo encryptString() che è quello creato da te con le variabili inputField e outputField oppure devo usare quello scritto nel messaggio precedente.
    Poi..ho fatto diversi tentativi, perchè in effetti io nell'interfaccia ho la JTextField "outputString" dove voglio visualizzare l'output..e non la "outputField". Quindi si, come hai detto tu, ovvio che non visualizzo niente. Ho provato in 300 modi.
    Adesso ho cambiato quelle due variabili inputString e outputString come hai detto tu.
    Però non capisco ancora una cosa(anche più ahah):
    se io tolgo
    
    private JTextField inputField;
    private JTextField outputField;
    
    quando poi creo il metodo che mi hai detto tu (encryptString) giustamente mi dice che quelle variabili le devo prima dichiarare.
    Poi. Ho provato a fare cosi sempre nel metodo ActionPerformed()
    
    encryptString();
    outputField.setText(outputField.getText());
    
    Ti spiego il ragionamento che faccio io: Quando premo il pulsante, parte il metodo encryptString descritto sopra. Per visualizzare la stringa criptata nella textfield di output, devo impostare un setText, come hai detto tu. Quindi prendo il testo della outputField nel metodo, che dovrebbe contenere appunto il testo criptato. Però a quanto pare non funziona, quindi non è la logica corretta. Oltretutto, ora che le variabili interne al costruttore GUI si chiamano come quelle del metodo encryptString(), mi consiglia di rinominarle.
    Boh, sono sempre più confuso
  • Re: Collegare listeners a pulsante

    Con quel metodo encryptString ti ho fatto solo confusione, facevo meglio a non metterlo. Provo a spiegarmi meglio perché ti basta davvero cambiare tre righe di codice, ma ti serve sbattere la testa anche su questo, mi pare che tu faccia ancora un po' confusione su variabili locali e di istanza.

    Il metodo encryptString che ti avevo scritto era solo un metodo comodo per non inserire tutto il codice all'interno del listener (in realtà puoi anche fare tutto in una riga di codice, ma se il codice si allunga perché vuoi fare controlli o altro potrebbe essere comodo avere un metodo da richiamare invece che inserire tutto nel listener).

    SE decidi di usare quel metodo, allora il codice all'interno del listener non deve più essere quel:
    
    Converter.encrypt(outputField.getText());
    
    ma deve solo essere l' invocazione del metodo encryptString (), farai tutto lì (leggere il testo del textfield di input, chiamare il metodo della classe Converter e settare il risultato sul textdfield di output).
    Ma se prosegui per questa strada ti accorgi che all'interno di encryptString (), o un qualsiasi altro metodo NON puoi accedere ai textfield che hai definito nel costruttore, perché essi sono appunto definiti e visibili solo all'interno di esso. Quindi hai bisogno di mantenere i textfield come variabili di istanza (quei inputField e outputField), nel costruttore dovrai istanziare quelle variabili (quindi l'istruzione per la creazione sarà solo "inputField = new JTextField (/*...*/);", NON "JTextField inputField = new JTextField (/*...*/);".
    Quest'ultima istruzione è infatti sbagliata, stai "mascherando" la variabile di istanza inputField definendone una nuova nel costuttore, che però non esiste all'esterno del costruttore. Tu vuoi invece creare l'oggetto e assegnarlo alla variabile definita nella classe.

    SE invece decidi di non usare un metodo esterno, ma di criptare la stringa e settare il testo direttamente nel listener del pulsante che aggiungi nel costruttore, allora non hai bisogno di mantenere i textfield come variabili d'istanza, perché all'interno del costruttore sono perfettamente visibili.
    Quindi non hai più bisogno di quel metodo encryptString (), lo puoi cancellare, tutto quello che fai in quel metodo verrà fatto direttamente nel listener, però a questo punto il getText () e il setText () andranno fatti a quei JTextField che crei nel costruttore, e che prima avevi chiamato inputString e outputString (ti avevo solo consigliato di chiamarli come avevo fatto io, ma il nome non è fondamentale).
  • Re: Collegare listeners a pulsante

    Ansharja ha scritto:


    Con quel metodo encryptString ti ho fatto solo confusione, facevo meglio a non metterlo. Provo a spiegarmi meglio perché ti basta davvero cambiare tre righe di codice, ma ti serve sbattere la testa anche su questo, mi pare che tu faccia ancora un po' confusione su variabili locali e di istanza.

    Il metodo encryptString che ti avevo scritto era solo un metodo comodo per non inserire tutto il codice all'interno del listener (in realtà puoi anche fare tutto in una riga di codice, ma se il codice si allunga perché vuoi fare controlli o altro potrebbe essere comodo avere un metodo da richiamare invece che inserire tutto nel listener).

    SE decidi di usare quel metodo, allora il codice all'interno del listener non deve più essere quel:
    
    Converter.encrypt(outputField.getText());
    
    ma deve solo essere l' invocazione del metodo encryptString (), farai tutto lì (leggere il testo del textfield di input, chiamare il metodo della classe Converter e settare il risultato sul textdfield di output).
    Ma se prosegui per questa strada ti accorgi che all'interno di encryptString (), o un qualsiasi altro metodo NON puoi accedere ai textfield che hai definito nel costruttore, perché essi sono appunto definiti e visibili solo all'interno di esso. Quindi hai bisogno di mantenere i textfield come variabili di istanza (quei inputField e outputField), nel costruttore dovrai istanziare quelle variabili (quindi l'istruzione per la creazione sarà solo "inputField = new JTextField (/*...*/);", NON "JTextField inputField = new JTextField (/*...*/);".
    Quest'ultima istruzione è infatti sbagliata, stai "mascherando" la variabile di istanza inputField definendone una nuova nel costuttore, che però non esiste all'esterno del costruttore. Tu vuoi invece creare l'oggetto e assegnarlo alla variabile definita nella classe.

    SE invece decidi di non usare un metodo esterno, ma di criptare la stringa e settare il testo direttamente nel listener del pulsante che aggiungi nel costruttore, allora non hai bisogno di mantenere i textfield come variabili d'istanza, perché all'interno del costruttore sono perfettamente visibili.
    Quindi non hai più bisogno di quel metodo encryptString (), lo puoi cancellare, tutto quello che fai in quel metodo verrà fatto direttamente nel listener, però a questo punto il getText () e il setText () andranno fatti a quei JTextField che crei nel costruttore, e che prima avevi chiamato inputString e outputString (ti avevo solo consigliato di chiamarli come avevo fatto io, ma il nome non è fondamentale).
    Incredibile! Finalmente ho capito!! No, è stato meglio che mi hai scritto quel metodo perchè in realtà ora mi è più chiaro tutto. Ho tenuto il metodo e quelle due variabili istanziate all'inizio. Poi, come mi hai detto tu(e che stupido io, che non me lo ricordavo) dovevo instanziarle nel costruttore con quella semplicissima riga di codice(perdonami ma dopo le vacanze era 2 mesi che non toccavo un compilatore e scrivevo codice).
    Però ti volevo chiedere ancora un favore. Sono riuscito con questo metodo qua..però con l'altro(ovvero eliminare il metodo enctyptedString e richiamare invece l'altro metodo con Converter.encrypt(); non riesco.Cioè, non capisco bene alcuni passaggi.
    Scrivo quello che non capisco:
    
    inputField.getText(); // prendo il testo scritto nella casella di input
    Converter.encrypt();//qui devo passare qualcosa dentro a sto metodo..ovvero la stringa che inserisco a mano..ho provato con inputField.getText()
    outputField.setText()//qui non so assolutamente il testo che deve prendere qual'è. Non è la stringa in input, ma quella criptata. Devo quindi di nuovo creare una variabile come quella creata nel tuo metodo per l'output?
    Io adesso vado a dormire, che sono stanchissimo e non ragiono più con la testa. Almeno posso dormire sapendo che mezza soluzione l'ho capita  f22 
    Se vuoi puoi rispondermi anche domani, tanto non ho fretta adesso. Sono curioso però di sapere qual'è l'altro modo per farlo, e secondo te qual'è meglio dei due.
    Grazie davvero tantissimo intanto per l'aiuto che mi hai dato. 
    Quando sei intervenuto tu nella discussione, sono rimasto felice, perchè so che spieghi veramente bene e perfino un ignorante come me prima o poi riesce a capire :D 
    A domani!
  • Re: Collegare listeners a pulsante

    L'altra soluzione in realtà è quasi identica alla precedente, cambiano solo alcuni particolari, ma la logica è sempre quella: prendi il testo da un textfield, lo passi al metodo Converter.encrypt (testoDelPrimoTextField), setti il risultato all'altro textfield.
    Cambia solo il fatto che puoi dimenticarti di passare per un metodo esterno al costruttore (encryptString () andrebbe eliminato) e che non serve tenere due variabili d'istanza (da eliminare anche quelle), ti basta solo riferirti ai textfield che definisci e crei nel costruttore.

    Davvero, tutto qui, i metodi sono praticamente uguali, non parlerei nemmeno di due soluzioni diverse, l'unica differenza è la visibilità delle variabili.

    E' meglio fare tutto nel costruttore o passare per un altro metodo? Dipende. A volte anche dai gusti, nel senso che se il metodo fosse lungo molte righe potrebbe anche solo sembrarti più ordinato il fatto di scrivere un'unica riga nel listener (la chiamata a un metodo) e scrivere il corpo del metodo da un'altra parte.

    Sicuramente se tu potessi richiamare quel metodo in più modi, ovvero non solo cliccando il bottone ma anche ad esempio premendo un pulsante in una menubar in alto (non è questo il caso ma a volte, soprattutto per applicazioni più grandi, è comodo avere più di un modo per fare la stessa operazione), sarebbe più corretto avere un metodo separato, per non dover ripetere lo stesso codice più volte (esponendoti anche ad errori, problemi di manutenzione del codice etc.).
    D'altro canto senza passare per un metodo puoi risparmiarti le due variabili d'istanza (più che altro perché sono un po' superflue, non è che occupino chissà che spazio).
    In questo caso non mi pare necessario avere un metodo in più per quelle poche righe di codice, io farei tutto nel costruttore, ma non è sbagliato tenerlo.
  • Re: Collegare listeners a pulsante

    Ansharja ha scritto:


    L'altra soluzione in realtà è quasi identica alla precedente, cambiano solo alcuni particolari, ma la logica è sempre quella: prendi il testo da un textfield, lo passi al metodo Converter.encrypt (testoDelPrimoTextField), setti il risultato all'altro textfield.
    Cambia solo il fatto che puoi dimenticarti di passare per un metodo esterno al costruttore (encryptString () andrebbe eliminato) e che non serve tenere due variabili d'istanza (da eliminare anche quelle), ti basta solo riferirti ai textfield che definisci e crei nel costruttore.

    Davvero, tutto qui, i metodi sono praticamente uguali, non parlerei nemmeno di due soluzioni diverse, l'unica differenza è la visibilità delle variabili.

    E' meglio fare tutto nel costruttore o passare per un altro metodo? Dipende. A volte anche dai gusti, nel senso che se il metodo fosse lungo molte righe potrebbe anche solo sembrarti più ordinato il fatto di scrivere un'unica riga nel listener (la chiamata a un metodo) e scrivere il corpo del metodo da un'altra parte.

    Sicuramente se tu potessi richiamare quel metodo in più modi, ovvero non solo cliccando il bottone ma anche ad esempio premendo un pulsante in una menubar in alto (non è questo il caso ma a volte, soprattutto per applicazioni più grandi, è comodo avere più di un modo per fare la stessa operazione), sarebbe più corretto avere un metodo separato, per non dover ripetere lo stesso codice più volte (esponendoti anche ad errori, problemi di manutenzione del codice etc.).
    D'altro canto senza passare per un metodo puoi risparmiarti le due variabili d'istanza (più che altro perché sono un po' superflue, non è che occupino chissà che spazio).
    In questo caso non mi pare necessario avere un metodo in più per quelle poche righe di codice, io farei tutto nel costruttore, ma non è sbagliato tenerlo.
    ahhh..ora mi è tutto più chiaro. Ti ringrazio davvero tanto, sei stato chiarissimo come sempre!
    Probabilmente tra un po' rivedrai un altra discussione aperta da me..perchè l'obiettivo finale di questo programma è leggere da un TXT(wordlist) delle parole, farci l hash e poi confrontarlo con quello inserito dall'utente(in pratica, decriptare l'hash).
    Mi metto a studiare la lettura da file in questi giorni..se non riesco, di sicuro chiederò qua
    Grazie ancora
Devi accedere o registrarti per scrivere nel forum
11 risposte