Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it L'avatar di cerza
    Registrato dal
    Oct 2009
    Messaggi
    310

    Gestione jradiobutton e ButtonGroup

    Salve a tutti,

    dovrei gestire un gruppo di radiobutton creati così

    codice:
    private ButtonGroup menu = new ButtonGroup();
    private JRadioButtonMenuItem radioButtonDay;
    private JRadioButtonMenuItem radioButtonHours;
    private JRadioButtonMenuItem radioButtonMinutes;
    
    
    
    radioButtonDay = new JRadioButtonMenuItem("Giorno"));
    radioButtonHours = new JRadioButtonMenuItem("Ore"));
    radioButtonMinutes = new JRadioButtonMenuItem("Minuti"));
    
    menu.add(radioButtonDay );
    menu.add(radioButtonHours );
    menu.add(radioButtonMinutes);
    a seguire ogni radioButton c'è una JTextField che deve essere o meno utilizzabile a seconda di quale radioButton è attivo in quel momento.
    Ho provato ad utilizzare il metodo isEnable() ed a seguito del risultato provavo a disabilitare/abilitare i campi successivi, ma non ha funzionato perché ovviamente tutti i radioButton risultano attivi.

    Avevo pensato di associare un listern al menu, ma non è andata neanche questa prova, come potrei fare?

    Grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    In che modo usavi il metodo isEnabled (penso che ti riferissi a quello)?

    Perché riferito al radio button non ha molto senso, ma potresti fare l'ovveride del metodo isEnabled () per i textfield, dove ritorni true o false a seconda che il corrispondente radio button sia selezionato (userai quindi isSelected () su ogni radio button).
    Questo in teoria dovrebbe funzionare ma penso dovrai richiamare il repaint sui textfield per rendere visibile la modifica ad ogni volta che cambi la selezione del radio button.

    Oppure potresti "ascoltare" ogni cambiamento di selezione, e modificare tu esplicitamente ogni textfield con il setEnabled (boolean value).

    Se vuoi provo a buttare giù un esempietto

  3. #3
    Utente di HTML.it L'avatar di cerza
    Registrato dal
    Oct 2009
    Messaggi
    310
    Grazie Ansharja,

    ho risolto implementando ActionListener, in questo modo

    codice:
    	@Override	public void actionPerformed(ActionEvent e) {
    		//Si indiviuda il radioButton selezionato
    		Object src = e.getSource();
    		if(src==radioButtonDay){
    			labelDay1.setEnabled(true);
    			fieldTextDay.setEnabled(true);
    			
    			labelHour1.setEnabled(false);
    			fieldTextHour.setEnabled(false);
    			
    			labelMinutes1.setEnabled(false);
    			fieldTextMinutes.setEnabled(false);
    		}
    
    
    		
    		if(src == radioButtonHours){
    			labelHour1.setEnabled(true);
    			fieldTextHour.setEnabled(true);
    			
    			labelDay1.setEnabled(false);
    			fieldTextDay.setEnabled(false);
    			
    			labelMinutes1.setEnabled(false);
    			fieldTextMinutes.setEnabled(false);
    		}
    
    
    		
    		if(src == radioButtonMinutes){
    			labelMinutes1.setEnabled(true);
    			fieldTextMinutes.setEnabled(true);
    			
    			labelDay1.setEnabled(false);
    			fieldTextDay.setEnabled(false);
    			
    			labelHour1.setEnabled(false);
    			fieldTextHour.setEnabled(false);
    		}
    		
    
    
    		
    	}
    Grazie a tutti

  4. #4
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Ok, magari potresti avere un tuo oggetto che contenga radio button, textfield e label (io setterei il testo direttamente sul radiobutton, ma non so come vuoi posizionare la label etc.) in modo da automatizzare il tutto a livello di oggetto, senza dover richiamare il setEnabled su ogni componente, avresti un codice più corto, pulito e mantenibile !

    E io userei un altro tipo di ascoltatore, un ItemListener ad esempio, anche se dovrebbe funzionare in ogni caso.

  5. #5
    Utente di HTML.it L'avatar di cerza
    Registrato dal
    Oct 2009
    Messaggi
    310
    Quote Originariamente inviata da Ansharja Visualizza il messaggio
    Ok, magari potresti avere un tuo oggetto che contenga radio button, textfield e label (io setterei il testo direttamente sul radiobutton, ma non so come vuoi posizionare la label etc.) in modo da automatizzare il tutto a livello di oggetto, senza dover richiamare il setEnabled su ogni componente, avresti un codice più corto, pulito e mantenibile !
    Si sarebbe sicuramente più pulito l'interfaccia grafica è un po' complicata, proverò comunque a seguire il tuo suggeriemento.


    Quote Originariamente inviata da Ansharja Visualizza il messaggio
    io userei un altro tipo di ascoltatore, un ItemListener ad esempio, anche se dovrebbe funzionare in ogni caso.
    In che modo useresti l'ItemListener, ci avevo provato prima dell'ActionListner ma non accadeva molto.
    Inoltre nella stessa schermata ho anche delle checkBox, come potrei verificare se le varie checkbox vengono selezionate?


    Grazie

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da cerza Visualizza il messaggio
    codice:
    	@Override	public void actionPerformed(ActionEvent e) {
    		//Si indiviuda il radioButton selezionato
    		Object src = e.getSource();
    		if(src==radioButtonDay){
    			labelDay1.setEnabled(true);
    			fieldTextDay.setEnabled(true);
    			
    			labelHour1.setEnabled(false);
    			fieldTextHour.setEnabled(false);
    			
    			labelMinutes1.setEnabled(false);
    			fieldTextMinutes.setEnabled(false);
    		}
    [ ..... ]
    Un codice del genere non solo è lungo e prolisso ma anche error-prone. Inoltre se aggiungessi un altro radiobutton in mutua-esclusione oltre ai 3 già presenti, non solo dovresti aggiungere un intero blocco if ma anche aggiungere codice negli altri 3 if!

    Una logica del genere, come minimo, la si risolve così:

    codice:
    public void actionPerformed(ActionEvent e) {
        Object src = e.getSource();
    
        labelDay1.setEnabled(src == radioButtonDay);
        fieldTextDay.setEnabled(src == radioButtonDay);
    
        labelHour1.setEnabled(src == radioButtonHours);
        fieldTextHour.setEnabled(src == radioButtonHours);
    
        // ecc...
    }
    (cioè, niente if!)
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Quote Originariamente inviata da cerza Visualizza il messaggio
    [..]
    In che modo useresti l'ItemListener, ci avevo provato prima dell'ActionListner ma non accadeva molto.
    Inoltre nella stessa schermata ho anche delle checkBox, come potrei verificare se le varie checkbox vengono selezionate?
    Puoi registrare su ogni radio button (funziona anche con i checkbox) un ItemListener, e all'interno del metodo (di cui devi fare l'ovveride) itemStateChanged (ItemEvent e) scegli cosa fare, in particolare puoi verificare se il componente è stato selezionato o meno in questo modo:

    codice:
    nomeDelTuoComponente.addItemListener (new ItemListener () {
        @Override public void itemStateChanged (ItemEvent e) {
            if (e.getStateChange () == ItemEvent.SELECTED)) {
                // ...
            }
            else {
                // ...
            }
        }
    })

    Per quanto riguarda il miglioramento del codice, non sapendo il design che hai scelto non è facile trovare subito la soluzione più adeguata, ma puoi prendere spunto da questo esempietto se vuoi:

    codice:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    public class RadioButtonTextField
    {
        public static void main (String [] a) {
            SwingUtilities.invokeLater (new Runnable () {
                @Override public void run () {
                    JFrame frame = new JFrame ("Radio Button Text Field");
                    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
                    frame.setContentPane (new MainPanel ());
                    frame.pack ();
                    frame.setLocationRelativeTo (null);
                    frame.setVisible (true);
                }
            });
        }
    }
    class MainPanel extends JPanel
    {
        private ButtonGroup buttonGroup;
        
        public MainPanel () {
            super (new GridLayout (3, 1, 0, 10));
            buttonGroup = new ButtonGroup ();
            add (createRadioButtonTextField ("Giorno"));
            add (createRadioButtonTextField ("Ora"));
            add (createRadioButtonTextField ("Minuto"));
            setBorder (new EmptyBorder (50, 50, 50, 50));
        }
        private JPanel createRadioButtonTextField (String text) {
            JRadioButton radioButton = new JRadioButton (text);
            buttonGroup.add (radioButton);
            JTextField textField = new JTextField (10);
            textField.setEnabled (radioButton.isSelected ());
            radioButton.addItemListener (new ItemListener () {
                @Override public void itemStateChanged (ItemEvent e) {
                    textField.setEnabled (e.getStateChange () == ItemEvent.SELECTED);
                }
            });
            JPanel panel = new JPanel (new BorderLayout (10, 0));
            panel.add (radioButton, BorderLayout.WEST);
            panel.add (textField, BorderLayout.CENTER);
            return panel;
        }
    }

    Immagino che tu avrai anche bisogno dei reference ai textfield in qualche punto per leggerne i valori, per quello parlavo di un oggetto (che qui non uso, creo tutto al volo nel metodo) che potrebbe inglobare il textfield, fornire un metodo per leggerne il testo (meglio rispetto ad avere un metodo che esponga direttamente il textfield a chiunque), etc., ma dipende appunto da quello che vuoi farci
    Ultima modifica di Ansharja; 20-09-2017 a 14:43

  8. #8
    Utente di HTML.it L'avatar di cerza
    Registrato dal
    Oct 2009
    Messaggi
    310
    Quote Originariamente inviata da Ansharja Visualizza il messaggio
    Puoi registrare su ogni radio button (funziona anche con i checkbox) un ItemListener, e all'interno del metodo (di cui devi fare l'ovveride) itemStateChanged (ItemEvent e) scegli cosa fare, in particolare puoi verificare se il componente è stato selezionato o meno in questo modo:

    codice:
    nomeDelTuoComponente.addItemListener (new ItemListener () {
        @Override public void itemStateChanged (ItemEvent e) {
            if (e.getStateChange () == ItemEvent.SELECTED)) {
                // ...
            }
            else {
                // ...
            }
        }
    })
    Innanzitutto grazie.
    Ma implementando ItemSelectable ci sono altri metodi, che non devo implementare per forza?
    Inoltre mi conviene fare una classe esterna alla classe dove creo i componenti grafici, in tal caso come faccio a capire se l'evento viene scatenato da un determinato radiobutton? perché al momento avendo implementato il metodo così

    codice:
    public void actionPerformed(ActionEvent e) {		// Si indiviuda il radioButton selezionato
    		Object src = e.getSource();
    
    
    		if (src == radioButtonDay) {
    se dovessi fare una classe esterna il riferimento a radioButtonDay non lo avrei più.
    Per quanto riguarda la pulizia del codice, ci posso pensare se rientro con la tempistica, altrimenti vale la regola "funziona allora è ok"

    Grazie

  9. #9
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Quote Originariamente inviata da cerza Visualizza il messaggio
    Ma implementando ItemSelectable ci sono altri metodi, che non devo implementare per forza?
    Di implementare ItemSelectable ci pensa il componente, non devi farlo tu.
    La classe AbstractButton implementa ItemSelectable, quindi ne ridefinisce tutti i metodi, in particolare addItemListener (ItemListener l).
    JRadioButton, JCheckBox, e le classi che derivano da JMenuItem (quindi anche JRadioButtonMenuItem) sono tutte sotto alla gerarchia di AbstractButton, quindi derivano il metodo addItemListener, che è quello che ho usato.

    Non ti devi quindi preoccupare di questo, tu aggiungi semplicemente al componente un listener come faresti con l'ActionListener, poi puoi farlo con una classe anonima o no, ma non c'è una grande differenza (il vantaggio della classe anonima è che "vede" le stesse variabili locali del metodo, quindi non devi passare alcun reference).

    Quote Originariamente inviata da cerza Visualizza il messaggio
    Inoltre mi conviene fare una classe esterna alla classe dove creo i componenti grafici, in tal caso come faccio a capire se l'evento viene scatenato da un determinato radiobutton? perché al momento avendo implementato il metodo così

    codice:
    public void actionPerformed(ActionEvent e) {        // Si indiviuda il radioButton selezionato
            Object src = e.getSource();
    
    
            if (src == radioButtonDay) {
    se dovessi fare una classe esterna il riferimento a radioButtonDay non lo avrei più.
    Questo dipende, hai davvero bisogno di avere il riferimento a radioButtonDay, etc.? Non posso saperlo senza vedere il resto del codice, ma su due piedi direi di no.
    Se lo scopo del radioButton è solo quello di attivare la corrispondente casella di testo, e non lo usi in altri parti del programma, avere il riferimento è superfluo, anzi ti costringe a mantenere delle variabili di istanza inutili.
    Se provi il codice d'esempio (se non l'hai già fatto, è direttamente compilabile ed eseguibile quindi ci metti un attimo), vedrai che il radio button in questione fa il suo dovere, ovvero attiva/disattiva il textfield corrispondente, e lo fa perché nel metodo è creato in relazione a quel determinato textfield, e aggiunge un listener che deve attivare/disattivare solo quello.

    Se a fronte dell'attivazione/disattivazione del radiobutton devi fare qualcosa di specifico, allora il reference lo puoi comunque tenere all'interno di questa classe contenitore di cui parlavamo, ma devi appunto valutare se sia necessario.

    Come detto in precedenza, invece, da qualche parte avrai bisogno di mantenere il reference ai vari textfield, perché di quelli dovresti poterne leggere il testo in futuro. Io lo farei in questo modo, modificando leggermente il codice di sopra (cambio solo la classe MainPanel):

    codice:
    class MainPanel extends JPanel
    {
        private ButtonGroup buttonGroup;
        private RadioButtonTextFieldPanel giorno;
        private RadioButtonTextFieldPanel ora;
        private RadioButtonTextFieldPanel minuto;
        
        public MainPanel () {
            super (new GridLayout (3, 1, 0, 10));
            buttonGroup = new ButtonGroup ();
            add (giorno = new RadioButtonTextFieldPanel ("Giorno"));
            add (ora = new RadioButtonTextFieldPanel ("Ora"));
            add (minuto = new RadioButtonTextFieldPanel ("Minuto"));
            setBorder (new EmptyBorder (50, 50, 50, 50));
        }
        
        private class RadioButtonTextFieldPanel extends JPanel
        {
            private JTextField textField;
            
            public RadioButtonTextFieldPanel (String radioButtonLabel) {
                super (new BorderLayout (10, 0));
                JRadioButton radioButton = new JRadioButton (radioButtonLabel);
                buttonGroup.add (radioButton);
                textField = new JTextField (10);
                textField.setEnabled (radioButton.isSelected ());
                radioButton.addItemListener (new ItemListener () {
                    @Override public void itemStateChanged (ItemEvent e) {
                        textField.setEnabled (e.getStateChange () == ItemEvent.SELECTED);
                    }
                });
                add (radioButton, BorderLayout.WEST);
                add (textField, BorderLayout.CENTER);
            }
            private String getText () {
                return textField.getText ();
            }
        }
    }

    Come vedi ora ho creato l'oggetto di cui parlavo, che incapsula il textfield e permette di leggerne il contenuto. Da MainPanel quindi sarai in grado di leggere ogni valore scrivendo ad esempio:

    codice:
    String giornoText = giorno.getText ();
    Dove ovviamente quel getText () è il metodo creato in RadioButtonTextFieldPanel, se il nome fa confusione si può cambiare ovviamente.
    In questa classe potresti anche salvare il reference al radiobutton, se ti dovesse servire.

  10. #10
    Utente di HTML.it L'avatar di cerza
    Registrato dal
    Oct 2009
    Messaggi
    310
    Grazie del suggerimento, in effetti senza if è molto meglio

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 © 2024 vBulletin Solutions, Inc. All rights reserved.