From fe40935e93b78c4a760f2a901e1c9c165ada33a8 Mon Sep 17 00:00:00 2001
From: Philipp Spohr <spohr.philipp@web.de>
Date: Sat, 19 Aug 2017 12:46:01 +0200
Subject: [PATCH] Rough but working presentation of solutions

---
 .../ba/yoshikoWrapper/core/AlgorithmTask.java | 17 ++--
 .../de/hhu/ba/yoshikoWrapper/core/CyCore.java |  3 +
 .../ba/yoshikoWrapper/gui/ClusterView.java    | 94 ++++++++++++++++---
 .../hhu/ba/yoshikoWrapper/gui/MainPanel.java  | 91 ++++++++++--------
 .../gui/ReductionRulesChooser.java            |  6 +-
 .../ba/yoshikoWrapper/gui/SolutionTab.java    | 31 ++++--
 .../ba/yoshikoWrapper/gui/SolutionsPanel.java |  2 +
 src/main/resources/YoshikoStrings.properties  |  7 +-
 .../resources/YoshikoStrings_de_DE.properties |  3 +-
 9 files changed, 182 insertions(+), 72 deletions(-)

diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java
index 44e785f..c0c423f 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java
@@ -15,7 +15,6 @@ import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger;
 import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface;
 import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_std__vectorT_int_t;
 import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_yskInput__LibraryInput;
