2010-10-16 17 views
31

jSpinner değeri değiştirildiğinde hemen güncellemeyi nasıl yapılır.JSpinner Değer değişikliği Olaylar

ChangeListener listener = new ChangeListener() { 
    public void stateChanged(ChangeEvent e) { 
    jLabel.setText(e.getSource()); 
    } 
}; 

spinner1.addChangeListener(listener); 

Yukarıdaki kod güncelleştirmek her yerde tekrar tıklamanız gerekir, otomatik etiket metnini değiştirmek etmez.

+1

dahaki sefer bir SSCCE (http://sscce.org) gönderin bu yeni sürümünü kullanabilirsiniz olmasıdır Kodu nasıl kullandığınızın bağlamını görebiliriz. – camickr

+0

Aynı sorun, henüz bir çözüm görmedim. Odağı JSpinner kayboluncaya kadar ChangeListener yöntemi çağrılmaz. Keylisteners ile bir geçici çözüm yaptım, ama bu çirkin – spuas

cevap

7

Gösterdiğiniz kod doğru görünüyor. Referans için işte bir örnek.

Ek: JSpinner'un odağı varken, sol ve sağ ok tuşları işareti taşır. Yukarı ok artışları ve aşağı ok, karet içeren alanı azaltır. Değişim, hem eğiricide hem de etikette (etkili) eş zamanlıdır.

JSpinner.DateEditor'un JFormattedTextField numarasına erişmek için, üst öğenin getTextField() yöntemini kullanın. Etiketi istenen şekilde güncellemek için uygun bir kulakçı dinleyici veya metin girişi dinleyicisi kullanılabilir.

Ek: here numaralı telefonun önerildiği gibi setCommitsOnValidEdit'u güncellemeyi güncelleyin. Burada

import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.util.Calendar; 
import java.util.Date; 
import javax.swing.JFormattedTextField; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSpinner; 
import javax.swing.JSpinner.DateEditor; 
import javax.swing.SpinnerDateModel; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import javax.swing.text.DefaultFormatter; 

/** 
* @see https://stackoverflow.com/questions/2010819 
* @see https://stackoverflow.com/questions/3949518 
*/ 
public class JSpinnerTest extends JPanel { 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame f = new JFrame("JSpinnerTest"); 
       f.add(new JSpinnerTest()); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 

    public JSpinnerTest() { 
     super(new GridLayout(0, 1)); 
     final JLabel label = new JLabel(); 
     final JSpinner spinner = new JSpinner(); 
     Calendar calendar = Calendar.getInstance(); 
     Date initDate = calendar.getTime(); 
     calendar.add(Calendar.YEAR, -5); 
     Date earliestDate = calendar.getTime(); 
     calendar.add(Calendar.YEAR, 10); 
     Date latestDate = calendar.getTime(); 
     spinner.setModel(new SpinnerDateModel(
      initDate, earliestDate, latestDate, Calendar.MONTH)); 
     DateEditor editor = new JSpinner.DateEditor(spinner, "MMM yyyy"); 
     spinner.setEditor(editor); 
     JFormattedTextField jtf = editor.getTextField(); 
     DefaultFormatter formatter = (DefaultFormatter) jtf.getFormatter(); 
     formatter.setCommitsOnValidEdit(true); 
     spinner.addChangeListener(new ChangeListener() { 

      @Override 
      public void stateChanged(ChangeEvent e) { 
       JSpinner s = (JSpinner) e.getSource(); 
       label.setText(s.getValue().toString()); 
      } 
     }); 
     label.setText(initDate.toString()); 
     this.add(spinner); 
     this.add(label); 
    } 
} 
+0

Bu doğru ama yukarıda belirtilen sorunu çözmez: el ile düzenleme yaparken, stateChanged sadece JSpinner odağı kaybeden sonra veya kullanıcı Enter tuşuna basar ama her biri ile değil Anahtar yazılan – spuas

+0

Cevabınızda hala bir çözüm yok. –

+0

@Andrei Vajna II: Aşağı oylamayı açıkladığınız için teşekkür ederim, ancak kullanıcı236501'e erteleyeceğim. Örneği doğruladım ve sahte bir ithalatı kaldırmak için güncelledim. – trashgod

2

Sorun klavyeden girerek manuel JSpinner değerini düzenlerken odak JSpinner tarafından kayıp veya preslenmiş Enter tuşu kadar kadar, stateChanged olayını harekete olmasıdır.

Değeri yüklemek isterseniz, her bir tuşanumarasına sahip olan JSpinner numaralarını içeren bir KeyListener gerekir.

Ben JSpinnerSpinnerNumberModel bir ile burada bir örnek bırakın:

formatter.setCommitsOnValidEdit(true); 

:

JSpinner spinner= new JSpinner(); 
spinner.setModel(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1)); 
spinner.addChangeListener(new ChangeListener() { 
    @Override 
    public void stateChanged(ChangeEvent e) { 
     jLabel.setText(spinner.getValue()); 
    } 
}); 
final JTextField jtf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); 
jtf.addKeyListener(new KeyAdapter() { 
    @Override 
    public void keyReleased(KeyEvent e) { 
     String text = jtf.getText().replace(",", ""); 
     int oldCaretPos = jtf.getCaretPosition(); 
     try { 
      Integer newValue = Integer.valueOf(text); 
      spinner.setValue(newValue); 
      jtf.setCaretPosition(oldCaretPos); 
     } catch(NumberFormatException ex) { 
      //Not a number in text field -> do nothing 
     } 
    } 
}); 
+1

