2016-11-09 69 views
2

我有一個controlsfx CheckListView(甚至與javafx ListView控件相同的問題),我想顯示RadioButtons而不是CheckBox。所以我通過從幾個javafx教程中獲得幫助來實現了自定義單元工廠,並且它正在工作。 問題是我選擇了第一個單選按鈕並向下滾動一點,這樣我的頂級單選按鈕中的幾個就會向上滾動並且不可見。然後我再次滾動,選擇現在消失了。javafx ListView與自定義單元格工廠不保留所選單元格

我調試代碼瞭解,每次都會創建新的單元,導致此問題,但不幸找不到解決方案。

我附上一個示例代碼,我從堆棧溢出它具有相同的問題。

package application; 
import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.ListCell; 
import javafx.scene.control.ListView; 
import javafx.scene.control.RadioButton; 
import javafx.scene.control.ToggleGroup; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class RadioButtonListView extends Application { 

    public static final ObservableList names = FXCollections.observableArrayList(); 
    private ToggleGroup group = new ToggleGroup(); 

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("List View Sample"); 

     final ListView listView = new ListView(); 
     listView.setPrefSize(200, 250); 
     listView.setEditable(true); 

     names.addAll("Adam", "Alex", "Alfred", "Albert", "Brenda", "Connie", "Derek", "Donny", "Lynne", "Myrtle", "Rose", "Rudolph", "Tony", "Trudy", "Williams", "Zach"); 

     listView.setItems(names); 
     listView.setCellFactory(param -> new RadioListCell()); 
     StackPane root = new StackPane(); 
     root.getChildren().add(listView); 
     primaryStage.setScene(new Scene(root, 200, 250)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    private class RadioListCell extends ListCell<String> { 
     @Override 
     public void updateItem(String obj, boolean empty) { 
      super.updateItem(obj, empty); 
      if (empty) { 
       setText(null); 
       setGraphic(null); 
      } else { 
       RadioButton radioButton = new RadioButton(obj); 
       radioButton.setToggleGroup(group); 
       // Add Listeners if any 
       setGraphic(radioButton); 
      } 
     } 
    } 
} 

請需要烏爾此幫助。(我使用JavaFX 8)

回答

4

你應該爲細胞創造一個單選按鈕(而不是創建一個新的每次updateItem(...)被調用,在使用適當的邏輯從數據表示的updateItem(...)方法更新其選擇狀態

private class RadioListCell extends ListCell<String> { 

    private final RadioButton radioButton = new RadioButton(); 

    RadioListCell() { 
     radioButton.setToggleGroup(group); 
     // Add listeners here... 
    } 

    @Override 
    public void updateItem(String obj, boolean empty) { 
     super.updateItem(obj, empty); 
     if (empty) { 
      setText(null); 
      setGraphic(null); 
     } else { 
      radioButton.setText(obj); 

      radioButton.setSelected(...); 

      setGraphic(radioButton); 
     } 
    } 
} 

,例如:

import java.util.Objects; 

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.ListCell; 
import javafx.scene.control.ListView; 
import javafx.scene.control.RadioButton; 
import javafx.scene.control.ToggleGroup; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class RadioButtonListView extends Application { 

    public static final ObservableList<String> names = FXCollections.observableArrayList(); 
    private ToggleGroup group = new ToggleGroup(); 

    private String selectedName ; 

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("List View Sample"); 

     final ListView<String> listView = new ListView<>(); 
     listView.setPrefSize(200, 250); 
     listView.setEditable(true); 

     names.addAll("Adam", "Alex", "Alfred", "Albert", "Brenda", "Connie", "Derek", "Donny", "Lynne", "Myrtle", "Rose", "Rudolph", "Tony", "Trudy", "Williams", "Zach"); 

     listView.setItems(names); 
     listView.setCellFactory(param -> new RadioListCell()); 
     StackPane root = new StackPane(); 
     root.getChildren().add(listView); 
     primaryStage.setScene(new Scene(root, 200, 250)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    private class RadioListCell extends ListCell<String> { 

     private final RadioButton radioButton = new RadioButton(); 

     RadioListCell() { 
      radioButton.setToggleGroup(group); 
      radioButton.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> { 
       if (isNowSelected) { 
        selectedName = getItem(); 
       } 
      }); 
     } 

     @Override 
     public void updateItem(String obj, boolean empty) { 
      super.updateItem(obj, empty); 
      if (empty) { 
       setText(null); 
       setGraphic(null); 
      } else { 
       radioButton.setText(obj); 

       radioButton.setSelected(Objects.equals(obj, selectedName)); 

       setGraphic(radioButton); 
      } 
     } 
    } 
} 
+0

你救了我的一天。非常感謝。其實我也嘗試過,但不知何故中途失利。我想把這個告訴你的知識。您的解決方案正在工作,但是如果我選擇第一個單選按鈕,它將被選中,但第11個單選按鈕的圓形(如果10個按鈕可見)將變得突出顯示。 (未選擇,但獲得焦點)。現在不是問題。再次感謝。 –

+0

http://imgur.com/EnfGCcP –

+1

@SaravanaKumar我可以看到爲什麼會發生,但我無法可靠地重現它。細胞中的選擇/聚焦有點棘手。 –