$darkmode
DENOPTIM
GUIPrepare.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2020 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.gui;
20
21import java.awt.BorderLayout;
22import java.awt.event.ActionEvent;
23import java.awt.event.ActionListener;
24import java.io.File;
25import java.io.FileWriter;
26import java.io.IOException;
27import java.util.ArrayList;
28
29import javax.swing.JButton;
30import javax.swing.JOptionPane;
31import javax.swing.JTabbedPane;
32import javax.swing.UIManager;
33import denoptim.exception.DENOPTIMException;
34import denoptim.files.FileFormat;
35import denoptim.files.FileUtils;
36import denoptim.main.Main.RunType;
37import denoptim.programs.combinatorial.FragSpaceExplorer;
38import denoptim.programs.denovo.GARunner;
39import denoptim.programs.fitnessevaluator.FitnessRunner;
40import denoptim.task.ProgramTask;
41import denoptim.task.StaticTaskManager;
42
51public class GUIPrepare extends GUICardPanel
52{
53
57 private static final long serialVersionUID = 6481647840284906676L;
58
62 protected JTabbedPane tabbedPane;
63
67 public ArrayList<IParametersForm> allParams;
68
72 public GUIPrepare(GUIMainPanel mainPanel, String newPanelName)
73 {
74 super(mainPanel, newPanelName);
75 super.setLayout(new BorderLayout());
76 this.allParams = new ArrayList<IParametersForm>();
77 initialize();
78 }
79
83 private void initialize()
84 {
85
86 // Parameters for the various components are divided in TABs
87 tabbedPane = new JTabbedPane(JTabbedPane.TOP);
88 super.add(tabbedPane, BorderLayout.CENTER);
89
90 // Buttons go below the tabs
91 ButtonsBar commandsPane = new ButtonsBar();
92 super.add(commandsPane, BorderLayout.SOUTH);
93
94 JButton btnLoadParams = new JButton("Load Parameters");
95 // Adding an Icon overwrites the fontsize, no matter the setFont
96 /*
97 JButton btnLoadParams = new JButton("Load Parameters",
98 UIManager.getIcon("FileView.directoryIcon"));
99 */
100 btnLoadParams.setToolTipText("<html>Reads a DENOPTIM parameter file,"
101 + "<br>and imports parameters into the form.</html>");
102 btnLoadParams.addActionListener(new ActionListener() {
103 public void actionPerformed(ActionEvent e) {
104 File inFile = GUIFileOpener.pickFile(btnLoadParams);
105 if (inFile == null || inFile.getAbsolutePath().equals(""))
106 {
107 return;
108 }
109
111
112 for (IParametersForm p : allParams)
113 {
114 p.setUnsavedChanges(false);
115 }
116 }
117 });
118 commandsPane.add(btnLoadParams);
119
120 JButton btnSaveParams = new JButton("Save Parameters");
121 // Adding an Icon overwrites the fontsize, no matter the setFont
122 /*
123 JButton btnSaveParams = new JButton("Save Parameters",
124 UIManager.getIcon("FileView.hardDriveIcon"));
125 */
126 btnSaveParams.setToolTipText("<html>Write all parameters to file."
127 + "<br>This will produce a DENOPTIM parameter file.</html>");
128 btnSaveParams.addActionListener(new ActionListener() {
129 public void actionPerformed(ActionEvent e) {
130 File outFile = GUIFileOpener.pickFileForSaving(btnSaveParams);
131 printAllParamsToFile(outFile);
132 if (outFile!=null)
133 FileUtils.addToRecentFiles(outFile, getFileFormat("PARAMS"));
134 }
135 });
136 commandsPane.add(btnSaveParams);
137
138 /*
139 //TODO
140 JButton btnValidate = new JButton("Validate Parameters",
141 btnValidate.setToolTipText("Check the correctness of the parameters");
142 btnValidate.addActionListener(new ActionListener() {
143 public void actionPerformed(ActionEvent e) {
144 //TODO
145 getNonImplementedError();
146 }
147 });
148 commandsPane.add(btnValidate);
149 */
150
151
152 JButton btnRun = new JButton("Run now...");//,
153 // UIManager.getIcon("Menu.arrowIcon"));
154 // Using the arrowIcon causes problems with adoptopenjdk-1.8
155 // due to casting of the JButton into a JMenuItem. This could be
156 // due to the fact that the arrow icon is meant for a menu.
157 btnRun.addActionListener(new ActionListener() {
158 public void actionPerformed(ActionEvent e) {
159 String msg = "<html><body width='%1s'><p>Running a DENOPTIM "
160 + "experiment from the graphical user interface "
161 + "(GUI) makes it dependent on "
162 + "the GUI itself. Therefore, if the GUI is closed "
163 + "or shut down, "
164 + "the experiment will be terminated as well.</p>"
165 + "<p>To avoid this, consider running your experiment "
166 + "as a batch process disconnected from the GUI.</p>"
167 + "<br>";
169 msg = msg + "<p>Continue?</p></body></html>";
170 //TODO: add capability of running in the background
171 String[] options = new String[]{"Yes", "Cancel"};
172 int res = JOptionPane.showOptionDialog(btnRun,
173 String.format(msg, 450),
174 "WARNING",
175 JOptionPane.DEFAULT_OPTION,
176 JOptionPane.QUESTION_MESSAGE,
177 UIManager.getIcon("OptionPane.warningIcon"),
178 options,
179 options[1]);
180 switch (res)
181 {
182 case 0:
183 String location = "unknownLocation";
184 try {
185 File wrkSpace = prepareWorkSpace();
186 File paramFile = instantiateParametersFile(wrkSpace);
187 if (printAllParamsToFile(paramFile))
188 {
189 ProgramTask task = buildProgramTask(paramFile,
190 wrkSpace);
192 } else {
193 throw new DENOPTIMException("Failed to make "
194 + "parameter file '" + paramFile + "'");
195 }
196 location = wrkSpace.getAbsolutePath();
197 } catch (DENOPTIMException e1) {
198 JOptionPane.showMessageDialog(btnRun,
199 "Could not start task. " + e1.getMessage()
200 + ". " + e1.getCause().getMessage(),
201 "ERROR",
202 JOptionPane.ERROR_MESSAGE);
203 return;
204 }
205
206 JOptionPane.showMessageDialog(btnRun,
207 "<html>Experiment submitted!<br>"
208 + "See under " + location+"<br>"
209 + "or 'File -&gt; Open Recent'</html>",
210 "Submitted",
211 JOptionPane.INFORMATION_MESSAGE);
212 break;
213
214 case 1:
215 break;
216 }
217 }
218 });
219 commandsPane.add(btnRun);
220
221
222 JButton btnCanc = new JButton("Close Tab");
223 // Adding the icon overrites font size no matter setFont
224 /*
225 JButton btnCanc = new JButton("Close Tab",
226 UIManager.getIcon("FileView.fileIcon"));
227 */
228 btnCanc.setToolTipText("Closes this tab.");
229 btnCanc.addActionListener(new removeCardActionListener(this));
230 commandsPane.add(btnCanc);
231
232 JButton btnHelp = new JButton("?");
233 btnHelp.setToolTipText("Help");
234 btnHelp.addActionListener(new ActionListener() {
235 public void actionPerformed(ActionEvent e) {
236 String txt = "<html><body width='%1s'>"
237 + "<p>This tab allows to create, inspect, and edit "
238 + "parameter used as input for DENOPTIM experiments. "
239 + "These parameters are then collected into an input "
240 + "file for DENOPTIM.</p>"
241 + "<br>"
242 + "<p>Hover over buttons and parameter fields to get "
243 + "informations on a specific parameter.</p></html>";
244 JOptionPane.showMessageDialog(btnHelp,
245 String.format(txt, 350),
246 "Tips",
247 JOptionPane.PLAIN_MESSAGE);
248 }
249 });
250 commandsPane.add(btnHelp);
251 }
252
253//------------------------------------------------------------------------------
254
255 private FileFormat getFileFormat(String string)
256 {
257
258 if (this instanceof GUIPrepareGARun)
259 {
260 switch(string)
261 {
262 case "PARAMS":
263 return FileFormat.GA_PARAM;
264 case "RUN":
265 return FileFormat.GA_RUN;
266 default:
267 throw new IllegalArgumentException("BUG: GUIPrepare"
268 + "subclasses must "
269 + "declare what kind of recent file to store. "
270 + "Current declaration is not valid. Report this "
271 + "to the development team.");
272 }
273 } else if (this instanceof GUIPrepareFSERun)
274 {
275 switch(string)
276 {
277 case "PARAMS":
278 return FileFormat.FSE_PARAM;
279 case "RUN":
280 return FileFormat.FSE_PARAM;
281 default:
282 throw new IllegalArgumentException("BUG: GUIPrepare"
283 + "subclasses must "
284 + "declare what kind of recent file to store. "
285 + "Current declaration is not valid. Report this "
286 + "to the development team.");
287 }
288 } else if (this instanceof GUIPrepareFitnessRunner)
289 {
290 switch(string)
291 {
292 case "PARAMS":
293 return FileFormat.FSE_PARAM;
294 case "RUN":
295 return FileFormat.FSE_PARAM;
296 default:
297 throw new IllegalArgumentException("BUG: GUIPrepare"
298 + "subclasses must "
299 + "declare what kind of recent file to store. "
300 + "Current declaration is not valid. Report this "
301 + "to the development team.");
302 }
303 }
304 return null;
305 }
306
307//------------------------------------------------------------------------------
308
310 {
311 RunType baseName =null;
312 if (this instanceof GUIPrepareGARun)
313 {
314 baseName = RunType.GA;
315 } else if (this instanceof GUIPrepareFSERun)
316 {
317 baseName = RunType.FSE;
318 } else if (this instanceof GUIPrepareFitnessRunner)
319 {
320 baseName = RunType.FIT;
321 }
322 return baseName;
323 }
324
325//------------------------------------------------------------------------------
326
327 private File instantiateParametersFile(File wrkSpace)
328 {
329 String baseName = getAchronimFromClass() + ".params";
330 File paramFile = new File (wrkSpace.getAbsolutePath()
331 + System.getProperty("file.separator") + baseName);
332 return paramFile;
333 }
334
335//------------------------------------------------------------------------------
336
342 private boolean printAllParamsToFile(File outFile)
343 {
344 StringBuilder sb = new StringBuilder();
345 for (IParametersForm p : allParams)
346 {
347 try
348 {
349 p.putParametersToString(sb);
350 }
351 catch (Exception e1)
352 {
353 JOptionPane.showMessageDialog(this,
354 e1.getMessage(),
355 "Error",
356 JOptionPane.ERROR_MESSAGE,
357 UIManager.getIcon("OptionPane.errorIcon"));
358 return false;
359 }
360 }
361
362 // It might be coming from a JOptionPane, which might return null
363 // upon user's attempt to cancel the printing task.
364 if (outFile == null)
365 {
366 return false;
367 }
368
369 try
370 {
371 FileWriter fw = new FileWriter(outFile);
372 fw.write(sb.toString());
373 fw.close();
374
375 for (IParametersForm p : allParams)
376 {
377 p.setUnsavedChanges(false);
378 }
379 }
380 catch (IOException io)
381 {
382 JOptionPane.showMessageDialog(this,
383 "Could not write to '" + outFile + "'!.",
384 "Error",
385 JOptionPane.PLAIN_MESSAGE,
386 UIManager.getIcon("OptionPane.errorIcon"));
387 return false;
388 }
389 return true;
390 }
391
392//------------------------------------------------------------------------------
393
401 private ProgramTask buildProgramTask(File configFile, File workDir)
402 throws DENOPTIMException
403 {
404 ProgramTask task = null;
405 if (this instanceof GUIPrepareGARun)
406 {
407 task = new GARunner(configFile, workDir);
408 } else if (this instanceof GUIPrepareFSERun)
409 {
410 task = new FragSpaceExplorer(configFile, workDir);
411 } else if (this instanceof GUIPrepareFitnessRunner)
412 {
413 task = new FitnessRunner(configFile, workDir);
414 }
415 return task;
416 }
417
418//------------------------------------------------------------------------------
419
421 {
422 String baseName = getAchronimFromClass() + "_run";
423 File parent = new File(GUIPreferences.tmpSpace);
424 File wrkSpace = FileUtils.getAvailableFileName(parent, baseName);
425 FileUtils.createDirectory(wrkSpace.getAbsolutePath());
426 return wrkSpace;
427 }
428//------------------------------------------------------------------------------
429
431 {
432 for (IParametersForm p : allParams)
433 {
434 try
435 {
436 p.importParametersFromDenoptimParamsFile(
437 file.getAbsolutePath());
438 }
439 catch (Exception e1)
440 {
441 if (e1.getMessage().equals("")
442 || e1.getMessage() == null)
443 {
444 e1.printStackTrace();
445 JOptionPane.showMessageDialog(this,
446 "<html>Exception occurred while importing"
447 + "parameters.<br>Please, report this to "
448 + "the DENOPTIM team.</html>",
449 "Error",
450 JOptionPane.ERROR_MESSAGE,
451 UIManager.getIcon("OptionPane.errorIcon"));
452 }
453 else
454 {
455 JOptionPane.showMessageDialog(this,
456 e1.getMessage(),
457 "Error",
458 JOptionPane.ERROR_MESSAGE,
459 UIManager.getIcon("OptionPane.errorIcon"));
460 }
461 }
462 }
463 }
464
465//-----------------------------------------------------------------------------
466
473 public boolean hasUnsavedChanges()
474 {
475 boolean res = false;
476 for (IParametersForm p : allParams)
477 {
478 if (p.hasUnsavedChanges())
479 {
480 res = true;
481 break;
482 }
483 }
484 return res;
485 }
486
487//-----------------------------------------------------------------------------
488
489}
static File getAvailableFileName(File parent, String baseName)
Define a filename that can be used, i.e., is still available, because no other file with the same pat...
Definition: FileUtils.java:729
static boolean createDirectory(String fileName)
Creates a directory.
Definition: FileUtils.java:231
static void addToRecentFiles(String fileName, FileFormat ff)
Appends an entry to the list of recent files.
Definition: FileUtils.java:67
Standardised horizontal bar with padded components, which are meant to be JButtons.
Definition: ButtonsBar.java:36
Component add(Component comp)
Definition: ButtonsBar.java:53
Remove the card from the deck of cards and takes care of removing also the entry in the list of activ...
Class of GUI panels meant to occupy one card in the deck-of-cards layout of the main panel.
GUIMainPanel mainPanel
The main panel (cards deck)
File opener for DENOPTIM GUI.
static File pickFile(Component parent)
static File pickFileForSaving(Component parent)
The main panel is a deck of cards that occupies all the GUI frame.
The collection of tunable preferences.
static String tmpSpace
Readable/writable space for tmp files.
Master form containing all sub-forms that need to be filled to define the input parameters for FragSp...
Form that allows to test the configuration of a fitness provider.
Master form containing all sub-forms that need to be filled to define the input parameters for Denopt...
Class representing the general structure of a form including a specific set of parameter collections.
Definition: GUIPrepare.java:52
FileFormat getFileFormat(String string)
RunType getAchronimFromClass()
void importParametersFromDenoptimParamsFile(File file)
GUIPrepare(GUIMainPanel mainPanel, String newPanelName)
Constructor.
Definition: GUIPrepare.java:72
boolean hasUnsavedChanges()
Check whether any of the parameter forms (i.e., a tab) in this list of tabs has unsaved changes.
static final long serialVersionUID
Version UID.
Definition: GUIPrepare.java:57
void initialize()
Initialize the panel with tabbedPane and buttons.
Definition: GUIPrepare.java:83
File instantiateParametersFile(File wrkSpace)
ProgramTask buildProgramTask(File configFile, File workDir)
The type of main to run is determined by which subclass calls this method.
JTabbedPane tabbedPane
Parameters for the various components are divided in TABs.
Definition: GUIPrepare.java:62
ArrayList< IParametersForm > allParams
Storage of parameters.
Definition: GUIPrepare.java:67
boolean printAllParamsToFile(File outFile)
Combinatorial exploration of the fragment space.
Programs that runs de novo design by a genetic algorithm.
Definition: GARunner.java:40
Task structure for any of the main programs in the denoptim project, such as genetic algorithm and co...
Manager for tasks submitted by the GUI.
File formats identified by DENOPTIM.
Definition: FileFormat.java:32
Types of runs that can be requested to the DENOPTIM Main class.
Definition: Main.java:63
GA
Run the genetic algorithm with DenoptimGA.
Definition: Main.java:72
FIT
stand-alone fitness evaluation
Definition: Main.java:83
FSE
Run a combinatorial generation of candidates with FragSpaceExplorer.
Definition: Main.java:78
Interface for parameter forms.