hey, bugün ilk kez (bu işin sonuna gelindiğinde): keylisteners kullanmayın - yeterince iyi değiller, çünkü alanın içine yapıştırılan metni özlüyorlar – kleopatra

43

cevap spinner en editörü bir çocuk JFormattedTextField kullanılan biçimlendirici yapılandırmaktır Ne yazık ki, bu kişinin eline geçmesi, giriş cümlesi kadar uzun ve kirli:

final JSpinner spinner = new JSpinner(); 
    JComponent comp = spinner.getEditor(); 
    JFormattedTextField field = (JFormattedTextField) comp.getComponent(0); 
    DefaultFormatter formatter = (DefaultFormatter) field.getFormatter(); 
    formatter.setCommitsOnValidEdit(true); 
    spinner.addChangeListener(new ChangeListener() { 

     @Override 
     public void stateChanged(ChangeEvent e) { 
      LOG.info("value changed: " + spinner.getValue()); 
     } 
    }); 

Biraz (ama fazla değil) temizleyici yolu NumberEditor alt sınıf ve CONFIG

+1

GetComponent'in ayrıntılarını kullanmak yerine, Oracle exmaples, JFormattedTextField: public JFormattedTextField getTextField (JSpinner spinner) {return ((JSpinner.DefaultEditor) spinner.getEditor()) getTextField(); } 'Hata denetimini kaldırdım ama bu başka bir olasılık. –

0

Ben yüzden bazı kuralları çiğnemenin olabilir ve ben geç olabilir yeniyim sağlayan bir yöntem ortaya çıkarmak için olabilir. Ama bazı cevapları biraz kafa karıştırıcı buldum, bu yüzden NetBeans IDE'de oynadım ve jformunuza yerleştirilmiş jspinner GUI bileşenine sağ tıklarsanız ve olaylar-> değişime giderseniz kodun sizin için oluşturulacağını keşfettim.

1

Geç bir yanıt olabilir, ancak yaklaşımımı kullanabilirsiniz.
spuas yukarıda belirtilen sorun, stateChanged olayının yalnızca odak kaybolduğunda veya Enter tuşuna basıldığında tetiklendiğidir.
KeyListeners'ı kullanmak da iyi bir fikir değildir.
Bunun yerine DocumentListener kullanmak daha iyi olurdu.Biraz spuas örneğini değiştirilmiş ve ben ne var:

JSpinner spinner= new JSpinner(); 
spinner.setModel(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1)); 
final JTextField jtf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); 
     jtf.getDocument().addDocumentListener(new DocumentListener() {    

     private volatile int value = 0; 

     @Override 
     public void removeUpdate(DocumentEvent e) { 
      showChangedValue(e);  
     } 

     @Override 
     public void insertUpdate(DocumentEvent e) { 
      showChangedValue(e);     
     } 

     @Override 
     public void changedUpdate(DocumentEvent e) { 
      showChangedValue(e);  
     } 

     private void showChangedValue(DocumentEvent e){ 
      try { 
       String text = e.getDocument().getText(0, e.getDocument().getLength()); 
       if (text==null || text.isEmpty()) return; 
        int val = Integer.parseInt(text).getValue(); 
       if (value!=val){ 
        System.out.println(String.format("changed value: %d",val));    
        value = val; 
       }  
      } catch (BadLocationException | NumberFormatException e1) { 
          //handle if you want 
      }   
     } 
}); 
0

son cevap biraz daha esnek hale getirmek için biraz yeniden düzenlenebilir. Bu yeni MyJSpinner'ı herhangi bir JSpinner yerine kullanabilirsiniz. En büyük değişiklik bu kadar JSpinner herhangi esas modelin (int, double, byte, vb)

public class MyJSpinner extends JSpinner{ 
     boolean setvalueinprogress=false; 
     public MyJSpinner() 
     { 
      super(); 
      final JTextField jtf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); 
      jtf.getDocument().addDocumentListener(new DocumentListener() {    

        @Override 
        public void removeUpdate(DocumentEvent e) { 
         showChangedValue(e);  
        } 

        @Override 
        public void insertUpdate(DocumentEvent e) { 
         showChangedValue(e);     
        } 

        @Override 
        public void changedUpdate(DocumentEvent e) { 
         showChangedValue(e);  
        } 

        private void showChangedValue(DocumentEvent e){ 
         try { 
          if (!setvalueinprogress) 
           MyJSpinner.this.commitEdit();  
         } catch (NumberFormatException | ParseException ex) { 
             //handle if you want 
          Exceptions.printStackTrace(ex); 
         }  
        } 
      }); 
     } 

    @Override 
    public void setValue(Object value) { 
     setvalueinprogress=true; 
     super.setValue(value); 
     setvalueinprogress=false; 
    } 

}