Connecting a Slider and Spinner that has a StringConverter

后端 未结 1 489
感动是毒
感动是毒 2020-12-11 18:21

For numeric input, it\'s sometimes convenient to synchronize an analog control to a text display. In this Swing example, a JSpinner and a JSlider e

相关标签:
1条回答
  • 2020-12-11 18:54

    Your INITIAL_VALUE is first used as the initialValue parameter to the spinner's constructor. Internally, the spinner's concrete SpinnerValueFactory is a DoubleSpinnerValueFactory that adds a ChangeListener to its value property; when the initial value is set again, the value hasn't really changed. Two approaches suggest themselves:

    1. Specify a different value to the constructor and set the desired one after adding the converter:

      Spinner spinner = new Spinner(MIN, MAX, -42, STEP_INCREMENT);
      spinner.getValueFactory().setConverter(…);
      spinner.getValueFactory().setValue(INITIAL_VALUE);
      
    2. Construct a SpinnerValueFactory with the desired initial value and use it to construct the spinner:

      SpinnerValueFactory factory = new SpinnerValueFactory
          .DoubleSpinnerValueFactory(MIN, MAX, INITIAL_VALUE, STEP_INCREMENT);
      factory.setConverter(…);
      Spinner spinner = new Spinner(factory);
      

    In addition, the example below replaces the two listeners with a bidirectional binding, which uses weak listeners to allow garbage collection of properties:

    slider.valueProperty().bindBidirectional(
        spinner.getValueFactory().valueProperty());
    

    Trivially, the spinner and slider can control each other. More commonly, each can stay synchronized in the course of controlling a property held by another model:

    model.xProperty().bindBidirectional(slider.valueProperty());
    model.xProperty().bindBidirectional(spinner.getValueFactory().valueProperty());
    

    import java.text.NumberFormat;
    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.Slider;
    import javafx.scene.control.Spinner;
    import javafx.scene.control.SpinnerValueFactory;
    import javafx.scene.layout.GridPane;
    import javafx.stage.Stage;
    import javafx.util.converter.PercentageStringConverter;
    
    /**
     * @see https://stackoverflow.com/a/55427307/230513
     * @see https://stackoverflow.com/a/6067986/230513
     */
    public class SpinSlider extends Application {
    
        private static final double MIN = 0;
        private static final double MAX = 1;
        private static final double INITIAL_VALUE = 0.5;
        private static final double STEP_INCREMENT = 0.1;
    
        @Override
        public void start(Stage primaryStage) {
            primaryStage.setTitle("SpinSlider");
            Slider slider = new Slider(MIN, MAX, INITIAL_VALUE);
            slider.setBlockIncrement(STEP_INCREMENT);
            SpinnerValueFactory factory = new SpinnerValueFactory
                .DoubleSpinnerValueFactory(MIN, MAX, INITIAL_VALUE, STEP_INCREMENT);
            factory.setConverter(new PercentageStringConverter(
                NumberFormat.getPercentInstance()));
            Spinner spinner = new Spinner(factory);
            slider.valueProperty().bindBidirectional(spinner.getValueFactory().valueProperty());
            GridPane root = new GridPane();
            root.addRow(0, slider, spinner);
            root.setPadding(new Insets(8, 8, 8, 8));
            root.setHgap(8);
            Scene scene = new Scene(root);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题