This discussion is archived
7 Replies Latest reply: Jan 17, 2013 1:38 AM by 967684 RSS

Resizing ListView Cell programmatically

967684 Newbie
Currently Being Moderated
Hello, i have ListView which contains some data, every cell has 3 labels and treeView.
What i need is to enlarge ListView cell (and all it children) when user select some cell.
How can i do that, please help?

Edited by: 964681 on Jan 15, 2013 6:10 AM
  • 1. Re: Resizing ListView Cell programmatically
    svanimpe Newbie
    Currently Being Moderated
    Have you tried one of the following:

    1) Using CSS, by using the selector ".list-cell:selected"
    2) Using a CellFactory, as described here: [http://docs.oracle.com/javafx/2/ui_controls/list-view.htm#CEGIIDDC], and overriding updateSelected(boolean) to react to changes in the selection.
  • 2. Re: Resizing ListView Cell programmatically
    967684 Newbie
    Currently Being Moderated
    As i said above, i defined listCell in different fxml which contains 3 label and treeView.
    I tried:
    .list-view:focused .list-cell:filled:focused:selected {
         -fx-cell-size: 200 ;
    }
    but then when i select particular item(cell) of a listView, cell size is expanded to 200 but treeView size stays the same.
  • 3. Re: Resizing ListView Cell programmatically
    984080 Explorer
    Currently Being Moderated
    Add
    myTreeView.requestLayout()
    when the cell is expanding.

    If this still not works, check the prefSize() and maxSize() of your treeview and make that it's big enough.
  • 4. Re: Resizing ListView Cell programmatically
    967684 Newbie
    Currently Being Moderated
    Nothing works, i am so desperate :(
  • 5. Re: Resizing ListView Cell programmatically
    967684 Newbie
    Currently Being Moderated
    Maybe it can help if someone knows how can i do this programmatically :

    .list-view:focused .list-cell:filled:focused:selected {
         -fx-cell-size: 200 ;
    }
  • 6. Re: Resizing ListView Cell programmatically
    James_D Guru
    Currently Being Moderated
    My first question here would be whether or not you really want a ListView. Would a simple VBox suffice? That should manage the layout when you expand nodes in the TreeView, and so on. If you just need the selection, it might turn out to be easier to manage the selection yourself, rather than manage the layout.

    If you really do need/want a ListView, though, see if this helps:
    import java.util.Arrays;
    import java.util.List;
    
    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.control.TreeItem;
    import javafx.scene.control.TreeView;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    public class ComplexListView extends Application {
    
      @Override
      public void start(Stage primaryStage) {
        final List<String> allData = Arrays.asList("One", "Two", "Three", "Four",
            "Five", "Six", "Seven", "Eight", "Nine", "Ten");
        final ObservableList<ComplexData> listViewData = FXCollections.observableArrayList();
        for (int i = 1; i <= allData.size(); i++) {
          listViewData.add(new ComplexData(allData.subList(0, i)));
        }
        final ListView<ComplexData> listView = new ListView<ComplexData>(listViewData);
        
        listView.setCellFactory(new Callback<ListView<ComplexData>, ListCell<ComplexData>>() {
          @Override
          public ListCell<ComplexData> call(ListView<ComplexData> listView) {
            return new ComplexDataListCell();
          }
        });
    
        final BorderPane root = new BorderPane();
        root.setCenter(listView);
        final Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
      }
    
      public static void main(String[] args) {
        launch(args);
      }
    
      private static class ComplexDataListCell extends ListCell<ComplexData> {
    
        private static final double SELECTED_HEIGHT = 200;
        private static final double DESELECTED_HEIGHT = 20;
    
        private final HBox hbox;
        private final Label label1;
        private final Label label2;
        private final Label label3;
        private final TreeView<String> treeView;
        private final TreeItem<String> root;
    
        ComplexDataListCell() {
          hbox = new HBox();
          label1 = new Label();
          label2 = new Label();
          label3 = new Label();
          root = new TreeItem<String>("Root");
          treeView = new TreeView<String>();
          treeView.setRoot(root);
          hbox.getChildren().addAll(label1, label2, label3, treeView);
          hbox.prefHeightProperty().bind(
              Bindings
                .when(selectedProperty())
                .then(SELECTED_HEIGHT)
                .otherwise(DESELECTED_HEIGHT)
          );
    
        }
    
        @Override
        public void updateItem(ComplexData data, boolean empty) {
          super.updateItem(data, empty);
          if (!empty) {
            label1.setText(data.getFirstString());
            label2.setText(data.getSecondString());
            label3.setText(data.getThirdString());
            root.getChildren().clear();
            for (String s : data.getTreeData()) {
              root.getChildren().add(new TreeItem<String>(s));
            }
            setGraphic(hbox);
          } else {
            setGraphic(null);
          }
    
        }
    
        // This will expand or collapse the root node when the list cell containing
        // it is selected or deselected,
        // respectively. This method can be omitted completely if this functionality
        // is not required.
        @Override
        public void updateSelected(boolean selected) {
          super.updateSelected(selected);
          root.setExpanded(selected);
        }
      }
    
      private static class ComplexData {
        private final String firstString;
        private final String secondString;
        private final String thirdString;
        private final List<String> treeData;
    
        ComplexData(List<String> treeData) {
          this.treeData = treeData;
          this.firstString = "Text 1";
          this.secondString = "Text 2";
          this.thirdString = "Text 3";
        }
    
        public String getFirstString() {
          return firstString;
        }
    
        public String getSecondString() {
          return secondString;
        }
    
        public String getThirdString() {
          return thirdString;
        }
    
        public List<String> getTreeData() {
          return treeData;
        }
    
      }
    }
    Edited by: James_D on Jan 16, 2013 10:02 AM (Refactored to use named inner class instead of Anonymous class for the ListCell implementation. Also used single instances of the controls and hbox, and bindings to manage the height of the hbox instead of directly setting in the updateSelected(...) method.)
  • 7. Re: Resizing ListView Cell programmatically
    967684 Newbie
    Currently Being Moderated
    This solved my problem :), line: hbox.prefHeightProperty().bind(Bindings.when(selectedProperty()).then(SELECTED_HEIGHT).otherwise(DESELECTED_HEIGHT));
    was decisive.

    I did this:

    AnchorPane anchorPane = FXMLLoader.load(new URL("url"));
    anchorPane.prefHeightProperty().bind(Bindings.when(selectedProperty()).then(x).otherwise(y));

    Thank you so much...

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points