Javafx:减少可检查列表框的事件



我有一个通用的Javafx列表框,可检查项(最多20项)。

当我(取消)选择一个项目时,将释放一个属性更改以更新程序的其他部分。到目前为止一切正常。

但我有额外的2个按钮(取消)一次选择所有项目。这也像预期的那样工作,但是我为每个项目获得一个事件,这意味着多达20个属性更改事件被触发,当一个就足够了。

这不是性能问题,也没有对事件做太多处理,但这是一种糟糕的风格。

有谁能提出更好的解决方案吗?
public class FilterBox extends AnchorPane {
ListView<Item> listFilter;
Button buttonAll;
Button buttonNone;
public FilterBox() {
init();
place();
action();
getChildren().addAll(listFilter, buttonAll, buttonNone);
handleChange();
}
private void init() {
listFilter = new ListView<>();
buttonAll = new Button("All");
buttonNone = new Button("None");
}
private void place() {
setTopAnchor(listFilter, 0d);
setBottomAnchor(listFilter, 40d);
setLeftAnchor(listFilter, 0d);
setRightAnchor(listFilter, 0d);
setBottomAnchor(buttonAll, 5d);
setLeftAnchor(buttonAll, 0d);
buttonAll.setPrefWidth(75d);
setBottomAnchor(buttonNone, 5d);
setRightAnchor(buttonNone, 0d);
buttonNone.setPrefWidth(75d);

}
private void action() {
listFilter.setCellFactory(CheckBoxListCell.forListView((Item item) -> item.selectedProperty()));
buttonAll.setOnAction((t) -> {
changeAll(true);
});
buttonNone.setOnAction((t) -> {
changeAll(false);
});
}
private void changeAll(Boolean state) {
for (Item i : listFilter.getItems()) {
i.setSelected(state);
}
}
private void setListener(Item item) {
item.selectedProperty().addListener((o, ov, nv) -> {
Trigger.setNewFilterEvent();
});
}
private void handleChange() {
HashSet<String> list = InputData.getSportList();
for (String s : list) {
Item item = new Item(s, true);
listFilter.getItems().add(item);
setListener(item);
}
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final BooleanProperty selected = new SimpleBooleanProperty();
public Item(String name, boolean on) {
setName(name);
setSelected(on);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final BooleanProperty selectedProperty() {
return this.selected;
}
public final boolean isSelected() {
return this.selectedProperty().get();
}
public final void setSelected(final boolean sel) {
this.selectedProperty().set(sel);
}
@Override
public String toString() {
return getName();
}
}
}

假设Trigger.setNewFilterEvent()是您想要的,当"select all"或者"取消全部选择";操作被触发,那么您可以使用boolean标志。

public class FilterBox {
private boolean ignoreIndividualChanges;
// other fields omitted for brevity
private void changeAll(boolean state) {
ignoreIndividualChanges = true;
try {
for (Item i : listFilter.getItems()) {
i.setSelected(state);
}
Trigger.setNewFilterEvent(); // fire one event
} finally {
ignoreIndividualChanges = false;
}
}
private void setListener(Item item) {
item.selectedProperty().addListener((obs, ov, nv) -> {
if (!ignoreIndividualChanges) {
Trigger.fireNewFilterEvent();
}
});
}
// other methods omitted for brevity
}

另外,请注意我将changeAll的参数类型从Boolean更改为boolean。这里没有理由使用引用类型,所以应该坚持使用基本类型。

最新更新