2012-09-20 125 views
2

我爲JavaFX應用程序製作了一個配置面板。我設法創建一個動態變化監聽如下:我的控制器這樣的範圍內使用它使用bindin進行驗證

public class InputMaskChecker implements ChangeListener<String> { 

    public static final String NUMERIC  = "^[0-9]*$"; 
    public static final String TEXTONLY  = "^\\w*$"; 
    public static final String PASSWORD  = "^[\\w\\+\\!\\?\\-\\$\\&\\%£]+$"; 
    public static final String DATASOURCE = "^([a-zA-Z]+:){3}@([a-zA-Z0-9]+:)+[a-zA-Z0-9]+$"; 
    public static final String TCPPORT  = "^(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[2-9]\\d{3}|1[1-9]\\d{2}|10[3-9]\\d|102[4-9])$"; 

    private static final String STYLE = "-fx-effect: dropshadow(gaussian, red, 4, 0.0, 0, 0);"; 

    public final BooleanProperty erroneous = new SimpleBooleanProperty(false); 

    private final String mask; 
    private final int max_lenght; 
    private final TextField control; 


    public InputMaskChecker(String mask, TextField control) { 
     this.mask = mask; 
     this.max_lenght = 0; 
     this.control = control; 
    } 

    public InputMaskChecker(String mask, int max_lenght, TextField control) { 
     this.mask = mask; 
     this.max_lenght = max_lenght; 
     this.control = control; 
    } 

    @Override 
    public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) { 
     erroneous.setValue(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0); 
     control.setStyle(erroneous.get() ? STYLE : "-fx-effect: null;"); 
    } 
} 

field1.textProperty().addListener(new InputMaskChecker(InputMaskChecker.DATASOURCE, field1)); 
field2.textProperty().addListener(new InputMaskChecker(InputMaskChecker.TEXTONLY, field2)); 
field3.textProperty().addListener(new InputMaskChecker(InputMaskChecker.PASSWORD, field3)); 
field4.textProperty().addListener(new InputMaskChecker(InputMaskChecker.NUMERIC, 1, field4)); 

它的工作原理與毛刺預計:我想有我SAVE按鈕在主控制器上對偵聽器做出反應的方式是,如果某個字段出現錯誤,它將被禁用。

它現在是我的頭腦風暴的要求。你有什麼建議嗎?

使用共享的SimpleBooleanProperty,AND-ing偵聽器不會明顯工作。

(解決方案)更新: 將一個private final BooleanBinding binding;變量添加到控制器。然後:

InputMaskChecker listener1 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field1); 
InputMaskChecker listener2 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field2); 
InputMaskChecker listener3 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field3); 
InputMaskChecker listener4 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field4); 

field1.textProperty().addListener(listener1); 
field2.textProperty().addListener(listener2); 
field3.textProperty().addListener(listener3); 
field4.textProperty().addListener(listener4); 

binding = new BooleanBinding() { 
    { 
    super.bind(listener1.erroneous, listener2.erroneous, listener3.erroneous, listener4.erroneous); 
    } 

    @Override 
    protected boolean computeValue() { 
     return (listener1.erroneous.get() || listener2.erroneous.get() || listener3.erroneous.get() || listener4.erroneous.get()); 
    } 
}; 

control.getDisableProperty().bind(binding); 

做;)

回答

0

我可以建議下一approache:

讓你InputMaskChecker狀態與public SimpleBooleanProperty valid;將在更新方法被稱爲:

@Override 
public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) { 
    valid.set(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0); 
    // BTW, I would suggest to use styleclasses instead for performance reasons 
    control.setStyle(valid.get() ? STYLE : "-fx-effect: null;): 
} 

那麼你就可以說在「保存」按鈕創建:

Button btn = new Button("Save"); 
btn.disableProperty().bind(
     listener1.valid.and(listener2.valid).and(listener3.valid).not()); 

或創建實用程序方法,它將添加偵聽器並更新「保存」禁用屬性。

+0

用低級綁定解決。 無論如何,你不能使用這樣的styleclasses。我嘗試過,但是,一旦添加了styleclass,它不會刪除它,甚至使用'.setEffect(new Dropshadow(...));'方法不起作用。 唯一的機會是'control.setStyle(valid.get()的方式:「-fx效果:空;);' – matticala

+0

setEffect()預計不工作的setStyle()在風格命令最優先級。鏈。見http://stackoverflow.com/questions/12333985/javafx-can-not-set-font-size-programmatically-after-font-being-set-by-css/12334881#12334881 –

+0

爲你解決問題的另一請將你的代碼作爲一個單獨的答案發布,並接受你自己的答案,而不是我的。 –