Руководство JavaFX Spinner
View more Tutorials:
Spinner похожи на ComboBox или List, он позволяет пользователю выбрать из набора значений. Похоже на ComboBox можно редактировать, Spinner так же позволяет пользователю добавлять значения. В отличии от ComboBox, Spinner не имеет выпадающий список, не отображает возможный спискок, в одно время он отображает только настоящее значение. Обычно используется вместо ComboBox или List когда имеется большой набор возможных значений.


Структура Spinner:

Простой пример ниже изображает Spinner с числовыми значениями.

SpinnerDemo.java
package org.o7planning.javafx.spinner; 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.FlowPane; import javafx.stage.Stage; public class SpinnerDemo extends Application { @Override public void start(Stage stage) { Label label = new Label("Select Level:"); final Spinner<Integer> spinner = new Spinner<Integer>(); final int initialValue = 3; // Value factory. SpinnerValueFactory<Integer> valueFactory = // new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 5, initialValue); spinner.setValueFactory(valueFactory); FlowPane root = new FlowPane(); root.setHgap(10); root.setVgap(10); root.setPadding(new Insets(10)); root.getChildren().addAll(label, spinner); Scene scene = new Scene(root, 400, 200); stage.setTitle("JavaFX Spinner (o7planning.org)"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { Application.launch(args); } }
Пример 2:

SpinnerDemo2.java
package org.o7planning.javafx.spinner; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; 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.FlowPane; import javafx.stage.Stage; public class SpinnerDemo2 extends Application { @Override public void start(Stage stage) { Label label = new Label("Select Month:"); ObservableList<String> months = FXCollections.observableArrayList(// "January", "February", "March", "April", // "May", "June", "July", "August", // "September", "October", "November", "December"); final Spinner<String> spinner = new Spinner<String>(); // Value factory. SpinnerValueFactory<String> valueFactory = // new SpinnerValueFactory.ListSpinnerValueFactory<String>(months); // Default value valueFactory.setValue("February"); spinner.setValueFactory(valueFactory); FlowPane root = new FlowPane(); root.setHgap(10); root.setVgap(10); root.setPadding(new Insets(10)); root.getChildren().addAll(label, spinner); Scene scene = new Scene(root, 400, 200); stage.setTitle("JavaFX Spinner (o7planning.org)"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { Application.launch(args); } }
JavaFX Spinner может настроить позицию и направление кнопке стрелки, если не настроено, по умолчанию будет направо и вертикальное направление.

SpinnerStyleDemo.java
package org.o7planning.javafx.spinner; import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Spinner; import javafx.scene.layout.FlowPane; import javafx.stage.Stage; public class SpinnerStyleDemo extends Application { @Override public void start(Stage stage) { String[] styleClasses = new String[] { "", // Default. Spinner.STYLE_CLASS_ARROWS_ON_RIGHT_HORIZONTAL, // Spinner.STYLE_CLASS_ARROWS_ON_LEFT_VERTICAL, // Spinner.STYLE_CLASS_ARROWS_ON_LEFT_HORIZONTAL, // Spinner.STYLE_CLASS_SPLIT_ARROWS_VERTICAL, // Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL }; FlowPane root = new FlowPane(); root.setHgap(10); root.setVgap(10); root.setPadding(new Insets(10)); for (String styleClass : styleClasses) { Spinner<Integer> spinner = new Spinner<Integer>(1, 20, 10); spinner.getStyleClass().add(styleClass); root.getChildren().add(spinner); } Scene scene = new Scene(root, 400, 200); stage.setTitle("JavaFX Spinner (o7planning.org)"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { Application.launch(args); } }
Обычно Spinner используются для отображения числовых значений. Н вы так же можете использовать для отображения любого Object. В примере ниже Spinner содержит набор объектов Language, и обрабатывает событие когда значение Spinner меняется.

SpinnerChangeEventDemo.java
package org.o7planning.javafx.spinner; import java.util.ArrayList; import java.util.List; import org.o7planning.javafx.model.Language; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; 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.FlowPane; import javafx.stage.Stage; public class SpinnerChangeEventDemo extends Application { @Override public void start(Stage stage) { Language vietnamese = new Language("vi", "Vietnamese", "Xin Chao"); Language english = new Language("en", "English", "Hello"); Language russian = new Language("ru", "Russian", "привет"); List<Language> languages = new ArrayList<Language>(); languages.add(vietnamese); languages.add(english); languages.add(russian); // Label label = new Label("Select Language:"); final Spinner<Language> spinner = new Spinner<Language>(); Label labelMessage = new Label("?"); // Value factory. SpinnerValueFactory<Language> valueFactory = // new SpinnerValueFactory<Language>() { @Override public void decrement(int steps) { Language current = this.getValue(); int idx = languages.indexOf(current); int newIdx = (languages.size() + idx - steps) % languages.size(); Language newLang = languages.get(newIdx); this.setValue(newLang); } @Override public void increment(int steps) { Language current = this.getValue(); int idx = languages.indexOf(current); int newIdx = (idx + steps) % languages.size(); Language newLang = languages.get(newIdx); this.setValue(newLang); } }; // Default value for Spinner valueFactory.setValue(vietnamese); spinner.setValueFactory(valueFactory); // When spinner change value. spinner.valueProperty().addListener(new ChangeListener<Language>() { @Override public void changed(ObservableValue<? extends Language> observable,// Language oldValue, Language newValue) { labelMessage.setText("Greeting: "+ newValue.getGreeting()); } }); FlowPane root = new FlowPane(); root.setHgap(10); root.setVgap(10); root.setPadding(new Insets(10)); root.getChildren().addAll(label, spinner, labelMessage); Scene scene = new Scene(root, 400, 200); stage.setTitle("JavaFX Spinner (o7planning.org)"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { Application.launch(args); } }
Language.java
package org.o7planning.javafx.model; public class Language { private String code; private String name; private String greeting; public Language() { } public Language(String code, String name) { this.code = code; this.name = name; } public Language(String code, String name, String greeting) { this.code = code; this.name = name; this.greeting = greeting; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } @Override public String toString() { return this.name; } }
Пользователь может добавить новое значение для Spinner, в следующем примере пользователь вводит значение и нажимает Enter, значение добавится в набор готовых значений Spinner.

SpinnerEditDemo.java
package org.o7planning.javafx.spinner; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; 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.control.SpinnerValueFactory.ListSpinnerValueFactory; import javafx.scene.layout.FlowPane; import javafx.stage.Stage; import javafx.util.StringConverter; public class SpinnerEditDemo extends Application { @Override public void start(Stage stage) { Label label = new Label("Select Level:"); final Spinner<Integer> spinner = new Spinner<Integer>(); // Editable. spinner.setEditable(true); // Item List. ObservableList<Integer> items = FXCollections.observableArrayList(1, 2, 3); // Value Factory: SpinnerValueFactory<Integer> valueFactory = // new SpinnerValueFactory.ListSpinnerValueFactory<>(items); // The converter to convert between text and item object. MyConverter converter = new MyConverter(); valueFactory.setConverter(converter); spinner.setValueFactory(valueFactory); spinner.getEditor().setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String text = spinner.getEditor().getText(); SpinnerValueFactory.ListSpinnerValueFactory<Integer>// valueFactory = (ListSpinnerValueFactory<Integer>) spinner.getValueFactory(); StringConverter<Integer> converter = valueFactory.getConverter(); Integer enterValue = converter.fromString(text); // If the list does not contains 'enterValue'. if (!valueFactory.getItems().contains(enterValue)) { // Add new item to list valueFactory.getItems().add(enterValue); // Set to current valueFactory.setValue(enterValue); } else { // Set to current valueFactory.setValue(enterValue); } } }); // FlowPane root = new FlowPane(); root.setHgap(10); root.setVgap(10); root.setPadding(new Insets(10)); root.getChildren().addAll(label, spinner); Scene scene = new Scene(root, 400, 200); stage.setTitle("JavaFX Spinner (o7planning.org)"); stage.setScene(scene); stage.show(); } class MyConverter extends StringConverter<Integer> { @Override public String toString(Integer object) { return object + ""; } @Override public Integer fromString(String string) { return Integer.parseInt(string); } } public static void main(String[] args) { Application.launch(args); } }