2014-09-17 9 views
5

Testowałem pokrętłem w Java 8u40tylko wstawić numery w Spinner Kontroli

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.Spinner; 
import javafx.scene.control.SpinnerValueFactory; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 

public class MainApp extends Application 
{ 
    public static void main(String[] args) 
    { 
     Application.launch(args); 
    } 

    @Override 
    public void start(Stage stage) 
    { 
     final Spinner spinner = new Spinner(); 

     spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 10000)); 
     spinner.setEditable(true); 

     GridPane grid = new GridPane(); 
     grid.setHgap(10); 
     grid.setVgap(10); 
     grid.setPadding(new Insets(10)); 

     int row = 0; 

     grid.add(new Label("Spinner:"), 0, row); 
     grid.add(spinner, 1, row); 

     Scene scene = new Scene(grid, 350, 300); 

     stage.setTitle("Hello Spinner"); 
     stage.setScene(scene); 
     stage.show(); 
    } 
} 

Jak mogę wstawić tylko numer w polu sterowania tarczy?

Teraz mogę wstawiać cyfry i tekst. Czy istnieje przykład, który można wykorzystać jako przykład?

+0

Czy znalazłeś lepsze rozwiązanie dla swojego problemu? – babyinEclipse

Odpowiedz

4
  • ponieważ Spinner wykorzystuje TextField jako redaktor, użytkownicy mogą wstawić dowolny ciąg do turbinki
  • dopiero po użytkownik wciśnie klawisz Enter następnie modelu Spinners (SpinnerValueFactory realizacja) sprawdza wprowadzone przez użytkownika

więc trzeba aby dodać walidację do edytora Spinners kodem:

// imports omitted 

public class MainApp extends Application { 

protected static final String INITAL_VALUE = "0"; 

public static void main(String[] args) { 
    Application.launch(args); 
} 

@Override 
public void start(Stage stage) { 
    final Spinner spinner = new Spinner(); 

    spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 10000, 
      Integer.parseInt(INITAL_VALUE))); 
    spinner.setEditable(true); 

    EventHandler<KeyEvent> enterKeyEventHandler; 

    enterKeyEventHandler = new EventHandler<KeyEvent>() { 

     @Override 
     public void handle(KeyEvent event) { 

      // handle users "enter key event" 
      if (event.getCode() == KeyCode.ENTER) { 

       try { 
    // yes, using exception for control is a bad solution ;-) 
      Integer.parseInt(spinner.getEditor().textProperty().get()); 
       } 
       catch (NumberFormatException e) { 

        // show message to user: "only numbers allowed" 

        // reset editor to INITAL_VALUE 
        spinner.getEditor().textProperty().set(INITAL_VALUE); 
       } 
      } 
     } 
    }; 

    // note: use KeyEvent.KEY_PRESSED, because KeyEvent.KEY_TYPED is to late, spinners 
    // SpinnerValueFactory reached new value before key released an SpinnerValueFactory will 
    // throw an exception 
    spinner.getEditor().addEventHandler(KeyEvent.KEY_PRESSED, enterKeyEventHandler); 

    GridPane grid = new GridPane(); 
    grid.setHgap(10); 
    grid.setVgap(10); 
    grid.setPadding(new Insets(10)); 

    int row = 0; 

    grid.add(new Label("Spinner:"), 0, row); 
    grid.add(spinner, 1, row); 

    Scene scene = new Scene(grid, 350, 300); 

    stage.setTitle("Hello Spinner"); 
    stage.setScene(scene); 
    stage.show(); 
} 
} 
  • spróbuj nie liczbach: CO de zastąpi Spinners zawartość edytora z INITIAL_VALUE
  • spróbować z numerami z granicy, błystki model będzie zresetować Spinners edytor do prawidłowej wartości
5

Nie do końca pewien o wymogu - zakładając, że chcesz, aby zapobiec wprowadzaniu znaków który nie przeanalizowałby prawidłowego numeru.

Jeśli tak, to użycie TextFormatter w edytorze Spinner przychodzi na ratunek: dzięki niemu będziesz monitorować każdą zmianę tekstu i zaakceptować lub odrzucić. Decyzja jest zawarta w filtrze formatyzatora. Bardzo prosta wersja (zdecydowanie więcej do zrobienia, zobacz DefaultFormatter Swinga)

// get a localized format for parsing 
NumberFormat format = NumberFormat.getIntegerInstance(); 
UnaryOperator<TextFormatter.Change> filter = c -> { 
    if (c.isContentChange()) { 
     ParsePosition parsePosition = new ParsePosition(0); 
     // NumberFormat evaluates the beginning of the text 
     format.parse(c.getControlNewText(), parsePosition); 
     if (parsePosition.getIndex() == 0 || 
       parsePosition.getIndex() < c.getControlNewText().length()) { 
      // reject parsing the complete text failed 
      return null; 
     } 
    } 
    return c; 
}; 
TextFormatter<Integer> priceFormatter = new TextFormatter<Integer>(
     new IntegerStringConverter(), 0, filter); 

spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(
     0, 10000, Integer.parseInt(INITAL_VALUE))); 
spinner.setEditable(true); 
spinner.getEditor().setTextFormatter(priceFormatter); 
+0

dół, czy chcesz wyjaśnić? – kleopatra

+0

Nie jest to oryginalne rozwiązanie niższego rzędu, ale oto moje wyjaśnienie: twoje dosłowne rozwiązanie nie zadziałało. Kiedy próbowałem go użyć, widoczna zawartość tarczy nie zmieniła się podczas wirowania. Wprawdzie spieszyłem się i nie doszedłem do głębi (nigdy nie sprawdzałem domyślnej wartości Swinga, jak sugerowałeś), ale fakt, że twój kod złamał podstawową mechanikę Spinnera był niefortunny - i na koniec uciekłam się do TextFields z walidacją na złożenie wniosku, błędy wyświetlane w oknie dialogowym, co było niezwykle smutnym, aczkolwiek jakoś praktycznym rozwiązaniem. –

+0

@GiulioPiancastelli dziękuję za twoją opinię :-) Minęło trochę czasu, ale stosunkowo pewne, że działało w momencie, gdy pisałem odpowiedź, przynajmniej nie mogę sobie wyobrazić, że nie sprawdziłbym standardowego zachowania - dzieje się jednak gówno. Może spróbuj jednego z tych dni i zaktualizuj w razie potrzeby. – kleopatra