-import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_ysk__ClusterEditingSolutions;
 
 public class AlgorithmTask extends AbstractTask {
 	
@@ -101,7 +100,7 @@ public class AlgorithmTask extends AbstractTask {
 		LibraryInterface.LibraryInput_setDefaultInsertionCost(input, insertionCostDefault);
 
 		//Call Yoshiko <<< Algorithm is performed here
-		SWIGTYPE_p_ysk__ClusterEditingSolutions solutions = LibraryInterface.processLibraryInput(
+		CyCore.currentSolutions = LibraryInterface.processLibraryInput(
 				input,
 				1,
 				bitMaskRules,
@@ -115,11 +114,11 @@ public class AlgorithmTask extends AbstractTask {
 		this.solutionsPanel.reset();
 
 		
-		long numberOfSolutions = LibraryInterface.ClusterEditingSolutions_getNumberOfSolutions(solutions);
+		long numberOfSolutions = LibraryInterface.ClusterEditingSolutions_getNumberOfSolutions(CyCore.currentSolutions);
 		taskMonitor.setStatusMessage("Found: "+numberOfSolutions+" solutions!");
 		
-		double modificationCost = LibraryInterface.ClusterEditingSolutions_getTotalCost(solutions);
-		taskMonitor.setStatusMessage("Paid a total modification cost of: "+modificationCost);
+		double modificationCost = LibraryInterface.ClusterEditingSolutions_getTotalCost(CyCore.currentSolutions);
+		taskMonitor.setStatusMessage(LocalizationManager.get("paidCost")+modificationCost);
 		
 		for (long i=0;i<numberOfSolutions;i++) {
 			
@@ -131,13 +130,14 @@ public class AlgorithmTask extends AbstractTask {
 			net.getDefaultNodeTable().deleteColumn(columnName);
 			net.getDefaultNodeTable().createColumn(columnName, String.class, false);
 			
-			long numberOfClusters = LibraryInterface.ClusterEditingSolutions_getNumberOfClusters(solutions, i);
+			long numberOfClusters = LibraryInterface.ClusterEditingSolutions_getNumberOfClusters(CyCore.currentSolutions, i);
+			tab.setClusterNumber(numberOfClusters);
 			
 			for (long k=0;k<numberOfClusters;k++) {
 				ClusterView cV = tab.addCluster(k);
 				cV.setTitle((k+1));
 				taskMonitor.setStatusMessage("Processing cluster "+(k+1)+" of "+numberOfClusters);
-				SWIGTYPE_p_std__vectorT_int_t cluster = LibraryInterface.ClusterEditingSolutions_getCluster(solutions, i, k);
+				SWIGTYPE_p_std__vectorT_int_t cluster = LibraryInterface.ClusterEditingSolutions_getCluster(CyCore.currentSolutions, i, k);
 				long sizeOfCluster = LibraryInterface.IntVector_size(cluster);
 				cV.setClusterSize(sizeOfCluster);
 				for (int l=0;l<sizeOfCluster;l++) { //Unsafe mismatch int long
@@ -154,9 +154,6 @@ public class AlgorithmTask extends AbstractTask {
 			}
 		}
 
-		solutionsPanel.revalidate();
-		solutionsPanel.repaint();
-		
 		LibraryInterface.delete_LibraryInput(input);		
 		taskMonitor.setProgress(1.0);
 	}
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java
index 33df2b9..d12307a 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java
@@ -3,8 +3,11 @@ package de.hhu.ba.yoshikoWrapper.core;
 import org.cytoscape.application.CyApplicationManager;
 import org.cytoscape.work.swing.DialogTaskManager;
 
+import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_ysk__ClusterEditingSolutions;
+
 public class CyCore {
 	public static CyApplicationManager cy;
 	public static DialogTaskManager dialogTaskManager;
 	public static ConfigurationManager cm;
+	public static SWIGTYPE_p_ysk__ClusterEditingSolutions currentSolutions;
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ClusterView.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ClusterView.java
index 9586f3e..fc3ffa0 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ClusterView.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ClusterView.java
@@ -1,11 +1,21 @@
 package de.hhu.ba.yoshikoWrapper.gui;
 
+import java.awt.Color;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
 import javax.swing.BoxLayout;
 import javax.swing.JLabel;
-import javax.swing.JList;
+import javax.swing.border.Border;
 
 import org.cytoscape.model.CyNode;
+import org.cytoscape.model.CyRow;
 
+import de.hhu.ba.yoshikoWrapper.core.CyCore;
 import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
 
 @SuppressWarnings("serial")
@@ -14,33 +24,87 @@ public class ClusterView extends ComfortPanel {
 	private final JLabel title;
 	private final JLabel clusterSize;
 	
-	private JList<String> nodeList;
+	
+	private final Border regularBorder = BorderFactory.createLineBorder(Color.GRAY);
+	private final Border highlightBorder = BorderFactory.createLineBorder(Color.RED);
+	
+	//SYMBOLIC LINKS
+	
+	/**Simple array list containing references to the nodes that are represented by this cluster view
+	 * 
+	 */
+	private ArrayList<CyNode> nodes;
 	
 	public ClusterView() {
+		//Swing init
 		this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
 		
-		this.title = new JLabel("CLUSTERTITLE");
-		this.clusterSize = new JLabel("CLUSTERLABEL");
-		this.nodeList = new JList<String>();
+		title = new JLabel("CLUSTERTITLE");
+		clusterSize = new JLabel("CLUSTERLABEL");
+		
+		this.addAll(title,clusterSize);
+		this.add(Box.createVerticalStrut(4));
 		
-		this.addAll(title,clusterSize,nodeList);
+		this.addMouseListener(mouseListener);
+		
+		this.setBorder(regularBorder);
+		//Other init
+		nodes = new ArrayList<CyNode>();
+	}
+	
+	public void addNode(CyNode node) {
+		this.add(
+			new JLabel(
+				CyCore.cy.getCurrentNetwork().getRow(node).get("name", String.class)
+			)
+		);
+		//Add symbolic link
+		nodes.add(node);
 	}
 	
 	public void setTitle(long x) {
 		this.title.setText(LocalizationManager.get("cluster")+" "+x);
-		revalidate();
-		repaint();
 	}
 
 	public void setClusterSize(long x) {
 		this.clusterSize.setText(LocalizationManager.get("clusterSize")+" "+x);
-		revalidate();
-		repaint();
 	}
 
-	public void addNode(CyNode node) {
-		this.nodeList.add(new JLabel(node.toString()));
-		revalidate();
-		repaint();
-	}
+
+	
+	private MouseListener mouseListener = new MouseListener() {
+
+		@Override
+		public void mouseClicked(MouseEvent e) {}
+
+		@Override
+		public void mousePressed(MouseEvent e) {
+			//Undo previous selection
+			
+			List<CyRow> allRows = CyCore.cy.getCurrentNetwork().getDefaultNodeTable().getAllRows();
+			for (CyRow r: allRows) {
+				r.set("selected", false);
+			}
+			
+			//Select nodes corresponding to the cluster
+			for (CyNode n : nodes) {
+				CyCore.cy.getCurrentNetwork().getRow(n).set("selected", true);
+			}
+		}
+		
+		@Override
+		public void mouseReleased(MouseEvent e) {}
+
+		@Override
+		public void mouseEntered(MouseEvent e) {
+			setBorder(highlightBorder);
+		}
+
+		@Override
+		public void mouseExited(MouseEvent e) {
+			setBorder(regularBorder);
+		}
+
+
+	};
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java
index b77de0d..d4c28ab 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java
@@ -21,6 +21,7 @@ import de.hhu.ba.yoshikoWrapper.core.AlgorithmTask;
 import de.hhu.ba.yoshikoWrapper.core.CyCore;
 import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
 import de.hhu.ba.yoshikoWrapper.core.YoshikoLoader;
+import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface;
 
 /**This class describes the Swing Panel that the user interacts with in cytoscape
  * @author Philipp Spohr, Aug 6, 2017
@@ -85,43 +86,8 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 		
 
 		JButton runButton = new JButton("RUN");
-		runButton.addActionListener(new ActionListener() {
-
-			
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				if (YoshikoLoader.isLibraryLoaded()){
-					AbstractTask yoshiko = new AlgorithmTask(
-						CyCore.cy.getCurrentNetwork(),
-						timeLimitSetter.getTimeLimit(), 
-						ecPanel.getWeightColumn(),
-						ecPanel.getPermanentColumn(),
-						ecPanel.getForbiddenColumn(),
-						ecPanel.getDefaultInsertionCost(),
-						ecPanel.getDefaultDeletionCost(),
-						reductionRulesChooser.getBitMask(),
-						reductionRulesChooser.getMultFactor(),
-						useTriangleCutsBox.isSelected(),
-						usePartitionCutsBox.isSelected(), 
-						useHeuristic.isSelected(), 
-						solutionsPanel
-					);
-					CyCore.dialogTaskManager.execute(new TaskIterator(1,yoshiko));
-					solutionsPanel.setVisible(true);
-				}
-				else {
-					JOptionPane.showMessageDialog(
-							null,
-							LocalizationManager.get("noLibTitle"),
-							LocalizationManager.get("noLibMessage"),
-							JOptionPane.ERROR_MESSAGE
-							);
-				}
-			}
-			
-		});
+		runButton.addActionListener(buttonListener);
 
-		
 		this.addAll(
 				langSwitcher,
 				libraryPanel,
@@ -138,6 +104,58 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 		this.setVisible(true);
 	}
 
+	/**
+	 * ButtonListener for the "Run" Button
+	 * Handles calling the algorithm and fetching/passing the arguments from swing components
+	 */
+	private ActionListener buttonListener = new ActionListener() {
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (YoshikoLoader.isLibraryLoaded()){
+				//Check if a solution exists, WARN THE USER!!!
+				if (CyCore.currentSolutions != null) {
+					int dialogResult = JOptionPane.showConfirmDialog (
+							null,
+							LocalizationManager.get("overrideSolution"),
+							LocalizationManager.get("warning"),
+							JOptionPane.YES_NO_OPTION
+					);
+					if (dialogResult != JOptionPane.YES_OPTION) {
+						return;
+					}
+					
+					LibraryInterface.delete_ClusterEditingSolutions(CyCore.currentSolutions);
+				}
+				solutionsPanel.setVisible(false);
+				AbstractTask yoshiko = new AlgorithmTask(
+					CyCore.cy.getCurrentNetwork(),
+					timeLimitSetter.getTimeLimit(), 
+					ecPanel.getWeightColumn(),
+					ecPanel.getPermanentColumn(),
+					ecPanel.getForbiddenColumn(),
+					ecPanel.getDefaultInsertionCost(),
+					ecPanel.getDefaultDeletionCost(),
+					reductionRulesChooser.getBitMask(),
+					reductionRulesChooser.getMultFactor(),
+					useTriangleCutsBox.isSelected(),
+					usePartitionCutsBox.isSelected(), 
+					useHeuristic.isSelected(), 
+					solutionsPanel
+				);
+				CyCore.dialogTaskManager.execute(new TaskIterator(1,yoshiko));
+				solutionsPanel.setVisible(true);
+			}
+			else {
+				JOptionPane.showMessageDialog(
+						null,
+						LocalizationManager.get("noLibTitle"),
+						LocalizationManager.get("noLibMessage"),
+						JOptionPane.ERROR_MESSAGE
+						);
+			}
+		}
+	};
 	
 	
 	//GETTER / SETTER
@@ -146,7 +164,6 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 		return this;
 	}
 
-
 	/* (non-Javadoc)
 	 * @see org.cytoscape.application.swing.CytoPanelComponent#getCytoPanelName()
 	 */
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java
index df7e33b..065fd92 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java
@@ -6,6 +6,9 @@ import java.awt.event.ActionListener;
 
 import javax.swing.BoxLayout;
 import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+
+import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
 
 @SuppressWarnings("serial")
 public class ReductionRulesChooser extends ComfortPanel{
@@ -35,7 +38,7 @@ public class ReductionRulesChooser extends ComfortPanel{
 		multFactor.setText("1.0");
 		SNPanel = new ComfortPanel();
 		
-		SNPanel.addAll(useSNRule,multFactor);
+		SNPanel.addAll(new JLabel(LocalizationManager.get("multFactor")),multFactor);
 		useSNRule.setSelected(true);
 
 		useSNRule.addActionListener(new ActionListener() {
@@ -57,6 +60,7 @@ public class ReductionRulesChooser extends ComfortPanel{
 				useACRule,
 				useHERule,
 				usePDRRule,
+				useSNRule,
 				SNPanel
 				);
 		//By default all reduction rules should be applied
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java
index 4245053..5eec772 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java
@@ -1,30 +1,47 @@
 package de.hhu.ba.yoshikoWrapper.gui;
 
+import java.awt.Dimension;
+
+import javax.swing.Box;
 import javax.swing.BoxLayout;
 import javax.swing.JLabel;
 import javax.swing.JScrollPane;
 
+import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
+
 @SuppressWarnings("serial")
 public class SolutionTab extends ComfortPanel {
 	
 	private final JScrollPane scrollPane;
-	private final JLabel testLabel;
+	private final ComfortPanel scrollPaneContent;
+	private final JLabel clusterCount;
 	
 	public SolutionTab() {
 		this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
 		//init swing components
-		scrollPane = new JScrollPane();
-		testLabel = new JLabel("test");
-		this.addAll(scrollPane,testLabel);
+		scrollPaneContent = new ComfortPanel();
+		scrollPaneContent.setLayout(new BoxLayout(scrollPaneContent,BoxLayout.Y_AXIS));
+		scrollPane = new JScrollPane(scrollPaneContent);
+
+		scrollPane.setPreferredSize(new Dimension(150,400));
+		
+		clusterCount = new JLabel("CLUSTERCOUNT");
+		this.addAll(clusterCount,scrollPane);
 	}
 	
 
 	public ClusterView addCluster(long k) {
 		ClusterView clusterView = new ClusterView();
-		scrollPane.add(clusterView);
-		scrollPane.revalidate();
-		scrollPane.repaint();
+		scrollPaneContent.add(clusterView);
+		scrollPaneContent.add(Box.createVerticalStrut(8));
 		return clusterView;
 	}
 
+
+	public void setClusterNumber(long numberOfClusters) {
+		clusterCount.setText(LocalizationManager.get("clusterFound")+numberOfClusters);
+	}
+	
+	
+
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionsPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionsPanel.java
index a7ae442..778c694 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionsPanel.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionsPanel.java
@@ -2,6 +2,7 @@ package de.hhu.ba.yoshikoWrapper.gui;
 
 import java.awt.Component;
 
+import javax.swing.BoxLayout;
 import javax.swing.Icon;
 import javax.swing.JTabbedPane;
 
@@ -16,6 +17,7 @@ public class SolutionsPanel extends ComfortPanel implements CytoPanelComponent{
 	private JTabbedPane solutionTabs;
 	
 	public SolutionsPanel() {
+		this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
 		solutionTabs = new JTabbedPane();
 		this.add(solutionTabs);
 	}
diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties
index 3f25f42..6b0a86b 100644
--- a/src/main/resources/YoshikoStrings.properties
+++ b/src/main/resources/YoshikoStrings.properties
@@ -7,4 +7,9 @@ restartNeeded = Changes only take effect after restart!
 noLibTitle = Library not loaded!
 noLibMessage = There is no Yoshiko Library currently loaded! You might have to specify its location.
 cluster = Cluster
-clusterSize = Cluster Size:
\ No newline at end of file
+clusterSize = Cluster Size:
+multFactor = Multiplicative Factor for SNR: 
+paidCost = Paid a total modification cost of:
+clusterFound = Clusters found:
+overrideSolution = Running Yoshiko will override previous solutions. Continue?
+warning = Warning
\ No newline at end of file
diff --git a/src/main/resources/YoshikoStrings_de_DE.properties b/src/main/resources/YoshikoStrings_de_DE.properties
index 57706bb..92b28a9 100644
--- a/src/main/resources/YoshikoStrings_de_DE.properties
+++ b/src/main/resources/YoshikoStrings_de_DE.properties
@@ -1,4 +1,5 @@
 resultsPanelTitle = Yoshiko Ergebnisse
 resolveLibPath = Yoshiko Library suchen
 clusterSize = Cluster Gr��e:
-solution = L�sung
\ No newline at end of file
+solution = L�sung
+clustersFound = Gefundene Cluster:
\ No newline at end of file
-- 
GitLab