title: JavaFX tableview hiding a selected row
body: <p>In my JavaFX application I am trying to hide the selected rows in the tableview. I used CSS as below.</p>
  
  <pre><code>.hideRow
  {
       -fx-cell-size: 0px;
       -fx-border-width: 0;
  }
  </code></pre>
  
  <p>I used the below row factory for the achieving the same.</p>
  
  <pre><code>import java.util.Collections;
  import javafx.beans.value.ChangeListener;
  import javafx.beans.value.ObservableValue;
  import javafx.collections.FXCollections;
  import javafx.collections.ListChangeListener;
  import javafx.collections.ObservableList;
  import javafx.event.EventHandler;
  import javafx.scene.control.TableRow;
  import javafx.scene.control.TableView;
  import javafx.scene.input.ClipboardContent;
  import javafx.scene.input.DataFormat;
  import javafx.scene.input.DragEvent;
  import javafx.scene.input.Dragboard;
  import javafx.scene.input.MouseButton;
  import javafx.scene.input.MouseEvent;
  import javafx.scene.input.TransferMode;
  import javafx.util.Callback;
  
  /
  
  **
   * This is the table view row style factory class. * This class is responsible
   * for performing style changes for enable,disable,hide and un hide of the rows.
   *
   * @param &lt;T&gt;
   */
  
  public class StyleChangingRowFactory&lt;T&gt; implements
      Callback&lt;TableView&lt;T&gt;, TableRow&lt;T&gt;&gt; {
      private TableRow rowSelected;
      private final String styleClass;
      private final ObservableList&lt;Integer&gt; styledRowIndices;
      private final Callback&lt;TableView&lt;T&gt;, TableRow&lt;T&gt;&gt; baseFactory;
  
      /**
       * Construct a &lt;code&gt;StyleChangingRowFactory&lt;/code&gt;, specifying the name of
       * the style class that will be applied to rows determined by
       * &lt;code&gt;getStyledRowIndices&lt;/code&gt; and a base factory to create the
       * &lt;code&gt;TableRow&lt;/code&gt;. If &lt;code&gt;baseFactory&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;,
       * default table rows will be created.
       *
       * @param styleClass The name of the style class that will be applied to
       * specified rows.
       * @param baseFactory A factory for creating the rows. If null, default
       * &lt;code&gt;TableRow&amp;lt;T&amp;gt;&lt;/code&gt;s will be created using the default
       * &lt;code&gt;TableRow&lt;/code&gt; constructor.
       */
      public StyleChangingRowFactory(String styleClass, Callback&lt;TableView&lt;T&gt;, TableRow&lt;T&gt;&gt; baseFactory) {
          this.styleClass = styleClass;
          this.baseFactory = baseFactory;
          this.styledRowIndices = FXCollections.observableArrayList();
      }
  
      /**
       * Construct a &lt;code&gt;StyleChangingRowFactory&lt;/code&gt;, which applies
       * &lt;code&gt;styleClass&lt;/code&gt; to the rows determined by
       * &lt;code&gt;getStyledRowIndices&lt;/code&gt;, and using default
       * &lt;code&gt;TableRow&lt;/code&gt;s.
       *
       * @param styleClass
       */
      public StyleChangingRowFactory(String styleClass) {
          this(styleClass, null);
      }
  
      @Override
      public TableRow&lt;T&gt; call(final TableView&lt;T&gt; tableView) {
          final TableRow&lt;T&gt; row;
          if (baseFactory == null) {
              row = new TableRow&lt;&gt;();
          } else {
              row = baseFactory.call(tableView);
          }
           row.setOnDragEntered(new EventHandler&lt;DragEvent&gt;() {
              @Override
              public void handle(DragEvent t) {
  
                  tableView.getSelectionModel().clearSelection();
                  tableView.getSelectionModel().selectRange(rowSelected.getIndex(), row.getIndex());
              }
          });
  
          row.setOnDragDetected(new EventHandler&lt;MouseEvent&gt;() {
  
              @Override
              public void handle(MouseEvent t) {
                  rowSelected = row;
                  Dragboard db = row.getTableView().startDragAndDrop(TransferMode.LINK);
                  ClipboardContent content = new ClipboardContent();
                  content.put(DataFormat.PLAIN_TEXT, "XData");
                  db.setContent(content);
                  tableView.getSelectionModel().clearSelection();
                  t.consume();
              }
          });
          row.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler&lt;MouseEvent&gt;() {
              @Override
              public void handle(MouseEvent event) {
                  rowSelected = row;
                  final int index = row.getIndex();
                  if (event.getButton() == MouseButton.SECONDARY &amp;&amp; index &gt;= 0 &amp;&amp; !tableView.getSelectionModel().isSelected(index)) {
                      tableView.getSelectionModel().clearSelection();
                  }
              }
          });
          row.indexProperty().addListener(new ChangeListener&lt;Number&gt;() {
              @Override
              public void changed(ObservableValue&lt;? extends Number&gt; obs,
                      Number oldValue, Number newValue) {
                  updateStyleClass(row);
              }
          });
          styledRowIndices.addListener(new ListChangeListener&lt;Integer&gt;() {
              @Override
              public void onChanged(Change&lt;? extends Integer&gt; change) {
                  updateStyleClass(row);
                  tableView.getColumns().get(0).setVisible(false);
                  tableView.getColumns().get(0).setVisible(true);
              }
          });
  
          return row;
      }
  
      /**
       *
       * @return The list of indices of the rows to which &lt;code&gt;styleClass&lt;/code&gt;
       * will be applied. Changes to the content of this list will result in the
       * style class being immediately updated on rows whose indices are either
       * added to or removed from this list.
       */
      public ObservableList&lt;Integer&gt; getStyledRowIndices() {
          return styledRowIndices;
      }
  
      private void updateStyleClass(TableRow&lt;T&gt; row) {
          final ObservableList&lt;String&gt; rowStyleClasses = row.getStyleClass();
          if (styledRowIndices.contains(row.getIndex())) {
              if (!rowStyleClasses.contains(styleClass)) {
                  rowStyleClasses.add(styleClass);
  
              }
          } else {
  // remove all occurrences of styleClass:
              rowStyleClasses.removeAll(Collections.singletonList(styleClass));
          }
      }
  
  }
  </code></pre>
  
  <p>I declared the row factory as </p>
  
  <pre><code>StyleChangingRowFactory  rowFactory = new StyleChangingRowFactory&lt;&gt;("hideRow");
  </code></pre>
  
  <p>I have two pop up menus in my table, they are hide and unhide.</p>
  
  <p>In my controller I used the below methods with implementation for those menus.</p>
  
  <pre><code>private void hidePressed() {
          rowFactory.getHiddenRowIndices().addAll(cfiTableView.getSelectionModel().getSelectedIndices());
      }
  
      private void unHidePressed() {
          rowFactory.getHiddenRowIndices().removeAll(cfiTableView.getSelectionModel().getSelectedIndices());
      }
  </code></pre>
  
  <p>The problem is when I hide the selected row(s). It is also hiding some other rows in the table view. Please help me to solve this issue.</p>