From f85f20d907dd4329e725e672f45c12b72adf185a Mon Sep 17 00:00:00 2001
From: Luca Keidel <info@lucakeidel.de>
Date: Wed, 8 Jun 2016 10:17:48 +0200
Subject: [PATCH] Fixed wallet and server GUI

---
 .gitignore                                    |   2 +
 src/fucoin/AbstractWallet.java                |   6 +-
 src/fucoin/Main.java                          |   3 +-
 src/fucoin/Wallet.java                        | 332 ++++++++--------
 src/fucoin/actions/join/ActionJoinAnswer.java |   2 +-
 .../persist/ActionSearchMyWalletAnswer.java   |   2 +-
 ...tionCommitDistributedCommitedTransfer.java | 101 ++---
 .../actions/transaction/ActionGetAmount.java  |   2 +-
 .../transaction/ActionInvokeSentMoney2.java   |  22 --
 ...ionPrepareDistributedCommitedTransfer.java |  45 +--
 ...pareDistributedCommitedTransferAnswer.java |   1 +
 .../transaction/ActionReceiveTransaction.java |   2 +-
 src/fucoin/gui/IWalletGuiControle.java        |   1 +
 src/fucoin/gui/LogMessage.java                |  26 ++
 src/fucoin/gui/WalletGui.java                 | 355 ++++++++++--------
 src/fucoin/supervisor/AmountTableModel.java   |  36 +-
 src/fucoin/supervisor/SuperVisor.java         | 162 ++++----
 17 files changed, 605 insertions(+), 495 deletions(-)
 delete mode 100644 src/fucoin/actions/transaction/ActionInvokeSentMoney2.java
 create mode 100644 src/fucoin/gui/LogMessage.java

diff --git a/.gitignore b/.gitignore
index 09e3bc9..917f1dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 /bin/
 /target/
+.idea/
+*.iml
diff --git a/src/fucoin/AbstractWallet.java b/src/fucoin/AbstractWallet.java
index e77b674..076a8f2 100644
--- a/src/fucoin/AbstractWallet.java
+++ b/src/fucoin/AbstractWallet.java
@@ -17,11 +17,15 @@ public abstract class AbstractWallet extends AbstractNode{
     public abstract void leave();
 	
     // The amount this wallet currently holds
-    public int amount;
+    protected int amount;
 
     // The name of this wallet (does never change, no 
     // duplicates in network assumed)
     public final String name;
+
+    public int getAmount(){
+        return amount;
+    }
     
     
 }
diff --git a/src/fucoin/Main.java b/src/fucoin/Main.java
index 494bce4..b911900 100644
--- a/src/fucoin/Main.java
+++ b/src/fucoin/Main.java
@@ -10,6 +10,7 @@ import com.typesafe.config.Config;
 import com.typesafe.config.ConfigFactory;
 
 import fucoin.actions.join.ServerActionJoin;
+import fucoin.actions.transaction.ActionInvokeSentMoney;
 import fucoin.supervisor.SuperVisor;
 
 
