private static void enableSendButtonOnSwingThread() {
    if (sendBitcoinConfirmAction != null) {
      sendBitcoinConfirmAction.setEnabled(SendBitcoinPanel.enableSendButton);
    }

    final String finalRegularTooltipText = regularTooltipText;
    final String finalPleaseWaitTooltipText = pleaseWaitTooltipText;

    if (sendButton != null) {
      if (SendBitcoinPanel.enableSendButton) {
        sendButton.setEnabled(true);
        sendButton.setToolTipText(HelpContentsPanel.createTooltipText(finalRegularTooltipText));
      } else {
        sendButton.setEnabled(false);
        sendButton.setToolTipText(HelpContentsPanel.createTooltipText(finalPleaseWaitTooltipText));
      }
    }

    if (thisPanel != null) {
      thisPanel.invalidate();
      thisPanel.validate();
      thisPanel.repaint();
    }
  }
  @Override
  public void loadForm() {
    // get the current address, label and amount from the model
    String address =
        this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.SEND_ADDRESS);
    String label =
        this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.SEND_LABEL);
    String amountNotLocalised =
        this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.SEND_AMOUNT);

    if (amountBTCTextField != null) {
      CurrencyConverterResult converterResult =
          CurrencyConverter.INSTANCE.parseToBTCNotLocalised(amountNotLocalised);

      if (converterResult.isBtcMoneyValid()) {
        parsedAmountBTC = converterResult.getBtcMoney();
        String amountLocalised =
            CurrencyConverter.INSTANCE.getBTCAsLocalisedString(converterResult.getBtcMoney());
        amountBTCTextField.setText(amountLocalised);
        if (notificationLabel != null) {
          notificationLabel.setText("");
        }
      } else {
        parsedAmountBTC = null;
        amountBTCTextField.setText("");
        if (notificationLabel != null) {
          notificationLabel.setText(converterResult.getBtcMessage());
        }
      }
    }

    if (address != null) {
      addressTextField.setText(address);
    } else {
      addressTextField.setText("");
    }
    if (label != null) {
      labelTextArea.setText(label);
    } else {
      labelTextArea.setText("");
    }

    // if there is a pending 'handleopenURI' that needs pasting into the
    // send form, do it
    String performPasteNow =
        this.bitcoinController
            .getModel()
            .getActiveWalletPreference(BitcoinModel.SEND_PERFORM_PASTE_NOW);
    if (Boolean.TRUE.toString().equalsIgnoreCase(performPasteNow)) {
      try {
        Address decodeAddress =
            new Address(this.bitcoinController.getModel().getNetworkParameters(), address);
        processDecodedString(
            com.google.bitcoin.uri.BitcoinURI.convertToBitcoinURI(
                decodeAddress, Utils.toNanoCoins(amountNotLocalised), label, null),
            null);
        this.bitcoinController
            .getModel()
            .setActiveWalletPreference(BitcoinModel.SEND_PERFORM_PASTE_NOW, "false");
        sendButton.requestFocusInWindow();

        mainFrame.bringToFront();
      } catch (AddressFormatException e) {
        throw new RuntimeException(e);
      }
    }
  }
  @Override
  public void displayView(DisplayHint displayHint) {
    super.displayView(displayHint);

    if (DisplayHint.WALLET_TRANSACTIONS_HAVE_CHANGED == displayHint) {
      return;
    }

    JTextField aTextField = new JTextField();

    labelTextArea.setBorder(aTextField.getBorder());

    String bringToFront = controller.getModel().getUserPreference(BitcoinModel.BRING_TO_FRONT);
    if (Boolean.TRUE.toString().equals(bringToFront)) {
      controller.getModel().setUserPreference(BitcoinModel.BRING_TO_FRONT, "false");
      mainFrame.bringToFront();
    }

    // disable any new changes if another process has changed the wallet
    if (this.bitcoinController.getModel().getActivePerWalletModelData() != null
        && this.bitcoinController
            .getModel()
            .getActivePerWalletModelData()
            .isFilesHaveBeenChangedByAnotherProcess()) {
      // files have been changed by another process - disallow edits
      mainFrame.setUpdatesStoppedTooltip(addressTextField);
      addressTextField.setEditable(false);
      addressTextField.setEnabled(false);

      if (sendButton != null) {
        sendButton.setEnabled(false);
        mainFrame.setUpdatesStoppedTooltip(sendButton);
      }
      if (pasteAddressButton != null) {
        pasteAddressButton.setEnabled(false);
        mainFrame.setUpdatesStoppedTooltip(pasteAddressButton);
      }
      titleLabel.setText(
          controller
              .getLocaliser()
              .getString("sendBitcoinPanel.sendingAddressesTitle.mayBeOutOfDate"));
      mainFrame.setUpdatesStoppedTooltip(titleLabel);
    } else {
      addressTextField.setToolTipText(null);
      addressTextField.setEditable(true);
      addressTextField.setEnabled(true);

      if (sendButton != null) {
        if (SendBitcoinPanel.enableSendButton) {
          sendButton.setEnabled(true);
          sendButton.setToolTipText(
              HelpContentsPanel.createTooltipText(
                  controller.getLocaliser().getString("sendBitcoinAction.tooltip")));
        } else {
          sendButton.setEnabled(false);
          sendButton.setToolTipText(
              HelpContentsPanel.createTooltipText(
                  controller.getLocaliser().getString("sendBitcoinAction.pleaseWait.tooltip")));
        }
      }
      if (pasteAddressButton != null) {
        pasteAddressButton.setEnabled(true);
        pasteAddressButton.setToolTipText(
            HelpContentsPanel.createTooltipText(
                controller.getLocaliser().getString("pasteAddressAction.tooltip")));
      }
      titleLabel.setText(
          controller.getLocaliser().getString("sendBitcoinPanel.sendingAddressesTitle"));
      titleLabel.setToolTipText(null);
    }
    checkDeleteSendingEnabled();
    updateAmountPanel();
  }
  @Override
  protected JPanel createFormPanel(JPanel formPanel, GridBagConstraints constraints) {
    formPanel.setBackground(ColorAndFontConstants.VERY_LIGHT_BACKGROUND_COLOR);

    JPanel buttonPanel = new JPanel();
    FlowLayout flowLayout = new FlowLayout();
    flowLayout.setAlignment(FlowLayout.LEADING);
    buttonPanel.setLayout(flowLayout);

    formPanel.setLayout(new GridBagLayout());

    // create stents and forcers
    createFormPanelStentsAndForcers(formPanel, constraints);

    MultiBitLabel addressLabel =
        new MultiBitLabel(controller.getLocaliser().getString("sendBitcoinPanel.addressLabel"));
    addressLabel.setToolTipText(
        HelpContentsPanel.createTooltipText(
            controller.getLocaliser().getString("sendBitcoinPanel.addressLabel.tooltip")));
    addressLabel.setHorizontalAlignment(JLabel.TRAILING);
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.gridx = 0;
    constraints.gridy = 1;
    constraints.weightx = 4.0;
    constraints.weighty = 0.2;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.anchor = GridBagConstraints.LINE_END;
    formPanel.add(addressLabel, constraints);
    String receiveAddressText =
        controller.getLocaliser().getString("receiveBitcoinPanel.addressLabel");
    MultiBitLabel notUsedReceiveAddressLabel = new MultiBitLabel(receiveAddressText);
    formPanel.add(
        MultiBitTitledPanel.createStent(
            (int) notUsedReceiveAddressLabel.getPreferredSize().getWidth()),
        constraints);

    int longFieldWidth = fontMetrics.stringWidth(MultiBitFrame.EXAMPLE_LONG_FIELD_TEXT);
    addressTextField = new MultiBitTextField("", 24, controller);
    addressTextField.setHorizontalAlignment(JTextField.LEADING);
    addressTextField.setMinimumSize(
        new Dimension(
            longFieldWidth,
            getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont()).getHeight()
                + TEXTFIELD_VERTICAL_DELTA));
    addressTextField.setPreferredSize(
        new Dimension(
            longFieldWidth,
            getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont()).getHeight()
                + TEXTFIELD_VERTICAL_DELTA));
    addressTextField.setMaximumSize(
        new Dimension(
            longFieldWidth,
            getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont()).getHeight()
                + TEXTFIELD_VERTICAL_DELTA));

    addressTextField.addKeyListener(new QRCodeKeyListener());
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.gridx = 2;
    constraints.gridy = 1;
    constraints.weightx = 1.0;
    constraints.weighty = 0.2;
    constraints.gridwidth = 3;
    constraints.anchor = GridBagConstraints.LINE_START;
    formPanel.add(addressTextField, constraints);

    ImageIcon copyIcon = ImageLoader.createImageIcon(ImageLoader.COPY_ICON_FILE);
    CopySendAddressAction copyAddressAction = new CopySendAddressAction(controller, this, copyIcon);
    MultiBitButton copyAddressButton = new MultiBitButton(copyAddressAction, controller);
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 6;
    constraints.gridy = 1;
    constraints.weightx = 1;
    constraints.gridwidth = 1;
    constraints.anchor = GridBagConstraints.LINE_START;
    formPanel.add(copyAddressButton, constraints);

    ImageIcon pasteIcon = ImageLoader.createImageIcon(ImageLoader.PASTE_ICON_FILE);
    PasteAddressAction pasteAddressAction =
        new PasteAddressAction(super.bitcoinController, this, pasteIcon);
    pasteAddressButton = new MultiBitButton(pasteAddressAction, controller);
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 8;
    constraints.gridy = 1;
    constraints.weightx = 10.0;
    constraints.weighty = 0.2;
    constraints.gridwidth = 1;
    constraints.anchor = GridBagConstraints.LINE_START;
    formPanel.add(pasteAddressButton, constraints);

    MultiBitLabel labelLabel =
        new MultiBitLabel(controller.getLocaliser().getString("sendBitcoinPanel.labelLabel"));
    labelLabel.setToolTipText(
        HelpContentsPanel.createTooltipText(
            controller.getLocaliser().getString("sendBitcoinPanel.labelLabel.tooltip")));
    labelLabel.setHorizontalAlignment(JLabel.TRAILING);
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 0;
    constraints.gridy = 3;
    constraints.weightx = 0.1;
    constraints.weighty = 1.0;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.anchor = GridBagConstraints.LINE_END;
    formPanel.add(labelLabel, constraints);

    JTextField aTextField = new JTextField();
    labelTextArea =
        new MultiBitTextArea("", AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS, 20, controller);
    labelTextArea.setBorder(aTextField.getBorder());
    labelTextArea.addKeyListener(new QRCodeKeyListener());

    final JScrollPane labelScrollPane =
        new JScrollPane(
            labelTextArea,
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    labelScrollPane.setOpaque(true);
    labelScrollPane.setBackground(ColorAndFontConstants.VERY_LIGHT_BACKGROUND_COLOR);
    labelScrollPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    labelScrollPane
        .getViewport()
        .addChangeListener(
            new ChangeListener() {
              @Override
              public void stateChanged(ChangeEvent e) {
                if (labelScrollPane.getVerticalScrollBar().isVisible()) {
                  labelScrollPane.setBorder(
                      BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
                } else {
                  labelScrollPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
                }
              }
            });
    labelScrollPane.setMinimumSize(
        new Dimension(
            longFieldWidth,
            getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont()).getHeight()
                    * AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS
                + TEXTFIELD_VERTICAL_DELTA
                + 6));
    labelScrollPane.setPreferredSize(
        new Dimension(
            longFieldWidth,
            getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont()).getHeight()
                    * AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS
                + TEXTFIELD_VERTICAL_DELTA
                + 6));
    labelScrollPane.getHorizontalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
    labelScrollPane.getVerticalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);

    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.gridx = 2;
    constraints.gridy = 3;
    constraints.weightx = 0.6;
    constraints.weighty = 1.0;
    constraints.gridwidth = 3;
    constraints.gridheight = 1;
    constraints.anchor = GridBagConstraints.LINE_START;
    formPanel.add(labelScrollPane, constraints);

    MultiBitLabel amountLabel =
        new MultiBitLabel(controller.getLocaliser().getString("sendBitcoinPanel.amountLabel"));
    amountLabel.setToolTipText(
        HelpContentsPanel.createTooltipText(
            controller.getLocaliser().getString("sendBitcoinPanel.amountLabel.tooltip")));
    amountLabel.setHorizontalAlignment(JLabel.TRAILING);
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 0;
    constraints.gridy = 5;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.1;
    constraints.weighty = 0.20;
    constraints.anchor = GridBagConstraints.LINE_END;
    formPanel.add(amountLabel, constraints);

    JPanel amountPanel = createAmountPanel();
    constraints.fill = GridBagConstraints.BOTH;
    constraints.gridx = 2;
    constraints.gridy = 5;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.1;
    constraints.weighty = 0.20;
    constraints.anchor = GridBagConstraints.LINE_START;
    formPanel.add(amountPanel, constraints);

    notificationLabel = new MultiBitLabel("");
    notificationLabel.setForeground(Color.RED);
    // notificationLabel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
    constraints.fill = GridBagConstraints.BOTH;
    constraints.gridx = 2;
    constraints.gridy = 6;
    constraints.gridwidth = 8;
    constraints.gridheight = 3;
    constraints.weightx = 0.1;
    constraints.weighty = 0.1;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING;
    formPanel.add(notificationLabel, constraints);

    Action helpAction;
    if (ComponentOrientation.LEFT_TO_RIGHT
        == ComponentOrientation.getOrientation(controller.getLocaliser().getLocale())) {
      helpAction =
          new HelpContextAction(
              controller,
              ImageLoader.HELP_CONTENTS_BIG_ICON_FILE,
              "multiBitFrame.helpMenuText",
              "multiBitFrame.helpMenuTooltip",
              "multiBitFrame.helpMenuText",
              HelpContentsPanel.HELP_SENDING_URL);
    } else {
      helpAction =
          new HelpContextAction(
              controller,
              ImageLoader.HELP_CONTENTS_BIG_RTL_ICON_FILE,
              "multiBitFrame.helpMenuText",
              "multiBitFrame.helpMenuTooltip",
              "multiBitFrame.helpMenuText",
              HelpContentsPanel.HELP_SENDING_URL);
    }
    HelpButton helpButton = new HelpButton(helpAction, controller);
    helpButton.setText("");

    String tooltipText =
        HelpContentsPanel.createMultilineTooltipText(
            new String[] {
              controller.getLocaliser().getString("sendBitcoinPanel.helpLabel1.message"),
              controller.getLocaliser().getString("sendBitcoinPanel.helpLabel2.message"),
              controller.getLocaliser().getString("sendBitcoinPanel.helpLabel3.message"),
              "\n",
              controller.getLocaliser().getString("multiBitFrame.helpMenuTooltip")
            });
    helpButton.setToolTipText(tooltipText);
    helpButton.setHorizontalAlignment(SwingConstants.LEADING);
    helpButton.setBorder(
        BorderFactory.createEmptyBorder(
            0, HELP_BUTTON_INDENT, HELP_BUTTON_INDENT, HELP_BUTTON_INDENT));
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.gridx = 0;
    constraints.gridy = 8;
    constraints.weightx = 1;
    constraints.weighty = 0.3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.anchor = GridBagConstraints.BELOW_BASELINE_LEADING;
    formPanel.add(helpButton, constraints);

    sendBitcoinConfirmAction =
        new SendBitcoinConfirmAction(super.bitcoinController, mainFrame, this);
    sendBitcoinConfirmAction.setEnabled(enableSendButton);
    sendButton = new MultiBitButton(sendBitcoinConfirmAction, controller);
    if (enableSendButton) {
      sendButton.setEnabled(true);
      sendButton.setToolTipText(
          HelpContentsPanel.createTooltipText(
              controller.getLocaliser().getString("sendBitcoinAction.tooltip")));
    } else {
      sendButton.setEnabled(false);
      sendButton.setToolTipText(
          HelpContentsPanel.createTooltipText(
              controller.getLocaliser().getString("sendBitcoinAction.pleaseWait.tooltip")));
    }

    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.gridx = 6;
    constraints.gridy = 5;
    constraints.weightx = 0.1;
    constraints.weighty = 0.1;
    constraints.gridwidth = 3;
    constraints.gridheight = 1;
    constraints.anchor = GridBagConstraints.LINE_START;
    formPanel.add(sendButton, constraints);

    Action sidePanelAction = new MoreOrLessAction(controller, this);
    sidePanelButton = new MultiBitButton(sidePanelAction, controller);
    sidePanelButton.setBorder(BorderFactory.createEmptyBorder());
    sidePanelButton.setBorderPainted(false);
    sidePanelButton.setFocusPainted(false);
    sidePanelButton.setContentAreaFilled(false);

    displaySidePanel();

    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 4;
    constraints.gridy = 3;
    constraints.weightx = 0.1;
    constraints.weighty = 0.3;
    constraints.gridwidth = 7;
    constraints.gridheight = 3;
    constraints.anchor = GridBagConstraints.BASELINE_TRAILING;
    formPanel.add(sidePanelButton, constraints);

    return formPanel;
  }