title: JavaFX WhatApp-Like ConversationView
body: <p>I'm trying to make a WhatsApp-Like Conversation-View in JavaFX.</p>
  
  <p>In order to make the sent messages appear on the right and the received messages appear on the left then I cannot use TextArea. How can I do it? I tried GridPane without TextArea but it didn't make things easier.</p>
  
  <p>Moreover, is it a good practice to make controls static?</p>
  
  <p>Extra: if you can also help me do the chat bubble behind the text, it would be great.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>public class ConversationView implements WhatAppView {
      private static Label nameLabel, statusLabel;
      private static TextField messageTextField;
      static TextArea messagesTextArea;
      private static GridPane conversationSection;
      private static Label changeViewLink;
      private static Button sendMsgButton;
  
  // private static int rowIndex = 1;
  
  public void showView() {
      AppMain.stage.setResizable(false);
      AppMain.stage.setWidth(350);
      AppMain.stage.setHeight(550);
      BorderPane rootPane = new BorderPane();
      rootPane.setPadding(new Insets(5, 5, 5, 5));
  
      final int sectionHeight = 55;
  
      StackPane contactSection = new StackPane();
      nameLabel = new Label("RW");
      statusLabel = new Label("Online");
      changeViewLink = new Label("Go Back");
      changeViewLink.setStyle("-fx-text-fill: blue;");
      changeViewLink.styleProperty().bind(
              Bindings.when(changeViewLink.hoverProperty())
                      .then(new SimpleStringProperty("-fx-underline: true; -fx-text-fill: blue;"))
                      .otherwise(new SimpleStringProperty("-fx-underline: false; -fx-text-fill: blue;")));
      changeViewLink.setOnMouseClicked(new EventHandler&lt;MouseEvent&gt;() {
          public void handle(MouseEvent event) {
              AppMain.changeView(new ChatsView());
          }
      });
      contactSection.getChildren().addAll(nameLabel, statusLabel, changeViewLink);
      StackPane.setAlignment(changeViewLink, Pos.TOP_RIGHT);
      StackPane.setAlignment(statusLabel, Pos.BOTTOM_CENTER);
      contactSection.setPrefHeight(sectionHeight);
  
      conversationSection = new GridPane();
      conversationSection.setStyle("-fx-background-image: url('whatsapp-wallpaper.jpg')");
  
      messagesTextArea = new TextArea();
      messagesTextArea.setEditable(false);
      // conversationSection.getColumnConstraints().addAll(new
      // ColumnConstraints(AppMain.stage.getWidth()/2 - 10), new
      // ColumnConstraints(AppMain.stage.getWidth()/2 - 10));
      conversationSection.add(messagesTextArea, 0, 0);
      conversationSection.setPrefSize(AppMain.stage.getWidth(), AppMain.stage.getHeight());
      // conversationSection.getStylesheets().add("conversation.css");
      ScrollPane scroll = new ScrollPane();
      scroll.setPrefSize(conversationSection.getWidth(), conversationSection.getHeight());
      scroll.setContent(conversationSection);
  
      FlowPane messageSection = new FlowPane();
      sendMsgButton = new Button("_Send");
      sendMsgButton.setDisable(true);
      sendMsgButton.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent event) {
              sendMsg();
          }
      });
      sendMsgButton.setPrefHeight(sectionHeight);
      Tooltip sendMsgToolTip = new Tooltip("Send Message");
      Tooltip.install(sendMsgButton, sendMsgToolTip);
  
      FlowPane.setMargin(sendMsgButton, new Insets(0, 0, 0, 5));
      messageTextField = new TextField();
      messageTextField.setPromptText("Type your message here...");
      Platform.runLater(new Runnable() { // 100% focus
          public void run() {
              messageTextField.requestFocus();
          }
      });
      messageTextField.setPrefWidth(AppMain.stage.getWidth() - AppMain.stage.getWidth() / 5);
      messageTextField.setPrefHeight(sectionHeight);
      messageTextField.setAlignment(Pos.TOP_LEFT);
      messageTextField.setOnKeyTyped(new EventHandler&lt;KeyEvent&gt;() {
          @Override
          public void handle(KeyEvent event) {
              if (messageTextField.getText() != null &amp;&amp; !messageTextField.getText().isEmpty()) {
                  sendMsgButton.setDisable(false);
              } else {
                  sendMsgButton.setDisable(true);
              }
          }
      });
      messageTextField.setOnKeyPressed(new EventHandler&lt;KeyEvent&gt;() {
          @Override
          public void handle(KeyEvent event) {
              if (event.getCode().equals(KeyCode.ENTER) &amp;&amp; messageTextField.getText() != null
                      &amp;&amp; !messageTextField.getText().isEmpty()) {
                  sendMsg();
              }
          }
      });
      messageSection.getChildren().add(messageTextField);
      messageSection.getChildren().add(sendMsgButton);
      messageSection.setPrefHeight(sectionHeight);
  
      rootPane.setTop(contactSection);
      rootPane.setCenter(conversationSection);
      rootPane.setBottom(messageSection);
  
      Scene scene = new Scene(rootPane);
      AppMain.stage.setScene(scene);
      AppMain.stage.setTitle("WhatsApp");
  }
  }
  
  
  
  public class AppMain extends Application {
  static Stage stage;
  
  @Override
  public void start(Stage primaryStage) throws Exception {
      stage = primaryStage;
      AppMain.stage.show();
      changeView(new ConversationView());
  }
  public static void changeView(WhatAppView view) {
     view.showView();
  }
  }
  
  public interface WhatAppView {
      public void showView();
  }
  </code></pre>