2014-12-20 10 views
1

。聚焦一個TableView中或TreeView中,我意識到,在我的JavaFX應用程序的所有tableViews和樹視圖都只要他們得到集中選擇第一行。因此,即使我點擊一個對應的滾動條,第一行也會被選中。既然我當然不想有這樣的行爲,我想問一下,是否有辦法避免這種行爲?第一行始終被選中當在JavaFX應用程序

編輯:我添加了一個簡單的例子,外幣2個不起眼的清單。這裏只要點擊一個空行,第一行就會被選中。

編輯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:我意識到第一行也被選中,當我排序表。然而,爲了避免這種情況,我創建了一個小黑客(這可能是一個非常糟糕的風格,但它現在工作)。

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。因此每次首先單擊標題時,選擇都會被清除。

然而,如下面的討論後,我想,這個bug會在下一版本的Java消失。

回答

0

可以使用table.getSelectionModel().clearSelection()清除所選行。因爲你要當你的表是越來越集中刪除它,只是把它裏面的監聽器表的focusedProperty的。

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

編輯爲comment

我不知道你正在嘗試用ListView,您的問題時談到TableViewTreeView做。

你應該使用相同的監聽器爲您ListView

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

注意:這將導致不能夠不能夠與點擊

更新選擇行:完整代碼

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

謝謝您的回答,恕不另行通知)項變更。但是,這種方法的問題在於,當我明確點擊一行時,偵聽器也會被觸發。在這種情況下,應該選擇該行。對不起,沒有正確指出這一點。那麼當我明確點擊一個非空行時,是否還有一種方法可以避免偵聽器觸發? – Duke134

+0

表格在第一次鼠標單擊時從不選擇一行。第一次鼠標點擊被保留爲焦點。從第二次點擊開始,表格將聽取行選擇。 – ItachiUchiha

+0

感謝您對我的問題如此感興趣。不過,我在第一篇文章中添加了一段代碼片段。所以當你啓動這個代碼並點擊一個空行時,第一行總是在應用程序中被選中,這對我來說是一個不直觀的行爲。 – Duke134

5

我有同樣的問題。找到這個答案非常有幫助:

How to make the first 2 rows in a JavaFX listview non-selectable

根據其jdk8您使用,這可能是修復的確切(更新)版本RT-25679(在RT-38517部分恢復)據我所知,一般來說,沒有公共API可以禁用集合視圖的自動聚焦/選擇。只有ListView有(無證!當心,它們可以在其屬性是禁用默認的行爲

// disable selecting the first item on focus gain - this is 
// not what is expected in the ComboBox control (unlike the 
// ListView control, which does this). 
listView.getProperties().put("selectOnFocusGain", false); 
// introduced between 8u20 and 8u40b7 
// with this, testfailures back to normal 
listView.getProperties().put("selectFirstRowByDefault", false); 
+0

嗨,謝謝你的提示。我試用了我的測試程序,它適用於ListViews!不幸的是,它並沒有解決TableViews的問題。儘管如此,在目前的版本1.8.0_40中,這個問題不再出現,所以這個修復不再是必需的(即使是表格)。如果可能的話,您可以使用您的程序試用當前的JDK版本,並告訴我它是否也解決了您的問題。 – Duke134

相關問題