title: How can I intercept and modify any attempt to change the title in a JavaFX Scene?
body: <p>With Swing, I had a class like this:</p>
  
  <pre><code>public class MyFrame extends JFrame {
      private static final String APP_NAME = "My App";
  
      // ...
  
      @Override
      public void setTitle(String newTitle) {
           super.setTitle(newTitle == null || newTitle.isEmpty() ? APP_NAME : newTitle + " - " + APP_NAME);
      }
  }
  </code></pre>
  
  <p>This would perform <strong>the behavior I want: guarantee the title always contains the app name, like <code>"Editing - My App"</code>, or if set to <code>null</code> or <code>""</code>, simply <code>"My App"</code>.</strong></p>
  
  <p>I attempted to replicate this behavior in JavaFX, but <a href="http://docs.oracle.com/javase/8/javafx/api/javafx/stage/Stage.html#setTitle-java.lang.String-" rel="nofollow"><code>Stage#setTitle</code> is <code>final</code></a>. So, I tried attaching a custom <code>ChangeListener&lt;String&gt;</code> to the <code>#titleProperty()</code> of the Scene (because <code>Scene#setTitle(String)</code> is <code>final</code>), but quickly fell short when I couldn't find a way to intercept and change the value before it appeared on the window, at least not without infinite recursion.</p>
  
  <p><strong>How do I intercept any attempts to change the title, modify such attempts, and then pass that value along to be the title in a JavaFX Scene?</strong></p>
  
  <p>Here's what I tried in JavaFX:</p>
  
  <pre><code>public static class MyWindow extends Stage {
      public static final String APP_NAME = "My App";
  
      /** this is what I'll pass a stage to if I can't or don't wish to make my own */
      public static void setupStage(Stage stage) {
          stage.initStyle(StageStyle.UNIFIED);
          stage.setTitle(APP_NAME);
          stage.titleProperty().addListener(new MyTitleChangeListener(APP_NAME));
      }
  
      public MyWindow() {
          super();
          setupStage(this);
      }
  
      // ...
  
      @Override
      public void setTitle(String newTitle) { // &lt;&lt;&lt; ERROR OCCURS &lt;&lt;&lt; I cannot do this because setTitle is final
           super.setTitle(newTitle == null || newTitle.isEmpty() ? APP_NAME : newTitle + " - " + APP_NAME);
      }
  
      // ...
  
      private static class MyTitleChangeListener implements ChangeListener&lt;String&gt; { // Because of that error, I tried this
          private final CharSequence titleBasis;
  
          MyTitleChangeListener(CharSequence initTitleBasis) {
              titleBasis = initTitleBasis;
          }
  
          @Override
          public void changed(ObservableValue&lt;? extends String&gt; observable, String oldTitle, String newTitle) {
              String correctedTitle = newTitle == null || newTitle.isEmpty() ? titleBasis : newTitle + " - " + titleBasis;
              // Here is where I don't know what to do.
              // Certainly something with correctedTitle, right?
          }
      }
  }
  </code></pre>