2011-12-26 9 views
5

Próbuję skonfigurować JSpinner za pomocą SpinnerNumberModel o wartości = 0.0005, min = 0.0, max = 1.0, a rozmiar kroku = 0.0005. Jednak gdy tworzę spinner z tymi parametrami, obserwuję bardzo dziwne zachowanie. Zamiast zaczynać od 0,0005 i zwiększać o 0,0005 za każdym kliknięciem strzałki w górę, wartość wydaje się wynosić 0.Nieparzysty zachowanie SpinnerNumberModel w Javie

Aby upewnić się, że nie jest to tylko kwestia formatowania, wydrukowałem wartość przędzarki po każda zmiana zdarzenia. Z pewnością za każdym kliknięciem strzałki w górę konsola pokazuje wartość jako 0, a następnie 0,0005, bez względu na to, ile razy kliknięcie zostało kliknięte.

Poniżej znajduje się kod, którego użyłem do przetestowania tego, w tym spinner o nieco innych wartościach, który działa dobrze dla celów porównawczych.

import javax.swing.*; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import java.awt.*; 

public class Main { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setSize(200, 80); 
     JPanel panel = new JPanel(); 
     panel.setLayout(new BorderLayout()); 
     final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005)); 
     final JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0.05, 0.0, 1.0, 0.05)); 
     panel.add(spinner1, BorderLayout.NORTH); 
     panel.add(spinner2, BorderLayout.SOUTH); 
     frame.add(panel); 
     spinner1.addChangeListener(new ChangeListener() { 
      public void stateChanged(ChangeEvent e) { 
       System.out.println("spinner1: " + ((Number) spinner1.getValue()).doubleValue()); 
      } 
     }); 
     spinner2.addChangeListener(new ChangeListener() { 
      public void stateChanged(ChangeEvent e) { 
       System.out.println("spinner2: " + ((Number) spinner2.getValue()).doubleValue()); 
      } 
     }); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} 

Czy ktoś może mi wytłumaczyć dlaczego spinner2 działa zgodnie z przeznaczeniem, ale spinner1 nie?

Dzięki.

Edycja: Dziękuję Peter za zaznaczenie, że formatowanie pola tekstowego pokrętła ma wpływ na zapisaną wartość. Aby pierwszy wirnik działał zgodnie z zamierzeniami, dodałem linię: spinner1.setEditor(new JSpinner.NumberEditor(spinner1, "0.0000"));.

+0

Dzięki za wejście. Rzeczywisty projekt, w którym po raz pierwszy spotkałem się z problemem, jest znacznie bardziej złożony. Kod, który tu zamieściłem, to przykład bardzo zdrowego szkieletu demonstrującego problem. –

+0

W porządku, edytowałem przykład, aby dołączyć JPanel do przechowywania dwóch spinnerów. Niestety, wciąż otrzymuję takie same wyniki dla pierwszego spinnera. –

+0

Używam JPanela i problem nadal istnieje. Próbowałem również (0,001, 0,0001), jak również model JSpinner (wartość, krok) i (0,0001, 0,001). Ani działa. Ale zamiast tego działa (0,001, 0,001). Czy to oznacza problem z dokładnością prezentacji JSpinner? – xorange

Odpowiedz

9

Problem w tym jest w JFormattedTextField używanej przez spinner. W tym edytorze można znaleźć:

public void commitEdit() throws ParseException { 
    AbstractFormatter format = getFormatter(); 

    if (format != null) { 
     setValue(format.stringToValue(getText()), false, true); 
    } 
} 

wyświetlacz spinner 0,0005 a 0,0, jeśli przyrost najpierw umieścić 0,0 w modelu, a następnie zwiększa się do 0,0005, to wydarzenie rzeczywiście oddaje to jednak swoją textfield widzi tylko 0,0

rozwiązaniem będzie więc zmiana formatowania pola tekstowego przędzarki.

można overide redaktorowi

final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005)) { 
     @Override 
     protected JComponent createEditor(SpinnerModel model) 
     { 
     return new NumberEditor(this, "0.0000");//needed decimal format 
     } 
    }; 
+0

Interesujące ... Zakładałem, że spinner zachowuje taką samą wartość podwójnej precyzji, niezależnie od tego, jak został sformatowany w polu tekstowym. Dzięki! –

+0

Dzięki Peter. Zmieniłem moje pytanie, dodając dodatkową linię, która służy podobnemu celowi. –