在JavaFX应用程序中聚焦TableView或TreeView时,总是选择第一行 [英] First Row Always Gets Selected When Focussing a TableView or TreeView in a JavaFX Application

查看:505
本文介绍了在JavaFX应用程序中聚焦TableView或TreeView时,总是选择第一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到JavaFX应用程序中的所有tableViews和treeViews都会一集中就选择第一行.结果,即使单击相应的滚动条,也将选择第一行.由于我当然不希望有这种行为,所以我想问一下是否有办法避免这种行为?

I realised that all tableViews and treeViews in my JavaFX application are selecting the first row as soon as they get focused. As a result even when I click on a corresponding scrollbar, the first row will be selected. Since I of course do not want to have such a behaviour, I would like to to ask, if there is a way to avoid this behaviour?

我添加了一个简单的示例,该示例创建了两个低级列表.在这里,只要点击空白行,就会选择第一行.

I added a simple example that creats two humble lists. Here as soon as one clicks on an empty row, the first row gets selected.

在代码中添加了两个小侦听器,这样就可以在不重新启动应用程序的情况下重复出现该问题.

EDIT 2: Added two small listener to the code, so that the problem is repeatable without restarting the application.

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();
    }
}

当我对表格进行排序时,我意识到第一行也被选中.但是,为避免这种情况,我创建了一个小技巧(这可能是一种非常糟糕的样式,但目前可以使用).

EDIT 3: I realised that the first row also gets selected, when I am sorting a table. However, to avoid this, I created a little hack (which is probably a very bad style, but it works for now).

  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在侦听器之前被激活.据我所知,只有标头是实例Label.结果,每次第一次单击标题时,都会清除选择.

So here the eventFilter is activated before the listener. As far as I can see, only the header is of instance Label. As a result each time the header is clicked first, the selection gets cleared.

但是,正如下面的文章中所讨论的那样,我猜该错误将在下一个Java版本中消失.

However, as discussed in the post below, I guess, the bug will disappear with the next java release.

推荐答案

您可以使用table.getSelectionModel().clearSelection()清除所选行.因为您想在表聚焦时将其删除,所以只需将其放在表的focusedProperty的Listener中即可.

You can use the table.getSelectionModel().clearSelection() for clearing the selected row. Because you want to remove it when your table is getting focused, just put it inside Listener of the focusedProperty of the table.

 table.focusedProperty().addListener((a,b,c) -> {
        ...
        table.getSelectionModel().clearSelection();
 });

编辑当您的问题涉及TableViewTreeView时,我不确定您要使用ListView做什么.

I am not sure what you are trying to do with a ListView, when your question talks about TableView and TreeView.

您应在ListView

l1.focusedProperty().addListener((a,b,c) -> {
    if(!l1.isPressed()) {
        l1.getSelectionModel().clearSelection();
    }
});

注意:这将导致无法一键选择行

Note : This will lead to not able to not able to select the rows with one click

更新:完整代码

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();
        });

        l1.focusedProperty().addListener((a,b,c) -> {
            if(!l1.isPressed()) {
                l1.getSelectionModel().clearSelection();
            }
        });

        primaryStage.show();
    }
}

这篇关于在JavaFX应用程序中聚焦TableView或TreeView时,总是选择第一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