title: JavaFX - using setRowFactory to highlight new rows
body: <p>I am writing a JavaFX app where a series of messages appear in a TableView.  When a new message appears, its row in the table should be highlighted, meaning its background color should be orange or something.  Once the user clicks it, the background color should clear, acknowledging the message was read.  Should be simple.</p>
  
  <p>I've done enough research to realize that I need to use a rowFactory to set or clear a row's background.  But I'm struggling with the mechanics of <code>setRowFactory()</code>.  The documentation on Oracle is over my head, and every example I pull up online seems radically different than the last one. </p>
  
  <p>Here's what I have:</p>
  
  <pre><code>public class Message {
      private boolean readOnce;
      private int date;
      private String msg;
  
      public Message(int date, String msg, String msg2){
          this.readOnce = false;
          this.date = date;
          this.msg = msg;
      }
  
      public boolean isReadOnce() {
          return readOnce;
      }
      public void setReadOnce(){
          readOnce = true;
      }
      // ...and more standard getters &amp; setters here...
   }
  </code></pre>
  
  <p>The TableView is set up in the main controller:</p>
  
  <pre><code>    @FXML   TableView&lt;Message&gt; messageTable;
      @FXML   TableColumn&lt;Message, Integer&gt;   Col1;
      @FXML   TableColumn&lt;Message, String&gt;    Col2;
      ObservableList&lt;Message&gt; tableItems;
  
  // ...
  
      // Setting up the Table:
      PropertyValueFactory&lt;Message, Integer&gt; dateProperty = new PropertyValueFactory&lt;Message, Integer&gt;("date");
      PropertyValueFactory&lt;Message, String&gt;  msgProperty  = new PropertyValueFactory&lt;Message, String&gt;("msg");
      Col1.setCellValueFactory( dateProperty );
      Col2.setCellValueFactory( msgProperty );
      messageTable.setItems( tableItems );
  
      // If we click an item in the table:        messageTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -&gt; {
          if (newSelection != null) {
              System.out.println("Troubleshoot:  You clicked: "+newSelection.getMsg());
              newSelection.setReadOnce(true);
          }
      });
  </code></pre>
  
  <p>And if I want to add a new message to the table, I just add it into the observable list:</p>
  
  <pre><code>public void addMsg(int num, String msg){
      tableItems.add(new Message(num, msg));
  }
  </code></pre>
  
  <p>So far, pretty easy.  But I'm all thumbs when it comes to the rowFactory:</p>
  
  <pre><code>    messageTable.setRowFactory(messageTable -&gt; {
          TableRow&lt;Message&gt; row = new TableRow&lt;&gt;();
          ObjectProperty&lt;Message&gt; opMsg = row.itemProperty();
          Message tmpMsg = opMsg.get();
          if(!tmpMsg.isReadOnce()){
              row.getStyleClass().add("highlight-message");     // defined in CSS
          } else {
              row.getStyleClass().add("clear-message");         // defined in CSS
          }
          return row;
      });
  </code></pre>
  
  <p>To be very honest, I have no idea what I'm doing here.  I understand that the rowFactory takes in the entire table and regenerates each row one-by-one.  What I don't understand is how does the RowFactory code examine each Message in the table and how can I access them?  Originally I thought these line might allow me to see the Message within the row:</p>
  
  <pre><code>        TableRow&lt;Message&gt; row = new TableRow&lt;&gt;();
          ObjectProperty&lt;Message&gt; opMsg = row.itemProperty();
          Message tmpMsg = opMsg.get();
  </code></pre>
  
  <p>But when I debug the code, tmpMsg == NULL.  So that's a big fat dead end.</p>
  
  <p>Anyone see what I'm doing wrong?  I've been researching this for about a week, getting absolutely no-where.  Any help anyone can offer is wildly appreciated.</p>
  
  <p>Many thanks,
  -RAO</p>