2015-08-24 2 views
3

Может кто-нибудь, пожалуйста, покажет мне пример Bindings.bindBidirectional, где текстовое поле привязано к двойному значению И текстовое поле отформатировано в нулевые десятичные разряды. У меня есть эта привязка:JavaFX 8 Связывание с цифровым форматом

Bindings.bindBidirectional(xProperty, sp.layoutXProperty(), converter); 

где xProperty является StringProperty и sp.layoutXProperty является DoubleProperty.

Я пробовал много различных преобразователей и, наконец, остановились на:

NumberFormat nf = NumberFormat.getInstance();  
StringConverter<Number> converter = new NumberStringConverter(nf); 

Тогда я попробовал:

nf.setParseIntegerOnly(true); 

Но безрезультатно. Это была лишь одна из многих попыток добиться результата. Вероятно, это прямолинейно, но информация о привязке разных свойств к формату кажется немногочисленной и далекой, или я пропустил очевидное?

ответ

3

Посмотрите на этот код и посмотреть, если это решит вашу проблему:

public class BindingTest { 
    static Property<String> sp; 
    static Property<Double> dp; 

    public static void main(String[] args) { 
     sp = new SimpleStringProperty(); 
     dp = new SimpleObjectProperty<>(); 

     StringConverter<Double> sc = new StringConverter<Double>() { 
      @Override 
      public String toString(Double object) { 
       if (object != null) 
        return Integer.toString((int) Math.round(object.doubleValue())); 
       else 
        return null; 
      } 

      @Override 
      public Double fromString(String string) { 
       Double d = Double.parseDouble(string); 
       sp.setValue(Integer.toString((int) Math.round(d))); 
       return d; 
      } 
     }; 

     Bindings.bindBidirectional(sp, dp, sc); 

     print(); 
     sp.setValue("3.14"); 
     print(); 
     dp.setValue(6.18); 
     print(); 
    } 

    public static void print() { 
     System.out.println("String: " + sp.getValue() + "\t" + "Double: " + dp.getValue()); 
    } 
} 

Выход:

String: null Double: null 
String: 3 Double: 3.14 
String: 6 Double: 6.18 
3

Там может быть различные подходы превращающего двойное значение до целого, которые используют различные закругления при преобразовании. Этот ответ аналогичен другим, с дополнительным фильтром, который позволяет вводить только целочисленные значения в текстовом поле:

@Override 
public void start(Stage stage) 
{ 
    TextField field = new TextField(); 
    DoubleProperty doubleProperty = new SimpleDoubleProperty(); 
    Label label = new Label(); 
    label.textProperty().bind(doubleProperty.asString()); 

    DecimalFormat format = new DecimalFormat(); 
    format.setParseIntegerOnly(true); // used while parsing the input text of textfield 
    format.setMaximumFractionDigits(0); // used while formatting the doubleProperty's bound value as output text of textfield 
    format.setGroupingUsed(false); // disable thousand grouping 
    format.setRoundingMode(RoundingMode.UP); // set rounding mode 

    Bindings.bindBidirectional(field.textProperty(), doubleProperty, new StringConverter<Number>() 
    { 
     @Override 
     public String toString(Number object) 
     { 
      return object == null ? "" : format.format(object); 
     } 


     @Override 
     public Number fromString(String string) 
     { 
      return (string != null && !string.isEmpty()) ? Double.valueOf(string) : null; 
     } 
    }); 

    // apply filter to allow only integer values 
    field.setTextFormatter(new TextFormatter<>(c -> 
    { 
     if (c.getControlNewText().isEmpty()) 
     { 
      return c; 
     } 

     ParsePosition parsePosition = new ParsePosition(0); 
     Object object = format.parse(c.getControlNewText(), parsePosition); 

     if (object == null || parsePosition.getIndex() < c.getControlNewText().length()) 
     { 
      return null; 
     } 
     else 
     { 
      return c; 
     } 

    })); 

    Button b = new Button("+1.6"); 
    b.setOnAction((e) -> 
    { 
     doubleProperty.set(doubleProperty.get() + 1.6); 
    }); 

    Scene scene = new Scene(new VBox(5)); 
    stage.setWidth(450); 
    stage.setHeight(250); 
    ((VBox) scene.getRoot()).getChildren().addAll(field, label, b); 
    stage.setScene(scene); 
    stage.show(); 
} 
+1

Спасибо за оба этих ответа. Я могу голосовать только за одного, поэтому я проголосую за первый ответ, но Улук дал мне и другие идеи с этим примером. Надеюсь, что эти примеры полезны и для других. – Frank

Смежные вопросы