我意识到 JavaFX 应用程序中的所有 tableView 和 treeView 在获得焦点后都会选择第一行。因此,即使我单击相应的滚动条,也会选择第一行。既然我当然不想有这样的行为,我想问一下,是否有办法避免这种行为?
编辑:我添加了一个简单的示例,它创建了两个简单的列表。在这里,只要单击空行,就会选择第一行。
编辑2:在代码中添加了两个小侦听器,以便在不重新启动应用程序的情况下可以重复问题。
package testlistview;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class TestListView extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
HBox root = new HBox();
root.setSpacing(10);
Scene primaryStageScene = new Scene(root);
primaryStage.setScene(primaryStageScene);
ListView<String> l1 = new ListView();
l1.getItems().addAll("a", "b", "c", "d", "e", "f", "g");
ListView<String> l2 = new ListView();
l2.getItems().addAll("1", "2", "3", "4", "5", "6", "7");
root.getChildren().addAll(l1, l2);
l1.setOnMouseClicked((MouseEvent e) -> {
l2.getSelectionModel().clearSelection();
});
l2.setOnMouseClicked((MouseEvent e) -> {
l1.getSelectionModel().clearSelection();
});
primaryStage.show();
}
}
编辑3:我意识到当我对表进行排序时,第一行也会被选中。然而,为了避免这种情况,我创建了一个小 hack(这可能是一个非常糟糕的风格,但它现在有效)。
private boolean sorted = false;
// (...)
tableView.addEventFilter(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
if (!tableView.isFocused()) {
if (e.getPickResult().getIntersectedNode() instanceof Label) {
sorted = true;
}
}
}
;
});
tableView.focusedProperty().addListener((a,b,c) -> {
if(!tableView.isPressed() || sorted) {
tableView.getSelectionModel().clearSelection();
sorted = false;
}
});
所以这里 eventFilter 在监听器之前被激活。据我所知,只有标题是实例标签。因此,每次首先单击标题时,选择都会被清除。
然而,正如下面的帖子中所讨论的,我猜这个错误将在下一个 java 版本中消失。