2017-04-26 17 views
2

我不明白爲什麼,如果Spinner調用ChangeListener兩次。我怎樣才能讓它只打一次電話?JavaFX微調工作不正確。 Spinner.valueProperty()。addListener改變了兩次

Controller.java

public class Controller { 
@FXML 
Spinner<Double> spinner; 
@FXML 
public void initialize(){ 
    spinner.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0,350,60,1)); 

    spinner.valueProperty().addListener(new ChangeListener<Double>() { 
     @Override 
     public void changed(ObservableValue<? extends Double> observable, Double oldValue, Double newValue) { 
      System.out.println("Old Value" + oldValue + "New Value" + newValue); 
     } 
    }); 
}} 

Main.java

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     Parent root =  FXMLLoader.load(getClass().getResource("sample.fxml")); 
     primaryStage.setTitle("Hello World"); 
     primaryStage.setScene(new Scene(root, 300, 275)); 
     primaryStage.show(); 
    } 
    public static void main(String[] args) { 
     launch(args); 
    }} 

日期:

Old Value 60.0 New Value 780.0 
Old Value 780.0 New Value 350.0 
+0

當它被調用兩次時,你輸入什麼值?大於350? – DVarga

+0

是的,我輸入780例如 – wakedeer

回答

1

這是因爲SpinnerValueFactory

spinner.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0,350,60,1)); 

Spinner的最大值爲350,您輸入780:值改變這個值,那麼因爲它變回350


最大價值更新:

默認情況下,Spinner的編輯器中的值將提交,當輸入鍵被按下。

爲了避免自動包圍例如,你可以嘗試覆蓋默認提交邏輯:

spinner.getEditor().setOnAction(e -> { 

    String text = spinner.getEditor().getText(); 
    SpinnerValueFactory<Double> valueFactory = spinner.getValueFactory(); 
    if (valueFactory != null) { 
     StringConverter<Double> converter = valueFactory.getConverter(); 
     if (converter != null) { 
      try{ 
       Double value = converter.fromString(text); 
       if (value >= minValue && value <= maxValue) 
        valueFactory.setValue(value); 
       else 
        valueFactory.setValue(Math.max(Math.min(maxValue, value), minValue)); 

       // This ensures that if the value us e.g. 350, then 450 entered, the text 
       // is updated to 350 again (rather than ramaining 450) 
       spinner.getEditor().setText(converter.toString(valueFactory.getValue())); 
      } catch(NumberFormatException nfe){ 
       spinner.getEditor().setText(converter.toString(valueFactory.getValue())); 
      } 
     } 
    } 

    e.consume(); 
}); 

和值定義爲:

double maxValue = 350; 
double minValue = 0; 
spinner.setValueFactory(
    new SpinnerValueFactory.DoubleSpinnerValueFactory(minValue, maxValue, 60, 1)); 

注:

最小值和最大值也可以從SpinnerValueFactory - 可惜不是在一個完全乾淨的方式,但也有一些鑄造:

spinner.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0, 350, 60, 1)); 

spinner.getEditor().setOnAction(e -> { 
    SpinnerValueFactory.DoubleSpinnerValueFactory valueFactory = (SpinnerValueFactory.DoubleSpinnerValueFactory) spinner.getValueFactory(); 

    if (valueFactory != null) { 
     StringConverter<Double> converter = valueFactory.getConverter(); 
     if (converter != null) { 
      try { 
       valueFactory.setValue(Math.max(Math.min(valueFactory.getMax(), 
         converter.fromString(spinner.getEditor().getText())), valueFactory.getMin())); 

       spinner.getEditor().setText(converter.toString(valueFactory.getValue())); 

      } catch(NumberFormatException nfe){ 
       spinner.getEditor().setText(converter.toString(valueFactory.getValue())); 
      } 
     } 
    } 

    e.consume(); 
}); 

但在這種情況下,沒有必要存儲的最大值和最小值,它們是從工廠本身有

+0

是的,但我怎麼能只有一個調用方法public void changed()? – wakedeer

+0

另一種選擇是在編輯器上設置一個'TextFormatter',否決(或修改)會超出範圍的更改。 –

+1

@James_D是的,這是絕對正確的。我只是不想創建一個tl;博士回答:) – DVarga