JavaFx TreeCell 如何在一秒后扩展节点
JavaFx TreeCell how to expand nodes after one second
我正在通用 TreeView 上实现拖放。
我的目的是在驻留一秒后在DragEntered事件中展开一个文件夹,实际代码:
setOnDragEntered(e -> {
TreeItem<TreeItemContent> enteredItem = getSourceItem(e);
if(model.isFolder(enteredItem)){
enteredItem.setGraphic(images.getFolderOpened());
enteredItem.setExpanded(true);
}
e.consume();
});
期望:
setOnDragEntered(e -> {
TreeItem<TreeItemContent> enteredItem = getSourceItem(e);
if(model.isFolder(enteredItem)){
if(dragDuration >= 1 sec){
enteredItem.setGraphic(images.getFolderOpened());
enteredItem.setExpanded(true);
}
}
e.consume();
});
这个范围有标准分辨率吗?或者我必须自己实现这个功能?
您可以使用 PauseTransition 添加延迟。在其 setOnFinished()
上,您可以添加在提供的时间过去后要执行的操作。
在 setOnDragEntered()
上,您可以启动 PauseTransition
,在 setOnDragExited()
上,检查 PauseTransition
的 status
是否仍在 RUNNING
状态,stop
吧。
这是一个简单的代码,它在 Button
上使用 setOnMouseEntered()
和 setOnMouseExited()
,而不是上面提到的两个事件。但是,这应该足以给你一个想法。
代码:
import javafx.animation.Animation;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Label label = new Label("Hi");
Button button = new Button("Add");
PauseTransition pt = new PauseTransition(Duration.millis(1000));
pt.setOnFinished( ( ActionEvent event ) -> {
label.setText(String.valueOf("Done!"));
});
button.setOnMouseEntered(event -> {
pt.play();
});
button.setOnMouseExited(event -> {
if(pt.getStatus() == Animation.Status.RUNNING) {
pt.stop();
label.setText("Interrupted");
}
});
VBox box = new VBox(20, label, button);
box.setAlignment(Pos.CENTER);
Scene scene = new Scene(box, 200, 200);
primaryStage.setTitle("Welcome");
primaryStage.setScene(scene);
primaryStage.show();
}
}
我还没有找到这个问题的标准解决方案,但我已经通过自定义实现解决了:
setOnDragEntered(e -> {
TreeItem<TreeItemContent> enteredItem = getSourceItem(e);
model.setEnteredItem(enteredItem);
if(model.isFolder(enteredItem)){
new Thread(()->{
try {
Thread.sleep(1000);
if(enteredItem == model.getEnteredItem()){
enteredItem.setGraphic(images.getFolderOpened());
enteredItem.setExpanded(true);
}
} catch (Exception e1) {}
}).start();
}
}
通过这种方式,我可以将第一个 enteredItem 与我在一秒钟后拥有的 enteredItem 进行比较。
完整性:
private TreeItem<TreeItemContent> getSourceItem(InputEvent e){
return ((TreeCell)e.getSource()).getTreeItem();
}
我正在通用 TreeView 上实现拖放。 我的目的是在驻留一秒后在DragEntered事件中展开一个文件夹,实际代码:
setOnDragEntered(e -> {
TreeItem<TreeItemContent> enteredItem = getSourceItem(e);
if(model.isFolder(enteredItem)){
enteredItem.setGraphic(images.getFolderOpened());
enteredItem.setExpanded(true);
}
e.consume();
});
期望:
setOnDragEntered(e -> {
TreeItem<TreeItemContent> enteredItem = getSourceItem(e);
if(model.isFolder(enteredItem)){
if(dragDuration >= 1 sec){
enteredItem.setGraphic(images.getFolderOpened());
enteredItem.setExpanded(true);
}
}
e.consume();
});
这个范围有标准分辨率吗?或者我必须自己实现这个功能?
您可以使用 PauseTransition 添加延迟。在其 setOnFinished()
上,您可以添加在提供的时间过去后要执行的操作。
在 setOnDragEntered()
上,您可以启动 PauseTransition
,在 setOnDragExited()
上,检查 PauseTransition
的 status
是否仍在 RUNNING
状态,stop
吧。
这是一个简单的代码,它在 Button
上使用 setOnMouseEntered()
和 setOnMouseExited()
,而不是上面提到的两个事件。但是,这应该足以给你一个想法。
代码:
import javafx.animation.Animation;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Label label = new Label("Hi");
Button button = new Button("Add");
PauseTransition pt = new PauseTransition(Duration.millis(1000));
pt.setOnFinished( ( ActionEvent event ) -> {
label.setText(String.valueOf("Done!"));
});
button.setOnMouseEntered(event -> {
pt.play();
});
button.setOnMouseExited(event -> {
if(pt.getStatus() == Animation.Status.RUNNING) {
pt.stop();
label.setText("Interrupted");
}
});
VBox box = new VBox(20, label, button);
box.setAlignment(Pos.CENTER);
Scene scene = new Scene(box, 200, 200);
primaryStage.setTitle("Welcome");
primaryStage.setScene(scene);
primaryStage.show();
}
}
我还没有找到这个问题的标准解决方案,但我已经通过自定义实现解决了:
setOnDragEntered(e -> {
TreeItem<TreeItemContent> enteredItem = getSourceItem(e);
model.setEnteredItem(enteredItem);
if(model.isFolder(enteredItem)){
new Thread(()->{
try {
Thread.sleep(1000);
if(enteredItem == model.getEnteredItem()){
enteredItem.setGraphic(images.getFolderOpened());
enteredItem.setExpanded(true);
}
} catch (Exception e1) {}
}).start();
}
}
通过这种方式,我可以将第一个 enteredItem 与我在一秒钟后拥有的 enteredItem 进行比较。
完整性:
private TreeItem<TreeItemContent> getSourceItem(InputEvent e){
return ((TreeCell)e.getSource()).getTreeItem();
}