Suggested Approach
我建议你看看controlsfx accomplishes this是如何使用这个库的,或者通过研究他们的源代码(如果合适的话)来学习他们的方法.
我判断了适用于style classes for validation feedback的控件SFX validation code.控制器sample usage通过css drop shadow effects提供反馈.这是一个简单的解决方案,比定制背景更容易.
我try 使用阴影效果来标记无效的文本字段,它似乎对我很有效.
对于文本字段以外的复杂控件(如范围滑块,其中范围刻度文本也有阴影),下拉阴影方法看起来有点奇怪,因此对于这些控件,您可能需要做一些更复杂的事情.
Example application
这将根据需要在字段上设置或取消设置invalid
样式的类.
.invalid {
-fx-effect: dropshadow(three-pass-box, tomato, 3, 0.8, 0, 0);
}
当invalid
样式类处于活动状态时,会触发阴影效果,以向用户提供字段无效的指示.
参考CSS effect documentation了解dropshadow效果的设置.
States
焦点值无效:
没有焦点的无效值:
具有焦点的有效值:
无焦点的有效值:
这个示例并不是一个健壮的验证框架,它只是一个示例,展示了如何为文本字段提供验证反馈样式.
该示例基于一个标准样式类进行操作,但如果您想了解它,可以使用you could use a psuedo-class.例如,与:focus
psuedo类类似,可以实现CSS :invalid
psuedo类.
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ValidatorApp extends Application {
public static final String CSS = "data:text/css," + // language=CSS
"""
.invalid {
-fx-effect: dropshadow(three-pass-box, tomato, 3, 0.8, 0, 0);
}
""";
@Override
public void start(Stage stage) throws Exception {
TextField integerTextField = new TextField();
IntegerTextFieldValidator validator = new IntegerTextFieldValidator();
validator.validate(integerTextField);
integerTextField.textProperty().addListener(o ->
validator.validate(integerTextField)
);
VBox layout = new VBox(10,
labelField("Enter an integer: ", integerTextField),
labelField("Enter any value: ", new TextField("foobar"))
);
layout.setPadding(new Insets(10));
Scene scene = new Scene(layout);
scene.getStylesheets().add(CSS);
stage.setScene(scene);
stage.show();
}
HBox labelField(String labelText, Node field) {
HBox box = new HBox(10, new Label(labelText), field);
box.setAlignment(Pos.BASELINE_LEFT);
return box;
}
public static void main(String[] args) {
launch(args);
}
}
import javafx.scene.Node;
import javafx.scene.control.TextField;
public class IntegerTextFieldValidator {
private static final String INVALID_STYLECLASS = "invalid";
public void validate(TextField textField) {
String text = textField.getText();
if (text == null) {
setInvalid(textField);
return;
}
try {
Integer.parseInt(text);
setValid(textField);
} catch (NumberFormatException e) {
setInvalid(textField);
}
}
private void setInvalid(Node node) {
if (!node.getStyleClass().contains(INVALID_STYLECLASS)) {
node.getStyleClass().add(INVALID_STYLECLASS);
}
}
private void setValid(Node node) {
node.getStyleClass().removeAll(INVALID_STYLECLASS);
}
}