/**
* Copyright 2012 multibit.org
*
* Licensed under the MIT license (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/mit-license.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.multibit.viewsystem.swing.view.dialogs;
import com.google.bitcoin.core.*;
import org.multibit.MultiBit;
import org.multibit.controller.Controller;
import org.multibit.controller.bitcoin.BitcoinController;
import org.multibit.exchange.CurrencyConverter;
import org.multibit.message.Message;
import org.multibit.message.MessageManager;
import org.multibit.model.bitcoin.WalletData;
import org.multibit.model.bitcoin.WalletTableData;
import org.multibit.model.core.CoreModel;
import org.multibit.utils.ImageLoader;
import org.multibit.viewsystem.swing.ColorAndFontConstants;
import org.multibit.viewsystem.swing.MultiBitFrame;
import org.multibit.viewsystem.swing.action.OkBackToParentAction;
import org.multibit.viewsystem.swing.view.components.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.List;
/**
* The transaction details dialog.
*/
public class TransactionDetailsDialog extends MultiBitDialog {
private static final String BLOCKCHAIN_INFO_PREFIX = "http://blockchain.info/tx-index/";
private static final String BLOCKEXPLORER_TRANSACTION_PREFIX = "http://blockexplorer.com/tx/";
private static final long serialVersionUID = 191435612345057705L;
private static final Logger log = LoggerFactory.getLogger(TransactionDetailsDialog.class);
private static final int HEIGHT_DELTA = 150;
private static final int WIDTH_DELTA = 440;
private static final int FIELD_SEPARATION = 12;
private final Controller controller;
private final BitcoinController bitcoinController;
private WalletTableData rowTableData;
private MultiBitLabel confidenceText;
private MultiBitLabel dateText;
private MultiBitLabel amountText;
private MultiBitLabel feeText;
private MultiBitLabel sizeText;
private JPanel mainPanel;
private JPanel detailPanel;
private MultiBitButton okButton;
public MultiBitButton getOkButton() {
return okButton;
}
private JScrollPane labelScrollPane;
private JScrollPane detailScrollPane;
private SimpleDateFormat dateFormatter;
private boolean initialisedOk = false;
/**
* Creates a new {@link TransactionDetailsDialog}.
*/
public TransactionDetailsDialog(BitcoinController bitcoinController, MultiBitFrame mainFrame, WalletTableData rowTableData) {
super(mainFrame, bitcoinController.getLocaliser().getString("transactionDetailsDialog.title"));
this.bitcoinController = bitcoinController;
this.controller = this.bitcoinController;
this.rowTableData = rowTableData;
try {
dateFormatter = new SimpleDateFormat("dd MMM yyyy HH:mm", controller.getLocaliser().getLocale());
ImageIcon imageIcon = ImageLoader.createImageIcon(ImageLoader.MULTIBIT_ICON_FILE);
if (imageIcon != null) {
setIconImage(imageIcon.getImage());
}
initUI();
applyComponentOrientation(ComponentOrientation.getOrientation(controller.getLocaliser().getLocale()));
// Put focus on okButton.
(new Thread() {
public void run() {
// Sleep long enough for the window to pop up.....
try {
Thread.sleep(200);
// request focus.
okButton.requestFocus();
Thread.sleep(400);
} catch (Exception e) {
// Not required.
}
// Request focus.
okButton.requestFocus();
}
}).start();
initialisedOk = true;
} catch (Exception e) {
String errorMessage = e.getClass().getName() + " " + e.getMessage();
log.error(errorMessage);
MessageManager.INSTANCE.addMessage(new Message(controller.getLocaliser().getString(
"privateKeysHandler.thereWasAnException", new String[] { errorMessage })));
}
}
/**
* Initialise transaction details dialog.
*/
public void initUI() {
FontMetrics fontMetrics = getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont());
int minimumHeight = fontMetrics.getHeight() * 14 + HEIGHT_DELTA;
int minimumWidth = Math.max(fontMetrics.stringWidth(MultiBitFrame.EXAMPLE_LONG_FIELD_TEXT),
fontMetrics.stringWidth("0123456789") * 5)
+ WIDTH_DELTA;
setMinimumSize(new Dimension(minimumWidth, minimumHeight));
positionDialogRelativeToParent(this, 0.5D, 0.45D);
mainPanel = new JPanel();
mainPanel.setOpaque(false);
setLayout(new BorderLayout());
add(mainPanel, BorderLayout.CENTER);
mainPanel.setLayout(new BorderLayout());
// get the transaction value out of the wallet data
BigInteger value = null;
try {
value = rowTableData.getTransaction().getValue(this.bitcoinController.getModel().getActiveWallet());
} catch (ScriptException e) {
log.error(e.getMessage(), e);
}
detailPanel = new JPanel(new GridBagLayout());
detailPanel.setBackground(ColorAndFontConstants.BACKGROUND_COLOR);
mainPanel.add(detailPanel, BorderLayout.CENTER);
GridBagConstraints constraints = new GridBagConstraints();
MultiBitLabel confidenceLabel = new MultiBitLabel("");
confidenceLabel.setText(controller.getLocaliser().getString("walletData.statusText"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(confidenceLabel, constraints);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 1;
constraints.gridy = 0;
constraints.weightx = 0.1;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(MultiBitTitledPanel.createStent(FIELD_SEPARATION), constraints);
confidenceText = new MultiBitLabel("");
confidenceText.setText(createStatusText(rowTableData.getTransaction()));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 0;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(confidenceText, constraints);
MultiBitLabel dateLabel = new MultiBitLabel("");
dateLabel.setText(controller.getLocaliser().getString("walletData.dateText"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 1;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(dateLabel, constraints);
dateText = new MultiBitLabel("");
if (rowTableData.getDate().getTime() > 0) {
dateText.setText(dateFormatter.format(rowTableData.getDate()));
}
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 1;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(dateText, constraints);
MultiBitLabel amountLabel = new MultiBitLabel("");
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 2;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(amountLabel, constraints);
amountText = new MultiBitLabel("");
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 2;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(amountText, constraints);
MultiBitLabel feeLabel = new MultiBitLabel("");
feeLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.feeLabel.text"));
feeLabel.setToolTipText(controller.getLocaliser().getString("transactionDetailsDialog.feeLabel.tooltip"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 3;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(feeLabel, constraints);
feeText = new MultiBitLabel("");
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 3;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(feeText, constraints);
MultiBitLabel totalDebitLabel = new MultiBitLabel("");
totalDebitLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.totalDebit"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 4;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(totalDebitLabel, constraints);
MultiBitLabel totalDebitText = new MultiBitLabel("");
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 4;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(totalDebitText, constraints);
BigInteger fee = rowTableData.getTransaction().calculateFee(this.bitcoinController.getModel().getActiveWallet());
feeText.setText(CurrencyConverter.INSTANCE.prettyPrint(Utils.bitcoinValueToPlainString(fee)));
if (BigInteger.ZERO.compareTo(value) > 0) {
// debit
amountLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.amountSent"));
try {
BigInteger totalDebit = rowTableData.getTransaction().getValue(this.bitcoinController.getModel().getActiveWallet()).negate();
BigInteger amountSent = totalDebit.subtract(fee);
totalDebitText.setText(CurrencyConverter.INSTANCE.prettyPrint(Utils.bitcoinValueToPlainString(totalDebit)));
amountText.setText(CurrencyConverter.INSTANCE.prettyPrint(Utils.bitcoinValueToPlainString(amountSent)));
} catch (ScriptException e) {
e.printStackTrace();
}
totalDebitLabel.setVisible(true);
totalDebitText.setVisible(true);
feeLabel.setVisible(true);
feeText.setVisible(true);
} else {
// Credit - cannot calculate fee so do not show.
try {
amountText.setText(CurrencyConverter.INSTANCE.prettyPrint(Utils.bitcoinValueToPlainString(rowTableData.getTransaction().getValue(
this.bitcoinController.getModel().getActiveWallet()))));
} catch (ScriptException e) {
e.printStackTrace();
}
amountLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.amountReceived"));
totalDebitLabel.setVisible(false);
totalDebitText.setVisible(false);
feeLabel.setVisible(false);
feeText.setVisible(false);
}
MultiBitLabel descriptionLabel = new MultiBitLabel("");
descriptionLabel.setText(controller.getLocaliser().getString("walletData.descriptionText"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 5;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(descriptionLabel, constraints);
MultiBitTextArea descriptionText = new MultiBitTextArea("", 2, 20, controller);
descriptionText.setText(createTransactionDescription(rowTableData.getTransaction()));
descriptionText.setEditable(false);
descriptionText.setFocusable(true);
labelScrollPane = new JScrollPane(descriptionText, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
labelScrollPane.setOpaque(true);
labelScrollPane.getViewport().setBackground(ColorAndFontConstants.BACKGROUND_COLOR);
labelScrollPane.setComponentOrientation(ComponentOrientation.getOrientation(controller.getLocaliser().getLocale()));
labelScrollPane.getHorizontalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
labelScrollPane.getVerticalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 2;
constraints.gridy = 5;
constraints.weightx = 0.3;
constraints.weighty = 0.2;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(labelScrollPane, constraints);
MultiBitLabel transactionDetailLabel = new MultiBitLabel("");
transactionDetailLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.transactionDetailText"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 6;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.ABOVE_BASELINE_TRAILING;
detailPanel.add(transactionDetailLabel, constraints);
MultiBitTextArea transactionDetailText = new MultiBitTextArea("", 5, 40, controller);
transactionDetailText.setEditable(false);
transactionDetailText.setText(rowTableData.getTransaction().toString());
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 2;
constraints.gridy = 6;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING;
detailScrollPane = new JScrollPane(transactionDetailText, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
detailScrollPane.setOpaque(true);
detailScrollPane.getViewport().setBackground(ColorAndFontConstants.BACKGROUND_COLOR);
detailScrollPane.setComponentOrientation(ComponentOrientation.getOrientation(controller.getLocaliser().getLocale()));
detailScrollPane.getHorizontalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
detailScrollPane.getVerticalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
detailPanel.add(detailScrollPane, constraints);
JLabel filler2 = new JLabel();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 5;
constraints.gridy = 6;
constraints.weightx = 0.1;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(filler2, constraints);
MultiBitLabel sizeLabel = new MultiBitLabel("");
feeLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.feeLabel.text"));
feeLabel.setToolTipText(controller.getLocaliser().getString("transactionDetailsDialog.feeLabel.tooltip"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
constraints.gridy = 7;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(sizeLabel, constraints);
sizeText = new MultiBitLabel("");
sizeLabel.setText(controller.getLocaliser().getString("transactionDetailsDialog.sizeLabel.text"));
sizeLabel.setToolTipText(controller.getLocaliser().getString("transactionDetailsDialog.sizeLabel.tooltip"));
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 7;
constraints.weightx = 0.3;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.anchor = GridBagConstraints.LINE_START;
detailPanel.add(sizeText, constraints);
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
try {
rowTableData.getTransaction().bitcoinSerialize(byteOutputStream);
sizeText.setText(controller.getLocaliser().getString("showPreferencesPanel.size.text", new Object[] {byteOutputStream.size()}));
} catch (IOException e1) {
e1.printStackTrace();
}
if (isBrowserSupported()) {
MultiBitButton openInBlockExplorerButton = new MultiBitButton(controller.getLocaliser().getString("transactionDetailsDialog.viewAtBlockExplorer"));
openInBlockExplorerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
try {
String blockExplorerTransactionURL = BLOCKEXPLORER_TRANSACTION_PREFIX + rowTableData.getTransaction().getHashAsString();
openURI(new URI(blockExplorerTransactionURL));
} catch (URISyntaxException e) {
log.debug(e.getMessage());
}
}});
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 2;
constraints.gridy = 8;
constraints.weightx = 0.4;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(openInBlockExplorerButton, constraints);
MultiBitButton openInBlockChainInfoButton = new MultiBitButton(controller.getLocaliser().getString("transactionDetailsDialog.viewAtBlockChainInfo"));
openInBlockChainInfoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
try {
String blockChainInfoTransactionInfo = BLOCKCHAIN_INFO_PREFIX + rowTableData.getTransaction().getHashAsString();
openURI(new URI(blockChainInfoTransactionInfo));
} catch (URISyntaxException e) {
log.debug(e.getMessage());
}
}});
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 3;
constraints.gridy = 8;
constraints.weightx = 0.4;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(openInBlockChainInfoButton, constraints);
}
OkBackToParentAction okAction = new OkBackToParentAction(controller, this);
okButton = new MultiBitButton(okAction, controller);
okButton.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent key) {
if (key.getKeyChar() == KeyEvent.VK_ENTER)
okButton.doClick();
}
});
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 4;
constraints.gridy = 8;
constraints.weightx = 0.4;
constraints.weighty = 0.1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_END;
detailPanel.add(okButton, constraints);
}
private String createStatusText(Transaction transaction) {
if (transaction.getLockTime() > 0) {
// Non standard transaction.
String transactionTrustfulness = MultiBit.getController().getLocaliser().getString("multiBitFrame.status.notConfirmedAndNotStandard") + ". ";
return transactionTrustfulness + transactionConfidenceToStringLocalised(transaction.getConfidence());
} else {
return transactionConfidenceToStringLocalised(transaction.getConfidence());
}
}
/**
* Create a description for a transaction.
*
* @return A description of the transaction
*/
private String createTransactionDescription(Transaction transaction) {
String toReturn = "";
WalletData perWalletModelData = this.bitcoinController.getModel().getActivePerWalletModelData();
if (perWalletModelData == null) {
return toReturn;
}
Wallet wallet = this.bitcoinController.getModel().getActiveWallet();
List<TransactionOutput> transactionOutputs = transaction.getOutputs();
BigInteger credit = transaction.getValueSentToMe(wallet);
BigInteger debit = null;
try {
debit = transaction.getValueSentFromMe(wallet);
} catch (ScriptException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
TransactionOutput myOutput = null;
TransactionOutput theirOutput = null;
if (transactionOutputs != null) {
for (TransactionOutput transactionOutput : transactionOutputs) {
if (transactionOutput != null && transactionOutput.isMine(perWalletModelData.getWallet())) {
myOutput = transactionOutput;
}
if (transactionOutput != null && !transactionOutput.isMine(perWalletModelData.getWallet())) {
theirOutput = transactionOutput;
}
}
}
if (credit != null && credit.compareTo(BigInteger.ZERO) > 0) {
// credit
try {
String addressString = "";
if (this.bitcoinController.getMultiBitService() != null && myOutput != null) {
Address toAddress = new Address(this.bitcoinController.getModel().getNetworkParameters(), myOutput
.getScriptPubKey().getPubKeyHash());
addressString = toAddress.toString();
}
String label = null;
if (perWalletModelData.getWalletInfo() != null) {
label = perWalletModelData.getWalletInfo().lookupLabelForReceivingAddress(addressString);
}
if (label != null && !label.equals("")) {
toReturn = controller.getLocaliser().getString("multiBitModel.creditDescriptionWithLabel",
new Object[] { addressString, label });
} else {
toReturn = controller.getLocaliser().getString("multiBitModel.creditDescription",
new Object[] { addressString });
}
} catch (ScriptException e) {
log.error(e.getMessage(), e);
}
}
if (debit != null && debit.compareTo(BigInteger.ZERO) > 0) {
// debit
try {
// see if the address is a known sending address
if (theirOutput != null) {
String addressString = theirOutput.getScriptPubKey().getToAddress(wallet.getNetworkParameters()).toString();
String label = null;
if (perWalletModelData.getWalletInfo() != null) {
label = perWalletModelData.getWalletInfo().lookupLabelForSendingAddress(addressString);
}
if (label != null && !label.equals("")) {
toReturn = controller.getLocaliser().getString("multiBitModel.debitDescriptionWithLabel",
new Object[] { addressString, label });
} else {
toReturn = controller.getLocaliser().getString("multiBitModel.debitDescription",
new Object[] { addressString });
}
}
} catch (ScriptException e) {
log.error(e.getMessage(), e);
}
}
return toReturn;
}
private boolean isBrowserSupported() {
if (!java.awt.Desktop.isDesktopSupported()) {
return false;
}
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
return false;
}
return true;
}
private void openURI(URI uri) {
try {
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
desktop.browse(uri);
} catch (IOException ioe) {
log.debug(ioe.getMessage());
Message message = new Message(controller.getLocaliser().getString("browser.unableToLoad", new String[]{ uri.toString(), ioe.getMessage()}));
MessageManager.INSTANCE.addMessage(message);
}
}
public boolean isInitialisedOk() {
return initialisedOk;
}
private String transactionConfidenceToStringLocalised(TransactionConfidence transactionConfidence) {
StringBuilder builder = new StringBuilder();
if (MultiBit.getController() != null && MultiBit.getController().getLocaliser() != null) {
int peers = transactionConfidence.getBroadcastByCount();
if (peers > 0) {
builder
.append(MultiBit.getController().getLocaliser().getString("transactionConfidence.seenBy"))
.append(" ");
builder.append(peers);
if (peers > 1)
builder
.append(" ")
.append(MultiBit.getController().getLocaliser().getString("transactionConfidence.peers"))
.append(". ");
else
builder
.append(" ")
.append(MultiBit.getController().getLocaliser().getString("transactionConfidence.peer"))
.append(". ");
}
switch (transactionConfidence.getConfidenceType()) {
case UNKNOWN:
builder.append(MultiBit.getController().getLocaliser().getString("transactionConfidence.unknownConfidenceLevel"));
break;
case DEAD:
builder.append(MultiBit.getController().getLocaliser().getString("transactionConfidence.dead"));
break;
case PENDING:
builder.append(MultiBit.getController().getLocaliser().getString("transactionConfidence.pending"));
break;
case BUILDING:
builder.append(MultiBit.getController().getLocaliser()
.getString("transactionConfidence.appearedInBestChain", new Object[] { transactionConfidence.getAppearedAtChainHeight() }));
break;
}
}
return builder.toString();
}
}