【发布时间】:2017-04-24 13:56:01
【问题描述】:
我有几个ComboBox 用于选择约会计划程序应用程序的日期和时间,但是当我自定义CellFactory 时,它只会在您第一次单击并展开时正确禁用正确的项目。基本上,它应该禁用允许您选择早于LocalDateTime.now() 的日期和时间的选项。这是一个显示不稳定行为的视频: https://www.youtube.com/watch?v=niGoIvVx9Y0
这是我的细胞工厂的代码:
startHour.setCellFactory((final ListView<String> param) -> {
return new ComboBoxListCell<String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(empty || item == null) {
setText(null);
setGraphic(null);
} else {
LocalDateTime selected = createDateTime(startDate.getValue(), item,
startMinute.getValue(), startMeridian.getValue());
if(selected.isBefore(LocalDateTime.now())) {
System.out.print(item + ", ");
setDisable(true);
setStyle(COMBOCELL_DISABLED_COLOR);
}
}
}
};
});
startMinute.setCellFactory((final ListView<String> listView) -> {
return new ComboBoxListCell<String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(empty || item == null) {
setText(null);
setGraphic(null);
} else {
LocalDateTime selected = createDateTime(startDate.getValue(), startHour.getValue(),
item, startMeridian.getValue());
if(selected.isBefore(LocalDateTime.now())) {
setDisable(true);
setStyle(COMBOCELL_DISABLED_COLOR);
}
}
}
};
});
startMeridian.setCellFactory((final ListView<String> listView) -> {
return new ComboBoxListCell<String>() {
@Override public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(empty || item == null) {
setText(null);
setGraphic(null);
} else {
LocalDateTime selected = createDateTime(startDate.getValue(), startHour.getValue(),
startMinute.getValue(), item);
if(selected.isBefore(LocalDateTime.now())) {
setDisable(true);
setStyle(COMBOCELL_DISABLED_COLOR);
}
}
}
};
});
选中的LocalDateTime是用这种方法计算的:
private LocalDateTime createDateTime(LocalDate date, String hour, String minute, String meridian) {
String dateTimeStr = date + " " + hour + " " + minute + " " + meridian;
return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd h m a"));
}
在startHour#setCellFactory 中,我插入了一个println 语句,显示所选项目转换为LocalDateTime,如果它出现在LocalDateTime.now() 之前,这是我得到的输出:
1、2、3、4、5、6、7、8、9、1、2、3、4、5、6、7、8、9、12、1、1、2、3、4 , 5, 6, 7, 8, 9, 12, 12, 12, 1, 9, 12, 1, 9, 12, 2, 1, 7, 9,
当前时间是上午 9:48,而选择的时间是上午 10:00,因此似乎满足了预期条件。但是,正如视频所示,在第一次扩展 ComboBox 之后,行为非常不稳定。对于DatePicker 节点,我有类似的单元工厂,它们工作得很好。
我是否误解了 ComboBox#setCellFactory 的用途?
【问题讨论】:
-
对不起,这里是视频链接:youtube.com/watch?v=niGoIvVx9Y0
-
从您的代码中,我意识到如果时间
isAfter(LocalDateTime.now())即您可能想在您的isBefore检查中添加一个else以撤消对单元格的禁用,则您什么也不做。 -
谢谢,这有助于在上下滚动时随机着色和禁用不正确的框,但它并没有解决当日子进一步改变时项目无法重新启用的问题.
-
没有看到更多代码,我希望您尝试更改日期,然后选择不同的小时或分钟,看看是否正确更新。我的想法是
CellFactorys 没有被调用,因为它们没有被更新,只有DatePicker正在更新。 -
是的,我几乎可以肯定,因为
CellFactorys 不会在日期更改时被调用。您可能必须绑定属性,以便在更改DatePicker时,它也会更改其他属性。我发现 MAY 的唯一帮助是dayCellFactoryProperty。我也不确定这是否可行,因为我没有测试程序可以尝试。祝你好运。