From 44e11a1a3ead1153d0797744afdf95dba2a95563 Mon Sep 17 00:00:00 2001
From: Philipp Spohr <spohr.philipp@web.de>
Date: Sat, 19 Aug 2017 17:42:04 +0200
Subject: [PATCH] Added a GUI component for choosing number of solutions
 smaller fixes

---
 .../ba/yoshikoWrapper/core/AlgorithmTask.java | 36 ++++++++++++++-----
 .../ba/yoshikoWrapper/core/NetworkParser.java |  2 --
 .../ba/yoshikoWrapper/core/YoshikoLoader.java |  2 ++
 .../ba/yoshikoWrapper/gui/ClusterView.java    |  1 -
 .../ba/yoshikoWrapper/gui/ComfortPanel.java   |  7 ++--
 .../ba/yoshikoWrapper/gui/FormatHelper.java   |  9 +++--
 .../yoshikoWrapper/gui/IntegerInputField.java |  9 +++--
 .../hhu/ba/yoshikoWrapper/gui/MainPanel.java  | 31 ++++++++++++++--
 .../gui/SolutionNumberChooser.java            | 26 ++++++++++++++
 .../ba/yoshikoWrapper/gui/SolutionsPanel.java |  9 ++++-
 .../yoshikoWrapper/gui/TimeLimitSetter.java   | 18 ++++++++--
 .../yoshikoWrapper/swig/LibraryInterface.java | 12 +++++--
 .../swig/LibraryInterfaceJNI.java             |  2 ++
 src/main/resources/YoshikoStrings.properties  |  7 +++-
 14 files changed, 145 insertions(+), 26 deletions(-)
 create mode 100644 src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionNumberChooser.java

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 c0c423f..fd1bcbd 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java
@@ -1,5 +1,4 @@
 package de.hhu.ba.yoshikoWrapper.core;
-//TODO: ADD LOGGER SYSTEM
 
 import org.cytoscape.model.CyColumn;
 import org.cytoscape.model.CyNetwork;
