gt:         sendButton.setOnAction(e -> onTrySendMessage());
context: /*
   * This file is part of Bisq.
   *
   * Bisq is free software: you can redistribute it and/or modify it
   * under the terms of the GNU Affero General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or (at
   * your option) any later version.
   *
   * Bisq is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
   * License for more details.
   *
   * You should have received a copy of the GNU Affero General Public License
   * along with Bisq. If not, see <http://www.gnu.org/licenses/>.
   */
  
  package bisq.desktop.main.shared;
  
  import bisq.desktop.components.AutoTooltipButton;
  import bisq.desktop.components.AutoTooltipLabel;
  import bisq.desktop.components.BisqTextArea;
  import bisq.desktop.components.BusyAnimation;
  import bisq.desktop.components.TableGroupHeadline;
  import bisq.desktop.main.overlays.popups.Popup;
  import bisq.desktop.util.DisplayUtils;
  import bisq.desktop.util.GUIUtil;
  
  import bisq.core.locale.Res;
  import bisq.core.support.SupportManager;
  import bisq.core.support.SupportSession;
  import bisq.core.support.dispute.Attachment;
  import bisq.core.support.messages.ChatMessage;
  
  import bisq.network.p2p.network.Connection;
  
  import bisq.common.Timer;
  import bisq.common.UserThread;
  import bisq.common.util.Utilities;
  
  import com.google.common.io.ByteStreams;
  
  import de.jensd.fx.fontawesome.AwesomeDude;
  import de.jensd.fx.fontawesome.AwesomeIcon;
  
  import javafx.stage.FileChooser;
  
  import javafx.scene.control.Button;
  import javafx.scene.control.Label;
  import javafx.scene.control.ListCell;
  import javafx.scene.control.ListView;
  import javafx.scene.control.TextArea;
  import javafx.scene.control.Tooltip;
  import javafx.scene.image.ImageView;
  import javafx.scene.input.KeyCode;
  import javafx.scene.input.KeyEvent;
  import javafx.scene.layout.AnchorPane;
  import javafx.scene.layout.HBox;
  import javafx.scene.layout.Pane;
  import javafx.scene.layout.Priority;
  import javafx.scene.layout.VBox;
  import javafx.scene.text.TextAlignment;
  
  import javafx.geometry.Insets;
  
  import org.fxmisc.easybind.EasyBind;
  import org.fxmisc.easybind.Subscription;
  
  import javafx.beans.property.ReadOnlyDoubleProperty;
  import javafx.beans.value.ChangeListener;
  
  import javafx.event.EventHandler;
  
  import javafx.collections.ListChangeListener;
  import javafx.collections.ObservableList;
  import javafx.collections.transformation.SortedList;
  
  import javafx.util.Callback;
  
  import java.net.MalformedURLException;
  import java.net.URL;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  import java.util.ArrayList;
  import java.util.Comparator;
  import java.util.Date;
  import java.util.List;
  import java.util.Optional;
  import java.util.concurrent.TimeUnit;
  
  import lombok.Getter;
  import lombok.Setter;
  import lombok.extern.slf4j.Slf4j;
  
  import javax.annotation.Nullable;
  
  @Slf4j
  public class ChatView extends AnchorPane {
  
      // UI
      private TextArea inputTextArea;
      private Button sendButton;
      private ListView<ChatMessage> messageListView;
      private Label sendMsgInfoLabel;
      private BusyAnimation sendMsgBusyAnimation;
      private TableGroupHeadline tableGroupHeadline;
      private VBox messagesInputBox;
  
      // Options
      @Getter
      Button extraButton;
      @Getter
      private ReadOnlyDoubleProperty widthProperty;
      @Setter
      boolean allowAttachments;
      @Setter
      boolean displayHeader;
  
      // Communication stuff, to be renamed to something more generic
      private ChatMessage chatMessage;
      private ObservableList<ChatMessage> chatMessages;
      private ListChangeListener<ChatMessage> disputeDirectMessageListListener;
      private Subscription inputTextAreaTextSubscription;
      private final List<Attachment> tempAttachments = new ArrayList<>();
      private ChangeListener<Boolean> storedInMailboxPropertyListener, acknowledgedPropertyListener;
      private ChangeListener<String> sendMessageErrorPropertyListener;
  
      private EventHandler<KeyEvent> keyEventEventHandler;
      private SupportManager supportManager;
      private Optional<SupportSession> optionalSupportSession = Optional.empty();
      private String counterpartyName;
  
      public ChatView(SupportManager supportManager, String counterpartyName) {
          this.supportManager = supportManager;
          this.counterpartyName = counterpartyName;
          allowAttachments = true;
          displayHeader = true;
      }
  
      public void initialize() {
          disputeDirectMessageListListener = c -> scrollToBottom();
  
          keyEventEventHandler = event -> {
              if (Utilities.isAltOrCtrlPressed(KeyCode.ENTER, event)) {
                  optionalSupportSession.ifPresent(supportSession -> {
                      if (supportSession.chatIsOpen() && inputTextArea.isFocused()) {
                          onTrySendMessage();
                      }
                  });
              }
          };
      }
  
      public void activate() {
          addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
      }
  
      public void deactivate() {
          removeEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
          removeListenersOnSessionChange();
      }
  
      public void display(SupportSession supportSession, ReadOnlyDoubleProperty widthProperty) {
          display(supportSession, null, widthProperty);
      }
  
      public void display(SupportSession supportSession,
                          @Nullable Button extraButton,
                          ReadOnlyDoubleProperty widthProperty) {
          optionalSupportSession = Optional.of(supportSession);
          removeListenersOnSessionChange();
          this.getChildren().clear();
          this.extraButton = extraButton;
          this.widthProperty = widthProperty;
  
          tableGroupHeadline = new TableGroupHeadline();
          tableGroupHeadline.setText(Res.get("support.messages"));
  
          AnchorPane.setTopAnchor(tableGroupHeadline, 10d);
          AnchorPane.setRightAnchor(tableGroupHeadline, 0d);
          AnchorPane.setBottomAnchor(tableGroupHeadline, 0d);
          AnchorPane.setLeftAnchor(tableGroupHeadline, 0d);
  
          chatMessages = supportSession.getObservableChatMessageList();
          SortedList<ChatMessage> sortedList = new SortedList<>(chatMessages);
          sortedList.setComparator(Comparator.comparing(o -> new Date(o.getDate())));
          messageListView = new ListView<>(sortedList);
          messageListView.setId("message-list-view");
  
          messageListView.setMinHeight(150);
          AnchorPane.setTopAnchor(messageListView, 30d);
          AnchorPane.setRightAnchor(messageListView, 0d);
          AnchorPane.setLeftAnchor(messageListView, 0d);
  
          VBox.setVgrow(this, Priority.ALWAYS);
  
          inputTextArea = new BisqTextArea();
          inputTextArea.setPrefHeight(70);
          inputTextArea.setWrapText(true);
  
          if (!supportSession.isDisputeAgent()) {
              inputTextArea.setPromptText(Res.get("support.input.prompt"));
          }
  
          sendButton = new AutoTooltipButton(Res.get("support.send"));
          sendButton.setDefaultButton(true);
  