@@ -22,7 +23,7 @@ public class Main {
 		Config config = ConfigFactory.parseFile(file);
 		ActorSystem system = ActorSystem.create("Core", config);
 		ActorRef superVisorActor = system.actorOf(SuperVisor.props(),"SuperVisor");
-		List<ActorRef> activeActors = new ArrayList<ActorRef>();
+		List<ActorRef> activeActors = new ArrayList<>();
 		ActorRef a1 = system.actorOf(Wallet.props(null,"","Main",superVisorActor),"Main");
 		ActorRef a2 = system.actorOf(Wallet.props(a1,"Main","Main2",superVisorActor),"Main2");
 		superVisorActor.tell(new ServerActionJoin("Main"), a1);
diff --git a/src/fucoin/Wallet.java b/src/fucoin/Wallet.java
index 70f26fd..9aa7c79 100644
--- a/src/fucoin/Wallet.java
+++ b/src/fucoin/Wallet.java
@@ -13,161 +13,181 @@ import fucoin.actions.transaction.ActionInvokeSentMoney;
 import fucoin.gui.IWalletControle;
 import fucoin.gui.IWalletGuiControle;
 
-public class Wallet extends AbstractWallet implements IWalletControle{
-	
-	private ActorRef preknownNeighbour;
-	private ActorRef remoteSuperVisorActor;
-	private IWalletGuiControle gui;
-	private String preknownNeighbourName;
-	private boolean isActive;
-
-	public Wallet(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) {
-		super(walletName);
-		this.preknownNeighbourName=preknownNeighbourName;
-		this.preknownNeighbour=preknownNeighbour;
-		this.remoteSuperVisorActor=remoteSuperVisorActor;
-	}
-
-	public void addAmount(int amount) {
-		setAmount(this.amount+amount);
-		log(" My amount is now "+this.amount);
-		
-	}
-
-	@Override
-	public void leave() {
-		getSelf().tell(new ActionInvokeLeave(), getSelf());
-	}
-
-	@Override
-	public void onReceive(Object message) {
-		log(message.getClass().getSimpleName());
-		
-		//log(getSender().path().name()+" invokes "+getSelf().path().name()+" to do "+message.getClass().getSimpleName());
-		if(message instanceof ActionInvokeRevive){
-			((ActionInvokeRevive) message).doAction(this);
-		}
-		if(!isActive&&!(message instanceof ActionInvokeRevive))return;
-		//System.out.println(message);
-		if(message instanceof ClientAction){
-			((ClientAction) message).doAction(this);
-		}
-		
-	}
-
-	@Override
-	public void preStart() throws Exception {
-		isActive=true;
-		if(gui!=null){
-			gui.setAddress(getAddress());
-		}
-		String path = "akka.tcp://Core@127.0.0.1:1234/user/Main";
-		//System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address()));
-		//log("my address should be "+getAddress());
-		//log(""+preknownNeighbour);
-		//knownNeighbors.put(getName(),getSelf());
-		
-		//System.out.println(knownNeighbors);
-		if(preknownNeighbour!=null){
-			addKnownNeighbor(preknownNeighbourName,preknownNeighbour);
-			preknownNeighbour.tell(new ActionJoin(), getSelf());
-			ActionJoinAnswer aja = new ActionJoinAnswer();
-			aja.someNeighbors.putAll(getKnownNeighbors());
-			aja.someNeighbors.put(name, getSelf());
-			preknownNeighbour.tell(aja, getSelf());
-			
-		}
-		//setAmount(100);
-		//remoteSuperVisorActor.tell(new ServerActionJoin(name), getSelf());
-	}
-	
-	@Override
-	public void postStop() throws Exception {
-		leave();
-		super.postStop();
-		
-	}
-	
-	
-	public static Props props(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) {
-		return Props.create(Wallet.class,new WalletCreator(preknownNeighbour,preknownNeighbourName,walletName,remoteSuperVisorActor));
-	}
-	
-	@Override
-	public boolean equals(Object obj) {
-		if(obj instanceof Wallet){
-			Wallet wobj = (Wallet) obj;
-			return amount==wobj.amount&&name.equals(wobj.name);
-		}
-		return false;
-	}
-
-	public void setGui(IWalletGuiControle gui) {
-		this.gui=gui;
-	}
-	
-	public void setAmount(int amount){
-		this.amount = amount;
-		if(remoteSuperVisorActor != null){
-			remoteSuperVisorActor.tell(new ActionGetAmountAnswer(getAddress(), getName(), amount), getSelf());
-		}
-		if(gui!=null){
-			gui.setAmount(this.amount);
-		}
-	}
-
-	public ActorRef getPreknownNeighbour() {
-		return preknownNeighbour;
-	}
-
-	public ActorRef getRemoteSuperVisorActor() {
-		return remoteSuperVisorActor;
-	}
-
-	public IWalletGuiControle getGui() {
-		return gui;
-	}
-
-	public String getPreknownNeighbourName() {
-		return preknownNeighbourName;
-	}
-
-	public boolean isActive() {
-		return isActive;
-	}
-	
-	@Override
-	public boolean addKnownNeighbor(String key, ActorRef value) {
-		log(key+" is newNeighbor?"+!getKnownNeighbors().containsKey(key));
-		if(getKnownNeighbors().containsKey(key)||key.equals(name)){
-			return false;
-		}
-		boolean newNeighbor = super.addKnownNeighbor(key, value);
-		if(gui!=null&&newNeighbor){
-			gui.addKnownAddress(key);
-		}
-		return newNeighbor;
-	}
-
-	public void setPreknownNeighbour(ActorRef preknownNeighbour) {
-		this.preknownNeighbour = preknownNeighbour;
-	}
-
-	public void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor) {
-		this.remoteSuperVisorActor = remoteSuperVisorActor;
-	}
-
-	public void setPreknownNeighbourName(String preknownNeighbourName) {
-		this.preknownNeighbourName = preknownNeighbourName;
-	}
-
-	public void setActive(boolean isActive) {
-		this.isActive = isActive;
-	}
-
-	@Override
-	public void send(String address, int amount) {
-		getSelf().tell(new ActionInvokeSentMoney(address, amount), getSelf());
-	}
+public class Wallet extends AbstractWallet implements IWalletControle {
+
+    private ActorRef preknownNeighbour;
+    private ActorRef remoteSuperVisorActor;
+    private IWalletGuiControle gui;
+    private String preknownNeighbourName;
+    private boolean isActive;
+
+    public Wallet(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) {
+        super(walletName);
+        this.preknownNeighbourName = preknownNeighbourName;
+        this.preknownNeighbour = preknownNeighbour;
+        this.remoteSuperVisorActor = remoteSuperVisorActor;
+    }
+
+    public void addAmount(int amount) {
+        setAmount(this.amount + amount);
+        log(" My amount is now " + this.amount);
+    }
+
+    @Override
+    public void leave() {
+        getSelf().tell(new ActionInvokeLeave(), getSelf());
+    }
+
+    @Override
+    public void onReceive(Object message) {
+
+        //log(getSender().path().name() + " invokes " + getSelf().path().name() + " to do " + message.getClass().getSimpleName());
+        if (message instanceof ActionInvokeRevive) {
+            ((ActionInvokeRevive) message).doAction(this);
+        }
+        if (!isActive && !(message instanceof ActionInvokeRevive)) return;
+        //System.out.println(message);
+        if (message instanceof ClientAction) {
+            ((ClientAction) message).doAction(this);
+        }
+
+    }
+
+    @Override
+    public void preStart() throws Exception {
+        isActive = true;
+        if (gui != null) {
+            gui.setAddress(getAddress());
+        }
+        String path = "akka.tcp://Core@127.0.0.1:1234/user/Main";
+        //System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address()));
+        //log("my address should be "+getAddress());
+        //log(""+preknownNeighbour);
+        //knownNeighbors.put(getName(),getSelf());
+
+        //System.out.println(knownNeighbors);
+        if (preknownNeighbour != null) {
+            addKnownNeighbor(preknownNeighbourName, preknownNeighbour);
+            preknownNeighbour.tell(new ActionJoin(), getSelf());
+            ActionJoinAnswer aja = new ActionJoinAnswer();
+            aja.someNeighbors.putAll(getKnownNeighbors());
+            aja.someNeighbors.put(name, getSelf());
+            preknownNeighbour.tell(aja, getSelf());
+
+        }
+        //setAmount(100);
+        //remoteSuperVisorActor.tell(new ServerActionJoin(name), getSelf());
+    }
+
+    @Override
+    public void postStop() throws Exception {
+        leave();
+        super.postStop();
+
+    }
+
+
+    public static Props props(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) {
+        return Props.create(Wallet.class, new WalletCreator(preknownNeighbour, preknownNeighbourName, walletName, remoteSuperVisorActor));
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Wallet) {
+            Wallet wobj = (Wallet) obj;
+            return amount == wobj.amount && name.equals(wobj.name);
+        }
+        return false;
+    }
+
+    public void setGui(IWalletGuiControle gui) {
+        this.gui = gui;
+    }
+
+    public void setAmount(int amount) {
+        this.amount = amount;
+        if (remoteSuperVisorActor != null) {
+            remoteSuperVisorActor.tell(new ActionGetAmountAnswer(getAddress(), getName(), amount), getSelf());
+        }
+        if (gui != null) {
+            gui.setAmount(this.amount);
+        }
+    }
+
+    public int getAmount() {
+        return amount;
+    }
+
+    public ActorRef getPreknownNeighbour() {
+        return preknownNeighbour;
+    }
+
+    public ActorRef getRemoteSuperVisorActor() {
+        return remoteSuperVisorActor;
+    }
+
+    public IWalletGuiControle getGui() {
+        return gui;
+    }
+
+    public String getPreknownNeighbourName() {
+        return preknownNeighbourName;
+    }
+
+    public boolean isActive() {
+        return isActive;
+    }
+
+    @Override
+    public boolean addKnownNeighbor(String key, ActorRef value) {
+        System.out.println(key + " is newNeighbor of "+name+"?" + !getKnownNeighbors().containsKey(key));
+        if (getKnownNeighbors().containsKey(key) || key.equals(name)) {
+            return false;
+        }
+
+        boolean newNeighbor = super.addKnownNeighbor(key, value);
+        if (gui != null && newNeighbor) {
+            gui.addKnownAddress(key);
+        }
+        return newNeighbor;
+    }
+
+    public void setPreknownNeighbour(ActorRef preknownNeighbour) {
+        this.preknownNeighbour = preknownNeighbour;
+    }
+
+    public void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor) {
+        this.remoteSuperVisorActor = remoteSuperVisorActor;
+    }
+
+    public void setPreknownNeighbourName(String preknownNeighbourName) {
+        this.preknownNeighbourName = preknownNeighbourName;
+    }
+
+    @Override
+    public void log(String msg) {
+        if (gui != null) {
+            gui.addLogMsg(msg);
+        } else {
+            System.out.println(msg);
+        }
+    }
+
+    public void logTransaction(String msg){
+        if (gui != null) {
+            gui.addTransactionLogMessage(msg);
+        } else {
+            System.out.println(msg);
+        }
+    }
+
+    public void setActive(boolean isActive) {
+        this.isActive = isActive;
+    }
+
+    @Override
+    public void send(String address, int amount) {
+        getSelf().tell(new ActionInvokeSentMoney(address, amount), getSelf());
+    }
 
 }
