<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>I've run into something similar, maybe even the same issue.</p>
    <p>My issue was that modifying the list of cell children (in a Skin
      for ListView) caused a 1 frame white flicker (my application is
      black, so it was annoying) because no CSS was applied yet to those
      newly added children.  This occured when the ListView first only
      had a few children and wasn't completely filled, and then
      switching to a list which required more cells to be created. I
      couldn't find a "correct" place to modify the list of children
      that would avoid the flicker (layoutChildren/computePrefWidth are
      places I tried).</p>
    <p>In the end I did this, and added a comment to remind me why the
      hack was there:</p>
    <p>    /*<br>
           * A pre-layout pulse listener is added to the current Scene
      to manage the<br>
           * cells before the CSS pass occurs (this could also be done
      with an AnimationTimer).<br>
           *<br>
           * If cells are not managed before the CSS pass, new cells
      will be rendered for<br>
           * one frame without CSS applied. This results in a visual
      artifact (a white flash<br>
           * for example if the background is supposed to be dark, while
      white is the default<br>
           * color without any CSS applied).<br>
           */<br>
          private final Runnable pulseListener = () -> {<br>
            int lines = vertical ? visibleColumns.get() :
      visibleRows.get();<br>
            int firstIndex = (int)(scrollPosition.get()) * lines;<br>
        <br>
            content.manageCells(firstIndex);<br>
          };</p>
    <p>Now, the reason I think this may be same issue is that you're
      also doing a modification of the children list during layout:
      setting the graphic is sort of equivalent to
      label.getChildren().add(graphic)<br>
    </p>
    <p>--John<br>
    </p>
    <div class="moz-cite-prefix">On 20/02/2023 20:58, Scott Palmer
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAL3e5iHpa=VP_tdG+hAPNAJ09jRSaSu8tcbu50W277D1yL5_CA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div class="gmail_default" style="font-family:arial,sans-serif">I'm
          seeing an odd issue with using CSS to colour a Shape when I
          have it as a child of a TextFlow.</div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif">My
          use case is a "rich" text Cell in a tree or list.  I want to
          have the text portion in multiple colours and so instead of
          using the graphic and text parts of a typical Cell, I'm using
          only the Graphic and setting it to a TextFlow to get the text
          colours. This means that I lose the ability to set a graphic
          independen to the text, and so the graphic is also added to
          the TextFlow.</div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif">To
          style the graphics, which are made of simple shapes, I'm using
          CSS.  It makes it easy to adapt the colours for when a cell is
          selected etc.  What I've noticed is that as the cell selection
          moves around the Shape component of the TextFlow flickers, as
          if it is drawn first using default colours and then the CSS is
          applied afterward.  I tried working around this by explicitly
          calling applyCss() on the Shape from the Cell's update method,
          but it did not help.  If I explicitly set the Stroke and Fill
          via the Shape API the flickering does not occur.  If I use
          CSS, but set the Shape as the Cell's graphic and resort to
          only having plain text, there is no flickering.</div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif">A
          test program that demonstrates this is below.</div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif">Bug
          or known limitation?</div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif">Scott</div>
        <div class="gmail_default" style="font-family:arial,sans-serif">------------------------------------</div>
        <div class="gmail_default" style="font-family:arial,sans-serif">package
          bugs;<br>
          <br>
          import javafx.application.Application;<br>
          import javafx.geometry.Insets;<br>
          import javafx.scene.Node;<br>
          import javafx.scene.Scene;<br>
          import javafx.scene.control.CheckBox;<br>
          import javafx.scene.control.ContentDisplay;<br>
          import javafx.scene.control.Label;<br>
          import javafx.scene.control.ListCell;<br>
          import javafx.scene.control.ListView;<br>
          import javafx.scene.control.Tab;<br>
          import javafx.scene.control.TabPane;<br>
          import javafx.scene.layout.HBox;<br>
          import javafx.scene.layout.VBox;<br>
          import javafx.scene.paint.Color;<br>
          import javafx.scene.shape.Circle;<br>
          import javafx.scene.shape.Rectangle;<br>
          import javafx.scene.shape.Shape;<br>
          import javafx.scene.text.Text;<br>
          import javafx.scene.text.TextFlow;<br>
          import javafx.stage.Stage;<br>
          <br>
          <br>
          public class CSSFlickerInTextFlow extends Application {<br>
          <br>
              public static void main(String[] args) {<br>
                  launch(args);<br>
              }<br>
          <br>
              private CheckBox onlyCssCB;<br>
          <br>
              @Override<br>
              public void start(Stage stage) throws Exception {<br>
                  ListView<String> list1 = new ListView<>();<br>
                  ListView<String> list2 = new ListView<>();<br>
                  var items1 = list1.getItems();<br>
                  var items2 = list2.getItems();<br>
                  for (int i = 1; i < 23; i++) {<br>
                      var x = "Item #"+i;<br>
                      items1.add(x);<br>
                      items2.add(x);<br>
                  }<br>
                  list1.setCellFactory(t -> new MyCell1());<br>
                  list2.setCellFactory(t -> new MyCell2());<br>
          <br>
                  onlyCssCB = new CheckBox("Use only CSS (shapes will
          flicker in TextFlow)");<br>
                  HBox buttons = new HBox(8, onlyCssCB);<br>
                  buttons.setPadding(new Insets(4));<br>
          <br>
                  Tab custom = new Tab("Everything in Graphic", list1);<br>
                  Tab withoutColoredText = new Tab("Graphic + Text",
          list2);<br>
                  TabPane tabs = new TabPane(custom,
          withoutColoredText);<br>
          <br>
                  VBox root = new VBox(<br>
                          new Label("""<br>
                                    Focus in list, cursor up and down,
          pay attention to the circle.<br>
                                    Try the same with the box checked -
          circle flickers.<br>
                                    Doesn't happen when not using the
          TextFlow.<br>
                                    """),<br>
                          buttons, tabs);<br>
                  root.setPadding(new Insets(4));<br>
                  var scene = new Scene(root);<br>
                  stage.setScene(scene);<br>
                  stage.setTitle("Flickering with CSS in TextFlow");<br>
                  stage.show();<br>
              }<br>
          <br>
              private Shape makeGraphic() {<br>
                  Shape graphic = new Circle(6);<br>
                  if (!onlyCssCB.isSelected()) {<br>
                      graphic.setFill(Color.SALMON); // CSS overrides
          these but causes flickering if not the same<br>
                      graphic.setStroke(Color.BLACK);<br>
                  }<br>
                  graphic.setStyle("-fx-fill: salmon; -fx-stroke:
          black;");<br>
                  return graphic;<br>
              }<br>
          <br>
              class MyCell1 extends ListCell<String> {<br>
          <br>
                  @Override<br>
                  protected void updateItem(String item, boolean empty)
          {<br>
                      super.updateItem(item, empty);<br>
                      setContentDisplay(ContentDisplay.GRAPHIC_ONLY);<br>
                      setText(null);<br>
                      if (!empty && item != null) {<br>
                          TextFlow flow = new TextFlow();<br>
                          Shape graphic = makeGraphic();<br>
                          graphic.setTranslateY(2);<br>
                          var nodeList = flow.getChildren();<br>
                          Text name = new Text(item + " : ");<br>
                          name.setStyle("-fx-fill:
          -fx-text-background-color;");<br>
                          Text extra = new Text("with Color");<br>
                         
          extra.setStyle("-fx-fill:ladder(-fx-background, white 49%,
          salmon 50%);");<br>
                          nodeList.add(graphic);<br>
                          nodeList.add(new Rectangle(4,0)); // gap<br>
                          nodeList.add(name);<br>
                          nodeList.add(extra);<br>
                          setGraphic(flow);<br>
                      } else {<br>
                          setGraphic(null);<br>
                      }<br>
                  }<br>
              }<br>
          <br>
              class MyCell2 extends ListCell<String> {<br>
                  @Override<br>
                  protected void updateItem(String item, boolean empty)
          {<br>
                      super.updateItem(item, empty);<br>
                      if (!empty && item != null) {<br>
                          setGraphic(makeGraphic());<br>
                          setText(item);<br>
                      } else {<br>
                          setText(null);<br>
                          setGraphic(null);<br>
                      }<br>
                  }<br>
              }<br>
          }<br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
      </div>
    </blockquote>
  </body>
</html>