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