private Button getNonBreakingLineButton() {
    Button ret =
        new Button(
            "", new ImageView(new Image("file:icons/nonbreakline.png", 24, 24, false, true)));
    Utils.setToolbarButtonStyle(ret);
    ret.setTooltip(new Tooltip(LabelGrabber.INSTANCE.getLabel("nonbreak.tooltip")));
    ret.setOnAction(
        (event) -> {
          int caretPos = lyricsArea.getArea().getCaretPosition();
          String[] parts = lyricsArea.getText().split("\n");
          int lineIndex = lineFromPos(lyricsArea.getText(), caretPos);
          String line = parts[lineIndex];
          if (line.trim().isEmpty()) {
            Platform.runLater(
                new Runnable() {

                  @Override
                  public void run() {
                    lyricsArea.getArea().replaceText(caretPos, caretPos, "<>");
                    lyricsArea.getArea().refreshStyle();
                  }
                });
          } else {
            int nextLinePos = nextLinePos(lyricsArea.getText(), caretPos);
            if (nextLinePos >= lyricsArea.getText().length()) {
              Platform.runLater(
                  new Runnable() {

                    @Override
                    public void run() {
                      lyricsArea.getArea().replaceText(nextLinePos, nextLinePos, "\n<>\n");
                      lyricsArea.getArea().refreshStyle();
                    }
                  });
            } else {
              Platform.runLater(
                  new Runnable() {

                    @Override
                    public void run() {
                      lyricsArea.getArea().replaceText(nextLinePos, nextLinePos, "<>\n");
                      lyricsArea.getArea().refreshStyle();
                    }
                  });
            }
          }
        });
    return ret;
  }
 /**
  * Get the spell checker button.
  *
  * <p>
  *
  * @return the spell checker button.
  */
 private Button getDictButton() {
   Button button =
       new Button("", new ImageView(new Image("file:icons/dictionary.png", 24, 24, false, true)));
   button.setTooltip(
       new Tooltip(LabelGrabber.INSTANCE.getLabel("run.spellcheck.label") + " (F7)"));
   button.setOnAction(
       new EventHandler<javafx.event.ActionEvent>() {
         @Override
         public void handle(javafx.event.ActionEvent t) {
           lyricsArea.runSpellCheck();
         }
       });
   button.disableProperty().bind(lyricsArea.spellingOkProperty());
   Utils.setToolbarButtonStyle(button);
   return button;
 }
  /** Create and initialise the song panel. */
  public BasicSongPanel() {
    final VBox centrePanel = new VBox();
    transposeDialog = new TransposeDialog();
    GridPane topPanel = new GridPane();

    titleField = new TextField();
    GridPane.setHgrow(titleField, Priority.ALWAYS);
    Label titleLabel = new Label(LabelGrabber.INSTANCE.getLabel("title.label"));
    GridPane.setConstraints(titleLabel, 1, 1);
    topPanel.getChildren().add(titleLabel);
    titleLabel.setLabelFor(titleField);
    GridPane.setConstraints(titleField, 2, 1);
    topPanel.getChildren().add(titleField);

    authorField = new TextField();
    GridPane.setHgrow(authorField, Priority.ALWAYS);
    Label authorLabel = new Label(LabelGrabber.INSTANCE.getLabel("author.label"));
    GridPane.setConstraints(authorLabel, 1, 2);
    topPanel.getChildren().add(authorLabel);
    authorLabel.setLabelFor(authorField);
    GridPane.setConstraints(authorField, 2, 2);
    topPanel.getChildren().add(authorField);

    centrePanel.getChildren().add(topPanel);
    lyricsArea = new SpellTextArea();
    lyricsArea.setMaxHeight(Double.MAX_VALUE);

    final VBox mainPanel = new VBox();
    ToolBar lyricsToolbar = new ToolBar();
    transposeButton = getTransposeButton();
    nonBreakingLineButton = getNonBreakingLineButton();
    lyricsToolbar.getItems().add(transposeButton);
    lyricsToolbar.getItems().add(nonBreakingLineButton);
    lyricsToolbar.getItems().add(new Separator());
    Region spacer = new Region();
    HBox.setHgrow(spacer, Priority.ALWAYS);
    lyricsToolbar.getItems().add(spacer);
    dictSelector = new ComboBox<>();
    Tooltip.install(
        dictSelector, new Tooltip(LabelGrabber.INSTANCE.getLabel("dictionary.language.text")));
    for (Dictionary dict : DictionaryManager.INSTANCE.getDictionaries()) {
      dictSelector.getItems().add(dict);
    }
    dictSelector
        .selectionModelProperty()
        .get()
        .selectedItemProperty()
        .addListener(
            new ChangeListener<Dictionary>() {

              @Override
              public void changed(
                  ObservableValue<? extends Dictionary> ov, Dictionary t, Dictionary t1) {
                lyricsArea.setDictionary(dictSelector.getValue());
              }
            });

    dictSelector.getSelectionModel().select(QueleaProperties.get().getDictionary());
    lyricsToolbar.getItems().add(dictSelector);
    lyricsToolbar.getItems().add(getDictButton());
    VBox.setVgrow(mainPanel, Priority.ALWAYS);
    mainPanel.getChildren().add(lyricsToolbar);
    VBox.setVgrow(lyricsArea, Priority.ALWAYS);
    mainPanel.getChildren().add(lyricsArea);
    centrePanel.getChildren().add(mainPanel);
    setCenter(centrePanel);
  }
 /**
  * Get the lyrics field.
  *
  * <p>
  *
  * @return the lyrics field.
  */
 public LyricsTextArea getLyricsField() {
   return lyricsArea.getArea();
 }
 private String getSaveHash() {
   return ""
       + lyricsArea.getText().hashCode()
       + titleField.getText().hashCode()
       + authorField.getText().hashCode();
 }