From 89c2be1f66a92550ef7cd45bf522df6c7cd87273 Mon Sep 17 00:00:00 2001
From: David Bohn <davbohn@googlemail.com>
Date: Wed, 22 Jun 2016 11:16:02 +0200
Subject: [PATCH] Fixed GUI lock explained in #17

---
 ...ionCommitDistributedCommittedTransfer.java |   2 +-
 ...areDistributedCommittedTransferAnswer.java |   2 +-
 .../java/fucoin/gui/FilteredLogModel.java     |   7 ++
 .../java/fucoin/gui/SuperVisorGuiControl.java |   2 +
 .../fucoin/gui/SuperVisorGuiControlImpl.java  | 106 +++++++---------
 .../java/fucoin/gui/SuperVisorThreadGUI.java  | 113 ++++++++++++++++++
 .../fucoin/supervisor/AmountTableModel.java   |   1 +
 .../fucoin/supervisor/SuperVisorImpl.java     |  23 +---
 8 files changed, 175 insertions(+), 81 deletions(-)
 create mode 100644 src/main/java/fucoin/gui/SuperVisorThreadGUI.java

diff --git a/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java b/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
index 6cddc6d..6c4b480 100644
--- a/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
+++ b/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
@@ -63,7 +63,7 @@ public class ActionCommitDistributedCommittedTransfer extends ClientAction {
             }
 
         }
-        wallet.addLogMsg("wallet.amounts:" + wallet.amounts);
+        //wallet.addLogMsg("wallet.amounts:" + wallet.amounts);
     }
 
 }
diff --git a/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransferAnswer.java b/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransferAnswer.java
index 658b149..01e90b3 100644
--- a/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransferAnswer.java
+++ b/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransferAnswer.java
@@ -27,7 +27,7 @@ public class ActionPrepareDistributedCommittedTransferAnswer extends Coordinator
     @Override
     protected void onAction(ActorRef sender, ActorRef self,
                             UntypedActorContext context, SuperVisorImpl superVisor) {
-        superVisor.addLogMsg("" + superVisor.getKnownNeighbors());
+        //superVisor.addLogMsg("" + superVisor.getKnownNeighbors());
         superVisor.addLogMsg("granted?" + granted);
         DistributedCommittedTransferRequest request = superVisor.getRequest(id);
         if (granted) {
diff --git a/src/main/java/fucoin/gui/FilteredLogModel.java b/src/main/java/fucoin/gui/FilteredLogModel.java
index 225e008..97ae91c 100644
--- a/src/main/java/fucoin/gui/FilteredLogModel.java
+++ b/src/main/java/fucoin/gui/FilteredLogModel.java
@@ -2,6 +2,7 @@ package fucoin.gui;
 
 import javax.swing.*;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 
@@ -66,4 +67,10 @@ public class FilteredLogModel extends AbstractListModel<LogMessage> {
             fireIntervalAdded(this, index, index);
         }
     }
+
+    public void emptyLog() {
+        log.removeAll(log);
+        filteredLog.removeAll(filteredLog);
+        refilter();
+    }
 }
diff --git a/src/main/java/fucoin/gui/SuperVisorGuiControl.java b/src/main/java/fucoin/gui/SuperVisorGuiControl.java
index 1d6919d..b8b29e5 100644
--- a/src/main/java/fucoin/gui/SuperVisorGuiControl.java
+++ b/src/main/java/fucoin/gui/SuperVisorGuiControl.java
@@ -7,4 +7,6 @@ public interface SuperVisorGuiControl extends TransactionLogger {
      */
     void onLeave();
 
+    public void updateTable(String address, String name, int amount);
+
 }
diff --git a/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java b/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java
index 43ccec3..b0c9a12 100644
--- a/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java
+++ b/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java
@@ -1,5 +1,6 @@
 package fucoin.gui;
 
+import fucoin.supervisor.AmountTableModel;
 import fucoin.supervisor.SuperVisorImpl;
 
 import javax.swing.*;
@@ -12,12 +13,12 @@ import java.awt.event.WindowEvent;
 
 public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
     private SuperVisorImpl superVisor;
-    private JFrame frame;
 
