diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java b/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java new file mode 100644 index 00000000..8d5b46aa --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java @@ -0,0 +1,31 @@ +package org.ethereum.gui; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import javax.swing.border.TitledBorder; +import java.awt.*; + +/** + * www.ethereumJ.com + * User: Roman Mandeleil + * Created on: 23/05/2014 13:51 + */ + +public class GUIUtils { + + + public static void addStyle(JTextField textField, String labelName){ + textField.setHorizontalAlignment(SwingConstants.RIGHT); + Border line = BorderFactory.createLineBorder(Color.LIGHT_GRAY); + TitledBorder titled = BorderFactory.createTitledBorder(line, labelName); + titled.setTitleFont(new Font("Verdana", 0, 13)); + titled.setTitleColor(new Color(213, 225, 185)); + Border empty = new EmptyBorder(5, 8, 5, 8); + CompoundBorder border = new CompoundBorder(titled, empty); + textField.setBorder(border); + textField.setForeground(new Color(143, 170, 220)); + textField.setFont(new Font("Monospaced", 0, 13)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java index f343e797..126c0591 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java @@ -11,9 +11,15 @@ import org.spongycastle.util.encoders.Hex; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.math.BigInteger; +import java.net.URL; import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; /** * www.ethereumJ.com @@ -22,61 +28,105 @@ import javax.swing.*; */ class PayOutDialog extends JDialog { + PayOutDialog dialog; + AddressState addressState = null; + JLabel statusMsg = null; public PayOutDialog(Frame parent, final AddressState addressState) { super(parent, "Payout details: ", false); + dialog = this; this.addressState = addressState; - JLabel receiver = new JLabel("receiver: "); final JTextField receiverInput = new JTextField(18); - receiverInput.setHorizontalAlignment(SwingConstants.RIGHT); + GUIUtils.addStyle(receiverInput, "Pay to:"); - final JLabel amount = new JLabel("amount: "); final JTextField amountInput = new JTextField(18); - amountInput.setHorizontalAlignment(SwingConstants.RIGHT); - amountInput.setText(addressState.getBalance().toString()); + GUIUtils.addStyle(amountInput, "Amount: "); + + final JTextField feeInput = new JTextField(5); + GUIUtils.addStyle(feeInput, "Fee: "); this.getContentPane().setBackground(Color.WHITE); - this.getContentPane().setLayout(new GridLayout(0, 1, 0, 0)); + this.getContentPane().setLayout(null); - JPanel row1 = new JPanel(); - row1.setBackground(Color.WHITE); - row1.add(receiver); - row1.add(receiverInput); - this.getContentPane().add(row1); + receiverInput.setBounds(70, 30, 350, 45); + this.getContentPane().add(receiverInput); - JPanel row2 = new JPanel(); - row2.setBackground(Color.WHITE); - row2.add(amount); - row2.add(amountInput); - this.getContentPane().add(row2); + amountInput.setBounds(70, 80, 250, 45); + this.getContentPane().add(amountInput); - JPanel row3 = new JPanel(); - row3.setBackground(Color.WHITE); + feeInput.setBounds(330, 80, 90, 45); + this.getContentPane().add(feeInput); - JButton sendButton = new JButton("Send"); - sendButton.addActionListener( - new ActionListener() { + URL rejectIconURL = ClassLoader.getSystemResource("buttons/reject.png"); + ImageIcon rejectIcon = new ImageIcon(rejectIconURL); + JLabel rejectLabel = new JLabel(rejectIcon); + rejectLabel.setToolTipText("Cancel"); + rejectLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + + JLabel statusMessage = new JLabel(""); + statusMessage.setBounds(50, 180, 400, 50); + statusMessage.setHorizontalAlignment(SwingConstants.CENTER); + this.statusMsg = statusMessage; + this.getContentPane().add(statusMessage); + + rejectLabel.setBounds(260, 145, 45, 45); + this.getContentPane().add(rejectLabel); + rejectLabel.setVisible(true); + rejectLabel.addMouseListener( + new MouseAdapter() { @Override - public void actionPerformed(ActionEvent e) { + public void mouseClicked(MouseEvent e) { + + dialog.dispose(); + }} + ); + + + URL approveIconURL = ClassLoader.getSystemResource("buttons/approve.png"); + ImageIcon approveIcon = new ImageIcon(approveIconURL); + JLabel approveLabel = new JLabel(approveIcon); + approveLabel.setToolTipText("Submit the transaction"); + approveLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + + approveLabel.setBounds(200, 145, 45, 45); + this.getContentPane().add(approveLabel); + approveLabel.setVisible(true); + + + approveLabel.addMouseListener( + new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + + + BigInteger fee = new BigInteger(feeInput.getText()); + BigInteger value = new BigInteger(amountInput.getText()); + byte[] address = Hex.decode( receiverInput.getText()); + // Client - ClientPeer peer = MainData.instance.getActivePeer(); + ClientPeer peer = MainData.instance.getActivePeer(); - BigInteger value = new BigInteger(amountInput.getText()); - byte[] address = Hex.decode(receiverInput.getText()); + if (peer == null){ + dialog.alertStatusMsg("Not connected to any peer"); + return; + } byte[] senderPrivKey = addressState.getEcKey().getPrivKeyBytes(); - byte[] nonce = addressState.getNonce() == BigInteger.ZERO ? - null : addressState.getNonce().toByteArray(); - byte[] gasPrice= Hex.decode("09184e72a000"); - byte[] gas = Hex.decode("4255"); + byte[] nonce = addressState.getNonce() == BigInteger.ZERO ? + null : addressState.getNonce().toByteArray(); - Transaction tx = new Transaction(nonce, gasPrice, gas, - address, BigIntegers.asUnsignedByteArray(value), null); + // todo: in the future it should be retrieved from the block + byte[] gasPrice = new BigInteger("10000000000000").toByteArray(); + + Transaction tx = new Transaction(nonce, gasPrice, + BigIntegers.asUnsignedByteArray(fee), + address, + BigIntegers.asUnsignedByteArray(value), null); try { tx.sign(senderPrivKey); @@ -87,15 +137,18 @@ class PayOutDialog extends JDialog { } peer.sendTransaction(tx); + dialog.infoStatusMsg("Transaction sent to the network, waiting for approve"); } } ); - row3.add(sendButton); - row3.add(new JButton("Cancel")); - row3.setAlignmentY(Component.TOP_ALIGNMENT); - this.getContentPane().add(row3); + feeInput.setText("1000"); + amountInput.setText("0"); + + this.getContentPane().revalidate(); + this.getContentPane().repaint(); + this.setResizable(false); } protected JRootPane createRootPane() { @@ -112,17 +165,39 @@ class PayOutDialog extends JDialog { KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE"); Action actionListener = new AbstractAction() { public void actionPerformed(ActionEvent actionEvent) { - setVisible(false); + dispose(); } }; InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); inputMap.put(stroke, "ESCAPE"); rootPane.getActionMap().put("ESCAPE", actionListener); - this.setSize(350, 140); + this.setSize(500, 255); this.setVisible(true); + return rootPane; } + + public void infoStatusMsg(String text){ + this.statusMsg.setForeground(Color.GREEN.darker().darker()); + this.statusMsg.setText(text); + } + + public void alertStatusMsg(String text){ + this.statusMsg.setForeground(Color.RED); + this.statusMsg.setText(text); + } + + + public static void main(String args[]) { + + AddressState as = new AddressState(); + + PayOutDialog pod = new PayOutDialog(null, as); + pod.setVisible(true); + + + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ToolBar.java b/ethereumj-core/src/main/java/org/ethereum/gui/ToolBar.java index 6847c174..f186723b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/ToolBar.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/ToolBar.java @@ -35,6 +35,7 @@ public class ToolBar extends JFrame { introLogger.info(""); introLogger.info("♢ EthereumJ [v0.5.1] "); introLogger.info("♢ Code by Roman Mandeleil, (c) 2014."); + introLogger.info("♢ Contribution: Nick Savers "); introLogger.info("♢ Based on a design by Vitaly Buterin."); introLogger.info(""); introLogger.info("java.version: " + System.getProperty("java.version")); diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java index 4e3b4c90..922c80a8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java @@ -113,7 +113,20 @@ public class MainData { return activePeer; } - public void addTransactions(List transactions) {} + + /* todo: here will be all the pending transaction approve + * 1) the dialog put a pending transaction her + * 2) the dialog send the transaction to a net + * 3) wherever the transaction got for the wire in will change to approve state + * 4) only after the approve a) Wallet state changes + * + * 5) After the block is received with that tx the pending been clean up + */ + public void addTransactions(List transactions) { + + + + } public List getPeers() { return peers; diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/EthereumPeerTasterHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/EthereumPeerTasterHandler.java index df94d30c..3d3eadd1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/EthereumPeerTasterHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/EthereumPeerTasterHandler.java @@ -56,7 +56,7 @@ public class EthereumPeerTasterHandler extends ChannelInboundHandlerAdapter { byte[] peerIdBytes = HashUtil.randomPeerId(); HelloMessage helloMessage = new HelloMessage((byte)0x11, (byte)0x00, "EthereumJ [v0.5.1] by RomanJ ", - (byte)0b00000111, (short)30303, peerIdBytes); + (byte)0b00000001, (short)30303, peerIdBytes); byte[] helloLength =ByteUtil.calcPacketLength(helloMessage.getPayload()); final ByteBuf buffer = ctx.alloc().buffer(helloMessage.getPayload().length + 8); diff --git a/ethereumj-core/src/main/resources/buttons/approve.png b/ethereumj-core/src/main/resources/buttons/approve.png new file mode 100644 index 00000000..c7455cc1 Binary files /dev/null and b/ethereumj-core/src/main/resources/buttons/approve.png differ diff --git a/ethereumj-core/src/main/resources/buttons/reject.png b/ethereumj-core/src/main/resources/buttons/reject.png new file mode 100644 index 00000000..95e30d03 Binary files /dev/null and b/ethereumj-core/src/main/resources/buttons/reject.png differ