在jquery中,有on
功能会自动将事件绑定到以后添加的项目(例如ajax调用),它看起来像这样:
$(document).on("click", ".my-class", function(){
// Do my event task here
});
现在每次将具有班级my-class
的项目添加到自动附加事件的dom中。
Java
或JavaFx
中有类似的内容吗?我想将我的事件保存在我的控制器中,并且在我喜欢用我正在处理的代码调用Helper Classes
时使用其他方法我不知道如何实现这一点。
所以我在控制器中有这个:
Tree tree = new Tree(currentMysqlConn);
tree.addDatabases(treeItem);
然后创建TreeItem
然后创建子项,并且这些子项在单击时具有事件。这是一个例子:
TreeItem<String> tableNode = new TreeItem<>("Tables", tableIcon);
tableNode.expandedProperty().addListener(new ChangeListener(){
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue){
if((boolean) newValue){
TableActions ta = new TableActions(tableNode);
ta.getTables(conn);
}
}
});
问题是,我在Helper Class
中有这个问题,那么我可以做些什么来将其移植到我的控制器中?因为那是在一个循环中。
答案 0 :(得分:3)
您可以使用任何可观察列表(例如,从TreeItem.getChildren()
或Parent.getChildren()
获得的列表)注册侦听器,并递归地让该侦听器向添加到列表中的任何子项注册相同的侦听器。
以下示例更新显示树视图中节点总数的标签。为此,我们需要知道何时将子节点添加到任何节点,因此我们需要与动态添加的节点关联的侦听器。您的用例可能略有不同,但如果您了解其工作原理,您应该能够实现所需。请注意,虽然我在这里没有任何其他类,但如果UI的内容从任何地方更改,控制器将通过听众适当地通知。
CountingTreeViewController.java:
import java.util.concurrent.atomic.AtomicInteger;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.collections.ListChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
public class CountingTreeViewController {
@FXML
private TextField itemTextField ;
@FXML
private TreeView<String> tree ;
@FXML
private Label countLabel ;
// binding that contains the total count of all nodes
// the computeValue() method recursively counts the number of children
// of each node
// This binding needs to be invalidated if the list of child nodes of any
// tree node changes...
private final IntegerBinding count = new IntegerBinding() {
@Override
protected int computeValue() {
// Note the AtomicInteger here is just used as a mutable wrapper.
// We don't care about the atomicity since it's only updated from
// one thread
return countNodes(tree.getRoot(), new AtomicInteger());
}
private int countNodes(TreeItem<?> node, AtomicInteger count) {
count.incrementAndGet();
for (TreeItem<?> child : node.getChildren()) {
countNodes(child, count);
}
return count.intValue();
}
};
// A ListChangeListener that will be associated with any tree node. It does two things:
// First, it invalidates the count binding above if the number of child nodes changes.
// Second, it adds the same listener to any new child nodes, and removes it from any nodes
// that are removed from the tree.
private final ListChangeListener<TreeItem<String>> childrenChanged
= new ListChangeListener<TreeItem<String>>() {
@Override
public void onChanged(
javafx.collections.ListChangeListener.Change<? extends TreeItem<String>> change) {
while (change.next()) {
if (change.wasAdded() || change.wasRemoved()) {
count.invalidate();
}
if (change.wasAdded()) {
for (TreeItem<String> item : change.getAddedSubList()) {
item.getChildren().addListener(childrenChanged);
}
} else if (change.wasRemoved()) {
for (TreeItem<String> item : change.getRemoved()) {
item.getChildren().removeListener(childrenChanged);
}
}
}
}
};
public void initialize(){
tree.getRoot().getChildren().addListener(childrenChanged);
countLabel.textProperty().bind(Bindings.format("Count: %s", count));
}
// add a new child node to the selected node (or the root if nothing's selected)
@FXML
private void addItem() {
TreeItem<String> item = tree.getSelectionModel().getSelectedItem();
if (item == null) {
item = tree.getRoot();
}
TreeItem<String> newItem = new TreeItem<>(itemTextField.getText());
newItem.setExpanded(true);
item.getChildren().add(newItem);
itemTextField.setText("");
itemTextField.requestFocus();
}
}
CountingTree.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.control.TreeItem?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="CountingTreeViewController">
<center>
<TreeView fx:id="tree">
<root>
<TreeItem value="Root" expanded="true" />
</root>
</TreeView>
</center>
<right>
<HBox alignment="CENTER" spacing="5">
<padding>
<Insets top="10" right="10" left="10" bottom="10"/>
</padding>
<TextField fx:id="itemTextField" onAction="#addItem"/>
<Button text="Add" onAction="#addItem"/>
</HBox>
</right>
<bottom>
<Label text="Count: 1" fx:id="countLabel"/>
</bottom>
</BorderPane>
CountingTree.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class CountingTree extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("CountingTree.fxml"));
primaryStage.setScene(new Scene(loader.load(), 800, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
答案 1 :(得分:0)
如果您可以访问TreeView的根节点,则可以非常简单地完成:
查看TreeItem和TreeModificationEvent文档。您可以为childrenModificationEvent的根节点添加侦听器。每当在根节点下添加或删除节点时,您将获得TreeModificationEvent,您可以在其中检索添加和删除的节点。