-    private FilteredLogModel log = new FilteredLogModel();
-    private JList<LogMessage> txtLog = new JList<>(log);
-    private JScrollPane logPane = new JScrollPane(txtLog);
-    private JCheckBox showDebug;
+    private AmountTableModel amountTableModel;
+
+    private SuperVisorThreadGUI threadGUI;
+
+    private boolean logActive = false;
 
     public SuperVisorGuiControlImpl(SuperVisorImpl sv) {
         superVisor = sv;
@@ -25,69 +26,32 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
     }
 
     private void init() {
-        //Show AWT window for runtime information
-        frame = new JFrame("Server");
-        JPanel contentPanel = new JPanel();
-        contentPanel.setLayout(new GridLayout(2, 1));
-
-        //Init Amount Table and SuperVisorImpl
-
-        JTable amountListView = new JTable(superVisor.getAmountTableModel());
-        superVisor.getAmountTableModel().addTableModelListener(e -> SwingUtilities.invokeLater(() -> frame.setTitle("Server (" + superVisor.getAmountTableModel().getRowCount() + " Wallets)")));
-        contentPanel.add(new JScrollPane(amountListView));
-
-        JPanel logPanel = new JPanel(new BorderLayout());
-
-        txtLog.setCellRenderer(new LogCellRenderer());
-
-        showDebug = new JCheckBox("Show debug messages in transaction log");
-        showDebug.setSelected(true);
-        showDebug.addItemListener(e -> {
-            if (e.getStateChange() == ItemEvent.SELECTED) {
-                log.clearFilter();
-            } else {
-                log.setTransactionFilter();
-            }
-        });
-
-        logPanel.add(showDebug, BorderLayout.NORTH);
-        logPanel.add(logPane, BorderLayout.CENTER);
-        contentPanel.add(logPanel);
-
-        frame.add(contentPanel, BorderLayout.CENTER);
-
-        //Exit Button and shutdown supervisor
-        JButton exitBtn = new JButton("Stop Supervisor");
-        exitBtn.addActionListener(e -> {
-            superVisor.exit();
-            frame.setVisible(false);
-            frame.dispose();
-        });
-        frame.add(exitBtn, BorderLayout.PAGE_END);
-        frame.setSize(800, 600);
-        frame.setVisible(true);
-
-        frame.addWindowListener(new WindowAdapter() {
-            @Override
-            public void windowClosing(WindowEvent e) {
-                super.windowClosing(e);
-                superVisor.exit();
-            }
-        });
+
+        amountTableModel = new AmountTableModel();
+
+        threadGUI = new SuperVisorThreadGUI(this);
+        threadGUI.init();
+
+    }
+
+    public void guiTerminated() {
+        superVisor.exit();
     }
 
     @Override
     public void onLeave() {
-        frame.dispose();
+        threadGUI.dispose();
     }
 
-    private void log(LogMessage logMessage) {
-        SwingUtilities.invokeLater(() -> {
-            log.addElement(logMessage);
+    @Override
+    public void updateTable(String address, String name, int amount) {
+        this.amountTableModel.updateTable(address, name, amount);
+    }
 
-            // auto scroll to the bottom
-            txtLog.ensureIndexIsVisible(log.getSize() - 1);
-        });
+    private void log(LogMessage logMessage) {
+        if (logActive) {
+            threadGUI.log(logMessage);
+        }
     }
 
     @Override
@@ -104,4 +68,24 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
     public void addTransactionLogMessageFail(String message) {
         log(new LogMessage(message, LogMessage.Context.TRANSACTION_FAIL));
     }
+
+    public AmountTableModel getAmountTableModel() {
+        return amountTableModel;
+    }
+
+    public void setAmountTableModel(AmountTableModel amountTableModel) {
+        this.amountTableModel = amountTableModel;
+    }
+
+    public void activateLogging() {
+        this.logActive = true;
+    }
+
+    public void disableLogging() {
+        this.logActive = false;
+    }
+
+    public boolean isLogActive() {
+        return logActive;
+    }
 }