diff --git a/src/fucoin/actions/join/ActionJoinAnswer.java b/src/fucoin/actions/join/ActionJoinAnswer.java
index b230b1a..0750e85 100644
--- a/src/fucoin/actions/join/ActionJoinAnswer.java
+++ b/src/fucoin/actions/join/ActionJoinAnswer.java
@@ -15,7 +15,7 @@ public class ActionJoinAnswer extends ClientAction{
 	public final HashMap<String, ActorRef> someNeighbors = new HashMap<>();
 	protected void onAction(ActorRef sender, ActorRef self,
 			UntypedActorContext context, Wallet wallet) {
-		log("someNeighbors:"+someNeighbors);
+		log("Addressed to "+self.path().name()+" from "+sender.path().name()+": someNeighbors:"+someNeighbors);
 		for(Entry<String, ActorRef> neighbor : someNeighbors.entrySet()){
 			wallet.addKnownNeighbor(neighbor.getKey(),neighbor.getValue());
 		}
diff --git a/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java b/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java
index 9336928..0635d72 100644
--- a/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java
+++ b/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java
@@ -14,7 +14,7 @@ public class ActionSearchMyWalletAnswer extends Persist {
 	@Override
 	protected void onAction(ActorRef sender, ActorRef self,
 			UntypedActorContext context, Wallet wallet) {
-		wallet.setAmount(w.amount);
+		wallet.setAmount(w.getAmount());
 		sender.tell(new ActionInvalidate(wallet.name), self);
 	}
 }
diff --git a/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java b/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java
index 2b72a72..5236bf4 100644
--- a/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java
+++ b/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java
@@ -6,52 +6,59 @@ import fucoin.Wallet;
 import fucoin.actions.ClientAction;
 import fucoin.supervisor.DistributedCommitedTransferRequest;
 
-public class ActionCommitDistributedCommitedTransfer extends ClientAction{
-
-	private ActorRef source;
-	private ActorRef target;
-	private int amount;
-	private boolean granted;
-	private long timestamp;
-	private long id;
-
-	
-	public ActionCommitDistributedCommitedTransfer(ActorRef source,
-			ActorRef target, int amount, boolean granted, long timestamp, long id) {
-		this.source=source;
-		this.target=target;
-		this.amount=amount;
-		this.granted=granted;
-		this.timestamp=timestamp;
-		this.id=id;
-	}
-
-	public ActionCommitDistributedCommitedTransfer(
-			DistributedCommitedTransferRequest outdatedRequest) {
-		this.source=outdatedRequest.getSource();
-		this.target=outdatedRequest.getTarget();
-		this.amount=0;
-		this.granted=false;
-		this.timestamp=outdatedRequest.getTimeout();
-		this.id=outdatedRequest.getId();
-	}
-
-	@Override
-	protected void onAction(ActorRef sender, ActorRef self,
-			UntypedActorContext context, Wallet wallet) {
-		log("ActionCommitDistributedCommitedTransfer is granted?"+granted);
-		if(granted){
-			Integer sourceAmount = wallet.amounts.getOrDefault(source,0);
-			Integer targetAmount = wallet.amounts.getOrDefault(target,0);
-			wallet.amounts.put(source,sourceAmount-amount);
-			wallet.amounts.put(target,targetAmount+amount);
-			if(source.compareTo(self)==0)wallet.amount-=amount;
-			else if(target.compareTo(self)==0)wallet.amount+=amount;
-			wallet.log("have now "+wallet.amounts.get(self)+" Fucoins");
-		}else{
-			log("abort transaction with id"+id);
-		}
-		log("wallet.amounts:"+wallet.amounts);	
-	}
+public class ActionCommitDistributedCommitedTransfer extends ClientAction {
+
+    private ActorRef source;
+    private ActorRef target;
+    protected int amount;
+    private boolean granted;
+    private long timestamp;
+    private long id;
+
+
+    public ActionCommitDistributedCommitedTransfer(ActorRef source,
+                                                   ActorRef target, int amount, boolean granted, long timestamp, long id) {
+        this.source = source;
+        this.target = target;
+        this.amount = amount;
+        this.granted = granted;
+        this.timestamp = timestamp;
+        this.id = id;
+    }
+
+    public ActionCommitDistributedCommitedTransfer(
+            DistributedCommitedTransferRequest outdatedRequest) {
+        this.source = outdatedRequest.getSource();
+        this.target = outdatedRequest.getTarget();
+        this.amount = 0;
+        this.granted = false;
+        this.timestamp = outdatedRequest.getTimeout();
+        this.id = outdatedRequest.getId();
+    }
+
+    @Override
+    protected void onAction(ActorRef sender, ActorRef self,
+                            UntypedActorContext context, Wallet wallet) {
+        System.out.println(self.path().name() + ": ActionCommitDistributedCommitedTransfer is granted?" + granted);
+        if (granted) {
+
+            Integer sourceAmount = wallet.amounts.getOrDefault(source, 0);
+            Integer targetAmount = wallet.amounts.getOrDefault(target, 0);
+            wallet.amounts.put(source, sourceAmount - amount);
+            wallet.amounts.put(target, targetAmount + amount);
+
+            if (source.compareTo(self) == 0) {
+                wallet.setAmount(wallet.getAmount() - amount);
+                wallet.logTransaction("Sent " + amount + " FUC to " + target.path().name());
+            } else if (target.compareTo(self) == 0) {
+                wallet.setAmount(wallet.getAmount() + amount);
+                wallet.logTransaction("Received " + amount + " FUC from " + source.path().name());
+            }
+
+        } else {
+            log("abort transaction with id" + id);
+        }
+        log("wallet.amounts:" + wallet.amounts);
+    }
 
 }
diff --git a/src/fucoin/actions/transaction/ActionGetAmount.java b/src/fucoin/actions/transaction/ActionGetAmount.java
index ad9737b..f14f8ae 100644
--- a/src/fucoin/actions/transaction/ActionGetAmount.java
+++ b/src/fucoin/actions/transaction/ActionGetAmount.java
@@ -9,7 +9,7 @@ public class ActionGetAmount extends Transaction {
 	@Override
 	protected void onAction(ActorRef sender, ActorRef self,
 			UntypedActorContext context, Wallet wallet) {
-		ActionGetAmountAnswer agaa = new ActionGetAmountAnswer(wallet.getAddress(),wallet.getName(),wallet.amount);
+		ActionGetAmountAnswer agaa = new ActionGetAmountAnswer(wallet.getAddress(),wallet.getName(),wallet.getAmount());
 		sender.tell(agaa, self);
 	}
 
diff --git a/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java b/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java
deleted file mode 100644
index 743e0b8..0000000
--- a/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package fucoin.actions.transaction;
-
-import akka.actor.ActorRef;
-import akka.actor.UntypedActorContext;
-import fucoin.Wallet;
-
-public class ActionInvokeSentMoney2 extends Transaction{
-	public final String name;
-	public final int amount;
-    public ActionInvokeSentMoney2(String name, int amount) {
-    	this.name=name;
-        this.amount = amount;
-    }
-	@Override
-	protected void onAction(ActorRef sender, ActorRef self,
-			UntypedActorContext context, Wallet wallet) {
-		if(wallet.getKnownNeighbors().containsKey(name)){
-			wallet.addAmount(-amount);
-			wallet.getKnownNeighbors().get(name).tell(new ActionReceiveTransaction(amount), self);
-		}
-	}
-}
diff --git a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java
index decf2b9..26eb49e 100644
--- a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java
+++ b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java
@@ -4,30 +4,31 @@ import akka.actor.ActorRef;
 import akka.actor.UntypedActorContext;
 import fucoin.Wallet;
 
-public class ActionPrepareDistributedCommitedTransfer extends Transaction{
+public class ActionPrepareDistributedCommitedTransfer extends Transaction {
 
-	private ActorRef source;
-	private ActorRef target;
-	private int amount;
-	private long timestamp;
-	private long id;
+    private ActorRef source;
+    private ActorRef target;
+    private int amount;
+    private long timestamp;
+    private long id;
 
-	public ActionPrepareDistributedCommitedTransfer(ActorRef source,
-			ActorRef target, int amount, long timestamp, long id) {
-		this.source=source;
-		this.target=target;
-		this.amount=amount;
-		this.timestamp=timestamp;
-		this.id=id;
-	}
+    public ActionPrepareDistributedCommitedTransfer(ActorRef source,
+                                                    ActorRef target, int amount, long timestamp, long id) {
+        this.source = source;
+        this.target = target;
+        this.amount = amount;
+        this.timestamp = timestamp;
+        this.id = id;
+    }
 
-	@Override
-	protected void onAction(ActorRef sender, ActorRef self,
-			UntypedActorContext context, Wallet wallet) {
-			boolean granted = sender.compareTo(source)==0	//sender is supervisor(bank) has allways money
-					||(wallet.amounts.containsKey(source) 	//sender is unknown, might be valid
-					&&wallet.amounts.getOrDefault(source,0)>=amount) ; //sender have enough money
-			sender.tell(new ActionPrepareDistributedCommitedTransferAnswer(source, target, amount,timestamp,granted,id),self);
-	}
+    @Override
+    protected void onAction(ActorRef sender, ActorRef self,
+                            UntypedActorContext context, Wallet wallet) {
+        boolean granted = amount > 0 &&
+                (sender.compareTo(source) == 0    //sender is supervisor(bank) has always money
+                || (wallet.amounts.containsKey(source)    //sender is unknown, might be valid
+                && wallet.amounts.getOrDefault(source, 0) >= amount)); //sender have enough money
+        sender.tell(new ActionPrepareDistributedCommitedTransferAnswer(source, target, amount, timestamp, granted, id), self);
+    }
 
 }
diff --git a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java
index e479c38..8a01b2e 100644
--- a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java
+++ b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java
@@ -34,6 +34,7 @@ public class ActionPrepareDistributedCommitedTransferAnswer extends CoordinatorT
 			if(request==null)//unknown DistributedCommitedTransferRequest ignore
 				return;
 			int newCount = request.addPositiveAnswer(sender);
+			System.out.println(newCount+" have agreed on request"+id);
 			if(newCount == superVisor.getKnownNeighbors().size()){
 				ActionCommitDistributedCommitedTransfer acdct = new ActionCommitDistributedCommitedTransfer(source,target,amount,true,timestamp,id);
 				for(ActorRef neighbor : request.getAnswers()){
diff --git a/src/fucoin/actions/transaction/ActionReceiveTransaction.java b/src/fucoin/actions/transaction/ActionReceiveTransaction.java
index 6abdc2a..da9aa55 100644
--- a/src/fucoin/actions/transaction/ActionReceiveTransaction.java
+++ b/src/fucoin/actions/transaction/ActionReceiveTransaction.java
@@ -13,6 +13,6 @@ public class ActionReceiveTransaction extends Transaction {
 	@Override
 	protected void onAction(ActorRef sender, ActorRef self,
 			UntypedActorContext context, Wallet wallet) {
-		wallet.addAmount(wallet.amount);
+		wallet.addAmount(wallet.getAmount());
 	}
 }
diff --git a/src/fucoin/gui/IWalletGuiControle.java b/src/fucoin/gui/IWalletGuiControle.java
index 55d46ac..dcfa621 100644
--- a/src/fucoin/gui/IWalletGuiControle.java
+++ b/src/fucoin/gui/IWalletGuiControle.java
@@ -6,6 +6,7 @@ public interface IWalletGuiControle {
 	public void setAmount(int amount);
 	public void addKnownAddress(String address);
 	public void addLogMsg(String msg);
+	public void addTransactionLogMessage(String message);
 	
 	
 	
diff --git a/src/fucoin/gui/LogMessage.java b/src/fucoin/gui/LogMessage.java
new file mode 100644
index 0000000..c2928d0
--- /dev/null
+++ b/src/fucoin/gui/LogMessage.java
@@ -0,0 +1,26 @@
+package fucoin.gui;
+
+
+public class LogMessage {
+
+    private String message;
+    private boolean transactionRelated;
+
+    public LogMessage(String message, boolean transactionRelated){
+        this.message = message;
+        this.transactionRelated = transactionRelated;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public boolean isTransactionRelated() {
+        return transactionRelated;
+    }
+
+    @Override
+    public String toString(){
+        return getMessage();
+    }
+}
diff --git a/src/fucoin/gui/WalletGui.java b/src/fucoin/gui/WalletGui.java
index 0c09c87..564eaea 100644
--- a/src/fucoin/gui/WalletGui.java
+++ b/src/fucoin/gui/WalletGui.java
@@ -1,163 +1,202 @@
 package fucoin.gui;
 
-import java.awt.BorderLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-
-import javax.swing.DefaultListModel;
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-
-public class WalletGui implements IWalletGuiControle{
-	DefaultListModel<String> log = new DefaultListModel<String>();
-	
-	private JFrame window = new JFrame("test");
-	JPanel topPanel = new JPanel();
-	JLabel lblMyAddress = new JLabel("My Address:");
-	JTextField txtMyAddress = new JTextField("<MyAddress>");
-	JLabel lblEmpty = new JLabel("");
-	JLabel lblMyAmount = new JLabel("My FUCs");
-	JTextField txtMyAmount = new JTextField("<MyFUCs>");
-	JPanel centerPanel = new JPanel();
-	JLabel lblSendTo = new JLabel("Send to:");
-	JComboBox<String> txtSendTo = new JComboBox<String>();
-	JLabel lblSendAmount = new JLabel("Amount:");
-	JTextField txtSendAmount = new JTextField("<Amount>");
-	JButton btnSend = new JButton("Send");
-	JButton btnSearch = new JButton("Search");
-	JButton btnStore = new JButton("Store");
-	JButton btnExit = new JButton("Exit");
-	JPanel bottomPanel = new JPanel();
-	JList<String> txtLog = new JList<String>(log);
-
-public WalletGui(IWalletControle walletControle) {
-
-	
-	window.setSize(400, 600);
-	window.setLayout(new GridLayout(3, 1));
-	topPanel.setLayout(new GridLayout(2, 3));
-	// Row 1
-	topPanel.add(lblMyAddress);
-	topPanel.add(txtMyAddress);
-	topPanel.add(lblEmpty);
-	// Row 2
-	topPanel.add(lblMyAmount);
-	topPanel.add(txtMyAmount);
-	window.add(topPanel);
-	//<hr>
-	centerPanel.setLayout(new GridLayout(4, 1));
-	// Row 1
-	JPanel centerup = new JPanel();
-	centerup.setLayout(new BorderLayout());
-	centerup.add(lblSendTo,BorderLayout.WEST);
-	centerup.add(txtSendTo,BorderLayout.CENTER);
-	centerPanel.add(centerup);
-	
-	JPanel centerup2 = new JPanel();
-	centerup2.setLayout(new BorderLayout());
-	JTextField sendToNewEdt = new JTextField();
-	centerup2.add(sendToNewEdt,BorderLayout.CENTER);
-	JButton addNewButton = new JButton("Add");
-	addNewButton.addActionListener(new ActionListener() {
-		
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			txtSendTo.addItem(sendToNewEdt.getText());
-		}
-	});
-	centerup2.add(addNewButton,BorderLayout.EAST);
-	centerPanel.add(centerup2);
-	
-	// Row 2
-	JPanel centerdown = new JPanel();
-	centerdown.setLayout(new GridLayout(1, 3));
-	centerdown.add(lblSendAmount);
-	centerdown.add(txtSendAmount);
-	centerdown.add(btnSend);
-	centerPanel.add(centerdown);
-	//centerPanel.add(new JLabel(""));
-	// Row 3
-	JPanel centerdown2 = new JPanel();
-	centerdown2.setLayout(new GridLayout(1, 3));
-	centerdown2.add(btnSearch);
-	centerdown2.add(btnStore);
-	centerdown2.add(btnExit);
-	centerPanel.add(centerdown2);
-	window.add(centerPanel);
-	//<hr>
-	bottomPanel.setLayout(new GridLayout(1, 1));
-	bottomPanel.add(txtLog);
-	window.add(bottomPanel);
-	window.setVisible(true);
-	
-	btnSend.addActionListener(new ActionListener() {
-		
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			walletControle.send(txtSendTo.getSelectedItem().toString(), Integer.parseInt(txtSendAmount.getText()));
-		}
-	});
-	
-	btnStore.addActionListener(new ActionListener() {
-		
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			
-		}
-	});
-	
-	btnExit.addActionListener(new ActionListener() {
-		
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			window.dispose();
-		}
-	});
-	
-	window.addWindowListener(new WindowAdapter() {
-		
-		@Override
-		public void windowClosing(WindowEvent e) {
-			System.out.println("window closing");
-			walletControle.leave();
-			super.windowClosing(e);
-			
-		}
-		@Override
-		public void windowClosed(WindowEvent e) {
-			System.out.println("window closing");
-			walletControle.leave();
-			super.windowClosing(e);
-		}
-	});
-}
+import com.sun.tools.javac.comp.Flow;
 
-@Override
-public void setAddress(String address) {
-	txtMyAddress.setText(address);
-	window.setTitle(address);
-}
-@Override
-public void setAmount(int amount) {
-	txtMyAmount.setText(""+amount);
-}
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Enumeration;
 
-@Override
-public void addKnownAddress(String address) {
-	
-	txtSendTo.addItem(address);
-}
-@Override
-public void addLogMsg(String msg) {
-	log.addElement(msg);	
-}
+import javax.swing.*;
+
+public class WalletGui implements IWalletGuiControle {
+
+    private DefaultListModel<LogMessage> log = new DefaultListModel<>();
+
+    private JFrame window = new JFrame("test");
+    private JPanel topPanel = new JPanel();
+    private JLabel lblMyAddress = new JLabel("My Address:");
+    private JTextField txtMyAddress = new JTextField("<MyAddress>");
+    private JLabel lblEmpty = new JLabel("");
+    private JLabel lblMyAmount = new JLabel("My FUCs");
+    private JTextField txtMyAmount = new JTextField("<MyFUCs>");
+    private JPanel centerPanel = new JPanel();
+    private JLabel lblSendTo = new JLabel("Send to:");
+    private JComboBox<String> txtSendTo = new JComboBox<>();
+    private JLabel lblSendAmount = new JLabel("Amount:");
+    private JTextField txtSendAmount = new JTextField("");
+    private JButton btnSend = new JButton("Send");
+    private JButton btnSearch = new JButton("Search");
+    private JButton btnStore = new JButton("Store");
+    private JButton btnExit = new JButton("Exit");
+    private JPanel bottomPanel = new JPanel();
+    private JList<LogMessage> txtLog = new JList<>(log);
+    private JScrollPane logPane = new JScrollPane(txtLog);
+    private JCheckBox showDebug;
+
+    public WalletGui(IWalletControle walletControle) {
+
+        window.setSize(400, 600);
+        window.setLayout(new GridLayout(3, 1));
+        topPanel.setLayout(new GridLayout(2, 3));
+        // Row 1
+        topPanel.add(lblMyAddress);
+        topPanel.add(txtMyAddress);
+        topPanel.add(lblEmpty);
+        // Row 2
+        topPanel.add(lblMyAmount);
+        topPanel.add(txtMyAmount);
+        window.add(topPanel);
+        //<hr>
+        centerPanel.setLayout(new GridLayout(4, 1));
+        // Row 1
+        JPanel centerup = new JPanel();
+        centerup.setLayout(new BorderLayout());
+        centerup.add(lblSendTo, BorderLayout.WEST);
+        centerup.add(txtSendTo, BorderLayout.CENTER);
+        centerPanel.add(centerup);
+
+        JPanel centerup2 = new JPanel();
+        centerup2.setLayout(new BorderLayout());
+        JTextField sendToNewEdt = new JTextField();
+        centerup2.add(sendToNewEdt, BorderLayout.CENTER);
+        JButton addNewButton = new JButton("Add");
+        addNewButton.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                txtSendTo.addItem(sendToNewEdt.getText());
+            }
+        });
+        centerup2.add(addNewButton, BorderLayout.EAST);
+        centerPanel.add(centerup2);
+
+        // Row 2
+        JPanel centerdown = new JPanel();
+        centerdown.setLayout(new GridLayout(1, 3));
+        centerdown.add(lblSendAmount);
+        centerdown.add(txtSendAmount);
+        centerdown.add(btnSend);
+        centerPanel.add(centerdown);
+        //centerPanel.add(new JLabel(""));
+        // Row 3
+        JPanel centerdown2 = new JPanel();
+        centerdown2.setLayout(new GridLayout(1, 3));
+        centerdown2.add(btnSearch);
+        centerdown2.add(btnStore);
+        centerdown2.add(btnExit);
+        centerPanel.add(centerdown2);
+        window.add(centerPanel);
+        //<hr>
+        bottomPanel.setLayout(new BorderLayout());
+
+        showDebug = new JCheckBox("Show debug messages in transaction log");
+        showDebug.addItemListener(e -> {
+            if (e.getStateChange() == ItemEvent.SELECTED) {
+                txtLog.setModel(log);
+            } else {
+                updateFilteredLog();
+            }
+        });
+
+        bottomPanel.add(showDebug, BorderLayout.NORTH);
+        bottomPanel.add(logPane, BorderLayout.CENTER);
+
+        window.add(bottomPanel);
+        window.setVisible(true);
+
+        btnSend.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                walletControle.send(txtSendTo.getSelectedItem().toString(), Integer.parseInt(txtSendAmount.getText()));
+            }
+        });
+
+        btnStore.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+
+            }
+        });
+
+        btnExit.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                window.dispose();
+            }
+        });
+
+        window.addWindowListener(new WindowAdapter() {
+
+            @Override
+            public void windowClosing(WindowEvent e) {
+                System.out.println("window closing");
+                walletControle.leave();
+                super.windowClosing(e);
+
+            }
+
+            @Override
+            public void windowClosed(WindowEvent e) {
+                System.out.println("window closing");
+                walletControle.leave();
+                super.windowClosing(e);
+            }
+        });
+    }
+
+    @Override
+    public void setAddress(String address) {
+        txtMyAddress.setText(address);
+        window.setTitle(address);
+    }
+
+    @Override
+    public void setAmount(int amount) {
+        txtMyAmount.setText(String.valueOf(amount));
+    }
+
+    @Override
+    public void addKnownAddress(String address) {
+        txtSendTo.addItem(address);
+    }
+
+    @Override
+    public void addLogMsg(String msg) {
+        log(new LogMessage(msg, false));
+    }
+
+    @Override
+    public void addTransactionLogMessage(String message) {
+        log(new LogMessage(message, true));
+    }
+
+    private void log(LogMessage logMessage) {
+        SwingUtilities.invokeLater(() -> {
+            log.addElement(logMessage);
+
+            if (!showDebug.isSelected()) {
+                updateFilteredLog();
+            }
+
+            // auto scroll to the bottom
+            txtLog.ensureIndexIsVisible(log.size() - 1);
+        });
+    }
+
+    private void updateFilteredLog() {
+
+        DefaultListModel<LogMessage> filteredLog = new DefaultListModel<>();
+        Enumeration<LogMessage> elements = log.elements();
+        while (elements.hasMoreElements()) {
+            LogMessage logMessage = elements.nextElement();
+            if (logMessage.isTransactionRelated()) {
+                filteredLog.addElement(logMessage);
+            }
+        }
+
+        txtLog.setModel(filteredLog);
+    }
 }
