Checkbox cell factory + Tableview

I'm writing a JavaFX client for my soap service, and of my fxml pages must contain a fully-editable TableView, which consists of Product-class entities.My table consists now of 2 text columns and one, which consists of Double values.I want to add a selection column with CheckBox items in it cells.Using a Ensemble demo app I extended a Cell class for using a CheckBoxes :
public class CheckBoxCell<S, T> extends TableCell<S, T> {
private final CheckBox checkBox;
private ObservableValue<T> ov;
public CheckBoxCell() {
    this.checkBox = new CheckBox();
    this.checkBox.setAlignment(Pos.CENTER);
    setAlignment(Pos.CENTER);
    setGraphic(checkBox);
@Override
public void updateItem(T item, boolean empty) {
    super.updateItem(item, empty);
    if (empty) {
        setText(null);
        setGraphic(null);
    } else {
        setGraphic(checkBox);
        if (ov instanceof BooleanProperty) {
            checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov);
        ov = getTableColumn().getCellObservableValue(getIndex());
        if (ov instanceof BooleanProperty) {
            checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov);
@Override
public void startEdit() {
    super.startEdit();
    if (isEmpty()) {
        return;
    checkBox.setDisable(false);
    checkBox.requestFocus();
@Override
public void cancelEdit() {
    super.cancelEdit();
    checkBox.setDisable(true);
}Then in fxml view controller class I set a cellFactory for requed TableColumn :
private Callback<TableColumn, TableCell> createCheckBoxCellFactory() {
    Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>  () {
        @Override
        public TableCell call(TableColumn p) {
            return new CheckBoxCell();
    return cellFactory;
products_table_remove.setCellFactory(createCheckBoxCellFactory());My question is :
1) how to fill this column with unchecked CheckBoxes using PropertyValueFactory if i have
private final ObservableList <Boolean> productsToRemove= FXCollections.observableArrayList();consists of Boolean.FALSE values then view is created. (TableView consists of Product class that does'nt have a Boolean property (only 3 String and one Double property)) ?
2) Can i get acess to Product object, which contain selected row using EventHandler :
private void setProductDescColumnCellHandler() {
    products_table_remove.setOnEditCommit(new EventHandler() {
        @Override
        public void handle(CellEditEvent t) {
        ...I saw a lot of examples with Entites, which have a Boolean field.In my case, i dont want to add boolean field to jax-ws generated classes.

Thanks for advice. I decided to create a Product wrapper class like so :
public class ProductWrapper extends Product {
    public ProductWrapper(Product product) {
        _product = product;
    final Product _product;
    Boolean to_delete = false;
    public Boolean getTo_delete() {
        return to_delete;
    public void setDelected(Boolean _delected) {
        this.to_delete = _delected;
    public double getCost() {
        return _product.getCost();
    public void setCost(double value) {
        _product.setCost(value);
    public String getDescription() {
        return _product.getDescription();
    public void setDescription(String value) {
        _product.setDescription(value);
    public String getName() {
        return _product.getName();
    public void setName(String value) {
        _product.setName(value);
    public Product getProduct() {
        return _product;
    public Boolean getDelected() {
        return to_delete;
}Then I use this wrapper in all factories :
products_table_remove.setCellValueFactory(new PropertyValueFactory<ProductWrapper, Boolean>("to_delete"));
products_table_remove.setCellFactory(createCheckBoxCellFactory());
private void setProductDeleteCellHandler() {
        products_table_remove.setOnEditStart(new EventHandler<CellEditEvent<ProductWrapper, Boolean>>() {
            @Override
            public void handle(CellEditEvent<ProductWrapper, Boolean> t) {
                System.out.println("Checked");
}My question - how to bind CheckBox click event to setProductDeleteCellHandler() method using that CheckBoxCell class :
public class CheckBoxCell<S, T> extends TableCell<S, T> {
private final CheckBox checkBox;
private ObservableValue<T> ov;
public CheckBoxCell() {
    this.checkBox = new CheckBox();
    this.checkBox.setAlignment(Pos.CENTER);
    setAlignment(Pos.CENTER);
    setGraphic(checkBox);
@Override
public void updateItem(T item, boolean empty) {
    super.updateItem(item, empty);
    if (empty) {
        setText(null);
        setGraphic(null);
    } else {
        setGraphic(checkBox);
        if (ov instanceof BooleanProperty) {
            checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov);
        ov = getTableColumn().getCellObservableValue(getIndex());
        if (ov instanceof BooleanProperty) {
            checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov);
@Override
public void startEdit() {
    super.startEdit();
    if (isEmpty()) {
        return;
    checkBox.setDisable(false);
    checkBox.requestFocus();
@Override
public void cancelEdit() {
    super.cancelEdit();
    checkBox.setDisable(true);
}

Similar Messages

  • JavaFX 2.0 TableView - Navigation of TableView Cell Factory using Keyboard

    Hi All,
    I have a particular query as regards a JavaFX TableView, specifically cell Navigation using the arrow Keys on the keyboard.
    I have a TableView of multiple rows and columns. Inside each of the table cells i have created a cellfactory that turns each of the cells into a TextInput Field. Essentially i am trying to create a good old Excel Spreadsheet in terms of look and feel. Although now i have the cellfactory and functionality working the way i would like, I have come accross an issue though in terms of the navigation using the keyboard arrow keys.
    I was wondering if anyone could advise as regards, how i can get the focus of the TextInput within my tableCell that im currently in, and then be able to move up/down/left/right using the keys without going out of the bounds of the TableView. Surely this has be built in to the API, or am i having this problem as im using a custom cell factory?
    I have read that in 2.2 there is improved nav functionality but we are not there yet and am trying to work around this issue.
    Input greatly appreciated
    Thanks

    I have made such features in my application, you can achieve this by adding event listener to TextCell:
    textField.setOnKeyReleased(new EventHandler< KeyEvent>() {
    public void handle(KeyEvent t) {
    if (t.getCode() == KeyCode.ENTER) {
    commitEdit(textField.getText());
    getTableView().getFocusModel().focusRightCell();
    getTableView().edit(getTableRow().getIndex(), getTableView().getFocusModel().getFocusedCell().getTableColumn());
    .....

  • What exactly is the "cell factory?"

    So I've been seeing this term a lot on the forums, as well as http://docs.oracle.com/javafx/2/ui_controls/table-view.htm and on the ensemble, but I'm not 100% sure what it is.... It seems like just a method to set data into your tables, like the table model? Anyone have a more in depth explanation than the one in the docs, I would appreciate it!!!
    Thanks,
    ~KZ

    Cell factories create cells. A cell is a Labeled Node which contains some extra properties and methods for maintaining an editing and selection state and a link back to a cell value. Cells are used in a few places in JavaFX, for example in ListViews and TableViews, as well as TreeTables and ComboBoxes. The Cell is the visual representation (Node) which corresponds to a backing data item. The trick is that there is not necessarily a static one to one correspondence between cells and data values.
    Let's take an example. Here is an empty ListView in a Scene. When I run the app, it displays the ListView at it's preferred height, with 17 rows.
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    public class ListViewSample extends Application {
      @Override public void start(Stage stage) {
        ListView listView = new ListView();
        VBox layout = new VBox();
        VBox.setVgrow(listView, Priority.ALWAYS);
        layout.getChildren().addAll(listView);
        stage.setScene(new Scene(layout));
        stage.show();
      public static void main(String[] args) { launch(args); }
    }Each one of those 17 rows is empty. No Cell Factory has been set, yet you can see alternating light and dark shaded rows. Each one of these rows in the ListView corresponds to a Cell and each cell has been generated by the default ListView cell factory. When I drag the stage's bottom border to increase the size of the stage, the list view increases in size. When I drag the stage's bottom border to decrease the size of the stage, the list view decreases in size. When the list view increases in size, more rows are visible. Each of the new cells for the larger list view are generated by the cell factory on an as needed basis; i.e. the cells were not created when the app was first run but only created as there was a greater visible area available to the ListView in which the ListView could display more cells.
    Now everything is pretty boring so far. Let's add some data, using the following line of code:
    listView.setItems(FXCollections.observableArrayList("apple", "orange", "pear"));Now you will see the strings "apple", "orange" and "pear" rendered in the first three cells of the ListView again by using the default cell factory for the ListView. Again this is pretty boring.
    What we will do now is add some mutators which will change the observable list backing the list view in response to some user actions:
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.event.*;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    import java.util.Collections;
    import java.util.Comparator;
    public class ListViewSample extends Application {
      @Override public void start(Stage stage) {
        final ListView<String> listView = new ListView<>();
        listView.setItems(FXCollections.observableArrayList("apple", "orange", "pear"));
        ListViewSorter listViewSorter = new ListViewSorter(listView).invoke();
        VBox layout = new VBox(10);
        VBox.setVgrow(listView, Priority.ALWAYS);
        listView.setMinHeight(0);
        layout.getChildren().addAll(
            listView,
            HBoxBuilder
                .create()
                .spacing(10)
                .children(
                    guavaCreator(listView),
                    listViewSorter.getSorter(),
                    listViewSorter.getReverser()
                .build()
        stage.setScene(new Scene(layout));
        stage.show();
      private Button guavaCreator(final ListView<String> listView) {
        final Button guavatron = new Button("Add Guava");
        guavatron.setOnAction(new EventHandler<ActionEvent>() {
          @Override public void handle(ActionEvent actionEvent) {
            listView.getItems().add("guava");
            guavatron.setDisable(true);
        return guavatron;
      public static void main(String[] args) { launch(args); }
      private class ListViewSorter {
        private final ListView<String> listView;
        private Button sorter;
        private Button reverser;
        public ListViewSorter(ListView<String> listView) {
          this.listView = listView;
        public Button getSorter() {
          return sorter;
        public Button getReverser() {
          return reverser;
        public ListViewSorter invoke() {
          sorter = new Button("Sort");
          sorter.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              Collections.sort(listView.getItems());
          final Comparator<String> REVERSE_SORT = new Comparator<String>() {
            @Override  public int compare(String s1, String s2) {
              return -1 * s1.compareTo(s2);
          reverser = new Button("Reverse Sort");
          reverser.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              Collections.sort(listView.getItems(), REVERSE_SORT);
          return this;
    }OK, now we have some extra buttons, the "Add guava" button will create a new item ("guava"), the "Sort" and "Reverse Sort", buttons will change the sort order of the backing list. Now to understand what happens behind the scenes when we use these buttons, let's take a look at the source code for the default list cell factory.
    new ListCell() {
       @Override public void updateItem(Object item, boolean empty) {
         super.updateItem(item, empty);
         if (empty) {
           setText(null);
           setGraphic(null);
         } else if (item instanceof Node) {
           setText(null);
           Node currentNode = getGraphic();
           Node newNode = (Node) item;
           if (currentNode == null || ! currentNode.equals(newNode)) {
             setGraphic(newNode);
         } else {
           setText(item == null ? "null" : item.toString());
           setGraphic(null);
    };This code is doing one of three things. If the list cell is empty, it sets the text and graphic to null, so you end up with a blank cell (the alternating light and dark grey bars are generated by the ListCell's parent setting differing style classes on alternate cells). If the item is a node, it sets the graphic to the node - this is the mechanism which allow you to place nodes directly in the backing list for the ListView and have the ListView display them OK. Otherwise a toString is called on the item to set the item's text (this is the case which is occurring for our simple example of Strings in the backing list).
    Now the important thing to note about the ListCell implementation is that the clever logic of translating the backing item for the cell to a visual representation is occurring in an updateItem call. This updateItem method is invoked by the JavaFX system on the ListCell whenever the backing item for the cell has been invalidated, for example the item has been edited, a new item added, or the items in the list have been reordered.
    So when somebody presses, the "Add Guava" button, a new ListCell is not created, instead updateItem is called on an already existing empty cell. This is because when we started the application, there was space for 17 rows, so 17 cells were already created, it is just that most of them were empty because we only had 3 items in the backing list for the ListView.
    Now, if we press one of the sort buttons to reorder the backing list, it will cause the existing list cells to become invalidated, and updateItem will be called on each of the cells according to the change permutations in the ObservableList. Note that as each item is updated, a new Labeled display node for the item is not created, instead the setText method is invoked which changes the text for the existing Labeled.
    There are a couple of extra cases to understand. Our backing list currently maxes out at 4 items. Let's say we drag the bottom of our stage up so that the available space for the ListView was made really small (e.g. only 2 rows high). In this case, you will two rows (cells) and a scrollbar you can use to scroll up and down. As you scroll up and down it seems that some rows are scrolling off the screen and some are scrolling on the screen. What is actually happening though is that the same two cells are remaining on screen and their contents being continually updated and replaced as backing items come in and out of view. This is the magic of how the ListView is able to achieve it's efficiency when dealing with potentially very large collections or collections where not all of the required data is available on the client at the current time. Instead of creating visual cells for all of the possible items which can be placed in the list, instead the ListView creates cells only for the visible items and updates the content of those cells on an as needed basis. This concept is known in the List Cell creators jargon as a Virtual Flow in a Virtualized control.
    OK, so that was a little more interesting, but there have been a lot of words so far, and no custom cell factory. This was partly on purpose - there is lot you can do with the default cell factory without needing to create your own custom cell factory.
    But sometimes you do actually want to create your own cell factory when you want fine control over the look or behaviour of the cells.
    Let's say you want to show each item in the list with a capitalized friendly name "Apple", "Orange" and "Pear" and an icon - a picture of the corresponding fruit. To do this you would create a cell factory - something that can produce the visual representation of these things from the corresponding data values.
    import javafx.application.Application;
    import javafx.collections.*;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.image.*;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class ListViewCustomCellFactorySample extends Application {
      ObservableMap<String, Image> iconMap = FXCollections.observableHashMap();
      @Override public void init() {
        iconMap.put(
          "apple", 
          new Image(
            "http://uhallnyu.files.wordpress.com/2011/11/green-apple.jpg",
            0, 32, true, true
        iconMap.put(
          "orange",
          new Image(
            "http://i.i.com.com/cnwk.1d/i/tim/2011/03/10/orange_iStock_000001331357X_540x405.jpg",
            0, 32, true, true
        iconMap.put(
          "pear",  
          new Image(
            "http://smoothiejuicerecipes.com/pear.jpg",
            0, 32, true, true
      @Override public void start(Stage stage) {
        final ListView<String> listView = new ListView<>();
        listView.setItems(FXCollections.observableArrayList("apple", "orange", "pear"));
        listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
          @Override public ListCell<String> call(ListView<String> stringListView) {
            return new LabeledIconListCell();
        VBox layout = new VBox(10);
        VBox.setVgrow(listView, Priority.ALWAYS);
        listView.setMinHeight(0);
        layout.getChildren().addAll(
            listView
        stage.setScene(new Scene(layout));
        stage.show();
      public static void main(String[] args) { launch(args); }
      private class LabeledIconListCell extends ListCell<String> {
        @Override protected void updateItem(String item, boolean empty) {
          super.updateItem(item, empty);
          if (item != null) {
            String friendlyText = item.toString();
            if (item.length() > 0) {
              friendlyText = item.substring(0, 1).toUpperCase() + item.substring(1);
            setText(friendlyText);
            setGraphic(
                StackPaneBuilder
                    .create()
                    .prefWidth(55)
                    .children(
                        new ImageView(
                            iconMap.get(item)
                    .build()
          } else {
            setText("");
            setGraphic(null);
    }Here what the cell factory has done is to check what value of the backing item for the cell is whenever that item has been updated, and set some customized label text and graphic representation for the cell.
    As a minor point, for efficiency, and because there are only a few of them, the required images are loaded and scaled up front so that they don't been to be reloaded every time the cell is updated with a different value (which if the image loading was within the cell's updateItem call could mean that the same image could potentially get loaded multiple times.
    My personal take on this is that it is powerful but complicated. Often people will gravitate towards using the complex ListView and TableView APIs when they don't necessarily need all of the functionality and virtualization efficiency capabilities that the virtualized controls offer. In many cases, simple layout mechanisms such VBoxes and Grids can be a better choice. However, if you have a need for the virtualized functions, then it's good to know that things like ListView and TableView are there if you can work out how to use them well in your case.
    Also note that JavaFX 2.2+ has numerous convenience methods for creating different kinds of cells which you may be able to use in standard cases to avoid some of the overhead in creating your own, for example the CheckBoxListCell, the ComboBoxListCell and the TextFieldListCell. And there are many more such simplifying higher level abstractions in the DataFX library.
    One other point worth observing is that if you have a list of mutatable objects, for example Person objects with a changable last name field, then you need to make the object an Observable object with an invalidation implementation if you want the updateItem call in the cell factory to be invoked automatically whenever the object is mutated.
    A cell factory and a cell value factory are different things, but that is probably a topic for a different post.
    I realize this was a round about and lengthy explanation - hopefully it served some purpose and helped to explain some of the mysteries of cell factories.
    http://docs.oracle.com/javafx/2/api/javafx/scene/control/Cell.html
    http://www.javafxdata.org
    http://docs.oracle.com/javafx/2/ui_controls/list-view.htm

  • How can I get an instance of my customize cell in tableview?

    Hi,I'd like to generate a customize tablecell in my tableview.but How can I get an instance of my customize cell in tableview when selected item changes?
    public class Person {
              private javafx.beans.property.BooleanProperty active;
              private StringProperty firstName;
              private StringProperty lastName;
              private StringProperty email;
              private Person(String fName, String lName, String email) {
                   this.active = new SimpleBooleanProperty(true);
                   this.firstName = new SimpleStringProperty(fName);
                   this.lastName = new SimpleStringProperty(lName);
                   this.email = new SimpleStringProperty(email);
              public javafx.beans.property.BooleanProperty activeProperty() { return active; }
              public StringProperty firstNameProperty() { return firstName; }
              public StringProperty lastNameProperty() { return lastName; }
              public StringProperty emailProperty() { return email; }
    final ObservableList<Person> data = FXCollections.observableArrayList(
                             new Person("Jacob", "Smith", "[email protected]"),
                             new Person("Isabella", "Johnson", "[email protected]"),
                             new Person("Ethan", "Williams", "[email protected]"),
                             new Person("Emma", "Jones", "[email protected]"),
                             new Person("Michael", "Brown", "[email protected]")
    public class RatingCell extends TableCell<Person,String> {
        private NabiSyncRating rating;//NabiSyncRating is a customize control.it has some method ,like change backgroud-color,value,etc.
        public RatingCell() {
             rating = new NabiSyncRating(-1);
        @Override
        public void startEdit() {
            super.startEdit();
            if (isEmpty()) {
                return;
            rating.setDisable(false);
            rating.requestFocus();
        @Override
        public void cancelEdit() {
            super.cancelEdit();
            rating.setDisable(true);
        public void commitEdit(String value) {
            super.commitEdit(value);
            rating.setDisable(true);
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
    Callback<TableColumn<Person, String>, TableCell<Person, String>> ratingCellFactory = new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
                        @Override
                        public TableCell<Person, String> call(
                                  TableColumn<Person, String> p) {
                             return new RatingCell();
    TableColumn firstNameCol = new TableColumn();
    firstNameCol.setCellFactory(ratingCellFactory);
    firstNameCol.setMinWidth(100);
    firstNameCol.setMaxWidth(224);
    firstNameCol.setResizable(true);
    tableView.getColumns().addAll(firstNameCol);
    tableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
                  @Override
                  public void changed(ObservableValue observable, Object oldvalue, Object newValue)
                               Person person=(Person)newValue;
                               //I'd like to get the instance of my customize control 'RatingCell' ,How can I get the RatingCell instance which in current row?
                         System.out.println("selected row is : " + newValue );
                  });

    HI,
    I have found a solution to find it
    First ,you need to set person property 'id' as the input parameter for your customized component method 'public void updateItem(String item, boolean empty)'
    ratingCol.setCellValueFactory(new PropertyValueFactory<Person,String>("id"));
    firstNameCol.setCellFactory(ratingCellFactory);and then you need to implement your customize component like this:
    import javafx.scene.control.ContentDisplay;
    import javafx.scene.control.TableCell;
    public class RatingCell extends TableCell<Person,String> {
        private NabiSyncRating rating;
        public RatingCell() {
             rating = new NabiSyncRating(5);
            this.setGraphic(rating);
            this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            this.setEditable(true);
        public void updateRating()
             if(rating!=null)
                  rating.selectRating();
        @Override
        public void startEdit() {
            super.startEdit();
            if (isEmpty()) {
                return;
            rating.setDisable(false);
            rating.requestFocus();
        @Override
        public void cancelEdit() {
            super.cancelEdit();
            rating.setDisable(true);
        public void commitEdit(String value) {
            super.commitEdit(value);
            rating.setDisable(true);
        @Override
        public void updateItem(String item, boolean empty) {
             if(item!=null && item.length()>0)
                  if(rating!=null)
                       rating.setId("NR"+item);
                       this.setId("NC"+item);
                super.updateItem(item, empty);
    } and find the current like this :
    tableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
                       @Override
                       public void changed(ObservableValue observable, Object oldvalue, Object newValue)
                            Person person=(Person)newValue;
                            Set<Node> colNodes=tableView.lookupAll("RatingCell");
                            for(Node nod:colNodes)
                                 System.out.println("person.email:"+"NC"+person.email.getValue()+"|nodId: " + nod.getId()+"\r\n" );
                                 if(("NC"+person.email.getValue()).equals(nod.getId()))
                                       System.out.println("get current instance" );
                                      ((RatingCell)nod).updateRating();
                       });Edited by: noob on Apr 20, 2012 4:49 PM

  • Tree in FXML (via cell factory)

    Hi,
    I am trying to create a tree in FXML, but I can't figure out how the event handling works.
    I know I need to add a cell factory and add the event handlers to the cells (since tree items don't have mouse events), but how can I
    create the cells in FXML?
    It seems I can add the cellFactory directly to the TreeView, since this code runs okay:
              <TreeView>
              <cellFactory></cellFactory>
                   <root>
                        <TreeItem value="root">
                             <children>
                                  <TreeItem value="c0">
                                       <children>
                                            <TreeItem value="c0topic0"></TreeItem>
                                            <TreeItem value="c0topic1"></TreeItem>
                                            <TreeItem value="c0topic2"></TreeItem>
                                            <TreeItem value="c0topic3"></TreeItem>                                        
                                       </children>
                                  </TreeItem>
                                  <TreeItem value="c1">
                                       <children>
                                            <TreeItem value="c1topic0"></TreeItem>
                                            <TreeItem value="c1topic1"></TreeItem>
                                            <TreeItem value="c1topic2"></TreeItem>                                        
                                       </children>                              
                                  </TreeItem>
                                  <TreeItem value="c2">
                                       <children>
                                            <TreeItem value="c2topic0"></TreeItem>
                                            <TreeItem value="c2topic1"></TreeItem>
                                            <TreeItem value="c2topic2"></TreeItem>
                                       </children>                              
                                  </TreeItem>                                                            
                             </children>
                        </TreeItem>
                   </root>
              </TreeView>But I don't know how I can implement a call-method and I can't add cells to the TreeItems (error: no valid tag).
    Does anyone have an idea or has even already implemented a tree in FXML?
    Thanks,
    Sela

    <TreeView fx:id="treeview">
        <root>
            <TreeItem fx:id="triRoot" value="%triRoot" expanded="true">
                <children>
                   <TreeItem fx:id="triReader" value="%triReader" expanded="true">
                      <graphic>
                          <ImageView>
                              <image>
                       <Image url="@triReader.png"/>
                   </image>
                </ImageView>
           </graphic>                              
                 <children>
                    <TreeItem fx:id="triReaderTopic0" value="%triReaderTopic0"></TreeItem>
                    <TreeItem fx:id="triReaderTopic1" value="%triReaderTopic1"></TreeItem>
                 </children>
             </TreeItem>
             <TreeItem fx:id="cat0" value="%cat0" expanded="true">
                <graphic>
                <ImageView>
                    <image>
                        <Image url="@icon1.png"/>
                    </image>
                </ImageView>
                </graphic>                              
                <children>
                    <TreeItem fx:id="cat0topic0" value="%cat0topic0"></TreeItem>                                        
                    <TreeItem fx:id="cat0topic1" value="%cat0topic1"></TreeItem>                                        
                </children>
             </TreeItem>
             <TreeItem fx:id="cat1" value="%cat1" expanded="true">
                <graphic>
                   <ImageView>
               <image>
                     <Image url="@icon2.png"/>
               </image>
         </ImageView>
               </graphic>                              
              <children>
              <TreeItem fx:id="cat1topic0" value="%cat1topic0"></TreeItem>
              <TreeItem fx:id="cat1topic1" value="%cat1topic1"></TreeItem>
              <TreeItem fx:id="cat1topic2" value="%cat1topic2"></TreeItem>                                   
              </children>                              
           </TreeItem>
           <TreeItem value="%cat2" expanded="true">
               <graphic>
                   <ImageView>
                 <image>
                      <Image url="@icon3.png"/>
                 </image>
                   </ImageView>
                </graphic>
                <children>
               <TreeItem fx:id="cat2topic0" value="%cat2topic0"></TreeItem>                                   
               <TreeItem fx:id="cat2topic1" value="%cat2topic1"></TreeItem>
               <TreeItem fx:id="cat2topic2" value="%cat2topic2"></TreeItem>
                </children>                              
             </TreeItem>                                                            
          </children>
       </TreeItem>
      </root>
    </TreeView> Here is the updated example. Within the controller I don't get the ids (fx:id="cat2topic0"), so I have to use the values to identify the TreeItem that
    is clicked. That is possible but of course I don't like it at all because the values are only variables and I want to be able to change them in the property files
    without touching the java code. I need to get the ids within the event handler.
    treeview.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
    @Override
                public TreeCell<String> call(TreeView<String> p) {
                     final MyTreeCell mytreecell = new MyTreeCell(itemcount++);
                     System.out.println(""+mytreecell.getId());
                     mytreecell.setOnMouseClicked(new EventHandler<MouseEvent>() {
                         @Override
                         public void handle(MouseEvent t) {

  • How to disable a default selection checkbox in the tableview

    Hi All,
             How to disable a default selection checkbox in the tableview ???
    I have  a tableview  with a iterator class mentioned on the iterator attribute of the table view. Table is a MULTISELECT tableview . Is it possible to disable or make it invisible a particular row selection check box?.
    For my scenario I have Currency values on all the columns and I want to do a sub total overall total for all the price column fields in the last row of that table. I archived this functionality using Iterator class method. But I don't want the user to delete that last row in any case.
    Thanks for your help in advance.
    Thanks,
    Greetson

    Hi,
      You can NOT disable the "Checkbox" of particular row using HTMLB. I had the same requirement. I achieved using <b>2 Tableviews</b>, one after another. 1st tableview will show all the rows and 2nd Tableview(without Table Header) and without any row. The <b>total</b> will be displayed as <b>Column title</b> of 2nd Tableview.
    Here is the code of 2nd tableview which we used to display the Total:
              <htmlb:tableView id                  = "tv2"
                               headerVisible       = "false"
                               keyColumn           = "appid"
                               footerVisible       = "false"
                               selectionMode       = "SINGLESELECT"
                               design              = "ALTERNATING"
                               fillUpEmptyRows     = "false"
                               visibleRowCount     = "0"
                               width               = "100%"
                               table               = "<%= tot_header %>" >
                <htmlb:tableViewColumns>
                  <htmlb:tableViewColumn columnName = "empno"
                                         title      = "Total"
                                         width      = "50"
                                         type       = "TEXT" >
                  </htmlb:tableViewColumn>
                  <htmlb:tableViewColumn columnName = "ename"
                                         title      = "  *      "
                                         width      = "90"
                                         type       = "TEXT" >
                  </htmlb:tableViewColumn>
                  <htmlb:tableViewColumn columnName = "appamount"
                                         title      = "   <%= tot_appamt %> "
                                         width      = "60" >
                  </htmlb:tableViewColumn>
                  <htmlb:tableViewColumn columnName = "ugjr_amt"
                                         width      = "60"
                                         title      = "<%= tot_ugjr %>" >
                  </htmlb:tableViewColumn>
                  <htmlb:tableViewColumn columnName = "apprvd"
                                         width      = "50"
                                         title      = "*" >
                  </htmlb:tableViewColumn>
                </htmlb:tableViewColumns>
              </htmlb:tableView>
    Hope this will help you.
    <b>Note: Reward each useful post.</b>
    Raja T
    Message was edited by:
            Raja T

  • Can we change the color of each cell in TableView in HTMLB

    Hi
    I want to change the cell color in TableView dynamically.
    Can we change the color of each cell in TableView in HTMLB?
    If yes, give the exact solution.
    Regards,
    Nithya

    Hi Nithya,
    You would have to implement your own ICellRenderer, see http://help.sap.com/javadocs/NW04S/SPS09/hb/com/sapportals/htmlb/table/ICellRenderer.html and then use http://help.sap.com/javadocs/NW04S/SPS09/hb/com/sapportals/htmlb/table/TableView.html#setCellRenderer(com.sapportals.htmlb.table.ICellRenderer)
    Also see TableView Cellls and how to add colors to table cells
    Hope it helps
    Detlev

  • Creating a new cell factory, how to bind to my object's property

    As near as I can tell, the javafx binding using observable values, alot like jgoodies and its not like SWT databinding or WPF binding.
    I was creating a cell factory for a TreeView. Just using a label to display the contents and calling toString, alot like the way it works now. However, I could not figure out to create a binding that would bind to a property on my domain object. Is there a way to specify the binding to the Label's text property so that whatever object that the cell's item's value has I can bind to a property that I specify on it e.g. the "name" property. But I could not see how to do that. Also, the only way I could figure out how to update the Label's value was from updateItem. I thought maybe I could even setup the binding in updateItem so that when the TreeItem's value changed at least it would automatically update the label binding, but the API did not seem to support that.
    What's the right coding pattern to use when using straight Java coding?
    I know in jgoodies I could do this using the PresentationModel approach or master-detail SWT or WPF with just specifying the property on the item's property that I want in WPF.
    public static class MyTreeCell extends TreeCell<Object> {
              Label label;
              public MyTreeCell() {
                   label = new Label();
                   setNode(label);
              @Override
              public void updateItem(TreeItem<Object> arg0, boolean arg1) {
                   if (arg0 != null && arg0.getValue() != null) {
                        System.out.println("New value: " + arg0.getValue());
                        label.setText(arg0.getValue().toString());
                   } else {
                        System.out.println("New value is null and this println is called alot, why is that?");
                   super.updateItem(arg0, arg1);
         }

    Well the presentation model thing worked fine and I have some machinery for the cell factory/cell item to obtain a tree cell based on the domain object type (a template/factory is placed into the properties in the scenegraph hierarchy). But its not smooth yet and the pattern does not quite translate well into javafx. Because the cell factory produces cells that could be used for a variety of domain object types, all the logic gets pushed down to the treecell subclass which makes it messy. Maybe this is where CSS selectors need to come in, you specify the class of a tree cell for a specific domain object type and you can set that at the root of the application so it cascades. I'll see if this approach works.
    Here's the code for the javafx version of jgoodies' presentation model, less the corner cases. This allows you to bind to a property and change the bean underneath that the property accesses. I'm not convinced that having properties has observable values directly on the objects is the right model for javafx because of the coupling to the actual object the property represents. Sometimes, you need to represent the property concept separate from the actual object instance. Maybe this already exists in the library.
          * An object binding object that creates object bindings based on property
          * names specified as strings. This is a convenience class. Generally, the
          * return values from <code>getProperty()</code> should be used for binding
          * not the factory itself. The object should be a domain object bean with
          * bean methods to get or set the value using java bean naming conventions.
          * When the bean itself changes, the properties fire to indicate that their
          * values may have changed and the observing object should update itself.
          * <p>
          * This only handles reading bean properties. Need to add set() logic.
          * <p>
          * TODO: Make this work better. Many corner cases to cover. Include PCL.
         public static class BeanBindingFactory<T> extends ObjectBinding<T> {
              T bean;
              Map<String, CaptiveObjectProperty> properties = new HashMap<String, CaptiveObjectProperty>();
              public Property getProperty(String property) {
                   if (property == null || property.isEmpty())
                        throw new IllegalArgumentException("Property cannot be null");
                   if (properties.containsKey(property))
                        return properties.get(property);
                   CaptiveObjectProperty p = new CaptiveObjectProperty(this, property);
                   properties.put(property, p);
                   return p;
              public void setBean(T bean) {
                   this.bean = bean;
                   for (CaptiveObjectProperty p : properties.values()) {
                        p.invalidate();
                   fireValueChangedEvent();
              public T getBean() {
                   return bean;
              @Override
              protected T computeValue() {
                   return bean;
               * Lazily get the method representing the property.
               * @author Mr. Java
               * @param <T>
              protected static class CaptiveObjectProperty<T> extends
                        ObjectPropertyBase<T> {
                   String property;
                   Method m;
                   BeanBindingFactory factory;
                   public CaptiveObjectProperty(BeanBindingFactory factory,
                             String property) {
                        this.property = property;
                        this.factory = factory;
                   @Override
                   public Object getBean() {
                        if (factory == null || factory.getBean() == null)
                             return null;
                        return factory.getBean();
                   @Override
                   public T getValue() {
                        if (m == null) {
                             m = getMethod();
                        if (m == null)
                             return null;
                        try {
                             Object rval = m.invoke(factory.getBean());
                             return (T) rval;
                        } catch (Exception e) {
                             e.printStackTrace();
                        return null;
                   @Override
                   public String getName() {
                        return property;
                    * Invalidate the method. Perhaps the bean changed to another object
                    * and we should find the method on the new object.
                   public void invalidate() {
                        m = null;
                        fireValueChangedEvent();
                   protected Method getMethod() {
                        if (factory == null || factory.getBean() == null)
                             return null;
                        String methodName = "get"
                                  + Character.toUpperCase(getName().charAt(0));
                        if (getName().length() > 1)
                             methodName += getName().substring(1);
                        try {
                             Method mtmp = factory.getBean().getClass()
                                       .getMethod(methodName, new Class<?>[0]);
                             return mtmp;
                        } catch (Exception e) {
                             e.printStackTrace();
                        return null;
         }

  • Iterate a TableColumns cell factory

    How to iterate a cell factory of a table columns cell and change its alignment property at run time.
    Thanks.

    How to iterate a cell factory of a table columns cell and change its alignment propertyI don't understand this question. A CellFactory doesn't have an alignment. A CellFactory produces Cells. Cells can be aligned, but not CellFactories.
    Please describe what are you trying to accomplish (preferably without mention of factory), for example, user clicks on a button and sees <insert text here> happen.
    How to iterate the cell factories of a table:
    for (TableColumn c: table.getColumns()) {
      Callback cellFactory = c.getCellFactory();
      System.out.println(cellFactory);
    }

  • ChoiceBox cell factory?

    Is there any reason why ChoiceBox doesn't use the same cell factory approach used by list/table/tree? Unless I'm missing something (?) it looks like the intention is that we should just add our nodes (i.e. cells) directly to the list of items.
    This is a little odd for me, I would normally want to put my data elements (Beans or enums) in the ChoiceBox and have the renderer take care of the rest, just like I do with lists/tables/trees. In the current model I am having to iterate over my data items and create a custom cell for each one, then when something is selected, etc, I have to get the data item out of my custom cell. It all feels a tad awkward?
    Edit: actually adding nodes doesn't seem to work either? I've resorted to creating a wrapper class for my Bean that provides a toString that does my formatting. In this approach, I also lose my underscores in my text (in the popup only, the button bit seems fine) - I assume this is something to do with mnemonics but I have not turned these on and can't see a simple way to turn them off. This all seems a bit wrong, what am I missing?

    Here's a simple little ComboBox that should tie us over until Jonathan writes us a real one. It's very light on features, but the basics work. You can obviously just copy and edit this code directly to suit your needs.
    The only slightly fancy thing I've done is add a 'Cell' interface to it so you can put in your own custom cell renderer for the current item (the popup list uses a normal cell factory). Just implement ComboBox.Cell with your custom Node and then call setCurrentItemCell. In a better implementation you would have a shared factory between the list and the current item, but we need to leave something for Jonathan to impress us with when he provides his real one ;)
    A couple of issues:
    * Ideally the popupList would shrink to fit its contents until it reaches a certain height and then it would start scrolling. Currently it just pops up at its preferred size, which is not as pretty as it could be. Anyone got any ideas on doing this better?
    * The closeOnEscape setting of the popup doesn't seem to be working. I think perhaps the List is blocking the keyboard input. I put a work around in using an event filter, but this shouldn't be needed in a perfect world.
    * The selection listener stuff only triggers if the selection is changed (which makes sense), we need something more like onAction or onCellClicked or something that fires when the user clicks a cell regardless of whether the selection was changed or not. I've used the selection model but also added a little event filter to catch the case when we click the already selected value.
    ComboBox.java
    package com.zenjava.playground.combo;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.Event;
    import javafx.event.EventHandler;
    import javafx.geometry.Bounds;
    import javafx.scene.Node;
    import javafx.scene.Parent;
    import javafx.scene.control.*;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Popup;
    import javafx.util.Callback;
    public class ComboBox<ItemType> extends BorderPane
        private ListView<ItemType> popupList;
        private Popup popup;
        private Cell<ItemType> currentItemCell;
        public ComboBox()
            popupList = new ListView<ItemType>();
            popupList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            popupList.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ItemType>()
                public void changed(ObservableValue<? extends ItemType> source, ItemType oldValue, ItemType newValue)
                    currentItemCell.updateItem(newValue);
                    popup.hide();
            // need to force escape key to close since default behaviour is not working
            popupList.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<Event>()
                public void handle(Event event)
                    KeyEvent keyEvent = (KeyEvent) event;
                    if (KeyCode.ESCAPE.equals(keyEvent.getCode()))
                        popup.hide();
            // need to force hiding of list for case when current selection is re-selected
            popupList.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<Event>()
                public void handle(Event event)
                    popup.hide();
            popup = new Popup();
            popup.getContent().add(popupList);
            popup.setAutoHide(true);
            popup.setAutoFix(true);
            popup.setHideOnEscape(true);
            // use your own style for this
            Button popupButton = new Button(">");
            popupButton.setOnAction(new EventHandler<ActionEvent>()
                public void handle(ActionEvent actionEvent)
                    showPopup();
            setRight(popupButton);
            setCurrentItemCell(new SimpleCell<ItemType>());
        public void setCurrentItemCell(Cell<ItemType> cell)
            currentItemCell = cell;
            Node node = currentItemCell.getNode();
            node.setOnMouseClicked(new EventHandler<Event>()
                public void handle(Event event)
                    showPopup();
            setCenter(node);
        public MultipleSelectionModel<ItemType> getSelectionModel()
            return popupList.getSelectionModel();
        public ObservableList<ItemType> getItems()
            return popupList.getItems();
        public void set(Callback<ListView<ItemType>, ListCell<ItemType>> cellFactory)
            popupList.setCellFactory(cellFactory);
        public void showPopup()
            Parent parent = getParent();
            Bounds childBounds = getBoundsInParent();
            Bounds parentBounds = parent.localToScene(parent.getBoundsInLocal());
            double layoutX = childBounds.getMinX()
                    + parentBounds.getMinX() + parent.getScene().getX() + parent.getScene().getWindow().getX();
            double layoutY = childBounds.getMaxY()
                    + parentBounds.getMinY() + parent.getScene().getY() + parent.getScene().getWindow().getY();
            popup.show(this, layoutX, layoutY);
        public static interface Cell<ItemType>
            Node getNode();
            void updateItem(ItemType item);
        public static class SimpleCell<ItemType> extends TextField implements Cell<ItemType>
            public SimpleCell()
                setEditable(false);
                setStyle("-fx-cursor: hand");
            public Node getNode()
                return this;
            public void updateItem(ItemType item)
                setText(item != null ? item.toString() : "");
    }And here's how you would use it:
    public void start(Stage stage) throws Exception
        FlowPane root = new FlowPane();
        root.setStyle("-fx-padding: 30");
        root.getChildren().add(new Label("Choose your destiny:"));
        ComboBox<String> combo = new ComboBox<String>();
        combo.setStyle("-fx-border-color: black; -fx-border-width: 1");
        combo.getItems().addAll("Make a difference", "Do no harm", "Start a Krispy Kreme franchise");
        combo.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>()
            public void changed(ObservableValue<? extends Object> source, Object oldValue, Object newValue)
                System.out.println("Your destiny: " + newValue);
        root.getChildren().add(combo);
        Scene scene = new Scene(root, 300, 200);
        stage.setScene(scene);
        stage.show();
    }

  • Merging cells in Tableview

    Hi,
    I am creating a tableview in which I would like to merge few cells for few of the rows (based on some condition). I am also trying to make use of Table Iterator for the same but not getting proper clue.
    Can someone please help.
    Thanks and regards,
    Sachin K

    There are about a millions sources here in this forum for that A quick search will provide several for you.
    Here are some links you should check out...
    BSP Element - Dynamic tableView with Internal Table
    And of course the basics...
    <a href="/people/brian.mckellar/blog/2004/06/11/bsp-trouble-shooting-getting-help">BSP Trouble Shooting: Getting Help</a>
    <a href="/people/brian.mckellar/blog/2003/10/31/bsp-programming-htmlb-tableview-iterator">BSP Programming: HTMLB TableView Iterator</a>
    Here is a code sample of doing something in the <b>IF_HTMLB_TABLEVIEW_ITERATOR~GET_COLUMN_DEFINITIONS</b>
    method IF_HTMLB_TABLEVIEW_ITERATOR~GET_COLUMN_DEFINITIONS .
      FIELD-SYMBOLS: <def> LIKE LINE OF p_column_definitions.
      APPEND INITIAL LINE TO p_column_definitions ASSIGNING <def>.
      <def>-COLUMNNAME = 'SID'.
      <def>-TITLE      = 'System'.
      <def>-WIDTH      = '10%'.
      <def>-SORT       = 'X'.
      APPEND INITIAL LINE TO p_column_definitions ASSIGNING <def>.
      <def>-COLUMNNAME  = 'STATUS'.
      <def>-TITLE       = 'Status'.
      <def>-WIDTH       = '10%'.
      <def>-SORT       = 'X'.
      APPEND INITIAL LINE TO p_column_definitions ASSIGNING <def>.
      <def>-COLUMNNAME = 'CREATIMEDA'.
      <def>-TITLE      = 'Date'.
      <def>-WIDTH      = '10%'.
      APPEND INITIAL LINE TO p_column_definitions ASSIGNING <def>.
      <def>-COLUMNNAME = 'CREATIMETI'.
      <def>-TITLE      = 'Time'.
      <def>-WIDTH      = '10%'.
      APPEND INITIAL LINE TO p_column_definitions ASSIGNING <def>.
      <def>-COLUMNNAME = 'ALERTMSG'.
      <def>-TITLE      = 'Text'.
      <def>-WIDTH      = '50%'.
      <def>-WRAPPING   = 'X'.
      APPEND INITIAL LINE TO p_column_definitions ASSIGNING <def>.
      <def>-COLUMNNAME = 'UNAME'.
      <def>-TITLE      = 'Assigned User'.
      <def>-WIDTH      = '10%'.
      <def>-SORT       = 'X'.
    endmethod.
    Follow that with the code from <i><b>IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_ROW_START</b></i>
    method IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_ROW_START .
      m_row_ref ?= p_row_data_ref.
    endmethod.
    and ending with this code from <i><b>IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_CELL_START</b></i>
    method IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_CELL_START .
    * Data Declarations
      DATA: dataValue TYPE STRING,
            tmp TYPE STRING,
            tmptext TYPE STRING.
      CASE p_column_key.
        WHEN 'STATUS'.
          dataValue = m_row_ref->STATUS.
          case dataValue.
            when ''.
              tmp = '@5B@'.
              tmptext = m_row_ref->STATUST.
            when 'C'.
              tmp = '@5B@'.
              tmptext = m_row_ref->STATUST.
            when 'D'.
              tmp = '@5D@'.
              tmptext = m_row_ref->STATUST.
            when 'E'.
              tmp = '@5C@'.
              tmptext = m_row_ref->STATUST.
          endcase.
          DATA: image TYPE REF TO CL_HTMLB_IMAGE.
          p_replacement_bee = cl_htmlb_image=>factory( id = 'img'
                      src = tmp
                      alt = tmptext ).
      ENDCASE.
    endmethod.

  • Access cell factory instance

    I have a tableview with a single column. I associated a cellfactory to it as given in the below code. I am trying to loop through all the cells values of a table column on click of a button. I am not sure how to get hold of cell's inner class instance i.e.EditingCell class as said in the given example. Please help me with the same code for this.
    2. Also, I have a requiremet where in I want to change the alignment or for example change the value of that cell on click of a button, by looping through all the rows of a single column. I know how to change in the underlying datastructure, but this is not what I want. I want to loop thru by getting value using cellfactory or cell value factory. any help will be of great use.
    Callback<TableColumn<Person,String>, TableCell<Person,String>> cellFactory =
        new Callback<TableColumn<Person,String>, TableCell<Person,String>>() {
            public TableCell<Person,String> call(TableColumn<Person,String> p) {
                return new EditingCell();
    firstNameCol.setCellFactory(cellFactory);Thanks.

    I think that's much too mighty for a general development user ;)But it'll teach 'them general development users' on how things work, while they're developing, using a representative dataset(!).
    I would let them select anything they're interested in regarding resources, stats, execution plans etc, on the appropriate environment. To learn and understand. It's only a SELECT.
    It's only giving answers on how CBO will behave or, in other words, how CBO will respond to a solution to a requirement.
    Developers who want to avoid trouble after developing should be aware of this, be able to understand it and use it.
    On a development environment a developer needs to be able to check how his/her queries/program works out like predicted/modeled. Access to V$ views is will help.
    If he/she doesn't do anything with it/insn't allowed to use it...OK, that's fine, we'll re-evaluate when we're in production...when all goes wrong...then the developer is the fan that has spread some s**t...and we'll have to pump in another bunch of $.
    I think that the fact the majority of developers who aren't allowed (by grants or privileges) to measure and test their solutions, is the same majority looking for/in search of/believing in/been told of *'Silver Bullets'*, which don't exist.
    Through time a lot of people have come to the conclusion: it depends.
    You need to test and measure, on your development schema.
    But anyway:
    v$instance is a bit of 'a strange duck in the pond' in that context ;)

  • Problem with checkbox selection in Tableview

    Hi All
    I am using table view with 8 columns - in the last 4 columns i have checkboxes for user input - i have a strange problem - when the table has multiple entries - for the last column i can only select the checkbox on line 1 - and i cannot select the checkbox on the remaining entries below - but for the other colums with checkboxes this is not the case
    The selection mode for the table is no line selection - since the table is already displayed with input enabled fields - this is to reduce the no of clicks for user
    Can anyone point out what is going wrong - how can i fix this - what i am doing wrong ?
    Thanks
    Sen

    Hi
    When i click on the checkbox for the 2nd or 3rd rows of the last column - nothing happens - the checkox is still active but nothing happens -
    this is the tableview code
    <htmlb:tableView id              = "Detail"
                     design          = "ALTERNATING"
                     headerText      = "Header Text"
                     onNavigate      = "onMyNavigate"
                     emptyTableText  = "test"
                     onRowSelection  = "onMyRowSelection"
                     fillUpEmptyRows = "false"
                     footerVisible   = "true"
                     visibleRowCount = "5"
                     table           = "<%= DETAILTAB %>"
                     iterator        = "<%= iterator %>" >
    and this is the code for the last column
    <htmlb:tableViewColumn columnName         = "OBSOFLGICON"
                               width               = "3"
                               type                = "user"
                               horizontalAlignment = "CENTER"
                               title               = "Obs" >
          <htmlb:checkbox />
        </htmlb:tableViewColumn>
    Thanks
    Sen

  • How can I select multiple cells in tableview with javafx only by mouse?

    I have an application with a tableview in javafx and i want to select multiple cells only by mouse (something like the selection which exists in excel).I tried with setOnMouseDragged but i cant'n do something because the selection returns only the cell from where the selection started.Can someone help me?

    For mouse drag events to propagate to nodes other than the node in which the drag initiated, you need to activate a "full press-drag-release gesture" by calling startFullDrag(...) on the initial node. (See the Javadocs for MouseEvent and MouseDragEvent for details.) Then you can register for MouseDragEvents on the table cells in order to receive and process those events.
    Here's a simple example: the UI is not supposed to be ideal but it will give you the idea.
    import java.util.Arrays;
    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.geometry.Insets;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.SelectionMode;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.input.MouseDragEvent;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.VBox;
    import javafx.scene.text.Font;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class DragSelectionTable extends Application {
        private TableView<Person> table = new TableView<Person>();
        private final ObservableList<Person> data =
            FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "[email protected]"),
                new Person("Isabella", "Johnson", "[email protected]"),
                new Person("Ethan", "Williams", "[email protected]"),
                new Person("Emma", "Jones", "[email protected]"),
                new Person("Michael", "Brown", "[email protected]")
        public static void main(String[] args) {
            launch(args);
        @Override
        public void start(Stage stage) {
            Scene scene = new Scene(new Group());
            stage.setTitle("Table View Sample");
            stage.setWidth(450);
            stage.setHeight(500);
            final Label label = new Label("Address Book");
            label.setFont(new Font("Arial", 20));
            table.setEditable(true);
            TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
            firstNameCol.setMinWidth(100);
            firstNameCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("firstName"));
            TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
            lastNameCol.setMinWidth(100);
            lastNameCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("lastName"));
            TableColumn<Person, String> emailCol = new TableColumn<>("Email");
            emailCol.setMinWidth(200);
            emailCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("email"));
            final Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory = new DragSelectionCellFactory();
            firstNameCol.setCellFactory(cellFactory);
            lastNameCol.setCellFactory(cellFactory);
            emailCol.setCellFactory(cellFactory);
            table.setItems(data);
            table.getColumns().addAll(Arrays.asList(firstNameCol, lastNameCol, emailCol));
            table.getSelectionModel().setCellSelectionEnabled(true);
            table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
            final VBox vbox = new VBox();
            vbox.setSpacing(5);
            vbox.setPadding(new Insets(10, 0, 0, 10));
            vbox.getChildren().addAll(label, table);
            ((Group) scene.getRoot()).getChildren().addAll(vbox);
            stage.setScene(scene);
            stage.show();
        public static class DragSelectionCell extends TableCell<Person, String> {
            public DragSelectionCell() {
                setOnDragDetected(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        startFullDrag();
                        getTableColumn().getTableView().getSelectionModel().select(getIndex(), getTableColumn());
                setOnMouseDragEntered(new EventHandler<MouseDragEvent>() {
                    @Override
                    public void handle(MouseDragEvent event) {
                        getTableColumn().getTableView().getSelectionModel().select(getIndex(), getTableColumn());
            @Override
            public void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (empty) {
                    setText(null);
                } else {
                    setText(item);
        public static class DragSelectionCellFactory implements Callback<TableColumn<Person, String>, TableCell<Person, String>> {
            @Override
            public TableCell<Person, String> call(final TableColumn<Person, String> col) {         
                return new DragSelectionCell();
        public static class Person {
            private final SimpleStringProperty firstName;
            private final SimpleStringProperty lastName;
            private final SimpleStringProperty email;
            private Person(String fName, String lName, String email) {
                this.firstName = new SimpleStringProperty(fName);
                this.lastName = new SimpleStringProperty(lName);
                this.email = new SimpleStringProperty(email);
            public String getFirstName() {
                return firstName.get();
            public void setFirstName(String fName) {
                firstName.set(fName);
            public String getLastName() {
                return lastName.get();
            public void setLastName(String fName) {
                lastName.set(fName);
            public String getEmail() {
                return email.get();
            public void setEmail(String fName) {
                email.set(fName);

  • Cannot tick checkbox cell editor in TreeNestedInTable UI

    Hi everyone,
    i have created a TreeNestedInTable UI using a Check Box cell editor.
    It all works fine except when I try to check on of the check boxes in the table it does not tick the box.  Instead, it highlughts the row.  I can, however, select multiple lines by using Ctrl+click.  This is not what I want however.
    Please advise if there is some setting that I am missing, perhaps.
    Many thanks.
    Christiaan

    Hi,
    check also this link
    http://help.sap.com/saphelp_nw04s/helpdata/en/9f/656442a1c4de54e10000000a155106/frameset.htm
    Matteo

Maybe you are looking for