2016-11-09 54 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我可以看到为什么会发生,但我无法可靠地重现它。细胞中的选择/聚焦有点棘手。 –