$darkmode
DENOPTIM
GUIGraphHandler.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.Color;
23import java.awt.Component;
24import java.awt.Cursor;
25import java.awt.Dimension;
26import java.awt.Graphics;
27import java.awt.event.ActionEvent;
28import java.awt.event.ActionListener;
29import java.io.File;
30import java.util.ArrayList;
31import java.util.HashMap;
32import java.util.List;
33import java.util.Map;
34import java.util.concurrent.atomic.AtomicInteger;
35import java.util.logging.Logger;
36
37import javax.swing.BoxLayout;
38import javax.swing.GroupLayout;
39import javax.swing.JButton;
40import javax.swing.JComboBox;
41import javax.swing.JComponent;
42import javax.swing.JLabel;
43import javax.swing.JOptionPane;
44import javax.swing.JPanel;
45import javax.swing.JScrollPane;
46import javax.swing.JSeparator;
47import javax.swing.JSpinner;
48import javax.swing.JSpinner.DefaultEditor;
49import javax.swing.SpinnerNumberModel;
50import javax.swing.SwingConstants;
51import javax.swing.UIManager;
52import javax.swing.event.ChangeEvent;
53import javax.swing.event.ChangeListener;
54
55import org.openscience.cdk.exception.CDKException;
56import org.openscience.cdk.interfaces.IAtomContainer;
57import org.openscience.cdk.interfaces.IChemObjectBuilder;
58import org.openscience.cdk.io.iterator.IteratingSMILESReader;
59import org.openscience.cdk.layout.StructureDiagramGenerator;
60import org.openscience.cdk.silent.SilentChemObjectBuilder;
61
62import denoptim.constants.DENOPTIMConstants;
63import denoptim.exception.DENOPTIMException;
64import denoptim.files.FileAndFormat;
65import denoptim.files.FileFormat;
66import denoptim.files.FileUtils;
67import denoptim.files.UndetectedFileFormatException;
68import denoptim.fragmenter.FragmenterTools;
69import denoptim.fragspace.FragmentSpace;
70import denoptim.ga.EAUtils;
71import denoptim.graph.AttachmentPoint;
72import denoptim.graph.DGraph;
73import denoptim.graph.Edge.BondType;
74import denoptim.graph.EmptyVertex;
75import denoptim.graph.GraphPattern;
76import denoptim.graph.SymmetricVertexes;
77import denoptim.graph.Template;
78import denoptim.graph.Template.ContractLevel;
79import denoptim.graph.Vertex;
80import denoptim.graph.Vertex.BBType;
81import denoptim.gui.GraphViewerPanel.LabelType;
82import denoptim.io.DenoptimIO;
83import denoptim.io.IteratingAtomContainerReader;
84import denoptim.molecularmodeling.ThreeDimTreeBuilder;
85import denoptim.programs.fragmenter.FragmenterParameters;
86import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
87
88
96public class GUIGraphHandler extends GUICardPanel
97{
101 private static final long serialVersionUID = 1L;
102
106 public static AtomicInteger graphHandlerTabUID =
107 new AtomicInteger(1);
108
112 protected ArrayList<DGraph> dnGraphLibrary =
113 new ArrayList<DGraph>();
114
119 private ArrayList<IAtomContainer> molLibrary =
120 new ArrayList<IAtomContainer>();
121
126
130 public static AtomicInteger graphUID = new AtomicInteger(1);
131
135 private int currGrphIdx = 0;
136
140 private boolean unsavedChanges = false;
141
142 // The panel that hosts graph, vertex, and molecular viewers
144
145 // The panel hosting buttons for manipulation of graphs
146 private JPanel graphCtrlPane;
147
148 // The panel hosting buttons for navigation in the list of graphs
149 private JPanel graphNavigPane;
150
151 // Components managing loading of the fragment space
152 private JButton btnFragSpace;
153 private String loadFSToolTip = "<html>Loads a space of graph building "
154 + "blocks (BB Space).<br>"
155 + "Graphs can be inspected without loading any space.<br>"
156 + "However, loading a space allows to edit and build"
157 + "graphs manually.</html>";
158
159 private JPanel pnlMouseMode;
160 private JButton btnPickMode;
161 private JButton btnMoveMode;
162
163 private JButton btnAddGraph;
164 private JButton btnGraphDel;
165
166 private JButton btnOpenGraphs;
167
168 private JSpinner graphNavigSpinner;
169 private JLabel totalGraphsLabel;
172
173 private JPanel pnlEditVrtxBtns;
174 private JButton btnAddLibVrtx;
175 private JButton btnAddEmptyVrtx;
176 private JButton btnDelSel;
177 private JButton btnAddChord;
178 private JButton btnAddSymSet;
179
180 private JPanel pnlShowLabels;
181 private JButton btnLabAPC;
182 private JButton btnLabBT;
183 private JButton btnLabBB;
184
185 private JPanel pnlSaveEdits;
186 private JButton btnSaveEdits;
187
194 private ArrayList<Vertex> compatVrtxs;
195
200 private Map<Integer,Integer> genToLocIDMap;
201
202 private boolean updateMolViewer = false;
203
204 private static final IChemObjectBuilder builder =
205 SilentChemObjectBuilder.getInstance();
206
207 private final String CONTRACTKEY = "CONTRACT";
208 private final String BBTYPEKEY = "BBTYPE";
209
210 private boolean painted;
211
215 private FragmentSpace fragSpace = null;
216
217//-----------------------------------------------------------------------------
218
219 @Override
220 public void paint(Graphics g) {
221 super.paint(g);
222
223 if (!painted) {
224 painted = true;
226 }
227 }
228
229//-----------------------------------------------------------------------------
230
235 {
236 super(mainPanel, "Graph Handler #"
237 + graphHandlerTabUID.getAndIncrement());
238 super.setLayout(new BorderLayout());
239 initialize();
240 }
241
242//-----------------------------------------------------------------------------
243
247 private void initialize()
248 {
249 // BorderLayout is needed to allow dynamic resizing!
250 this.setLayout(new BorderLayout());
251
252 // This card structure includes center, east and south panels:
253 // - (Center) where graphs/vertices/molecules are visualised
254 // - (East) graph controls
255 // - (South) general controls (load, save, close)
256
258 this.add(visualPanel,BorderLayout.CENTER);
259
260 // General panel on the right: it containing all controls
261 graphCtrlPane = new JPanel();
262 graphCtrlPane.setVisible(true);
263 graphCtrlPane.setLayout(new BoxLayout(graphCtrlPane,
264 SwingConstants.VERTICAL));
265
266 // Controls to navigate the list of dnGraphs
267 graphNavigPane = new JPanel();
268 JLabel navigationLabel1 = new JLabel("Graph ");
269 JLabel navigationLabel2 = new JLabel("Number of loaded graphs: ");
270 totalGraphsLabel = new JLabel("0");
271
272 graphNavigSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 0, 1));
273 graphNavigSpinner.setToolTipText("Move to graph number # in the "
274 + "currently loaded library.");
275 graphNavigSpinner.setMaximumSize(new Dimension(75,20));
276 graphNavigSpinner.addChangeListener(graphSpinnerListener);
277
278 btnAddGraph = new JButton("Add Graphs");
279 btnAddGraph.setToolTipText("Append a graph to the currently loaded "
280 + "list of graphs.");
281 btnAddGraph.addActionListener(new ActionListener() {
282 public void actionPerformed(ActionEvent e) {
283 String[] options = new String[]{"Build", "Convert", "File",
284 "Cancel"};
285 int res = JOptionPane.showOptionDialog(btnAddGraph,
286 "<html>Please choose whether to start creations "
287 + "of a new graph (Build), <br>"
288 + "use fragmentation to convert molecules from a "
289 + "file (Convert), <br>"
290 + "or import graph from file (File).</html>",
291 "Specify source of new graph",
292 JOptionPane.DEFAULT_OPTION,
293 JOptionPane.QUESTION_MESSAGE,
294 UIManager.getIcon("OptionPane.warningIcon"),
295 options,
296 options[3]);
297 switch (res)
298 {
299 case 0:
300 if (fragSpace==null)
301 {
302 JOptionPane.showMessageDialog(btnAddGraph,
303 "<html>No space of building blocks (BB Space) "
304 + "is currently loaded!<br>"
305 + "You must load a BB Space to build graphs "
306 + "that<br>"
307 + "contain molecular frgments. <br>"
308 + "However, without definign a BB Space, "
309 + "you can still build<br>"
310 + "graphs made of empty vertexes (i.e., "
311 + "vertexes contain<br>"
312 + "no atoms, but only attachment points)."
313 + "</html>",
314 "WARNING",
315 JOptionPane.WARNING_MESSAGE,
316 UIManager.getIcon("OptionPane.warningIcon"));
317 }
318 try
319 {
321 } catch (DENOPTIMException e1)
322 {
323 e1.printStackTrace();
324 JOptionPane.showMessageDialog(btnAddGraph,
325 "<html>Could not create graph!<br>"
326 + "Exception thrown when starting the "
327 + "construction<br>"
328 + "of a new graph. Please, report this to "
329 + "the authors.</html>",
330 "Error",
331 JOptionPane.ERROR_MESSAGE,
332 UIManager.getIcon("OptionPane.errorIcon"));
333 return;
334 }
335 break;
336
337 case 1:
338 {
339 File inFile = GUIFileOpener.pickFile(btnAddGraph);
340 if (inFile == null
341 || inFile.getAbsolutePath().equals(""))
342 {
343 return;
344 }
345
346 // All settings of the process are defined in the dialog
347 // and collected in the FragmenterParameters
349 boolean result =
351 settings,
352 this.getClass().getClassLoader(),
354 true);
355 if (!result)
356 return;
357
358 String pathnameLastUsedCutRules =
360 if (pathnameLastUsedCutRules != null
361 && !pathnameLastUsedCutRules.isBlank())
362 {
363 GUIPreferences.lastCutRulesFile =
364 new File(pathnameLastUsedCutRules);
365 }
366
367 appendGraphsFromConvertingMolecule(inFile, settings,
369 break;
370 }
371
372 case 2:
373 {
374 File inFile = GUIFileOpener.pickFileWithGraph(
376 if (inFile == null
377 || inFile.getAbsolutePath().equals(""))
378 {
379 return;
380 }
381 appendGraphsFromFile(inFile);
382 break;
383 }
384 }
385 }
386 });
387 btnGraphDel = new JButton("Remove");
388 btnGraphDel.setToolTipText("<html>Remove the present graph from the "
389 + "library.<br><br><b>WARNING:</b> this action cannot be "
390 + "undone!</html>");
391 btnGraphDel.addActionListener(new ActionListener() {
392 public void actionPerformed(ActionEvent e) {
393 try {
395 } catch (DENOPTIMException e1) {
396 System.out.println("Exception while removing the current "
397 + "graph:");
398 e1.printStackTrace();
399 }
400 }
401 });
402
403 GroupLayout lyoAddDetGraphs = new GroupLayout(graphNavigPane);
404 graphNavigPane.setLayout(lyoAddDetGraphs);
405 lyoAddDetGraphs.setAutoCreateGaps(true);
406 lyoAddDetGraphs.setAutoCreateContainerGaps(true);
407 lyoAddDetGraphs.setHorizontalGroup(lyoAddDetGraphs.createParallelGroup(
408 GroupLayout.Alignment.CENTER)
409 .addGroup(lyoAddDetGraphs.createSequentialGroup()
410 .addComponent(navigationLabel1)
411 .addComponent(graphNavigSpinner))
412 .addGroup(lyoAddDetGraphs.createSequentialGroup()
413 .addComponent(navigationLabel2)
414 .addComponent(totalGraphsLabel))
415 .addGroup(lyoAddDetGraphs.createSequentialGroup()
416 .addComponent(btnAddGraph)
417 .addComponent(btnGraphDel)));
418 lyoAddDetGraphs.setVerticalGroup(lyoAddDetGraphs.createSequentialGroup()
419 .addGroup(lyoAddDetGraphs.createParallelGroup(
420 GroupLayout.Alignment.CENTER)
421 .addComponent(navigationLabel1)
422 .addComponent(graphNavigSpinner))
423 .addGroup(lyoAddDetGraphs.createParallelGroup()
424 .addComponent(navigationLabel2)
425 .addComponent(totalGraphsLabel))
426 .addGroup(lyoAddDetGraphs.createParallelGroup()
427 .addComponent(btnAddGraph)
428 .addComponent(btnGraphDel)));
430
431
432 graphCtrlPane.add(new JSeparator());
433
434
435 JLabel mouseModeLab = new JLabel("Mouse mode:");
436 btnPickMode = new JButton("Pick");
437 btnPickMode.setToolTipText("Makes the mouse select vertex on click.");
438 btnPickMode.addActionListener(new ActionListener() {
439 @Override
440 public void actionPerformed(ActionEvent e)
441 {
442 visualPanel.setMouseMode(ModalGraphMouse.Mode.PICKING);
443 }
444 });
445 btnMoveMode = new JButton("Move");
446 btnMoveMode.setToolTipText("Makes mouse move the graph view.");
447 btnMoveMode.addActionListener(new ActionListener() {
448 @Override
449 public void actionPerformed(ActionEvent e)
450 {
451 visualPanel.setMouseMode(ModalGraphMouse.Mode.TRANSFORMING);
452 }
453 });
454 pnlMouseMode = new JPanel();
455 GroupLayout lyoMouseModeLayout = new GroupLayout(pnlMouseMode);
456 pnlMouseMode.setLayout(lyoMouseModeLayout);
457 lyoMouseModeLayout.setAutoCreateGaps(true);
458 lyoMouseModeLayout.setAutoCreateContainerGaps(true);
459 lyoMouseModeLayout.setHorizontalGroup(lyoMouseModeLayout.createParallelGroup(
460 GroupLayout.Alignment.CENTER)
461 .addComponent(mouseModeLab)
462 .addGroup(lyoMouseModeLayout.createSequentialGroup()
463 .addComponent(btnMoveMode)
464 .addComponent(btnPickMode)));
465 lyoMouseModeLayout.setVerticalGroup(lyoMouseModeLayout.createSequentialGroup()
466 .addComponent(mouseModeLab)
467 .addGroup(lyoMouseModeLayout.createParallelGroup()
468 .addComponent(btnMoveMode)
469 .addComponent(btnPickMode)));
471
472
473 graphCtrlPane.add(new JSeparator());
474
475
476 // Controls to alter the presently loaded graph (if any)
477 pnlEditVrtxBtns = new JPanel();
478 JLabel edtVertxsLab = new JLabel("Edit Graph:");
479
480 btnFragSpace = new JButton("Load BBSpace");
481 btnFragSpace.setToolTipText(loadFSToolTip);
482 btnFragSpace.addActionListener(new ActionListener() {
483 @Override
484 public void actionPerformed(ActionEvent e) {
485 try
486 {
488 } catch (Exception e1)
489 {
490 JOptionPane.showMessageDialog(btnAddLibVrtx,
491 "<html>Failed to define a space "
492 + "of building blocks from the given input.</html>",
493 "Error",
494 JOptionPane.ERROR_MESSAGE,
495 UIManager.getIcon("OptionPane.errorIcon"));
496 return;
497 }
498 btnFragSpace.setText("Change BBSpace");
499 }
500 });
501
502 btnAddLibVrtx = new JButton("Add Vertex from BBSpace");
503 btnAddLibVrtx.setToolTipText("<html>Choose a new vertex from the "
504 + "loaded space of building blocks and<br>"
505 + "append it to the "
506 + "attachment point/s selected in the current graph.<html>");
507 btnAddLibVrtx.setEnabled(false);
508 btnAddLibVrtx.addActionListener(new ActionListener() {
509 public void actionPerformed(ActionEvent e) {
510 if (fragSpace==null)
511 {
512 JOptionPane.showMessageDialog(btnAddLibVrtx,
513 "<html>No space of building blocks is currently "
514 + "loaded!<br>"
515 + "You must first load a space in order to add"
516 + "vertexes from such space.</html>",
517 "Error",
518 JOptionPane.ERROR_MESSAGE,
519 UIManager.getIcon("OptionPane.errorIcon"));
520 return;
521 }
522 ArrayList<AttachmentPoint> selAps =
524 if (selAps.size() == 0)
525 {
526 JOptionPane.showMessageDialog(btnAddLibVrtx,
527 "<html>No attachment point selected!<br>"
528 + "Drag the mouse to select APs.<br> "
529 + "Click again to unselect.</html>",
530 "Error",
531 JOptionPane.ERROR_MESSAGE,
532 UIManager.getIcon("OptionPane.errorIcon"));
533 return;
534 }
536
537 // Update viewer
539
540 // Protect edited system
541 unsavedChanges = true;
543
544 // The molecular representation is updated when we save changes
546 updateMolViewer = true;
547 }
548 });
549
550
551 btnAddEmptyVrtx = new JButton("Add Empty Vertex");
552 btnAddEmptyVrtx.setToolTipText(String.format("<html><body width='%1s'>"
553 + "Creates an empty vertex and appends it "
554 + "to the attachment points selected in the current graph.<br>"
555 + "Empty vertices have attachment points but do not contain "
556 + "atoms. Therefore, they can be used as place holders to define the "
557 + "graph structure without specifing an actual vertex."
558 + "<html>", 350));
559 btnAddEmptyVrtx.setEnabled(true);
560 btnAddEmptyVrtx.addActionListener(new ActionListener() {
561 public void actionPerformed(ActionEvent e) {
562 ArrayList<AttachmentPoint> selAps =
563 new ArrayList<AttachmentPoint> ();
564 if (dnGraph != null)
565 {
567 if (selAps.size() == 0)
568 {
569 //This would overwrite the current graph, so no-go!
570 JOptionPane.showMessageDialog(btnAddEmptyVrtx,
571 "<html>No attachment point selected!<br>"
572 + "Drag the mouse to select APs.<br> "
573 + "Click again to unselect.</html>",
574 "Error",
575 JOptionPane.ERROR_MESSAGE,
576 UIManager.getIcon("OptionPane.errorIcon"));
577 return;
578 }
579 }
581 }
582 });
583
584
585 btnDelSel = new JButton("Remove Vertex");
586 btnDelSel.setToolTipText("<html>Removes the selected vertices from "
587 + "the system.<br><br><b>WARNING:</b> this action cannot be "
588 + "undone!</html>");
589 btnDelSel.setEnabled(false);
590 btnDelSel.addActionListener(new ActionListener() {
591 public void actionPerformed(ActionEvent e) {
592 ArrayList<Vertex> selVrtx =
594 if (selVrtx.size() == 0)
595 {
596 JOptionPane.showMessageDialog(btnDelSel,
597 "<html>No vertex selected! Drag the "
598 + "mouse to select vertices."
599 + "<br>Click on background to unselect.</html>",
600 "Error",
601 JOptionPane.ERROR_MESSAGE,
602 UIManager.getIcon("OptionPane.errorIcon"));
603 return;
604 }
605
606 // Prevent removal of the scaffold
607 /*
608 DENOPTIMVertex src = dnGraph.getSourceVertex();
609 for (DENOPTIMVertex v : selVrtx)
610 {
611 if (v == src)
612 {
613 JOptionPane.showMessageDialog(btnDelSel,
614 "<html>The scaffold cannot be removed."
615 + "</html>",
616 "Error",
617 JOptionPane.ERROR_MESSAGE,
618 UIManager.getIcon("OptionPane.errorIcon"));
619 return;
620 }
621 }
622 */
623
624 for (Vertex v : selVrtx)
625 {
627 }
628
629 // Update viewer
631
632 // Protect the temporary "dnGraph" obj
633 unsavedChanges = true;
635
636 // The molecular representation is updated when we save changes
638 updateMolViewer = true;
639 }
640 });
641
642 // Controls to add chord (ring closing edge)
643 btnAddChord = new JButton("Add Chord");
644 btnAddChord.setToolTipText("<html>Add a ring-closing edge between two "
645 + "selected vertices.<html>");
646 btnAddChord.setEnabled(false);
647 btnAddChord.addActionListener(new ActionListener() {
648 public void actionPerformed(ActionEvent e) {
649 ArrayList<Vertex> selVrtxs =
651 if (selVrtxs.size() != 2)
652 {
653 JOptionPane.showMessageDialog(btnAddChord,
654 "<html>Number of selected vertices: "
655 + selVrtxs.size() + " <br>"
656 + "Please, drag the mouse and "
657 + "select only two vertices!<br> "
658 + "Click again to unselect.</html>",
659 "Error",
660 JOptionPane.ERROR_MESSAGE,
661 UIManager.getIcon("OptionPane.errorIcon"));
662 return;
663 }
664 addChordOnGraph(selVrtxs);
665
666 // Update viewer
668
669 // Protect edited system
670 unsavedChanges = true;
672
673 // The molecular representation is updated when we save changes
675 updateMolViewer = true;
676 }
677 });
678
679 // Controls to add chord (ring closing edge)
680 btnAddSymSet = new JButton("Set as Symmetric");
681 btnAddSymSet.setToolTipText("<html>Add a symmetric set that includes "
682 + "all selected vertexes.<html>");
683 btnAddSymSet.setEnabled(false);
684 btnAddSymSet.addActionListener(new ActionListener() {
685 public void actionPerformed(ActionEvent e) {
686 List<Vertex> selVrtxs =
688 if (selVrtxs.size() < 2)
689 {
690 JOptionPane.showMessageDialog(btnAddSymSet,
691 "<html>Number of selected vertices: "
692 + selVrtxs.size() + " <br>"
693 + "Please, drag the mouse and "
694 + "select two or more vertices!<br> "
695 + "Click again to unselect.</html>",
696 "Error",
697 JOptionPane.ERROR_MESSAGE,
698 UIManager.getIcon("OptionPane.errorIcon"));
699 return;
700 }
701 try
702 {
704 new SymmetricVertexes(selVrtxs));
705 } catch (DENOPTIMException e1)
706 {
707 JOptionPane.showMessageDialog(btnAddSymSet,
708 String.format("<html><body width='%1s'>"
709 + "Could not create SymmetriSet:<br>"
710 + e1.getMessage() + "</html>", 300),
711 "Error",
712 JOptionPane.ERROR_MESSAGE,
713 UIManager.getIcon("OptionPane.errorIcon"));
714 return;
715 }
716
717 // Update viewer
719
720 // Protect edited system
721 unsavedChanges = true;
723
724 // The molecular representation is updated when we save changes
726 updateMolViewer = true;
727 }
728 });
729
730
731 GroupLayout lyoEditVertxs = new GroupLayout(pnlEditVrtxBtns);
732 pnlEditVrtxBtns.setLayout(lyoEditVertxs);
733 lyoEditVertxs.setAutoCreateGaps(true);
734 lyoEditVertxs.setAutoCreateContainerGaps(true);
735 lyoEditVertxs.setHorizontalGroup(lyoEditVertxs.createParallelGroup(
736 GroupLayout.Alignment.CENTER)
737 .addComponent(edtVertxsLab)
738 .addComponent(btnFragSpace)
739 .addComponent(btnAddLibVrtx)
740 .addComponent(btnAddEmptyVrtx)
741 .addComponent(btnDelSel)
742 .addComponent(btnAddChord)
743 .addComponent(btnAddSymSet));
744 lyoEditVertxs.setVerticalGroup(lyoEditVertxs.createSequentialGroup()
745 .addComponent(edtVertxsLab)
746 .addComponent(btnFragSpace)
747 .addComponent(btnAddLibVrtx)
748 .addComponent(btnAddEmptyVrtx)
749 .addComponent(btnDelSel)
750 .addComponent(btnAddChord)
751 .addComponent(btnAddSymSet));
753
754 graphCtrlPane.add(new JSeparator());
755
756 // Controls of displayed attributes
757 pnlShowLabels = new JPanel();
758 JLabel lblShowHideLabels = new JLabel("Show/Hide labels:");
759
760 btnLabAPC = new JButton("APClass");
761 btnLabAPC.addActionListener(new showHideLabelsListener(btnLabAPC,
762 LabelType.APC));
763 btnLabAPC.setEnabled(false);
764 btnLabAPC.setToolTipText("Show/Hide attachment point class labels.");
765
766 btnLabBT = new JButton("BndTyp");
767 btnLabBT.addActionListener(new showHideLabelsListener(btnLabBT,
768 LabelType.BT));
769 btnLabBT.setEnabled(false);
770 btnLabBT.setToolTipText("Show/Hide bond type labels.");
771
772 btnLabBB = new JButton("BBID");
773 btnLabBB.addActionListener(new showHideLabelsListener(btnLabBB,
774 LabelType.BBID));
775 btnLabBB.setEnabled(false);
776 btnLabBB.setToolTipText("Show/Hide building block ID labels.");
777
778 GroupLayout lyoShowAttr = new GroupLayout(pnlShowLabels);
779 pnlShowLabels.setLayout(lyoShowAttr);
780 lyoShowAttr.setAutoCreateGaps(true);
781 lyoShowAttr.setAutoCreateContainerGaps(true);
782 lyoShowAttr.setHorizontalGroup(lyoShowAttr.createParallelGroup(
783 GroupLayout.Alignment.CENTER)
784 .addComponent(lblShowHideLabels)
785 .addComponent(btnLabAPC)
786 .addComponent(btnLabBT)
787 .addComponent(btnLabBB));
788 lyoShowAttr.setVerticalGroup(lyoShowAttr.createSequentialGroup()
789 .addComponent(lblShowHideLabels)
790 .addComponent(btnLabAPC)
791 .addComponent(btnLabBT)
792 .addComponent(btnLabBB));
794
795 graphCtrlPane.add(new JSeparator());
796
797 // Control for unsaved changes
798 pnlSaveEdits = new JPanel();
799 btnSaveEdits = new JButton("Save Changes");
800 btnSaveEdits.setForeground(Color.RED);
801 btnSaveEdits.setEnabled(false);
802 btnSaveEdits.setToolTipText("<html>Save the current graph replacing"
803 + " <br>the original one in the currently loaded library.</html>");
804 btnSaveEdits.addActionListener(new ActionListener() {
805 public void actionPerformed(ActionEvent e) {
807 }
808 });
811 this.add(graphCtrlPane,BorderLayout.EAST);
812
813 // Panel with buttons to the bottom of the frame
814 ButtonsBar commandsPane = new ButtonsBar();
815 super.add(commandsPane, BorderLayout.SOUTH);
816
817 btnOpenGraphs = new JButton("Import Graphs");
818 btnOpenGraphs.setToolTipText("Reads graphs or structures from file.");
819 btnOpenGraphs.addActionListener(new ActionListener() {
820 public void actionPerformed(ActionEvent e) {
821 File inFile = GUIFileOpener.pickFile(btnOpenGraphs);
822 if (inFile == null || inFile.getAbsolutePath().equals(""))
823 {
824 return;
825 }
826 importGraphsFromFile(inFile);
827 }
828 });
829 commandsPane.add(btnOpenGraphs);
830
831 JButton btnSaveGraphs = new JButton("Export Graphs");
832 btnSaveGraphs.setToolTipText("Write all graphs to a file.");
833 btnSaveGraphs.addActionListener(new ActionListener() {
834 public void actionPerformed(ActionEvent e) {
835 FileAndFormat fileAndFormat =
837 if (fileAndFormat == null)
838 {
839 return;
840 }
841 File outFile = fileAndFormat.file;
842 try
843 {
844 outFile = DenoptimIO.writeGraphsToFile(outFile,
845 fileAndFormat.format, dnGraphLibrary,
846 Logger.getLogger("GUILogger"),
847 GUI.PRNG);
848 }
849 catch (Exception ex)
850 {
851 JOptionPane.showMessageDialog(btnSaveGraphs,
852 "Could not write to '" + outFile + "'!.",
853 "Error",
854 JOptionPane.PLAIN_MESSAGE,
855 UIManager.getIcon("OptionPane.errorIcon"));
856 return;
857 }
859 unsavedChanges = false;
860 FileUtils.addToRecentFiles(outFile, fileAndFormat.format);
861 }
862 });
863 commandsPane.add(btnSaveGraphs);
864
865 JButton btnSaveVrtxs = new JButton("Export Vertexes");
866 btnSaveVrtxs.setToolTipText("Write all graphs to a file.");
867 btnSaveVrtxs.addActionListener(new ActionListener() {
868 public void actionPerformed(ActionEvent e) {
869 FileAndFormat fileAndFormat =
871 if (fileAndFormat == null)
872 {
873 return;
874 }
875 File outFile = fileAndFormat.file;
876 try
877 {
878 List<Vertex> vertexes = new ArrayList<Vertex>();
879 for (DGraph graph : dnGraphLibrary)
880 {
881 vertexes.addAll(graph.getVertexList());
882 }
883 outFile = DenoptimIO.writeVertexesToFile(outFile,
884 fileAndFormat.format, vertexes, false);
885 }
886 catch (Exception ex)
887 {
888 ex.printStackTrace();
889 JOptionPane.showMessageDialog(btnSaveVrtxs,
890 "Could not write to '" + outFile + "'!",
891 "Error",
892 JOptionPane.PLAIN_MESSAGE,
893 UIManager.getIcon("OptionPane.errorIcon"));
894 return;
895 }
897 unsavedChanges = false;
898 FileUtils.addToRecentFiles(outFile, fileAndFormat.format);
899 }
900 });
901 commandsPane.add(btnSaveVrtxs);
902
903 JButton btnSaveTmpl = new JButton("Export Templates");
904 btnSaveTmpl.setToolTipText("Make templates from the graphs and same "
905 + "them to file");
906 btnSaveTmpl.addActionListener(new ActionListener() {
907 public void actionPerformed(ActionEvent e) {
908
909 ConfigTemplateDialog tmplPropDialog = new ConfigTemplateDialog(
910 btnSaveTmpl, dnGraphLibrary.size());
911 tmplPropDialog.pack();
912 Object o = tmplPropDialog.showDialog();
913 if (o == null)
914 {
915 return;
916 }
917
918 @SuppressWarnings("unchecked")
919 Map<String,List<Object>> configs = (Map<String,List<Object>>) o;
920
921 ArrayList<Vertex> templates =
922 new ArrayList<Vertex>();
923 for (int i=0; i<dnGraphLibrary.size(); i++)
924 {
925 Template t = new Template(
926 (BBType) configs.get(BBTYPEKEY).get(i));
929 configs.get(CONTRACTKEY).get(i));
930 templates.add(t);
931 }
932
933 FileAndFormat fileAndFormat =
935 if (fileAndFormat == null)
936 {
937 return;
938 }
939 File outFile = fileAndFormat.file;
940 try
941 {
942 // The writing method may change the extension. So we need
943 // to get the return value.
944 outFile = DenoptimIO.writeVertexesToFile(outFile,
945 fileAndFormat.format,
946 templates);
947 }
948 catch (Exception ex)
949 {
950 ex.printStackTrace();
951 JOptionPane.showMessageDialog(btnSaveTmpl,
952 "Could not write to '" + outFile + "'! "
953 + "Hint: "+ex.getMessage(),
954 "Error",
955 JOptionPane.ERROR_MESSAGE,
956 UIManager.getIcon("OptionPane.errorIcon"));
957 return;
958 }
960 unsavedChanges = false;
961 FileUtils.addToRecentFiles(outFile, fileAndFormat.format);
962 }
963 });
964 commandsPane.add(btnSaveTmpl);
965
966 JButton btnCanc = new JButton("Close Tab");
967 btnCanc.setToolTipText("Closes this graph handler.");
968 btnCanc.addActionListener(new removeCardActionListener(this));
969 commandsPane.add(btnCanc);
970
971 JButton btnHelp = new JButton("?");
972 btnHelp.setToolTipText("<html>Hover over the buttons and fields "
973 + "to get a tip.</html>");
974 btnHelp.addActionListener(new ActionListener() {
975 public void actionPerformed(ActionEvent e) {
976 String txt = "<html><body width='%1s'>"
977 + "<p>This tab allows to create, inspect, and edit "
978 + "the graphs that DENOPTIM used to define candidate "
979 + "items, such as molecules.</p>"
980 + "<br>"
981 + "<p>In general, you can hover over any button or"
982 + "viewer to get a tip on its usage.</p>"
983 + "<br>"
984 + "<p>DENOPTIMGraphs is drawn in the "
985 + "central panel (i.e., the graph viewer). "
986 + "Each vertex is shown as a rounded square, and each "
987 + "edge as an arrow (or a line, for undirected edges)."
988 + " The color of a node represent the type of building"
989 + "block:<ul>"
990 + "<li>red for the scaffold,</li>"
991 + "<li>orange for ring-closing vertices,</li>"
992 + "<li>green for capping groups,</li>"
993 + "<li>blue for standard fragments,</li>"
994 + "<li>yellow for attachment points.</li>"
995 + "</ul></p>"
996 + "<p>If the loaded DENOPTIMGraph is associated with "
997 + "a chemical structure, the latter is shown in the "
998 + "molecular viewer (bottom-left panel).</p>"
999 + "<p>The content of a vertex in the graph viewer, "
1000 + "i.e., a molecular fragment or an embedded graph, "
1001 + "can be shown in the vertex viewer (top-left panel) "
1002 + "upon selecting (see below) that vertex in the graph "
1003 + "viewer. </p>"
1004 + "<p>A space of building blocks must be loaded to "
1005 + "enable inspection of graph vertexes that depend on"
1006 + "a building block space.</p>"
1007 + "<br>"
1008 + "<p><b>Control the graph view</b></p>"
1009 + "<ul>"
1010 + "<li>Use mouse mode <i>Pick</i> to enable selection "
1011 + "of vertexes by single left click.</li>"
1012 + "<li>Use mouse mode <i>Move</i> to drag the graph in "
1013 + "any direction, <code>ALT</code>+drag to rotate, and "
1014 + "<code>CTRL</code>+drag to skew the graph. Wheel, or "
1015 + "analogous, to zoom in/out.</li>"
1016 + "</ul>Mouse mode can be changed also by double click "
1017 + "in the graph area, away from any vertex/edge, and "
1018 + "hitting <code>p</code> for <i>Pick</i> or "
1019 + "<code>t</code> for <i>Move</i> "
1020 + "(or <i>Transform</i>).</p>"
1021 + "<p>Right-click in the graph viewer shows a menu "
1022 + "with shortcuts to refine node location, or "
1023 + "show/hide graph labels.</p>"
1024 + "<br>"
1025 + "<p><b>Control the fragment and molecular views</b>"
1026 + "</p>"
1027 + "<p>Right-click on the Jmol viewer will open the "
1028 + "Jmol menu. However, any change on the molecular "
1029 + "object will not be saved.</p></html>";
1030 JOptionPane.showMessageDialog(btnHelp,
1031 String.format(txt, 500),
1032 "Tips",
1033 JOptionPane.PLAIN_MESSAGE);
1034 }
1035 });
1036 commandsPane.add(btnHelp);
1037 }
1038
1039//-----------------------------------------------------------------------------
1040
1041 private class showHideLabelsListener implements ActionListener
1042 {
1043 private JComponent parent;
1045 private Map<LabelType,Boolean> lastIteration = new HashMap<>();
1046
1048 {
1049 this.labTyp = labTyp;
1050 this.parent = parent;
1051 for (LabelType lt : LabelType.values())
1052 lastIteration.put(lt, false);
1053 }
1054
1055 @Override
1056 public void actionPerformed(ActionEvent e) {
1058 {
1059 boolean show = !lastIteration.get(labTyp);
1061 lastIteration.put(labTyp,show);
1062 }
1063 else
1064 {
1065 JOptionPane.showMessageDialog(parent,
1066 "<html>No elements selected! Drag the "
1067 + "mouse to select elements."
1068 + "<br>Click on background to unselect.</html>",
1069 "Error",
1070 JOptionPane.ERROR_MESSAGE,
1071 UIManager.getIcon("OptionPane.errorIcon"));
1072 }
1073 }
1074 }
1075
1076//-----------------------------------------------------------------------------
1077
1078 private void enableGraphDependentButtons(boolean enable)
1079 {
1080 btnAddLibVrtx.setEnabled(enable);
1081 //btnAddEmptyVrtx.setEnabled(enable); //Always enabled
1082 btnDelSel.setEnabled(enable);
1083 btnAddChord.setEnabled(enable);
1084 btnAddSymSet.setEnabled(enable);
1085 btnLabAPC.setEnabled(enable);
1086 btnLabBT.setEnabled(enable);
1087 btnLabBB.setEnabled(enable);
1088 }
1089
1090//-----------------------------------------------------------------------------
1091
1093 ArrayList<AttachmentPoint> selAps)
1094 {
1095 GUIEmptyVertexMaker makeEmptyVertexDialog =
1096 new GUIEmptyVertexMaker(this, selAps.size()==0);
1097 makeEmptyVertexDialog.pack();
1098 Object evObj = makeEmptyVertexDialog.showDialog();
1099 if (evObj == null)
1100 {
1101 return;
1102 }
1103 Vertex ev = (EmptyVertex) evObj;
1104 ArrayList<Vertex> lst = new ArrayList<Vertex>(1);
1105 lst.add(ev);
1106 GUIVertexSelector fragSelector = new GUIVertexSelector(this, false);
1107 fragSelector.ctrlPane.setVisible(false);
1108 if (selAps.size() == 0)
1109 {
1110 fragSelector.btnDone.setText("Confirm");
1111 fragSelector.setRequireApSelection(false);
1112 } else {
1113 fragSelector.btnDone.setText("Confirm Selected AP");
1114 fragSelector.setRequireApSelection(true);
1115 }
1116 fragSelector.load(lst, 0);
1117 Object selected = fragSelector.showDialog();
1118 if (selected == null)
1119 {
1120 return;
1121 }
1122
1123 @SuppressWarnings("unchecked")
1124 ArrayList<Integer> trgFragApId =
1125 ((ArrayList<ArrayList<Integer>>)selected).get(0);
1126 int incomingAPId = trgFragApId.get(1);
1127
1128 if (selAps.size() == 0)
1129 {
1130 currGrphIdx = dnGraphLibrary.size();
1132 try
1133 {
1134 dnGraph.addVertex(ev);
1135 } catch (DENOPTIMException e1)
1136 {
1137 e1.printStackTrace();
1138 JOptionPane.showMessageDialog(this,"Could not make the "
1139 + "new graph. " + e1.getMessage(),
1140 "Error",
1141 JOptionPane.PLAIN_MESSAGE,
1142 UIManager.getIcon("OptionPane.errorIcon"));
1143 return;
1144 }
1145 } else {
1146 extendCurrentGraph(ev.getAP(incomingAPId), selAps);
1147 }
1148
1149 // Update viewer
1152
1153 // Protect edited system
1154 unsavedChanges = true;
1156
1157 // The molecular representation is updated when we save changes
1159 updateMolViewer = true;
1160 }
1161
1162//-----------------------------------------------------------------------------
1163
1169 throws DENOPTIMException
1170 {
1171 BBType rootType = BBType.SCAFFOLD;
1172 String msg = "<html><body width='%1s'>"
1173 + "Please choose the type of building block to use as first "
1174 + "vertex of the graph.";
1175 String[] options = null;
1176 String defaultOpt = null;
1177 if (fragSpace!=null)
1178 {
1179 options = new String[]{"Scaffold", "Fragment", "EmptyVertex",
1180 "Cancel"};
1181 defaultOpt = options[3];
1182 msg = msg + "Use a scaffold if the graph is meant to "
1183 + "represent a necessary portion of a candidate entity.</html>";
1184 } else {
1185 options = new String[]{"EmptyVertex", "Cancel"};
1186 defaultOpt = options[1];
1187 }
1188 int res = JOptionPane.showOptionDialog(this,String.format(msg,350),
1189 "Specify type of initial building block",
1190 JOptionPane.DEFAULT_OPTION,
1191 JOptionPane.QUESTION_MESSAGE,
1192 UIManager.getIcon("OptionPane.warningIcon"),
1193 options,
1194 defaultOpt);
1195 if (fragSpace==null)
1196 {
1197 res = res + 10;
1198 }
1199
1200 ArrayList<Vertex> vrtxLib = new ArrayList<Vertex>();
1201 switch (res)
1202 {
1203 case 0:
1204 rootType = BBType.SCAFFOLD;
1206 {
1207 vrtxLib.add(bb.clone());
1208 }
1209 break;
1210
1211 case 1:
1212 rootType = BBType.FRAGMENT;
1214 {
1215 vrtxLib.add(bb.clone());
1216 }
1217 break;
1218
1219 case 10:
1220 case 2:
1221 // In this case we do not use the fragment space. So, all the
1222 // index-based operations on the fragment space that are done
1223 // after this 'switch' block make no sense. Instead, we use the
1224 // same method called by the "Add Empty Vertex" button.
1225 ArrayList<AttachmentPoint> selectedAPs = new ArrayList<>();
1227 return;
1228
1229 case 11:
1230 case 3:
1231 return;
1232 }
1233 if (vrtxLib.size() == 0)
1234 {
1235 JOptionPane.showMessageDialog(this,"No building blocks of the "
1236 + "choosen type.",
1237 "Error",
1238 JOptionPane.PLAIN_MESSAGE,
1239 UIManager.getIcon("OptionPane.errorIcon"));
1240 return;
1241 }
1242
1243 // Select the scaffold
1244 GUIVertexSelector fragSelector = new GUIVertexSelector(this, false);
1245 fragSelector.setRequireApSelection(false);
1246 fragSelector.load(vrtxLib, 0);
1247 Object selected = fragSelector.showDialog();
1248 if (selected == null)
1249 {
1250 return;
1251 }
1252
1253 @SuppressWarnings("unchecked")
1254 ArrayList<Integer> trgFragApId = ((ArrayList<ArrayList<Integer>>)selected)
1255 .get(0);
1256 int scaffFragId = trgFragApId.get(0);
1257
1258 // Create the new graph
1259 currGrphIdx = dnGraphLibrary.size();
1261
1262 // Create the node
1263 int firstBBId = 1;
1264 Vertex firstVertex = null;
1265 try
1266 {
1267 firstVertex = Vertex.newVertexFromLibrary(
1268 firstBBId, scaffFragId, rootType, fragSpace);
1269 } catch (DENOPTIMException e)
1270 {
1271 JOptionPane.showMessageDialog(this,"Could not retrieve the "
1272 + "requested building blocks. " + e.getMessage(),
1273 "Error",
1274 JOptionPane.PLAIN_MESSAGE,
1275 UIManager.getIcon("OptionPane.errorIcon"));
1276 return;
1277 }
1278
1279 dnGraph.addVertex(firstVertex);
1280
1281 // Put the graph to the viewer
1284 unsavedChanges = true;
1285 updateMolViewer = true;
1287 }
1288
1289//-----------------------------------------------------------------------------
1290
1292 {
1293 dnGraph = new DGraph();
1294 dnGraph.setGraphId(graphUID.getAndIncrement());
1295 // Add new graph and corresponding mol representation (must exist)
1297 //NB: we add an empty molecular representation to keep the list
1298 // of graphs and that of mol.rep. in sync
1299 molLibrary.add(builder.newAtomContainer());
1302 }
1303
1304//-----------------------------------------------------------------------------
1305
1311 private void addChordOnGraph(ArrayList<Vertex> rcvs)
1312 {
1313 if (rcvs.size() != 2)
1314 {
1315 JOptionPane.showMessageDialog(this,
1316 "<html>Number of selected vertices: "
1317 + rcvs.size() + " <br>"
1318 + "Please, drag the mouse and "
1319 + "select only two vertices!<br> "
1320 + "Click again to unselect.</html>",
1321 "Error",
1322 JOptionPane.ERROR_MESSAGE,
1323 UIManager.getIcon("OptionPane.errorIcon"));
1324 return;
1325 }
1326
1327 try
1328 {
1329 dnGraph.addRing(rcvs.get(0), rcvs.get(1));
1330 } catch (DENOPTIMException e)
1331 {
1333 dnGraph.addRing(rcvs.get(0), rcvs.get(1), bt);
1334 }
1335 }
1336
1337//-----------------------------------------------------------------------------
1338
1346 ArrayList<AttachmentPoint> selAps)
1347 {
1348 // For extensions of existing graphs we need to know where to extend
1349 if (selAps.size() == 0)
1350 {
1351 JOptionPane.showMessageDialog(this,"No AP selected in the "
1352 + "graph.",
1353 "Error",
1354 JOptionPane.PLAIN_MESSAGE,
1355 UIManager.getIcon("OptionPane.errorIcon"));
1356 return;
1357 }
1358
1359 // Create clones of fragments and put the into 'compatFrags'
1361
1362 ArrayList<Vertex> vertxLib = new ArrayList<Vertex>();
1363 String[] options = new String[]{"Any Vertex",
1364 "Compatible Vertices ("+compatVrtxs.size()+")",
1365 "Capping group"};
1366 int res = JOptionPane.showOptionDialog(this,
1367 "<html>Choose a subset of possible vertices:</html>",
1368 "Choose Vertex Subset",
1369 JOptionPane.DEFAULT_OPTION,
1370 JOptionPane.QUESTION_MESSAGE,
1371 UIManager.getIcon("OptionPane.warningIcon"),
1372 options,
1373 options[0]);
1374
1375 switch (res)
1376 {
1377 case 0:
1378 vertxLib = new ArrayList<Vertex>();
1380 {
1381 vertxLib.add(bb.clone());
1382 }
1383 break;
1384
1385 case 1:
1386 vertxLib = compatVrtxs;
1387 break;
1388
1389 case 2:
1390 vertxLib = new ArrayList<Vertex>();
1392 {
1393 vertxLib.add(bb.clone());
1394 }
1395 break;
1396 default:
1397 return;
1398 }
1399
1400 if (vertxLib.size() == 0)
1401 {
1402 JOptionPane.showMessageDialog(this,"No vertexes in the library",
1403 "Error",
1404 JOptionPane.PLAIN_MESSAGE,
1405 UIManager.getIcon("OptionPane.errorIcon"));
1406 return;
1407 }
1408
1409 // Select the incoming fragment and its AP to use
1410
1411 GUIVertexSelector fragSelector = new GUIVertexSelector(this,false);
1412 fragSelector.setRequireApSelection(true);
1413 fragSelector.load(vertxLib, 0);
1414 Object selected = fragSelector.showDialog();
1415 if (selected == null)
1416 {
1417 return;
1418 }
1419 @SuppressWarnings("unchecked")
1420 ArrayList<Integer> trgFragApId =
1421 ((ArrayList<ArrayList<Integer>>)selected).get(0);
1422 Vertex chosenVrtx = vertxLib.get(trgFragApId.get(0));
1423
1424 extendCurrentGraph(chosenVrtx.getAP(trgFragApId.get(1)),selAps);
1425 }
1426
1427//-----------------------------------------------------------------------------
1428
1429 private void extendCurrentGraph(AttachmentPoint apOnIncomingVrtx,
1430 ArrayList<AttachmentPoint> selAps)
1431 {
1432 Vertex chosenVrtx = apOnIncomingVrtx.getOwner();
1433 if (chosenVrtx == null)
1434 return;
1435
1436 int apIdOnIncVrtx = apOnIncomingVrtx.getIndexInOwner();
1437
1438 for (int i=0; i<selAps.size(); i++)
1439 {
1440 AttachmentPoint srcAp = selAps.get(i);
1441 Vertex trgVertex = chosenVrtx.clone();
1442 trgVertex.setVertexId(dnGraph.getMaxVertexId()+1);
1443 AttachmentPoint trgAp = trgVertex.getAP(apIdOnIncVrtx);
1444 try
1445 {
1446 dnGraph.appendVertexOnAP(srcAp, trgAp);
1447 } catch (DENOPTIMException e) {
1448 JOptionPane.showMessageDialog(this,"Unable to make new edge. "
1449 + e.getMessage(),
1450 "Error",
1451 JOptionPane.PLAIN_MESSAGE,
1452 UIManager.getIcon("OptionPane.errorIcon"));
1453 return;
1454 }
1455 }
1456 }
1457
1458//-----------------------------------------------------------------------------
1459
1461 ArrayList<AttachmentPoint> srcAPs)
1462 {
1463 compatVrtxs = new ArrayList<Vertex>();
1464
1465 // WARNING: here I re-do most of what is already done in
1466 // FragmentSpace.getFragmentsCompatibleWithTheseAPs.
1467 // However, here we add additional data to (clones) of the
1468 // fragments, so that I can easily highlight the compatible APs in
1469 // the selection GUI.
1470
1471 // First we get all possible APs on any fragment
1472 ArrayList<AttachmentPoint> compatAps =
1474
1475 // then keep unique fragment identifiers, and store unique
1476 genToLocIDMap = new HashMap<Integer,Integer>();
1477
1478 String PRESELPROP = GUIVertexSelector.PRESELECTEDAPSFIELD;
1479 String PRESELPROPSEP = GUIVertexSelector.PRESELECTEDAPSFIELDSEP;
1480
1481 for (AttachmentPoint ap : compatAps)
1482 {
1483 int vId = ap.getOwner().hashCode();
1484 int apId = ap.getOwner().getIndexOfAP(ap);
1485 if (genToLocIDMap.keySet().contains(vId))
1486 {
1487 Vertex vrtx = compatVrtxs.get(genToLocIDMap.get(vId));
1488 String prop = vrtx.getProperty(PRESELPROP).toString();
1489 vrtx.setProperty(PRESELPROP,prop+PRESELPROPSEP+apId);
1490 }
1491 else
1492 {
1493 Vertex bb = ap.getOwner().clone();
1494 bb.setProperty(PRESELPROP,apId);
1495 genToLocIDMap.put(vId,compatVrtxs.size());
1496 compatVrtxs.add(bb);
1497 }
1498 }
1499 }
1500
1501//-----------------------------------------------------------------------------
1502
1507 public void importGraphsFromFile(File file)
1508 {
1510
1511 try {
1512 switch (FileUtils.detectFileFormat(file))
1513 {
1514 case GRAPHSDF:
1515 molLibrary = DenoptimIO.readSDFFile(file.getAbsolutePath());
1516 break;
1517
1518 case GRAPHJSON:
1520 Logger.getLogger("GUILogger"), GUI.PRNG);
1521 for (int i=0; i<dnGraphLibrary.size(); i++)
1522 {
1524 dnGraphLibrary.get(i),true));
1525 }
1526 break;
1527
1528 case CANDIDATESDF:
1529 molLibrary = DenoptimIO.readSDFFile(file.getAbsolutePath());
1530 break;
1531
1532 default:
1533 for (int i=0; i<dnGraphLibrary.size(); i++)
1534 {
1535 molLibrary.add(builder.newAtomContainer());
1536 }
1537 }
1538 } catch (Throwable e) {
1539 System.out.println("Could not read graphs from " + file);
1540 for (int i=0; i<dnGraphLibrary.size(); i++)
1541 {
1542 molLibrary.add(builder.newAtomContainer());
1543 }
1544 mainPanel.setCursor(Cursor.getPredefinedCursor(
1545 Cursor.DEFAULT_CURSOR));
1546 }
1547
1548 // Display the first
1549 currGrphIdx = 0;
1550
1553 }
1554
1555//-----------------------------------------------------------------------------
1556
1557 private void appendGraphsFromConvertingMolecule(File file,
1558 FragmenterParameters frgParams, Component parent)
1559 {
1560 // Reading molecules is format-agnostic manner
1561 List<IAtomContainer> mols = new ArrayList<IAtomContainer>();
1562 boolean make2D = false;
1563 StructureDiagramGenerator sdg = null;
1564 IteratingAtomContainerReader iterMolsToFragment = null;
1565 try
1566 {
1567 iterMolsToFragment = new IteratingAtomContainerReader(file);
1568 if (iterMolsToFragment.getIteratorType().equals(
1569 IteratingSMILESReader.class))
1570 {
1571 frgParams.setWorkingIn3D(false);
1572 frgParams.setAddExplicitH(true);
1573 make2D = true;
1574 sdg = new StructureDiagramGenerator();
1575 }
1576 } catch (Exception e1)
1577 {
1578 String msg = "<html><body width='%1s'>Could not read molecules "
1579 + "from '" + file.getAbsolutePath() + "' and convert them "
1580 + "to graphs.</html>";
1581 JOptionPane.showMessageDialog(parent, String.format(msg,400),
1582 "Error",
1583 JOptionPane.ERROR_MESSAGE,
1584 UIManager.getIcon("OptionPane.errorIcon"));
1585 return;
1586 }
1587
1588 // Make empty fragment space or use the loaded one to identify capping
1589 if (fragSpace == null)
1590 {
1591 fragSpace = new FragmentSpace();
1592 }
1593
1594 // Read and convert molecules one by one
1595 List<DGraph> graphs = new ArrayList<DGraph>();
1596 int i=0;
1597 while (iterMolsToFragment.hasNext())
1598 {
1599 i++;
1600 IAtomContainer mol = iterMolsToFragment.next();
1601 FragmenterTools.prepareMolToFragmentation(mol, frgParams, i);
1602 if (make2D)
1603 {
1604 try
1605 {
1606 sdg.generateCoordinates(mol);
1607 } catch (CDKException e)
1608 {
1609 // Ignore
1610 e.printStackTrace();
1611 }
1612 }
1613 DGraph graph = null;
1614 try {
1616 frgParams.getCuttingRules(), frgParams.getLogger(),
1617 frgParams.getScaffoldingPolicy(),
1618 frgParams.getLinearAngleLimit(),
1619 fragSpace);
1620 } catch (DENOPTIMException de)
1621 {
1622 String msg = "<html><body width='%1s'>Unable to convert "
1623 + "molecule " + i + " (" + mol.getAtomCount()
1624 + " atoms) to DENOPTIM graph. " + de.getMessage()
1625 + "</html>";
1626 JOptionPane.showMessageDialog(parent, String.format(msg,400),
1627 "Error",
1628 JOptionPane.WARNING_MESSAGE,
1629 UIManager.getIcon("OptionPane.warningIcon"));
1630 continue;
1631 }
1632
1633 if (frgParams.embedRingsInTemplate())
1634 {
1635 try {
1636 DGraph modGraph = graph.embedPatternsInTemplates(
1638 fragSpace, frgParams.getEmbeddedRingsContract());
1639 graph = modGraph;
1640 } catch (DENOPTIMException e) {
1641 String msg = "<html><body width='%1s'>Unable to embed "
1642 + "ring systems of molecule " + i
1643 + " (" + mol.getAtomCount()
1644 + " atoms) into Templates. Returning graph without "
1645 + "embedding of rings. " + e.getMessage()
1646 + "</html>";
1647 JOptionPane.showMessageDialog(parent, String.format(msg,400),
1648 "Error",
1649 JOptionPane.WARNING_MESSAGE,
1650 UIManager.getIcon("OptionPane.warningIcon"));
1651 }
1652 }
1653
1654 graphs.add(graph);
1655 mols.add(mol);
1656 }
1657
1658 // Signal no result obtained
1659 if (graphs.size() < 1)
1660 {
1661 JOptionPane.showMessageDialog(parent,
1662 "<html>Conversion produced no graphs!</html>",
1663 "Error",
1664 JOptionPane.WARNING_MESSAGE,
1665 UIManager.getIcon("OptionPane.warningIcon"));
1666 return;
1667 }
1668
1669 //
1670 int oldSize = dnGraphLibrary.size();
1671 if (graphs.size() > 0)
1672 {
1673 dnGraphLibrary.addAll(graphs);
1674 molLibrary.addAll(mols);
1675
1676 // WE choose to display the first of the imported ones
1677 currGrphIdx = oldSize;
1678
1681 }
1682 }
1683
1684//-----------------------------------------------------------------------------
1685
1686 private void appendGraphsFromFile(File file)
1687 {
1688 // Reading graphs is format-agnostic
1689 ArrayList<DGraph> graphs = readGraphsFromFile(file);
1690
1691 // Try to read or make molecular representations
1692 ArrayList<IAtomContainer> mols = new ArrayList<IAtomContainer>();
1693 FileFormat ff = null;
1694 try
1695 {
1696 ff = FileUtils.detectFileFormat(file);
1697 } catch (Exception e1)
1698 {
1699 // we'll ignore the format specific tasks
1700 }
1701 switch (ff)
1702 {
1703 case GRAPHSDF:
1704 try {
1706 file.getAbsolutePath()));
1707 } catch (DENOPTIMException e) {
1708 System.err.println("WARNING: Could not read molecular "
1709 + "representation from " + file);
1710 for (int i=0; i<graphs.size(); i++)
1711 {
1712 molLibrary.add(builder.newAtomContainer());
1713 }
1714 }
1715 break;
1716
1717 default:
1718 // Add empty place holders
1719 for (int i=0; i<graphs.size(); i++)
1720 {
1721 molLibrary.add(builder.newAtomContainer());
1722 }
1723 break;
1724 }
1725
1726 int oldSize = dnGraphLibrary.size();
1727 if (graphs.size() > 0)
1728 {
1729 dnGraphLibrary.addAll(graphs);
1730 molLibrary.addAll(mols);
1731
1732 // WE choose to display the first of the imported ones
1733 currGrphIdx = oldSize;
1734
1737 }
1738 }
1739
1740//-----------------------------------------------------------------------------
1741
1742 private ArrayList<DGraph> readGraphsFromFile(File file)
1743 {
1744 ArrayList<DGraph> graphs = new ArrayList<DGraph>();
1745 try
1746 {
1747 try
1748 {
1749 graphs = DenoptimIO.readDENOPTIMGraphsFromFile(file);
1750 }
1752 {
1753 String[] options = {"Abandon", "SDF", "JSON"};
1754 int res = JOptionPane.showOptionDialog(this,
1755 "<html>Failed to detect file type from file's "
1756 + "extension.<br>"
1757 + "Please, tell me how to interpret file <br>"
1758 + "'" + file.getAbsolutePath() + "'<br>"
1759 + "or 'Abandon' to give up.</html>",
1760 "Specify File Type",
1761 JOptionPane.DEFAULT_OPTION,
1762 JOptionPane.QUESTION_MESSAGE,
1763 UIManager.getIcon("OptionPane.warningIcon"),
1764 options,
1765 options[0]);
1766 switch (res)
1767 {
1768 case 0:
1769 graphs = new ArrayList<DGraph>();
1770 break;
1771
1772 case 1:
1774 file.getAbsolutePath());
1775 break;
1776
1777 case 2:
1779 file.getAbsolutePath());
1780 break;
1781 }
1782 }
1783 }
1784 catch (Exception e)
1785 {
1786 e.printStackTrace();
1787 String msg = "<html><body width='%1s'>Could not read graph from "
1788 + "file <br> "
1789 + "'" + file.getAbsolutePath()
1790 + "'<br>Hint on cause: ";
1791 msg = msg + e.getClass().getName()+ " (";
1792 if (e.getCause() != null)
1793 {
1794 msg = msg + e.getCause();
1795 }
1796 if (e.getMessage() != null)
1797 {
1798 msg = msg + " " + e.getMessage();
1799 }
1800 msg = msg + ")";
1801 msg = msg + "</html>";
1802 JOptionPane.showMessageDialog(this,String.format(msg,400),
1803 "Error",
1804 JOptionPane.PLAIN_MESSAGE,
1805 UIManager.getIcon("OptionPane.errorIcon"));
1806 }
1807 return graphs;
1808 }
1809
1810//-----------------------------------------------------------------------------
1811
1815 private void loadCurrentGraphIdxToViewer(boolean keepSprites)
1816 {
1817 if (dnGraphLibrary == null)
1818 {
1819 JOptionPane.showMessageDialog(this,
1820 "No list of graphs loaded.",
1821 "Error",
1822 JOptionPane.PLAIN_MESSAGE,
1823 UIManager.getIcon("OptionPane.errorIcon"));
1824 return;
1825 }
1826
1827 // Clears the "dnGraph" and GUI components, but keep memory of the
1828 // status of the graph of an easy recovery
1830
1832
1833 if (molLibrary.get(currGrphIdx).getAtomCount() > 0)
1834 {
1836 molLibrary.get(currGrphIdx), keepSprites);
1837 } else {
1839 keepSprites);
1840 }
1841
1843 }
1844
1845//-----------------------------------------------------------------------------
1846
1851 private void clearCurrentSystem()
1852 {
1853 // Get rid of currently loaded graph
1854 dnGraph = null;
1856 }
1857
1858//-----------------------------------------------------------------------------
1859
1861 {
1862 graphNavigSpinner.setModel(new SpinnerNumberModel(currGrphIdx+1, 1,
1863 dnGraphLibrary.size(), 1));
1864 totalGraphsLabel.setText(Integer.toString(dnGraphLibrary.size()));
1865 }
1866
1867//-----------------------------------------------------------------------------
1868
1869 private class GraphSpinnerChangeEvent implements ChangeListener
1870 {
1871 private boolean inEnabled = true;
1872
1874 {}
1875
1881 public void setEnabled(boolean var)
1882 {
1883 this.inEnabled = var;
1884 }
1885
1886 @Override
1887 public void stateChanged(ChangeEvent event)
1888 {
1889 if (!inEnabled)
1890 {
1891 return;
1892 }
1893
1894 //NB here we convert from 1-based index in GUI to 0-based index
1895 currGrphIdx = ((Integer) graphNavigSpinner.getValue())
1896 .intValue() - 1;
1898 }
1899 }
1900
1901//-----------------------------------------------------------------------------
1902
1903 private void loadFragmentSpace() throws Exception
1904 {
1905 // Define the fragment space via a new dialog
1906 FSParamsDialog fsDefinitionDialog = new FSParamsDialog(this);
1907 fsDefinitionDialog.pack();
1908 fsDefinitionDialog.setVisible(true);
1910 fragSpace = fsDefinitionDialog.makeFragSpace();
1911 }
1912
1913//-----------------------------------------------------------------------------
1914
1916 {
1917 btnSaveEdits.setEnabled(false);
1918 btnAddGraph.setEnabled(true);
1919 btnOpenGraphs.setEnabled(true);
1920
1921 if (dnGraphLibrary.size()==0)
1922 {
1923 graphNavigSpinner.setModel(new SpinnerNumberModel(0,0,0,0));
1924 }
1925 else
1926 {
1927 graphNavigSpinner.setModel(new SpinnerNumberModel(currGrphIdx+1, 1,
1928 dnGraphLibrary.size(), 1));
1929 }
1930 ((DefaultEditor) graphNavigSpinner.getEditor())
1931 .getTextField().setEditable(true);
1932 ((DefaultEditor) graphNavigSpinner.getEditor())
1933 .getTextField().setForeground(Color.BLACK);
1934
1936 }
1937
1938//-----------------------------------------------------------------------------
1939
1940 private void protectEditedSystem()
1941 {
1942 btnSaveEdits.setEnabled(true);
1943 btnAddGraph.setEnabled(false);
1944 btnOpenGraphs.setEnabled(false);
1945
1946 graphNavigSpinner.setModel(new SpinnerNumberModel(currGrphIdx+1,
1947 currGrphIdx+1, currGrphIdx+1, 1));
1948 ((DefaultEditor) graphNavigSpinner.getEditor())
1949 .getTextField().setEditable(false);
1950 ((DefaultEditor) graphNavigSpinner.getEditor())
1951 .getTextField().setForeground(Color.GRAY);
1952
1954 }
1955
1956//-----------------------------------------------------------------------------
1957
1959 {
1960 // Clears the "dnGraph" and GUI components, but keep memory of the
1961 // status of the graph of an easy recovery, though since the old graph
1962 // is being removed, the recovered data is not needed anymore.
1964
1965 // Actual removal from the library
1966 if (dnGraphLibrary.size()>0)
1967 {
1969 molLibrary.remove(currGrphIdx);
1970 int libSize = dnGraphLibrary.size();
1971
1972 if (libSize > 0)
1973 {
1974 if (currGrphIdx>=0 && currGrphIdx<libSize)
1975 {
1976 //we keep currGrphIdx as it will correspond to the next item
1977 }
1978 else
1979 {
1981 }
1982
1983 // We use the currGrphIdx to load another dnGraph
1986 }
1987 else
1988 {
1989 currGrphIdx = -1;
1990 //Spinner will be fixed by the deprotection routine
1991 totalGraphsLabel.setText(Integer.toString(
1992 dnGraphLibrary.size()));
1996 }
1998 }
1999 }
2000
2001//-----------------------------------------------------------------------------
2002
2003 private void saveUnsavedChanges()
2004 {
2005 // Overwrite dnGraph in library
2007
2008 // WARNING: the dnGraph in the visualPanel should be in sync because any
2009 // changes to it has resulted in an update of the graphViewer.
2010 // Still, it is possible to introduce code modifications that make it
2011 // go out of sync.
2012 // Here, we ASSUME the graph displayed in the graphViewer component
2013 // of the visualPanel is in sync with dnGraph. Therefore, we just
2014 // rebuild the molecular viewer.
2015
2016 if (updateMolViewer)
2017 {
2018 IAtomContainer mol = visualPanel.updateMolevularViewer();
2019 if (mol != null)
2020 {
2021 molLibrary.set(currGrphIdx, mol);
2022 mol.setProperty(DENOPTIMConstants.PROVENANCE,
2023 "ManuallyBuilt");
2024 } else {
2025 // Logging done within visualPanel
2026 molLibrary.set(currGrphIdx, builder.newAtomContainer());
2027 }
2028 updateMolViewer = false;
2029 }
2030
2031 // Release constraints
2033 }
2034
2035//-----------------------------------------------------------------------------
2036
2042 public boolean hasUnsavedChanges()
2043 {
2044 return unsavedChanges;
2045 }
2046
2047//-----------------------------------------------------------------------------
2048
2049 /*
2050 * This is needed to stop JUNG and Jmol threads upon closure of this
2051 * gui card.
2052 */
2053 public void dispose()
2054 {
2056 }
2057
2058//-----------------------------------------------------------------------------
2059
2063 @SuppressWarnings("serial")
2065 {
2066 private JPanel centralPanel;
2067 private JScrollPane scrollPanel;
2068 private JPanel listPanel;
2069
2070 //------------------------------------------------------------------------------
2071
2078 public ConfigTemplateDialog(Component refForPlacement, int num)
2079 {
2080 super(refForPlacement);
2081 setTitle("Define Properties of Templates");
2082 centralPanel = new JPanel();
2083 centralPanel.setLayout(new BoxLayout(
2084 centralPanel, SwingConstants.VERTICAL));
2085
2086 listPanel = new JPanel();
2087 listPanel.setLayout(new BoxLayout(listPanel, SwingConstants.VERTICAL));
2088 scrollPanel = new JScrollPane(listPanel);
2089 for (int i=0; i<num; i++)
2090 listPanel.add(new TemplateConfiguration(i));
2091 centralPanel.add(scrollPanel);
2092
2093 this.btnDone.setText("OK");
2094 this.btnDone.setToolTipText("Confirm properties.");
2095 this.btnDone.addActionListener(new ActionListener() {
2096
2097 @Override
2098 public void actionPerformed(ActionEvent e) {
2099 // Collect data from form
2100 Map<String,List<Object>> selection =
2101 new HashMap<String,List<Object>>();
2102 selection.put(CONTRACTKEY, new ArrayList<>());
2103 selection.put(BBTYPEKEY, new ArrayList<>());
2104 for (Component c : listPanel.getComponents())
2105 {
2106 if (c instanceof TemplateConfiguration)
2107 {
2110 selection.get(CONTRACTKEY).add(
2111 tc.contractCmb.getSelectedItem());
2112 selection.get(BBTYPEKEY).add(
2113 tc.bbTypeCmb.getSelectedItem());
2114 }
2115 }
2116 result = selection;
2117 close();
2118 }
2119 });
2120
2121 this.btnCanc.setEnabled(true);
2122 this.btnCanc.setVisible(true);
2123 this.btnCanc.setToolTipText("Abandon");
2124
2125 super.addToCentralPane(centralPanel);
2126 }
2127
2128//------------------------------------------------------------------------------
2129
2134 private class TemplateConfiguration extends JPanel
2135 {
2136 JComboBox<ContractLevel> contractCmb = new JComboBox<ContractLevel>(
2137 ContractLevel.values());
2138
2139 private String contractTolTip = "<html><body width='%1s'>"
2140 + "Speicfy the type of contract of the template, i.e., "
2141 + "to what "
2142 + "extent the graph embedded in the template can change in "
2143 + "structure and/or identity of the vertexes.</html>";
2144
2145 JComboBox<BBType> bbTypeCmb = new JComboBox<BBType>(BBType.values());
2146
2147 private String bbtTolTip = "<html><body width='%1s'>"
2148 + "Speicfy the type of building block of the vertex. This"
2149 + "determines, for instance, the type of other vertexes "
2150 + "that can be used to replace thi one (if such mutation "
2151 + "is permitted).</html>";
2152
2153 private int szTolTip = 250;
2154
2161 {
2162 super();
2163 this.add(new JLabel("#" + (id+1)));
2164
2165 JLabel contractLbl = new JLabel(" Contract:");
2166 contractLbl.setToolTipText(String.format(contractTolTip,
2167 szTolTip));
2168 this.add(contractLbl);
2169 contractCmb.setToolTipText(String.format(contractTolTip,
2170 szTolTip));
2171 this.add(contractCmb);
2172
2173 JLabel bbtLbl = new JLabel(" Building Block Type:");
2174 bbtLbl.setToolTipText(String.format(bbtTolTip,szTolTip));
2175 this.add(bbtLbl);
2176 bbTypeCmb.setToolTipText(String.format(bbtTolTip,szTolTip));
2177 bbTypeCmb.setSelectedItem(BBType.FRAGMENT);
2178 this.add(bbTypeCmb);
2179
2180 //Other properties should be added here
2181
2182 }
2183 }
2184 }
2185
2186//-----------------------------------------------------------------------------
2187
2188}
General set of constants used in DENOPTIM.
static final String PROVENANCE
SDF tag containing provenance data for a graph.
A file with a conventional representation of its format.
static FileFormat detectFileFormat(File inFile)
Inspects a file/folder and tries to detect if there is one of the data sources that is recognized by ...
Definition: FileUtils.java:399
static void addToRecentFiles(String fileName, FileFormat ff)
Appends an entry to the list of recent files.
Definition: FileUtils.java:67
Exception thrown when the format of a file is not recognized.
static boolean prepareMolToFragmentation(IAtomContainer mol, FragmenterParameters settings, int index)
Do any pre-processing on a IAtomContainer meant to be fragmented.
Class defining a space of building blocks.
ArrayList< AttachmentPoint > getAPsCompatibleWithThese(ArrayList< AttachmentPoint > srcAPs)
Searches for all attachment points that are compatible with the given list of attachment points.
ArrayList< Vertex > getCappingLibrary()
ArrayList< Vertex > getScaffoldLibrary()
ArrayList< Vertex > getFragmentLibrary()
Helper methods for the genetic algorithm.
Definition: EAUtils.java:107
static DGraph makeGraphFromFragmentationOfMol(IAtomContainer mol, List< CuttingRule > cuttingRules, Logger logger, ScaffoldingPolicy scaffoldingPolicy)
Converts a molecule into a DGraph by fragmentation and re-assembling of the fragments.
Definition: EAUtils.java:1044
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1325
DGraph embedPatternsInTemplates(GraphPattern pattern, FragmentSpace fragSpace)
Searches for the given pattern type and generated a new graph where each set of (clones of) vertexes ...
Definition: DGraph.java:4845
void removeVertex(Vertex vertex)
Remove a vertex from this graph.
Definition: DGraph.java:1347
void setGraphId(int id)
Definition: DGraph.java:264
void appendVertexOnAP(AttachmentPoint srcAP, AttachmentPoint trgAP)
Append a vertex to this graph: adds the new vertex to the list of vertices belonging to the graph,...
Definition: DGraph.java:6005
void addSymmetricSetOfVertices(SymmetricVertexes symSet)
Adds a symmetric set of vertices to this graph.
Definition: DGraph.java:889
void addRing(Ring ring)
Definition: DGraph.java:1258
An empty vertex has the behaviors of a vertex, but has no molecular structure.
A collection of Vertexs that are related by a relation that we call "symmetry", even though this clas...
void setInnerGraph(DGraph innerGraph)
Definition: Template.java:298
void setContractLevel(ContractLevel contract)
Imposes the given contract to this template.
Definition: Template.java:214
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:62
abstract Vertex clone()
Returns a deep-copy of this vertex.
void setVertexId(long vertexId2)
Definition: Vertex.java:282
Object getProperty(Object property)
Definition: Vertex.java:1224
void setProperty(Object key, Object property)
Definition: Vertex.java:1236
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:1008
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
Definition: Vertex.java:215
Standardised horizontal bar with padded components, which are meant to be JButtons.
Definition: ButtonsBar.java:36
Component add(Component comp)
Definition: ButtonsBar.java:53
A modal dialog to define a fragment space and load it.
FragmentSpace makeFragSpace()
Reads all the parameters, calls the interpreters, and eventually creates the static FragmentSpace obj...
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 pickFileWithGraph(Component parent)
static File pickFile(Component parent)
GUI component to provide pathname where to save stuff.
static FileAndFormat pickFileForSavingVertexes(Component parent)
static FileAndFormat pickFileForSavingGraphs(Component parent)
Utility class for a form to configure a template via the GUI.
Dialog to configure one or more templates.
ConfigTemplateDialog(Component refForPlacement, int num)
Creates a modal dialog with a specified number of limes allowing to configure the properties of the t...
void setEnabled(boolean var)
Enables/disable the listener.
showHideLabelsListener(JComponent parent, LabelType labTyp)
A panel that understands DENOPTIM graphs and allows to create and edit them.
FragmentSpace fragSpace
The fragment space this handler works with.
void appendGraphsFromConvertingMolecule(File file, FragmenterParameters frgParams, Component parent)
ArrayList< DGraph > readGraphsFromFile(File file)
static AtomicInteger graphHandlerTabUID
Unique identified for instances of this handler.
final GraphSpinnerChangeEvent graphSpinnerListener
void extendGraphFromFragSpace(ArrayList< AttachmentPoint > selAps)
Extends the current graph by appending a node to a specific free AP on the growing graph.
DGraph dnGraph
The unsaved version of the currently loaded graph.
ArrayList< DGraph > dnGraphLibrary
The currently loaded list of graphs.
static final long serialVersionUID
Version UID.
GraphVertexMolViewerPanel visualPanel
static AtomicInteger graphUID
Unique identified for graphs built here.
void importGraphsFromFile(File file)
Imports graphs from file.
void startGraphFromFragSpaceOrCreationOfEmptyVertex()
Start the construction of a new graph from scratch.
void addChordOnGraph(ArrayList< Vertex > rcvs)
Edits the currently loaded graph by adding a chord involving the two selected vertices.
Map< Integer, Integer > genToLocIDMap
Map converting fragIDs in fragment library to fragIDs in subset of compatible fragments.
static final IChemObjectBuilder builder
boolean unsavedChanges
Flag signaling that loaded data has changes since last save.
void collectFragAndAPsCompatibleWithSelectedAPs(ArrayList< AttachmentPoint > srcAPs)
void clearCurrentSystem()
Clears the current graph viewer but keeps track of the latest graph loaded.
GUIGraphHandler(GUIMainPanel mainPanel)
Constructor.
boolean hasUnsavedChanges()
Check whether there are unsaved changes.
void extendCurrentGraph(AttachmentPoint apOnIncomingVrtx, ArrayList< AttachmentPoint > selAps)
void loadCurrentGraphIdxToViewer(boolean keepSprites)
Loads the graph corresponding to the field currGrphIdx.
void enableGraphDependentButtons(boolean enable)
ArrayList< IAtomContainer > molLibrary
The currently loaded list of molecular representations of the graphs.
void initialize()
Initialize the panel and add buttons.
void createEmptyVertexAndPlaceItInGraph(ArrayList< AttachmentPoint > selAps)
ArrayList< Vertex > compatVrtxs
Subset of vertices for compatible building block selecting GUI.
int currGrphIdx
The index of the currently loaded dnGraph [0–(n-1)}.
Graphical User Interface of the DENOPTIM package.
Definition: GUI.java:57
static final Randomizer PRNG
Random number generator specific for the GUI, and any of its tasks.
Definition: GUI.java:96
The main panel is a deck of cards that occupies all the GUI frame.
JButton btnDone
The button that is used to launch the processing of the data given to the open dialog,...
Object showDialog()
Shows the dialog and restrains the modality to it, until the dialog gets closed.
A panel with a viewer capable of visualising DENOPTIM fragments and allows to create and edit fragmen...
static boolean dialogToDefineCuttingRules(FragmenterParameters settings, ClassLoader classLoader, Component parent, boolean setMolToGraphSettings)
Starts a dialog to define the on-the-fly fragmentation settings.
A modal dialog with a viewer that understands the different types of DENOPTIM vertex and allows to se...
void load(List< Vertex > fragments, int initialId)
Load the list of vertexes to choose from.
void setRequireApSelection(boolean enforced)
Allows to control whether confirming the selection of a vertex without having selected an attachment ...
static final String PRESELECTEDAPSFIELD
Property used to pre-select APs.
static final String PRESELECTEDAPSFIELDSEP
Separator in property used to pre-select APs.
A panel that collects three viewers:
ArrayList< AttachmentPoint > getAPsSelectedInViewer()
Identifies which attachment points are selected in the graph viewer.
void clearMolecularViewer()
Clears the molecular viewer and hides it behind the empty card.
void setMouseMode(ModalGraphMouse.Mode mode)
Alters the functionality of mouse in the graph visualization panel.
ArrayList< Vertex > getSelectedNodesInViewer()
Identifies which vertices are selected in the graph viewer.
void bringCardToTopOfMolViewer(String cardName)
Allows to show the given card in the molecular structure viewer.
void moveDividerLocation()
Moved the divider to the location configured by some content-based reasoning.
void clearCurrentSystem()
Clears the current graph viewer but keeps track of the latest graph loaded.
void renderMolVieverToNeedUpdate()
Triggers the generation of the molecular representation of the loaded graph.
void resetFragViewerCardDeck()
Changes the appearance of the vertex visualisation panel to an empty card that is consistent with the...
void loadDnGraphToViewer(DGraph dnGraph, IAtomContainer mol, boolean keepSprites)
Loads the given graph into the graph viewer.
void alterLabels(LabelType labelName, boolean show)
Adds/Removes labels to the graph components that are presently selected.
IAtomContainer updateMolevularViewer()
Updates the molecular representation of the loaded graph.
Utility methods for input/output.
static File writeVertexesToFile(File file, FileFormat format, List< Vertex > vertexes)
Writes vertexes to file.
static ArrayList< IAtomContainer > readSDFFile(String fileName)
Reads a file containing multiple molecules (multiple SD format))
static ArrayList< DGraph > readDENOPTIMGraphsFromJSONFile(String fileName)
Reads a list of DGraphs from a JSON file.
static File writeGraphsToFile(File file, FileFormat format, List< DGraph > modGraphs, Logger logger, Randomizer randomizer)
Writes the graphs to file.
static ArrayList< DGraph > readDENOPTIMGraphsFromFile(File inFile)
Reads a list of DGraphs from file.
static ArrayList< DGraph > readDENOPTIMGraphsFromSDFile(String fileName)
Reads a list of <DGraphs from a SDF file.
An iterator that take IAtomContainers from a file, possibly using an available iterating reader,...
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
Logger getLogger()
Get the name of the program specific logger.
Parameters controlling execution of the fragmenter.
void setAddExplicitH(boolean addExplicitH)
Give true to add explicit H atoms on all atoms.
boolean embedRingsInTemplate
Flag that enables the embedding of rings in templates upon conversion of molecules into DGraph.
void setWorkingIn3D(boolean workingIn3D)
Sets boolean variable workingIn3D.
File formats identified by DENOPTIM.
Definition: FileFormat.java:32
Possible chemical bond types an edge can represent.
Definition: Edge.java:303
Enum specifying to what extent the template's inner graph can be changed.
Definition: Template.java:104
The type of building block.
Definition: Vertex.java:87