Newsgroup: it.comp.java
Titolo: consiglio da esperti  e comportamento strano di keyevent

Buonasera vi chiedo un consiglio su come procedere per ottenere la
seguente cosa.
Voglio realizzare una classe che extends jpanel in cui ci sono delle
jtextfield che si aggiornano automaticamente
quando viene modificato il valore di ogniuna , esempio scrivo un
numero nella prima e automaticamente cambia il valore all'interno
della seconda e della terza (tramite degli algoritmi ovvio) , scrivo
un numero nella seconda e cambia la terza, e così via...
Avevo pensato di agire cosi: realizzare un listener personalizzato che
estendeva keyadapter (tanto mi bastava il metodo keytyped. All'interno
della classe Jpanel,quella che contiene le jtextfield registro ogni
singola Jtextfield così passando al costruttore anche ogni singolo
oggetto in modo che lo incapsuli e riesca a modificarne i dati,
 
public class MyPercentCalculator extends javax.swing.JPanel {
    public MyPercentCalculator() {
           ......
        MyPercentCalculatorListener l = new
MyPercentCalculatorListener(txt1,txt2,txt3);
        txt1.addKeyListener(l);
        txt2.addKeyListener(l);
        txt3.addKeyListener(l);
.......
il listener cosi scritto
public class MyPercentCalculatorListener extends KeyAdapter{
    private JTextField value1,value2,value3;
    public MyPercentCalculatorListener(JTextField value1,JTextField
value2,JTextField value3){
        this.value1 = value1;
        this.value2 = value2;
        this.value3 = value3;
    }
    @Override
    public void keyPressed(KeyEvent e) {
         System.out.println(value1.getText());
        .........
 
ho notato che il listener si comporta in modo strano ossia quando
scrivo un numero nella textfileld1 si scaturisce giustamente l'evento
keyevent, ma il valore che ritorna non è quello realmente contenuto
nella textfield , ma precedente, quindi digito un'altro tasto e mi da
il valore che mi avrebbe dovuto dare prima, non so se sono stato
chiaro; questo secondo me è molto strano....
anzichè un keylistener ho provato ad utilizzare un document listener e
le cose vanno meglio , ma secondo me concettualmente dovrebbe
funzionare anche con keylistener.
Vi chiedo quindi di darmi una spiegazione secondo voi, e soprattutto
come voi invece approccereste se dovreste realizzare una cosa del
genere per esempio avevo anche pensato di creare dei fields pubblici
nella classe panel tramite i quali assegnare all'interno del listener
i valori esempio
 
public class MyPercentCalculator extends javax.swing.JPanel {
    public MyPercentCalculator() {
        public JTextField text1 ;
        public JTextField text2 ;
   ......
        MyPercentCalculatorListener l = new
MyPercentCalculatorListener(this);
        txt1.addKeyListener(l);
        txt2.addKeyListener(l);
        txt3.addKeyListener(l);
.......
il listener cosi scritto
public class MyPercentCalculatorListener extends KeyAdapter{
 
    public MyPercentCalculatorListener(MyPercentCalculator pcalc){
          this.pcalc = pcalc;
...........................
    }
    @Override
    public void keyPressed(KeyEvent e) {
          pcalc.txt1setExt("");
..................
però nn mi  piace rinunciare all'incapsulamento e utilizzare variabili
pubbliche,
ditemi voi grazie...

 ditemi voi grazie...
 
Da me funziona bene KeyEvent, ti ho fatto questo esempio guarda se ti puo' andare bene, Ciao.
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
class DemoKeyAdapter extends KeyAdapter {
     private JTextField dest;
     public DemoKeyAdapter(JTextField dest) {
         this.dest = dest;
     }
     public void keyTyped(KeyEvent e) {
         dest.setText(dest.getText() + e.getKeyChar());
     }
}
class Demo extends JFrame {
     public Demo() {
         setSize(300, 200);
         setLayout(new FlowLayout());
         JTextField tf1 = new JTextField(20);
         JTextField tf2 = new JTextField(20);
         tf1.addKeyListener(new DemoKeyAdapter(tf2));
         add(tf1);
         add(tf2);
     }
     public static void main(String args[]) {
         new Demo().setVisible(true);
     }
}

On 27 Gen, 01:01, coder <c...@nomail.not> wrote:

Ciao ti ringrazio molto per la risposta, ho provato la tua classe e
funziona per quello per cui è stata progettata , ma non è quello di
cui mi occorre.
infatti
 dest.setText(dest.getText() + e.getKeyChar());
non fa altro che aggiungere il carattere digitato da tastiera alla
testbox2, a me quello che invece serve è considerare tutto il valore
della prima text box e aggiornare tutta la seconda esempio
se nella prima textbox c'è scritto 10 e io metto 2 al posto dello 0 ,
voglio che venga considerato 12 e in base a questo aggiorno la
seconda....non so se mi spiego

 cui mi occorre.
 
Avevo capito male, versione 0.2 :)
 
class DemoKeyAdapter extends KeyAdapter {
     private JTextField dest;
     public DemoKeyAdapter(JTextField dest) {
         this.dest = dest;
     }
     public void keyReleased(KeyEvent e) {
         JTextField source = (JTextField)e.getSource();
         dest.setText(source.getText());
     }
}
 
Ho usato la keyReleased.
Probabilmente la keyReleased e la keyPressed sono chiamate prima che il buffer interno (quello che ottieni getText())
sia stato aggiornato con l'ultimo carattere e quindi non andavano bene. Con la keyReleased il buffer e' aggiornato.
Non so, magari ci sono anche altri eventi della JTextField da ascoltare, non ho approfondito. Ciao.
 

 Probabilmente la keyReleased e la keyPressed
 
Volevo scrivere
Probabilmente la keyTyped e la keyPressed


Probabilmente è come dici tu, ora la provo e ti dico,
nel frattempo che ne pensi della situazione che ho illustrato sopra
come alternativa
cioè quella di utilizzare le jtexfield pubbliche e di passare al
listener l'oggetto panel che li contiene
in modo che possa prendere direttamente i valori e aggiornarli , a me
personalmente
non piace, ma tu che dici ?

 non piace, ma tu che dici ?
 
Neanche a me piace.
In generale gli oggetti dovrebbero avere tra di loro la minima conoscenza
necessaria per funzionare, non di piu'.
In questo c'e' un JPanel passato di troppo.
Ciao.

On 27 Gen, 20:56, coder <c...@nomail.not> wrote:

sono d'accordo, l'incapsulamento è una delle prerogative di java....
grazie del tuo contributo
ciao

On 27 Gen, 20:56, coder <c...@nomail.not> wrote:

sono d'accordo l'incapsulamento è una delle prerogative di java....
 
Ultima cosa, anzichè un keylistener, che ne dici di un
documentlistener, l'ho provato e funziona...
 

 oggetto in modo che lo incapsuli e riesca a modificarne i dati,
Poiche' il JTextField estende JTextComponent, e quindi ne condivide il 
modello MVC, sarebbe forse preferibile utilizzare un DocumentListener, 
al quale vengono comunicati gli eventi della view.

 il 26.01.2012 23:27, Scrive 
godme...@tiscali.it
 150390368:> Buonasera vi chiedo un consiglio su come procedere per ottenere la

non comprendo bene questa tua affermazione, cioè sono d'accordo sul
fatto che JTextField
estende JTextComponent però non capisco il PERCHè sarebbe meglio
utilizzare un document listener
quando le JTextField hanno il loro listener o adapter (meglio ancora)
diretto , spiegati meglio
ciao

il 06.02.2012 12:00, Scrive 
godm...@tiscali.it
 104846272:

Beh, la mia era solo un'ipotesi. Dipendentemente dall'uso che l'utente 
fara' dei tuoi JTextField, ascoltare gli eventi keytyped potrebbe non 
essere sufficiente. Ad esempio se l'utente scrive 'abcde' poi sposta il 
cursore tra la b e la c, poi cancella la b tramite tasto back-space o 
cancella la c tramite tasto canc, la tua keytyped non ti dirà dov'era il 
cursore e soprattutto non ti dirà il risultato finale dell'operazione, 
mentre il DocumentEvent ti dice sia l'offset che la lunghezza della 
modifica. Inoltre i tre metodi di DocumentListener (changedUpdate 
insertUpdate e removeUpdate) ti aiuteranno a capire cos'è successo nel 
model (il Document).
 

 il 06.02.2012 12:00, Scrive 
godme...@tiscali.it
 104846272:

Ti ringrazio per la spiegazione, effettivamente quello che dici è da
prendere in considerazione
 
Grazie tutti a voi che siete intervenuti.


Allora su giusto suggerimento del Dr Ugo 
ho voluto utilizzare un Document listener...non l'avessi mai fatto.....!!!!
Vi spiego: ho una classe così realizzata:
un pannello che implementa DocumentListener. All'interno del pannello ci sono tre jtextfield ed ogniuno registra il proprio listener
 
txt1.getDocument().addDocumentListener(this);
txt2.getDocument().addDocumentListener(this);
txt3.getDocument().addDocumentListener(this);
 
nel metodo 
public void insertUpdate(DocumentEvent e) {
 
...
 
inserisco delle operazioni. 
Mi sono però accorto di questo strano comportamento:
l'evento si verifica sia quando la textfield prende il focus che quando lo perde
quindi quano mi sposto da una textfield all'altra inevitabilmente si verifica l'evento sia per la casella che perde il focus che per quella che lo acquisisce, e poi tutte le volte che digito qualcosa , a me serve però che si verifichi solo su inserimento
come posso fare ??


Buongiorno a tutti, volevo aggiornarvi a seguito di alcune prove che ho fatto : mi sono accorto che l'effetto da me citato è dovuto al formatter delle jtextfield. 
Infatti sia quando la jtextfield acquista il focus, sia quando lo perde il formatter scrive; posso dirlo perchè ho inserito un controllo che mi dica quanti caratteri vengono scritti ed effettivamente ogni volta che acquista o perde il focus vengono segnalati 4 caratteri infatti il valore di partenza è 0.00 
a questo punto ho tolto il valore di default e la formattazione e non si verificava nessun documentevent;
pertanto il problema rimane, come faccio a intercettare esclusivamente gli eventi scaturiti 
da immissione da tastiera ?
 
ringrazio fin da ora a chi contribuirà con il suo aiuto