diff --git a/src/fucoin/supervisor/AmountTableModel.java b/src/fucoin/supervisor/AmountTableModel.java
index fb91ce4..a8a6a8a 100644
--- a/src/fucoin/supervisor/AmountTableModel.java
+++ b/src/fucoin/supervisor/AmountTableModel.java
@@ -1,15 +1,33 @@
 package fucoin.supervisor;
 
 import javax.swing.table.DefaultTableModel;
+import java.util.Vector;
 
-public class AmountTableModel extends DefaultTableModel{
-public AmountTableModel() {
-	super(new Object[]{"Address","Name","Amount"},0);
-}
+public class AmountTableModel extends DefaultTableModel {
 
-public void clear() {
-	while(getRowCount()>0){
-		removeRow(0);
-	}
-}
+    public AmountTableModel() {
+        super(new Object[]{"Address", "Name", "Amount"}, 0);
+    }
+
+    public void clear() {
+        while (getRowCount() > 0) {
+            removeRow(0);
+        }
+    }
+
+    public void updateTable(String address, String name, int amount) {
+
+        Vector<Object> rows = this.getDataVector();
+        for (int i = 0; i < rows.size(); i++) {
+           if (rows.get(i) instanceof Vector){
+               Vector<Object> row = (Vector<Object>) rows.get(i);
+               if(row.get(0).equals(address)){
+                   setValueAt(amount, i, 2);
+                   return;
+               }
+           }
+        }
+
+        this.addRow(new Object[]{address, name, amount});
+    }
 }
diff --git a/src/fucoin/supervisor/SuperVisor.java b/src/fucoin/supervisor/SuperVisor.java
index a6adcaa..807af32 100644
--- a/src/fucoin/supervisor/SuperVisor.java
+++ b/src/fucoin/supervisor/SuperVisor.java
@@ -14,83 +14,95 @@ import akka.actor.ActorRef;
 import akka.actor.Props;
 import fucoin.AbstractNode;
 import fucoin.actions.Action;
+import fucoin.actions.ClientAction;
 import fucoin.actions.persist.ActionInvokeUpdate;
+import fucoin.actions.transaction.ActionGetAmountAnswer;
+import fucoin.actions.transaction.SuperVisorAction;
 
 public class SuperVisor extends AbstractNode {
 
-	
-	private AmountTableModel amountTableModel;
-	private Label averageamountLbl;
-
-	public SuperVisor(AmountTableModel amountTableModel, Label averageamountLbl) {
-		this.amountTableModel = amountTableModel;
-		this.averageamountLbl = averageamountLbl;
-	}
-
-	@Override
-	public void onReceive(Object msg) {
-		log(msg.getClass().getSimpleName());
-		
-		((Action) msg).doAction(this);
-	}
-
-	Semaphore mutex = new Semaphore(1);
-	private Map<Long,DistributedCommitedTransferRequest> requestQueue;
-
-	public static Props props() {
-		return Props.create(SuperVisor.class, new SuperVisorCreator());
-	}
-
-	public void updateValues() {
-		getSelf().tell(new ActionInvokeUpdate(), getSelf());
-	}
-
-	public void exit() {
-		getContext().stop(getSelf());
-	}
-
-	@Override
-	public void postStop() throws Exception {
-		super.postStop();
-	}
-
-	public void addDistributedCommitedTransferRequest(
-			DistributedCommitedTransferRequest request) {
-		requestQueue.put(request.getId(),request);
-	}
-
-	@Override
-	public void preStart() throws Exception {
-		super.preStart();
-		requestQueue = new HashMap<Long,DistributedCommitedTransferRequest>();
-		self().tell(new ActionUpdateQueue(), self());
-	}
-	/**
-	 * filters the request for outdated and removes them
-	 * @return deleted outdated request
-	 */
-	public List<DistributedCommitedTransferRequest> updateList(){
-		List<Long> deletesIds = new ArrayList<Long>();
-		List<DistributedCommitedTransferRequest> deletes = new ArrayList<DistributedCommitedTransferRequest>();
-		for(Entry<Long, DistributedCommitedTransferRequest> outdatedRequest : requestQueue.entrySet()){
-			if(outdatedRequest.getValue().getTimeout()<System.currentTimeMillis()){
-				deletesIds.add(outdatedRequest.getKey());
-				deletes.add(outdatedRequest.getValue());
-			}
-		}
-		for(Long delete : deletesIds){
-			requestQueue.remove(delete);
-		}
-		
-		return deletes;
-	}
-	
-	public DistributedCommitedTransferRequest getRequest(Long id) {
-		DistributedCommitedTransferRequest searchedrequest = requestQueue.get(id);
-		return searchedrequest ;
-	}
-
-	public void deleteRequest(DistributedCommitedTransferRequest request) {
-		requestQueue.remove(request.getId());
-	}
+
+    private AmountTableModel amountTableModel;
+    private Label averageamountLbl;
+
+    public SuperVisor(AmountTableModel amountTableModel, Label averageamountLbl) {
+        this.amountTableModel = amountTableModel;
+        this.averageamountLbl = averageamountLbl;
+    }
+
+    @Override
+    public void onReceive(Object msg) {
+
+        // dirty but necessary since ActionGetAmountAnswer is a
+        // ClientAction for some reason
+        if (msg instanceof ActionGetAmountAnswer) {
+            ActionGetAmountAnswer answer = (ActionGetAmountAnswer) msg;
+            amountTableModel.updateTable(answer.address, answer.name, answer.amount);
+        } else if (msg instanceof SuperVisorAction) {
+            ((Action) msg).doAction(this);
+        }
+    }
+
+    Semaphore mutex = new Semaphore(1);
+    private Map<Long, DistributedCommitedTransferRequest> requestQueue;
+
+    public static Props props() {
+        return Props.create(SuperVisor.class, new SuperVisorCreator());
+    }
+
+    public void updateValues() {
+        getSelf().tell(new ActionInvokeUpdate(), getSelf());
+    }
+
+    public void exit() {
+        getContext().stop(getSelf());
+    }
+
+    @Override
+    public void postStop() throws Exception {
+        super.postStop();
+    }
+
+    public void addDistributedCommitedTransferRequest(
+            DistributedCommitedTransferRequest request) {
+        System.out.println("Füge Request in queue ein: " + request.getId());
+        requestQueue.put(request.getId(), request);
+    }
+
+    @Override
+    public void preStart() throws Exception {
+        super.preStart();
+        requestQueue = new HashMap<>();
+        self().tell(new ActionUpdateQueue(), self());
+    }
+
+    /**
+     * filters the request for outdated and removes them
+     *
+     * @return deleted outdated request
+     */
+    public List<DistributedCommitedTransferRequest> updateList() {
+        List<Long> deletesIds = new ArrayList<Long>();
+        List<DistributedCommitedTransferRequest> deletes = new ArrayList<DistributedCommitedTransferRequest>();
+        for (Entry<Long, DistributedCommitedTransferRequest> outdatedRequest : requestQueue.entrySet()) {
+            if (outdatedRequest.getValue().getTimeout() < System.currentTimeMillis()) {
+                deletesIds.add(outdatedRequest.getKey());
+                deletes.add(outdatedRequest.getValue());
+            }
+        }
+        for (Long delete : deletesIds) {
+            requestQueue.remove(delete);
+        }
+
+        return deletes;
+    }
+
+    public DistributedCommitedTransferRequest getRequest(Long id) {
+        DistributedCommitedTransferRequest searchedrequest = requestQueue.get(id);
+        return searchedrequest;
+    }
+
+    public void deleteRequest(DistributedCommitedTransferRequest request) {
+        requestQueue.remove(request.getId());
+    }
 }
-- 
GitLab