diff --git a/src/main/java/fucoin/gui/SuperVisorThreadGUI.java b/src/main/java/fucoin/gui/SuperVisorThreadGUI.java
new file mode 100644
index 0000000..d5d7a1b
--- /dev/null
+++ b/src/main/java/fucoin/gui/SuperVisorThreadGUI.java
@@ -0,0 +1,113 @@
+package fucoin.gui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+/**
+ *
+ */
+public class SuperVisorThreadGUI {
+    private JFrame frame;
+
+    private FilteredLogModel log = new FilteredLogModel();
+    private JList<LogMessage> txtLog = new JList<>(log);
+    private JScrollPane logPane = new JScrollPane(txtLog);
+    private JCheckBox showDebug;
+    private JCheckBox activateLogging;
+    private SuperVisorGuiControlImpl superVisorGuiControl;
+
+    public SuperVisorThreadGUI(SuperVisorGuiControlImpl superVisorGuiControl) {
+
+        this.superVisorGuiControl = superVisorGuiControl;
+    }
+
+    public void init() {
+        new Thread(() -> {
+            //Show AWT window for runtime information
+            frame = new JFrame("Server");
+            JPanel contentPanel = new JPanel();
+            contentPanel.setLayout(new GridLayout(2, 1));
+
+            JTable amountListView = new JTable(superVisorGuiControl.getAmountTableModel());
+            superVisorGuiControl.getAmountTableModel().addTableModelListener(e -> SwingUtilities.invokeLater(() -> frame.setTitle("Server (" + superVisorGuiControl.getAmountTableModel().getRowCount() + " Wallets)")));
+            contentPanel.add(new JScrollPane(amountListView));
+
+            JPanel logPanel = new JPanel(new BorderLayout());
+
+            txtLog.setCellRenderer(new LogCellRenderer());
+
+            showDebug = new JCheckBox("Show debug messages in transaction log");
+            showDebug.setSelected(true);
+            showDebug.addItemListener(e -> {
+                if (e.getStateChange() == ItemEvent.SELECTED) {
+                    log.clearFilter();
+                } else {
+                    log.setTransactionFilter();
+                }
+            });
+
+            activateLogging = new JCheckBox("Activate logging");
+            activateLogging.setSelected(superVisorGuiControl.isLogActive());
+            activateLogging.addItemListener(e -> {
+                if (e.getStateChange() == ItemEvent.SELECTED) {
+                    superVisorGuiControl.activateLogging();
+                    log.emptyLog();
+                } else {
+                    superVisorGuiControl.disableLogging();
+                }
+            });
+
+            JPanel configPanel = new JPanel();
+
+            configPanel.add(activateLogging);
+            configPanel.add(showDebug);
+
+            //logPanel.add(activateLogging, BorderLayout.NORTH);
+            logPanel.add(configPanel, BorderLayout.NORTH);
+            logPanel.add(logPane, BorderLayout.CENTER);
+            contentPanel.add(logPanel);
+
+            frame.add(contentPanel, BorderLayout.CENTER);
+
+            //Exit Button and shutdown supervisor
+            JButton exitBtn = new JButton("Stop Supervisor");
+            exitBtn.addActionListener(e -> {
+                superVisorGuiControl.guiTerminated();
+                frame.setVisible(false);
+                frame.dispose();
+            });
+
+            if (!superVisorGuiControl.isLogActive()) {
+                this.log(new LogMessage("Logging is currently disabled."));
+            }
+
+            frame.add(exitBtn, BorderLayout.PAGE_END);
+            frame.setSize(800, 600);
+            frame.setVisible(true);
+
+            frame.addWindowListener(new WindowAdapter() {
+                @Override
+                public void windowClosing(WindowEvent e) {
+                    super.windowClosing(e);
+                    superVisorGuiControl.guiTerminated();
+                }
+            });
+        }).start();
+    }
+
+    public void dispose() {
+        frame.dispose();
+    }
+
+    public void log(LogMessage logMessage) {
+        SwingUtilities.invokeLater(() -> {
+            log.addElement(logMessage);
+
+            // auto scroll to the bottom
+            txtLog.ensureIndexIsVisible(log.getSize() - 1);
+        });
+    }
+}
diff --git a/src/main/java/fucoin/supervisor/AmountTableModel.java b/src/main/java/fucoin/supervisor/AmountTableModel.java
index b25a22f..80378e9 100644
--- a/src/main/java/fucoin/supervisor/AmountTableModel.java
+++ b/src/main/java/fucoin/supervisor/AmountTableModel.java
@@ -1,5 +1,6 @@
 package fucoin.supervisor;
 
+import javax.swing.*;
 import javax.swing.table.DefaultTableModel;
 import java.util.Vector;
 
diff --git a/src/main/java/fucoin/supervisor/SuperVisorImpl.java b/src/main/java/fucoin/supervisor/SuperVisorImpl.java
index dfff7f1..ee0d68c 100644
--- a/src/main/java/fucoin/supervisor/SuperVisorImpl.java
+++ b/src/main/java/fucoin/supervisor/SuperVisorImpl.java
@@ -9,34 +9,29 @@ import fucoin.gui.SuperVisorGuiControl;
 import fucoin.AbstractNode;
 import fucoin.gui.TransactionLogger;
 
+import javax.swing.*;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import static akka.dispatch.Futures.future;
+public class SuperVisorImpl extends AbstractNode implements TransactionLogger {
 
-public class SuperVisorImpl extends AbstractNode implements TransactionLogger{
-
-    private AmountTableModel amountTableModel;
+    //private AmountTableModel amountTableModel;
 
     private Map<Long, DistributedCommittedTransferRequest> requestQueue;
 
     private SuperVisorGuiControl gui;
 
     public SuperVisorImpl() {
-        this.amountTableModel = new AmountTableModel();
+
     }
 
     public void setGuiControl(SuperVisorGuiControl gui) {
         this.gui = gui;
     }
 
-    public SuperVisorImpl(AmountTableModel amountTableModel) {
-        this.amountTableModel = amountTableModel;
-    }
-
     @Override
     public void onReceive(Object msg) {
 
@@ -44,7 +39,7 @@ public class SuperVisorImpl extends AbstractNode implements TransactionLogger{
         // ClientAction for some reason
         if (msg instanceof ActionGetAmountAnswer) {
             ActionGetAmountAnswer answer = (ActionGetAmountAnswer) msg;
-            amountTableModel.updateTable(answer.address, answer.name, answer.amount);
+            SwingUtilities.invokeLater(() -> gui.updateTable(answer.address, answer.name, answer.amount));
         } /* TODO: Whats happened here?? Why we can invoke doAction of abstract class? */ else if (msg instanceof SuperVisorAction) {
             ((Action) msg).doAction(this);
         }
@@ -111,14 +106,6 @@ public class SuperVisorImpl extends AbstractNode implements TransactionLogger{
         requestQueue.remove(request.getId());
     }
 
-    public AmountTableModel getAmountTableModel() {
-        return amountTableModel;
-    }
-
-    public void setAmountTableModel(AmountTableModel amountTableModel) {
-        this.amountTableModel = amountTableModel;
-    }
-
     @Override
     public void addLogMsg(String message) {
         if (gui != null) {
-- 
GitLab