I'm trying to make a WhatsApp-Like Conversation-View in JavaFX.
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.
Moreover, is it a good practice to make controls static?
Extra: if you can also help me do the chat bubble behind the text, it would be great.
Here is my 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<MouseEvent>() {
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<ActionEvent>() {
@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<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (messageTextField.getText() != null && !messageTextField.getText().isEmpty()) {
sendMsgButton.setDisable(false);
} else {
sendMsgButton.setDisable(true);
}
}
});
messageTextField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (event.getCode().equals(KeyCode.ENTER) && messageTextField.getText() != null
&& !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();
}