我希望能够以hh:mm:ss格式在javafx文本字段中输入时间。我该如何格式化文本字段?我已经有了正则表达式方法,所以它只接受数字作为输入:
namespace App\Http\Controllers;
use App\Repositories\SearchRepository
class SearchController extends Controller {
public function __construct(SearchRepository $search) {
$this->search = $search;
}
public function searchAction() {
$result = $this->search->getDetails();
// return to view or whatever
}
public function printAction() {
$result = $this->search->getDetails();
// print excel code or whatever
}
}
我还有一个限制文本字段允许的字符数量的方法:
public void format(TextField t, String regex){
TextFormatter<String> formatter = new TextFormatter<String>( change -> {
change.setText(change.getText().replaceAll(regex, ""));
return change;
});
t.setTextFormatter(formatter);
}
然而,这些都没有帮助我获得我想要的时间格式。理想情况是初始文本为00:00:00,用户只能编辑数字,无法触及冒号。如果我能够确保每个冒号之间有2个数字,即用户应该无法移动数字,如0:000:00,那也很棒。
感谢您的帮助。
答案 0 :(得分:3)
已经设计了一个用于格式化日期的类,您可以将其用于TextField
's textFormatter
:SimpleDateFormat
TextField tf = new TextField();
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
tf.setTextFormatter(new TextFormatter<>(new DateTimeStringConverter(format), format.parse("00:00:00")));
请参阅SimpleDateFormat
的javadoc,以获得有关字符含义的更详细说明。
您还可以使用3个不同的TextField
并删除背景和边框,并将它们放在HBox
中以获取不可编辑的:
:
TextField hours = new TextField();
TextField minutes = new TextField();
TextField seconds = new TextField();
StringConverter<Integer> minSecConverter = new IntRangeStringConverter(0, 59);
minutes.setTextFormatter(new TextFormatter<>(minSecConverter, 0));
seconds.setTextFormatter(new TextFormatter<>(minSecConverter, 0));
hours.setTextFormatter(new TextFormatter<>(new IntRangeStringConverter(0, 23), 0));
prepareTextField(hours);
prepareTextField(minutes);
prepareTextField(seconds);
HBox fields = new HBox(hours, createLabel(),minutes, createLabel(), seconds);
fields.setPadding(new Insets(4));
fields.setStyle("-fx-background-color: white;");
public static void prepareTextField(TextField tf) {
tf.setAlignment(Pos.CENTER);
tf.setBackground(Background.EMPTY);
tf.setBorder(Border.EMPTY);
tf.setPadding(Insets.EMPTY);
tf.setPrefColumnCount(2);
}
public static class IntRangeStringConverter extends StringConverter<Integer> {
private final int min;
private final int max;
public IntRangeStringConverter(int min, int max) {
this.min = min;
this.max = max;
}
@Override
public String toString(Integer object) {
return String.format("%02d", object);
}
@Override
public Integer fromString(String string) {
int integer = Integer.parseInt(string);
if (integer > max || integer < min) {
throw new IllegalArgumentException();
}
return integer;
}
}
public static Label createLabel() {
Label label = new Label(":");
label.setPrefWidth(3);
return label;
}
答案 1 :(得分:2)
我正在使用这个简单的类,直到与DatePicker对应的TimePicker变得可用。这里的策略是在场失去焦点时检查输入。如果它与正则表达式(可选的秒和可选的AM,PM,am,pm)不匹配,它会通过发出蜂鸣声来引起用户注意,用格式正确的条目替换条目,请求焦点,并突出显示条目。我使validate()公开,以便容器(例如,对话框)也可以在关闭之前检查有效性(例如,如果通过按下OK按钮丢失焦点):
public class TimeTextField extends TextField
{
public TimeTextField(String init) {
super(init) ;
focusedProperty().addListener((o, oldV, newV) -> changed(newV));
}
public TimeTextField() {
this("12:00 PM");
}
private void changed(boolean focus) {
if (!focus) {
if (!validate()) {
setText("12:00 PM");
selectAll();
requestFocus();
Toolkit.getDefaultToolkit().beep();
}
}
}
public boolean validate() {
return getText()
.matches("(0?[1-9]|1[0-2]):[0-5][0-9](:[0-5][0-9])? ?[APap][mM]$");
}
}
答案 2 :(得分:-1)
您应该插入&#39;:&#39;靠自己。因为这样用户只允许插入数字。在每两个数字后面插入&#39;:&#39;在改变监听器内部。另外很容易插入时间。