我创建了一个Treeview(javafx),它看起来像:
我现在想要的是,只有“tour”-树项是可选择的。但我不知道怎么做。
我已经用ChangeListener尝试过了,但我只能用它刷新选项卡(TabPane)的内容...刷新很好...但是可以选择“delivery”-TreeItems:(
public void showTours(List<Tour> pTours) {
treeViewPane.getSelectionModel().selectedItemProperty().addListener(treeItemChangeListener);
TreeItem tTreeRoot = new TreeItem<>("Root", new ImageView(Icons.getIcon24("truck_blue.png")));
tTreeRoot.setExpanded(true);
treeViewPane.setRoot(tTreeRoot);
for (Tour tTour : pTours) {
TreeItem<Object> tTourItem = new TreeItem<>(tTour);
tTreeRoot.getChildren().add(tTourItem);
if (tTour.getDeliveries() != null) {
for (Delivery tDelivery : tTour.getDeliveries()) {
TreeItem<Object> tDeliveryItem = new TreeItem<>(tDelivery);
tTourItem.getChildren().add(tDeliveryItem);
}
}
}
}
private final ChangeListener<TreeItem> treeItemChangeListener = (observable, oldValue, newValue) -> {
if (newValue != null && newValue.getValue() instanceof Tour){
Tour selectedTour = (Tour) newValue.getValue();
reloadTabContent(selectedTour);
}
};
在JavaFX中修改任何控件中的选择行为似乎有点麻烦;但是这样做的“正确”方法是为树定义一个自定义选择模型。最简单的方法是包装默认的选择模型,并将方法调用委托给它,如果选择索引是不应该选择的项,则否决选择。
当调用select
方法时,最好尽可能选择一些内容,否则键盘导航将中断。
下面是一个实现:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.MultipleSelectionModel;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class CustomTreeSelectionModelExample extends Application {
@Override
public void start(Stage primaryStage) {
TreeItem<Object> root = new TreeItem<>("Root");
for (int i = 1 ; i <= 5 ; i++) {
TreeItem<Object> item = new TreeItem<>(new Tour("Tour "+i));
for (int j = 1 ; j <= 5; j++) {
Delivery delivery = new Delivery("Delivery "+j);
item.getChildren().add(new TreeItem<>(delivery));
}
root.getChildren().add(item);
}
TreeView<Object> tree = new TreeView<>();
tree.setSelectionModel(new TourSelectionModel(tree.getSelectionModel(), tree));
tree.setRoot(root);
primaryStage.setScene(new Scene(new BorderPane(tree), 400, 400));
primaryStage.show();
}
public static class TourSelectionModel extends MultipleSelectionModel<TreeItem<Object>> {
private final MultipleSelectionModel<TreeItem<Object>> selectionModel ;
private final TreeView<Object> tree ;
public TourSelectionModel(MultipleSelectionModel<TreeItem<Object>> selectionModel, TreeView<Object> tree) {
this.selectionModel = selectionModel ;
this.tree = tree ;
selectionModeProperty().bindBidirectional(selectionModel.selectionModeProperty());
}
@Override
public ObservableList<Integer> getSelectedIndices() {
return selectionModel.getSelectedIndices() ;
}
@Override
public ObservableList<TreeItem<Object>> getSelectedItems() {
return selectionModel.getSelectedItems() ;
}
@Override
public void selectIndices(int index, int... indices) {
List<Integer> indicesToSelect = Stream.concat(Stream.of(index), IntStream.of(indices).boxed())
.filter(i -> tree.getTreeItem(i).getValue() instanceof Tour)
.collect(Collectors.toList());
if (indicesToSelect.isEmpty()) {
return ;
}
selectionModel.selectIndices(indicesToSelect.get(0),
indicesToSelect.stream().skip(1).mapToInt(Integer::intValue).toArray());
}
@Override
public void selectAll() {
List<Integer> indicesToSelect = IntStream.range(0, tree.getExpandedItemCount())
.filter(i -> tree.getTreeItem(i).getValue() instanceof Tour)
.boxed()
.collect(Collectors.toList());
if (indicesToSelect.isEmpty()) {
return ;
}
selectionModel.selectIndices(0,
indicesToSelect.stream().skip(1).mapToInt(Integer::intValue).toArray());
}
@Override
public void selectFirst() {
IntStream.range(0, tree.getExpandedItemCount())
.filter(i -> tree.getTreeItem(i).getValue() instanceof Tour)
.findFirst()
.ifPresent(selectionModel::select);
}
@Override
public void selectLast() {
IntStream.iterate(tree.getExpandedItemCount() - 1, i -> i - 1)
.limit(tree.getExpandedItemCount())
.filter(i -> tree.getTreeItem(i).getValue() instanceof Tour)
.findFirst()
.ifPresent(selectionModel::select);
}
@Override
public void clearAndSelect(int index) {
int toSelect = index ;
int direction = selectionModel.getSelectedIndex() < index ? 1 : -1 ;
while (toSelect >= 0 && toSelect < tree.getExpandedItemCount() && ! (tree.getTreeItem(toSelect).getValue() instanceof Tour)) {
toSelect = toSelect + direction ;
}
if (toSelect >= 0 && toSelect < tree.getExpandedItemCount()) {
selectionModel.clearAndSelect(toSelect);
}
}
@Override
public void select(int index) {
int toSelect = index ;
int direction = selectionModel.getSelectedIndex() < index ? 1 : -1 ;
while (toSelect >= 0 && toSelect < tree.getExpandedItemCount() && ! (tree.getTreeItem(toSelect).getValue() instanceof Tour)) {
toSelect = toSelect + direction ;
}
if (toSelect >= 0 && toSelect < tree.getExpandedItemCount()) {
selectionModel.select(toSelect);
}
}
@Override
public void select(TreeItem<Object> obj) {
if (obj.getValue() instanceof Tour) {
selectionModel.select(obj);
}
}
@Override
public void clearSelection(int index) {
selectionModel.clearSelection(index);
}
@Override
public void clearSelection() {
selectionModel.clearSelection();
}
@Override
public boolean isSelected(int index) {
return selectionModel.isSelected(index);
}
@Override
public boolean isEmpty() {
return selectionModel.isEmpty();
}
@Override
public void selectPrevious() {
int current = selectionModel.getSelectedIndex() ;
if (current > 0) {
IntStream.iterate(current - 1, i -> i - 1).limit(current)
.filter(i -> tree.getTreeItem(i).getValue() instanceof Tour)
.findFirst()
.ifPresent(selectionModel::select);
}
}
@Override
public void selectNext() {
int current = selectionModel.getSelectedIndex() ;
if (current < tree.getExpandedItemCount() - 1) {
IntStream.range(current + 1, tree.getExpandedItemCount())
.filter(i -> tree.getTreeItem(i).getValue() instanceof Tour)
.findFirst()
.ifPresent(selectionModel::select);
}
}
}
public static class Tour {
private final String name ;
public Tour(String name) {
this.name = name ;
}
public String getName() {
return name ;
}
@Override
public String toString() {
return getName();
}
}
public static class Delivery {
private final String name;
public Delivery(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
}
public static void main(String[] args) {
launch(args);
}
}
我用Spring靴和Spring安全。 我这样添加基于url的安全性 有没有办法只授权get、post、put…在url上担任某些角色?
我正在spring boot中创建一个REST api,目前我有一个映射来获取用户和特定用户的列表。 假设我的用户是这样的: 还有,在发送更新用户的请求时,请求体是否需要正确嵌套? 两者都是有效的还是2号?
我已经为我的应用程序实现了shedlock,对于我们拥有的两台服务器来说,它运行良好,没有任何问题。 我们现在在另一个域上添加了两个新服务器,shedlock也会选择它们。(好吧,这就是它的本意) 我有一份工作,创建pdf文件并将其放在文件夹中。添加的新服务器无权访问这些文件夹。因此,当这两个新服务器选择作业时,我的作业将失败。 有没有可能告诉夏洛克从我的两台服务器中选择任何一台,或者不选择另外两
问题内容: 鉴于以下课程 当我们验证它(例如,使用@Valid)并且如果Website.url不遵守我的自定义@ValidUrl约束时,我们将遇到约束冲突(例如,“ URL不可访问”)。 我想知道如果用户愿意,是否可以忽略该验证。 脚步: 第一次验证表格 引发约束冲突并将其显示给用户 用户选择“我知道,仍然添加”,然后重新提交 第二次验证表单,验证@ValidUrl以外的所有内容 问题答案: 您可
我使用的是React路由器V4,我有此路由器的配置: 是可选的语言参数,它应该与模式匹配,例如、或不匹配。例如,应用程序利用这些路由: 另外,我还有一个额外的组件,在其中我定义了函数的路由: 因此,我希望实现的结果是,只接受允许的语言代码(和空参数),而不接受的代码将被重定向到组件。 可能吗?如何实现这一目标? 非常感谢这个例子
我想问,有没有可能限制我的模板函数,使它只接受我指定的几种类型?这就是如何告诉编译器在我使用cout< 更明确地说,这就是我要做的: