gpt4 book ai didi

java - JavaFX 中的文本字段验证

转载 作者:行者123 更新时间:2023-12-04 04:52:48 25 4
gpt4 key购买 nike

在文本字段中,我想通过以下方式执行操作:

-> 为时间设置默认文本 00:00:00,因为文本字段是时间,字段的字符长度为 8。

-> 如果光标在位置 0(零),如果我按下一个数字键,它应该替换位置 0 的值并将光标移动到下一个位置。

   eg : 00:00:00
20:00:00

解释:现在光标 z 在位置 0 并且我按下键 2 它应该替换位置 0 中的值 0 并移动到位置 1

当我按下任何非数字键时,它不应替换任何值,但光标应移动到下一个位置。

最佳答案

这完美地工作:

    import java.util.regex.Pattern;  
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.IndexRange;
import javafx.scene.control.Label;

import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TimeTextFieldTest extends Application {
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(5);
root.setPadding(new Insets(5));
Label hrLabel = new Label();
Label minLabel = new Label();
Label secLabel = new Label();
TimeTextField timeTextField = new TimeTextField();
hrLabel.textProperty().bind(Bindings.format("Hours: %d", timeTextField.hoursProperty()));
minLabel.textProperty().bind(Bindings.format("Minutes: %d", timeTextField.minutesProperty()));
secLabel.textProperty().bind(Bindings.format("Seconds: %d", timeTextField.secondsProperty()));
root.getChildren().addAll(timeTextField, hrLabel, minLabel, secLabel);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public static class TimeTextField extends TextField {

enum Unit {HOURS, MINUTES, SECONDS};
private final Pattern timePattern ;
private final ReadOnlyIntegerWrapper hours ;
private final ReadOnlyIntegerWrapper minutes ;
private final ReadOnlyIntegerWrapper seconds ;

public TimeTextField() {
this("00:00:00");
}
public TimeTextField(String time) {
super(time);
timePattern = Pattern.compile("\\d\\d:\\d\\d:\\d\\d");
if (! validate(time)) {
throw new IllegalArgumentException("Invalid time: "+time);
}
hours = new ReadOnlyIntegerWrapper(this, "hours");
minutes = new ReadOnlyIntegerWrapper(this, "minutes");
seconds = new ReadOnlyIntegerWrapper(this, "seconds");
hours.bind(new TimeTextField.TimeUnitBinding(Unit.HOURS));
minutes.bind(new TimeTextField.TimeUnitBinding(Unit.MINUTES));
seconds.bind(new TimeTextField.TimeUnitBinding(Unit.SECONDS));
}

public ReadOnlyIntegerProperty hoursProperty() {
return hours.getReadOnlyProperty();
}

public int getHours() {
return hours.get() ;
}

public ReadOnlyIntegerProperty minutesProperty() {
return minutes.getReadOnlyProperty();
}

public int getMinutes() {
return minutes.get();
}

public ReadOnlyIntegerProperty secondsProperty() {
return seconds.getReadOnlyProperty();
}

public int getSeconds() {
return seconds.get();
}

@Override
public void appendText(String text) {
// Ignore this. Our text is always 8 characters long, we cannot append anything
}

@Override
public boolean deleteNextChar() {
boolean success = false ;

// If there's a selection, delete it:
final IndexRange selection = getSelection();
if (selection.getLength()>0) {
int selectionEnd = selection.getEnd();
this.deleteText(selection);
this.positionCaret(selectionEnd);
success = true ;
} else {
// If the caret preceeds a digit, replace that digit with a zero and move the caret forward. Else just move the caret forward.
int caret = this.getCaretPosition();
if (caret % 3 != 2) { // not preceeding a colon
String currentText = this.getText();
setText(currentText.substring(0, caret) + "0" + currentText.substring(caret+1));
success = true ;
}
this.positionCaret(Math.min(caret+1, this.getText().length()));
}
return success ;
}

@Override
public boolean deletePreviousChar() {
boolean success = false ;
// If there's a selection, delete it:
final IndexRange selection = getSelection();
if (selection.getLength()>0) {
int selectionStart = selection.getStart();
this.deleteText(selection);
this.positionCaret(selectionStart);
success = true ;
} else {
// If the caret is after a digit, replace that digit with a zero and move the caret backward. Else just move the caret back.
int caret = this.getCaretPosition();
if (caret % 3 != 0) { // not following a colon
String currentText = this.getText();
setText(currentText.substring(0, caret-1) + "0" + currentText.substring(caret));
success = true ;
}
this.positionCaret(Math.max(caret-1, 0));
}
return success ;
}

@Override
public void deleteText(IndexRange range) {
this.deleteText(range.getStart(), range.getEnd());
}

@Override
public void deleteText(int begin, int end) {
// Replace all digits in the given range with zero:
StringBuilder builder = new StringBuilder(this.getText());
for (int c = begin; c<end; c++) {
if (c % 3 != 2) { // Not at a colon:
builder.replace(c, c+1, "0");
}
}
this.setText(builder.toString());
}

@Override
public void insertText(int index, String text) {
// Handle an insert by replacing the range from index to index+text.length() with text, if that results in a valid string:
StringBuilder builder = new StringBuilder(this.getText());
builder.replace(index, index+text.length(), text);
final String testText = builder.toString();
if (validate(testText)) {
this.setText(testText);
}
this.positionCaret(index + text.length());
}

@Override
public void replaceSelection(String replacement) {
final IndexRange selection = this.getSelection();
if (selection.getLength()==0) {
this.insertText(selection.getStart(), replacement);
} else {
this.replaceText(selection.getStart(), selection.getEnd(), replacement);
}
}

@Override
public void replaceText(IndexRange range, String text) {
this.replaceText(range.getStart(), range.getEnd(), text);
}

@Override
public void replaceText(int begin, int end, String text) {
if (begin==end) {
this.insertText(begin, text);
} else {
// only handle this if text.length() is equal to the number of characters being replaced, and if the replacement results in a valid string:
if (text.length() == end - begin) {
StringBuilder builder = new StringBuilder(this.getText());
builder.replace(begin, end, text);
String testText = builder.toString();
if (validate(testText)) {
this.setText(testText);
}
this.positionCaret(end);
}
}
}

private boolean validate(String time) {
if (! timePattern.matcher(time).matches()) {
return false ;
}
String[] tokens = time.split(":");
assert tokens.length == 3 ;
try {
int hours = Integer.parseInt(tokens[0]);
int mins = Integer.parseInt(tokens[1]);
int secs = Integer.parseInt(tokens[2]);
if (hours < 0 || hours > 23) {
return false ;
}
if (mins < 0 || mins > 59) {
return false ;
}
if (secs < 0 || secs > 59) {
return false ;
}
return true ;
} catch (NumberFormatException nfe) {
// regex matching should assure we never reach this catch block
assert false ;
return false ;
}
}

private final class TimeUnitBinding extends IntegerBinding {

final Unit unit ;
TimeUnitBinding(Unit unit) {
this.bind(textProperty());
this.unit = unit ;
}
@Override
protected int computeValue() {
// Crazy enum magic
String token = getText().split(":")[unit.ordinal()];
return Integer.parseInt(token);
}

}

}
}

关于java - JavaFX 中的文本字段验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17188712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com