title: JavaFX - Why does changing the header text of a dialog make the button bar invisible?
body: <p>Here is a small sample from my custom dialog, which is meant to display the progress of a running <code>javafx.concurrent.Task</code>.</p>
  <pre class="lang-java prettyprint-override"><code>DialogPane pane = this.getDialogPane()
  pane.getButtonTypes().addAll(ButtonType.CANCEL);
  
  pane.headerTextProperty().bind(task.titleProperty());
  pane.contentTextProperty().bind(task.messageProperty());
  </code></pre>
  <p>For some reason, the buttons in the button bar disappeared, but only after some text updated. After further investigation, I found that binding the header text of a dialog seems to remove all the buttons in the button bar. Why would this happen, and what would I do to stop the buttons from being hidden?</p>
  <p>EDIT: Here's an MCVE demonstrating the problem.</p>
  <pre><code>import javafx.application.Application;
  import javafx.beans.property.ObjectProperty;
  import javafx.beans.property.SimpleObjectProperty;
  import javafx.concurrent.Task;
  import javafx.scene.Scene;
  import javafx.scene.control.*;
  import javafx.scene.layout.StackPane;
  import javafx.stage.Modality;
  import javafx.stage.Stage;
  
  public class MCVE extends Application {
    public static class CustomDialog extends Dialog&lt;ButtonType&gt; {
  
      public CustomDialog(Task&lt;?&gt; task) {
        this.initModality(Modality.APPLICATION_MODAL);
  
        DialogPane pane = this.getDialogPane();
        {
          pane.getButtonTypes().addAll(ButtonType.CANCEL);
          pane.headerTextProperty().bind(task.titleProperty());
        }
  
        setOnCloseRequest(event -&gt; {
          if (task.isRunning()) event.consume();
        });
      }
    }
  
    public static void main(String[] args) {
      launch(args);
    }
  
    @Override
    public void start(Stage stage) {
      StackPane root = new StackPane();
      Button starter = new Button(&quot;Showcase&quot;);
      starter.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
  
      root.getChildren().add(starter);
      Scene scene = new Scene(root, 500, 500);
      stage.setScene(scene);
      stage.show();
  
  
      starter.setOnAction(event -&gt; {
        Task&lt;Void&gt; task = new Task&lt;&gt;() {
          @Override
          protected Void call() throws Exception {
            updateTitle(&quot;Before loop&quot;);
            try {
              Thread.sleep(1000);
            } catch (InterruptedException ignored) {
              if (isCancelled()) return null;
            }
            for (int i = 1; i &lt;= 20; i++) {
              updateTitle(&quot;loop &quot; + i);
  
              try {
                Thread.sleep(1000);
              } catch (InterruptedException ignored) {
                if (isCancelled()) return null;
              }
            }
            return null;
          }
        };
        Thread worker = new Thread(task);
  
        worker.start();
        new CustomDialog(task).showAndWait();
      });
    }
  }
  </code></pre>