@@ -35,7 +34,11 @@ public class AlgorithmTask extends AbstractTask {
 	private boolean separatePartitionCuts;
 	private boolean separateTriangles;
 	private boolean useHeuristic;
+	private int numberOfSolutions;
 	private SolutionsPanel solutionsPanel;
+	
+	//temps
+	private SWIGTYPE_p_yskInput__LibraryInput input;
 
 	public AlgorithmTask(
 			CyNetwork net,
@@ -50,6 +53,7 @@ public class AlgorithmTask extends AbstractTask {
 			boolean separatePartitionCuts,
 			boolean separateTriangles,
 			boolean useHeuristic,
+			int numberOfSolutions,
 			SolutionsPanel solutionsPanel
 			) 
 	{
@@ -65,6 +69,7 @@ public class AlgorithmTask extends AbstractTask {
 		this.separatePartitionCuts = separatePartitionCuts;
 		this.separateTriangles = separateTriangles;
 		this.useHeuristic = useHeuristic;
+		this.numberOfSolutions = numberOfSolutions;
 		this.solutionsPanel = solutionsPanel;
 	}
 
@@ -86,7 +91,7 @@ public class AlgorithmTask extends AbstractTask {
 		taskMonitor.setProgress(0.1);
 
 		//Generate an input instance from the network
-		SWIGTYPE_p_yskInput__LibraryInput input = NetworkParser.parseNetwork(
+		input = NetworkParser.parseNetwork(
 				net,
 				nodeMap,
 				weightColumn,
@@ -102,24 +107,24 @@ public class AlgorithmTask extends AbstractTask {
 		//Call Yoshiko <<< Algorithm is performed here
 		CyCore.currentSolutions = LibraryInterface.processLibraryInput(
 				input,
-				1,
+				numberOfSolutions,
 				bitMaskRules,
 				multiplicativeFactor, 
 				separatePartitionCuts,
 				separateTriangles,
 				useHeuristic
-				);
+		);
+		
 		taskMonitor.setProgress(0.9);
 
 		this.solutionsPanel.reset();
-
 		
 		long numberOfSolutions = LibraryInterface.ClusterEditingSolutions_getNumberOfSolutions(CyCore.currentSolutions);
 		taskMonitor.setStatusMessage("Found: "+numberOfSolutions+" solutions!");
 		
 		double modificationCost = LibraryInterface.ClusterEditingSolutions_getTotalCost(CyCore.currentSolutions);
 		taskMonitor.setStatusMessage(LocalizationManager.get("paidCost")+modificationCost);
-		
+		solutionsPanel.setCost(modificationCost);
 		for (long i=0;i<numberOfSolutions;i++) {
 			
 			taskMonitor.setStatusMessage("Processing solution "+(i+1)+" of "+numberOfSolutions);
@@ -154,7 +159,22 @@ public class AlgorithmTask extends AbstractTask {
 			}
 		}
 
-		LibraryInterface.delete_LibraryInput(input);		
-		taskMonitor.setProgress(1.0);
+		LibraryInterface.delete_LibraryInput(input);
+		input = null;
+		
+		//Provide some useful info
+		if (LibraryInterface.ClusterEditingSolutions_isTimedOut(CyCore.currentSolutions)) {
+			throw new Exception(LocalizationManager.get("timedOutMessage"));
+		}
+		
+		
+	}
+	
+	@Override
+	public void cancel() {
+		if (input != null) {
+			LibraryInterface.delete_LibraryInput(input);
+		}
+		super.cancel();
 	}
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java
index 8c3fd59..62079e0 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java
@@ -75,8 +75,6 @@ public class NetworkParser {
 					}
 				}
 
-				System.out.println("Found Edge: "+edgeEntry.get("name", String.class)+ " with weight:"+weight);
-
 				logger.debug("Found Edge: "+edgeEntry.get("name", String.class)+ " with weight:"+weight);
 				
 				LibraryInterface.LibraryInput_addEdge(
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java
index fc42a4d..0934c7c 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java
@@ -5,6 +5,7 @@ import java.io.File;
 import org.slf4j.Logger;
 
 import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger;
+import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface;
 
 public class YoshikoLoader {
 	
@@ -32,6 +33,7 @@ public class YoshikoLoader {
 			//e.printStackTrace();
 			return;
 		}
+		LibraryInterface.setVerbosity(3);
 		isLoaded = true;
 	}
 	
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 fc3ffa0..5893ac4 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ClusterView.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ClusterView.java
@@ -85,7 +85,6 @@ public class ClusterView extends ComfortPanel {
 			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);
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ComfortPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ComfortPanel.java
index e2e320d..dbe4b53 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ComfortPanel.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ComfortPanel.java
@@ -3,6 +3,10 @@ package de.hhu.ba.yoshikoWrapper.gui;
 import javax.swing.JComponent;
 import javax.swing.JPanel;
 
+/**
+ * Custom extension of the standard JPanel that provides some comfort functions
+ *
+ */
 @SuppressWarnings("serial")
 public class ComfortPanel extends JPanel {
 	
@@ -15,6 +19,5 @@ public class ComfortPanel extends JPanel {
 			this.add(c);
 		}
 		
-	}
-	
+	}	
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java
index 48aed6c..e85294a 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java
@@ -8,11 +8,15 @@ import javax.swing.text.NumberFormatter;
 public class FormatHelper {
 	
 	public static NumberFormatter getIntegerFormatter() {
+		return getIntegerFormatter(0, Integer.MAX_VALUE);
+	}
+	
+	public static NumberFormatter getIntegerFormatter(int minValue, int maxValue) {
 		NumberFormat format = NumberFormat.getInstance();
 	    NumberFormatter formatter = new NumberFormatter(format);
 	    formatter.setValueClass(Integer.class);
-	    formatter.setMinimum(0);
-	    formatter.setMaximum(Integer.MAX_VALUE);
+	    formatter.setMinimum(minValue);
+	    formatter.setMaximum(maxValue);
 	    formatter.setCommitsOnValidEdit(true);
 	    
 	    return formatter;
@@ -29,4 +33,5 @@ public class FormatHelper {
 	    return formatter;
 	}
 
+
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/IntegerInputField.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/IntegerInputField.java
index fe400a1..09d40d6 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/IntegerInputField.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/IntegerInputField.java
@@ -8,12 +8,17 @@ import javax.swing.JFormattedTextField;
 @SuppressWarnings("serial")
 public class IntegerInputField extends JFormattedTextField{
 
+	public IntegerInputField(int minValue, int maxValue) {
+		super(FormatHelper.getIntegerFormatter(minValue,maxValue));
+		this.setColumns(8);
+	}
+
 	public IntegerInputField() {
 		super(FormatHelper.getIntegerFormatter());
-		this.setColumns(8);
+		this.setColumns(8);	
 	}
 
-	public int getTimeLimit() {
+	public int getValueAsInt() {
 		return Integer.parseInt(getText());
 	}
 }
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 d4c28ab..bdabdfb 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java
@@ -16,11 +16,13 @@ import org.cytoscape.application.swing.CytoPanelComponent;
 import org.cytoscape.application.swing.CytoPanelName;
 import org.cytoscape.work.AbstractTask;
 import org.cytoscape.work.TaskIterator;
+import org.slf4j.Logger;
 
 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.logging.YoshikoLogger;
 import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface;
 
 /**This class describes the Swing Panel that the user interacts with in cytoscape
@@ -45,12 +47,15 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 	
 	private final ReductionRulesChooser reductionRulesChooser;
 	
-	
 	private final JCheckBox useTriangleCutsBox;
 	private final JCheckBox usePartitionCutsBox;
 	
+
+	private final SolutionNumberChooser solutionNumberChooser;
+	
 	//SYMBOLIC LINKS
 	private final SolutionsPanel solutionsPanel;
+	private final Logger logger = YoshikoLogger.getInstance().getLogger();
 	
 	/**
 	 * Main constructor, creates a new Panel and initializes subcomponents
@@ -72,21 +77,25 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 		heuristicGroup = new ButtonGroup();
 		useILP = new JRadioButton("Use Integer Linear Programming");
 		useILP.setSelected(true);
+
 		useHeuristic = new JRadioButton("Use Heuristic");
 		heuristicGroup.add(useILP);
 		heuristicGroup.add(useHeuristic);
 		
-
+		solutionNumberChooser = new SolutionNumberChooser();
+		
 		reductionRulesChooser = new ReductionRulesChooser();
 		
 		timeLimitSetter = new TimeLimitSetter();
 				
 		useTriangleCutsBox = new JCheckBox("Use Triangle Cuts");
 		usePartitionCutsBox = new JCheckBox("Use Partition Cuts");
-		
 
 		JButton runButton = new JButton("RUN");
 		runButton.addActionListener(buttonListener);
+		//Link time limit option to ILP
+		useILP.addActionListener(ilpHeuristicSwitch);
+		useHeuristic.addActionListener(ilpHeuristicSwitch);
 
 		this.addAll(
 				langSwitcher,
@@ -98,6 +107,7 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 				reductionRulesChooser,
 				useTriangleCutsBox,
 				usePartitionCutsBox,
+				solutionNumberChooser,
 				runButton
 				);
 		
@@ -141,13 +151,16 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 					useTriangleCutsBox.isSelected(),
 					usePartitionCutsBox.isSelected(), 
 					useHeuristic.isSelected(), 
+					solutionNumberChooser.getSolCount(),
 					solutionsPanel
 				);
 				CyCore.dialogTaskManager.execute(new TaskIterator(1,yoshiko));
 				solutionsPanel.setVisible(true);
+
 			}
 			else {
 				JOptionPane.showMessageDialog(
+						
 						null,
 						LocalizationManager.get("noLibTitle"),
 						LocalizationManager.get("noLibMessage"),
@@ -157,6 +170,18 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent {
 		}
 	};
 	
+	ActionListener ilpHeuristicSwitch = new ActionListener() {
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (useILP.isSelected()) {
+				timeLimitSetter.setEnabled(true);
+			}
+			else {
+				timeLimitSetter.setEnabled(false);
+			}
+		}	
+	};
+	
 	
 	//GETTER / SETTER
 
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionNumberChooser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionNumberChooser.java
new file mode 100644
index 0000000..dc90480
--- /dev/null
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionNumberChooser.java
@@ -0,0 +1,26 @@
+package de.hhu.ba.yoshikoWrapper.gui;
+
+import javax.swing.JLabel;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+
+import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
+
+@SuppressWarnings("serial")
+public class SolutionNumberChooser extends ComfortPanel {
+	private final JSpinner numSolutionsSetter;
+	private final JLabel label;
+	
+	public SolutionNumberChooser() {
+		//Swing Component init
+		numSolutionsSetter = new JSpinner();
+		numSolutionsSetter.setModel(new SpinnerNumberModel(1,1,Integer.MAX_VALUE,1));
+		label = new JLabel(LocalizationManager.get("nrSolutions"));
+		this.addAll(label, numSolutionsSetter);
+		 
+	}
+
+	public int getSolCount() {
+		return (int)numSolutionsSetter.getValue();
+	}
+}
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 778c694..cb6373e 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionsPanel.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionsPanel.java
@@ -4,6 +4,7 @@ import java.awt.Component;
 
 import javax.swing.BoxLayout;
 import javax.swing.Icon;
+import javax.swing.JLabel;
 import javax.swing.JTabbedPane;
 
 import org.cytoscape.application.swing.CytoPanelComponent;
@@ -15,11 +16,13 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
 public class SolutionsPanel extends ComfortPanel implements CytoPanelComponent{
 	
 	private JTabbedPane solutionTabs;
+	private JLabel costLabel;
 	
 	public SolutionsPanel() {
 		this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
 		solutionTabs = new JTabbedPane();
-		this.add(solutionTabs);
+		costLabel = new JLabel("COST");
+		this.addAll(costLabel,solutionTabs);
 	}
 	
 	public SolutionTab addSolutionTab(long i) {
@@ -31,6 +34,10 @@ public class SolutionsPanel extends ComfortPanel implements CytoPanelComponent{
 		return tab;
 	}
 
+	public void setCost(double modificationCost) {
+		costLabel.setText(LocalizationManager.get("cost")+" "+modificationCost);
+	}
+	
 	public void reset() {
 		solutionTabs.removeAll();
 	}
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/TimeLimitSetter.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/TimeLimitSetter.java
index c5445d6..993afbb 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/TimeLimitSetter.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/TimeLimitSetter.java
@@ -5,6 +5,8 @@ import java.awt.event.ActionListener;
 
 import javax.swing.JCheckBox;
 
+import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
+
 @SuppressWarnings("serial")
 public class TimeLimitSetter extends ComfortPanel{
 
@@ -12,8 +14,9 @@ public class TimeLimitSetter extends ComfortPanel{
 	private IntegerInputField numberField;
 	
 	public TimeLimitSetter() {
-		checkBox = new JCheckBox("Use time limit (s):");
+		checkBox = new JCheckBox(LocalizationManager.get("timeLimitILP"));
 		numberField = new IntegerInputField();
+		numberField.setText("60");
 		numberField.setEnabled(false); //By default time limit is turned off
 		checkBox.addActionListener(
 				new ActionListener() {
@@ -29,11 +32,22 @@ public class TimeLimitSetter extends ComfortPanel{
 		this.addAll(checkBox,numberField);
 	}
 	
+	public void setEnabled(boolean enabled) {
+		if (enabled) {
+			this.checkBox.setEnabled(enabled);
+			this.numberField.setEnabled(this.checkBox.isSelected());
+		}
+		else {
+			this.checkBox.setEnabled(enabled);
+			this.numberField.setEnabled(enabled);
+		}
+	}
+	
 	public int getTimeLimit() {
 		if (!checkBox.isSelected()) {
 			return -1;
 		}
-		return numberField.getTimeLimit();
+		return numberField.getValueAsInt();
 	}
 
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java
index f742a24..273cc97 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java
@@ -80,6 +80,10 @@ public class LibraryInterface {
     return LibraryInterfaceJNI.ClusterEditingSolutions_getTotalCost(SWIGTYPE_p_ysk__ClusterEditingSolutions.getCPtr(self));
   }
 
+  public static boolean ClusterEditingSolutions_isTimedOut(SWIGTYPE_p_ysk__ClusterEditingSolutions self) {
+    return LibraryInterfaceJNI.ClusterEditingSolutions_isTimedOut(SWIGTYPE_p_ysk__ClusterEditingSolutions.getCPtr(self));
+  }
+
   public static void delete_ClusterEditingSolutions(SWIGTYPE_p_ysk__ClusterEditingSolutions self) {
     LibraryInterfaceJNI.delete_ClusterEditingSolutions(SWIGTYPE_p_ysk__ClusterEditingSolutions.getCPtr(self));
   }
@@ -113,8 +117,8 @@ public class LibraryInterface {
     return LibraryInterfaceJNI.getVersionString();
   }
 
-  public static SWIGTYPE_p_ysk__ClusterEditingSolutions processLibraryInput(SWIGTYPE_p_yskInput__LibraryInput libIn, int nrOptimalSolutions, String rulesBitMask, double multiplicativeFactor, boolean useHeuristic, boolean separatePartitionCuts, boolean separateTriangles) {
-    long cPtr = LibraryInterfaceJNI.processLibraryInput(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(libIn), nrOptimalSolutions, rulesBitMask, multiplicativeFactor, useHeuristic, separatePartitionCuts, separateTriangles);
+  public static SWIGTYPE_p_ysk__ClusterEditingSolutions processLibraryInput(SWIGTYPE_p_yskInput__LibraryInput libIn, int nrOptimalSolutions, String rulesBitMask, double multiplicativeFactor, boolean separatePartitionCuts, boolean separateTriangles, boolean useHeuristic) {
+    long cPtr = LibraryInterfaceJNI.processLibraryInput(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(libIn), nrOptimalSolutions, rulesBitMask, multiplicativeFactor, separatePartitionCuts, separateTriangles, useHeuristic);
     return (cPtr == 0) ? null : new SWIGTYPE_p_ysk__ClusterEditingSolutions(cPtr, false);
   }
 
@@ -122,4 +126,8 @@ public class LibraryInterface {
     LibraryInterfaceJNI.setTimeLimit(limit);
   }
 
+  public static void setVerbosity(int level) {
+    LibraryInterfaceJNI.setVerbosity(level);
+  }
+
 }
diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java
index 7eeb8c9..3870b0d 100644
--- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java
+++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java
@@ -26,6 +26,7 @@ public class LibraryInterfaceJNI {
   public final static native long ClusterEditingSolutions_getSolution(long jarg1, long jarg2);
   public final static native long ClusterEditingSolutions_getNumberOfSolutions(long jarg1);
   public final static native double ClusterEditingSolutions_getTotalCost(long jarg1);
+  public final static native boolean ClusterEditingSolutions_isTimedOut(long jarg1);
   public final static native void delete_ClusterEditingSolutions(long jarg1);
   public final static native long new_LibraryInput();
   public final static native void delete_LibraryInput(long jarg1);
@@ -36,4 +37,5 @@ public class LibraryInterfaceJNI {
   public final static native String getVersionString();
   public final static native long processLibraryInput(long jarg1, int jarg2, String jarg3, double jarg4, boolean jarg5, boolean jarg6, boolean jarg7);
   public final static native void setTimeLimit(int jarg1);
+  public final static native void setVerbosity(int jarg1);
 }
diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties
index 6b0a86b..a6b05e6 100644
--- a/src/main/resources/YoshikoStrings.properties
+++ b/src/main/resources/YoshikoStrings.properties
@@ -12,4 +12,9 @@ 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
+warning = Warning
+timeLimitILP = Use time limit for ILP (s):
+timedOutTitle = Timeout
+timedOutMessage = The ILP exceeded the time-limit!
+cost = Cost:
+nrSolutions = Number of Solutions:
\ No newline at end of file
-- 
GitLab