$darkmode
DENOPTIM
GraphVertexMolViewerPanel.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.CardLayout;
23import java.awt.Dimension;
24import java.beans.PropertyChangeEvent;
25import java.beans.PropertyChangeListener;
26import java.beans.PropertyChangeListenerProxy;
27import java.util.ArrayList;
28import java.util.logging.Logger;
29
30import javax.swing.JLabel;
31import javax.swing.JPanel;
32import javax.swing.JSplitPane;
33
34import org.openscience.cdk.interfaces.IAtomContainer;
35import org.openscience.cdk.interfaces.IChemObjectBuilder;
36import org.openscience.cdk.silent.SilentChemObjectBuilder;
37
38import denoptim.graph.AttachmentPoint;
39import denoptim.graph.DGraph;
40import denoptim.graph.EmptyVertex;
41import denoptim.graph.Fragment;
42import denoptim.graph.Template;
43import denoptim.graph.Vertex;
44import denoptim.gui.GraphViewerPanel.JVertex;
45import denoptim.gui.GraphViewerPanel.JVertexType;
46import denoptim.gui.GraphViewerPanel.LabelType;
47import denoptim.molecularmodeling.ThreeDimTreeBuilder;
48import denoptim.utils.MoleculeUtils;
49import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
50
51
63public class GraphVertexMolViewerPanel extends JSplitPane
64{
68 private static final long serialVersionUID = 1L;
69
73 private DGraph dnGraph;
74
80
81 private JSplitPane leftPane;
83 private JPanel fragViewerPanel;
84 private JPanel fragViewerHeader;
85 private JPanel fragViewerCardHolder;
86 private JPanel fragViewerEmptyCard;
88 private JPanel fragViewerNoFSCard;
91 private JPanel molViewerPanel;
92 private JPanel molViewerHeader;
93 private JPanel molViewerCardHolder;
94 private JPanel molViewerEmptyCard;
96 protected final String NOFSCARDNAME = "noFSCard";
97 protected final String EMPTYCARDNAME = "emptyCard";
98 protected final String NOTDUABLECARDNAME = "notDoableCard";
99 protected final String UPDATETOVIEW = "updateCard";
100 protected final String MOLVIEWERCARDNAME = "molViewerCard";
101 protected final String FRAGVIEWERCARDNAME = "fragViewerCard";
102 protected final String TMPLVIEWERCARDNAME = "tmplViewwerCard";
104
105 //Default divider location
106 private final double DEFDIVLOC = 0.5;
107 private double defDivLoc = DEFDIVLOC;
108
109 private static final IChemObjectBuilder builder =
110 SilentChemObjectBuilder.getInstance();
111
112//-----------------------------------------------------------------------------
113
118 {
119 initialize();
120 }
121
122//-----------------------------------------------------------------------------
123
127 private void initialize()
128 {
129 setOrientation(JSplitPane.HORIZONTAL_SPLIT);
130 setOneTouchExpandable(true);
131 // WARNING: setting the divider location has to be node after the
132 // split pane is visible
133 //setDividerLocation(defDivLoc);
134 setResizeWeight(0.5);
135
136 // In the left part we have the mol and frag viewers
137 leftPane = new JSplitPane();
138 leftPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
139 leftPane.setOneTouchExpandable(true);
140 leftPane.setResizeWeight(0.5);
141 setLeftComponent(leftPane);
142
144 setRightComponent(graphViewer);
145 graphViewer.addPropertyChangeListener(
146 new PropertyChangeListenerProxy(
148 new NodeClickedListener()));
149 graphViewer.addPropertyChangeListener(
150 new PropertyChangeListenerProxy(
153
154 fragViewerPanel = new JPanel(new BorderLayout());
155 fragViewerHeader = new JPanel();
156 fragViewerHeader.add(new JLabel("Node content:"));
157 String fragViewerToolTip = "<html>This viewer shows the "
158 + "content of the selected vertex.<br>"
159 + "Click on a node to select it and display its "
160 + "content here.</html>";
161 fragViewerHeader.setToolTipText(fragViewerToolTip);
162 fragViewerPanel.add(fragViewerHeader, BorderLayout.NORTH);
163 fragViewerCardHolder = new JPanel(new CardLayout());
164
165 fragViewerPanel.add(fragViewerCardHolder, BorderLayout.CENTER);
166
167 fragViewerEmptyCard = new JPanel();
168 String txt = "<html><body width='%1s'><center>No chosen node.</center>"
169 + "</html>";
170 fragViewerEmptyCard.add(new JLabel(String.format(txt, 120)));
171 fragViewerEmptyCard.setToolTipText(fragViewerToolTip);
173
174 fragViewerNotDuableCard = new JPanel();
175 String txtn = "<html><body width='%1s'><center>Content not visualizable"
176 + "</center></html>";
177 fragViewerNotDuableCard.add(new JLabel(String.format(txtn, 120)));
178 fragViewerNotDuableCard.setToolTipText(fragViewerToolTip);
180
181 fragViewerNoFSCard = new JPanel();
182 String txtb = "<html><body width='%1s'><center>To inspect the content "
183 + "of nodes, please load a space of building blocks, "
184 + "and re-open this tab.</center></html>";
185 fragViewerNoFSCard.add(new JLabel(String.format(txtb, 120)));
186 fragViewerNoFSCard.setToolTipText(fragViewerToolTip);
188
189 fragViewer = new FragmentViewPanel(false);
191
192 ((CardLayout) fragViewerCardHolder.getLayout()).show(
194
195 leftPane.setTopComponent(fragViewerPanel);
196
197 // The molecular viewer is embedded in a container structure that
198 // is meant to show/hide the molViewer according to specific needs.
199 molViewerPanel = new JPanel(new BorderLayout());
200 molViewerHeader = new JPanel();
201 molViewerHeader.add(new JLabel("Associated Structure:"));
202 String molViewerToolTip = "<html>This viewer shows the chemical "
203 + "structure associated with the current graph.</html>";
204 molViewerHeader.setToolTipText(molViewerToolTip);
205 molViewerPanel.add(molViewerHeader, BorderLayout.NORTH);
206 molViewerCardHolder = new JPanel(new CardLayout());
207
208 molViewerPanel.add(molViewerCardHolder, BorderLayout.CENTER);
209
210 molViewerEmptyCard = new JPanel();
211 String txt2 = "<html><body width='%1s'><center>No chemical "
212 + "structure.</center>"
213 + "</html>";
214 molViewerEmptyCard.add(new JLabel(String.format(txt2, 120)));
215 molViewerEmptyCard.setToolTipText(molViewerToolTip);
217
218 molViewerNeedUpdateCard = new JPanel();
219 String txt2b = "<html><body width='%1s'><center>Save changes to "
220 + "update the molecular representation.</center>"
221 + "</html>";
222 molViewerNeedUpdateCard.add(new JLabel(String.format(txt2b, 120)));
223 molViewerNeedUpdateCard.setToolTipText(molViewerToolTip);
225
229 ((CardLayout) molViewerCardHolder.getLayout()).show(
231
232 leftPane.setBottomComponent(molViewerPanel);
233 }
234
235//-----------------------------------------------------------------------------
236
245 public void loadDnGraphToViewer(DGraph dnGraph, IAtomContainer mol,
246 boolean keepSprites)
247 {
248 try {
249 loadDnGraphToViewer(dnGraph,keepSprites);
252 } catch (Exception e) {
253 e.printStackTrace();
254 System.out.println("Could not read molecular data: "+
255 e.getCause() + " " + e.getMessage());
257 }
258 }
259
260//-----------------------------------------------------------------------------
261
268 public void loadDnGraphToViewer(DGraph dnGraph, boolean keepLabels)
269 {
270 this.dnGraph = dnGraph;
272
273 // Keep a snapshot of the old data visualized
274 if (keepLabels)
275 {
277 } else {
278 oldGSStatus = null;
279 }
280
283
284 if (dnGraph.getVertexCount()==1)
285 {
286 defDivLoc = 0.85; //Rezising occures upon painting.
287 leftPane.setDividerLocation(1.0); // hide redundant jmol panel
289 }
290 }
291
292//-----------------------------------------------------------------------------
293
300 {
301 // We lease data in the viewer to increase speed of execution, but the
302 // leftover is outdated! This is the meaning of 'true'
303 molViewer.clearAll(true);
305 }
306
307//-----------------------------------------------------------------------------
308
316 public IAtomContainer updateMolevularViewer()
317 {
318 // We lease data in the viewer to increase speed of execution, but the
319 // leftover is outdated! This is the meaning of 'true'
320 molViewer.clearAll(true);
321
322 IAtomContainer mol = builder.newAtomContainer();
323 if (!dnGraph.containsAtoms())
324 {
326 return mol;
327 }
328
329 Logger logger = Logger.getLogger(GUI.GUILOGGER);
331 try {
334 } catch (Throwable t) {
335 t.printStackTrace();
336 System.out.println("Couldn't make 3D-tree representation: "
337 + t.getMessage());
338 }
339
340 if (mol.getAtomCount() > 0)
341 {
342 try {
345 } catch (Exception e) {
346 e.printStackTrace();
347 System.out.println("Could not read molecular data: "+
348 e.getCause() + " " + e.getMessage());
350 }
351 } else {
353 }
354 return mol;
355 }
356
357//-----------------------------------------------------------------------------
358
365 {
366 if (fragViewer != null)
367 {
368 // We lease data in the viewer to increase speed of execution, but the
369 // leftover is outdated! This is the meaning of 'true'
370 fragViewer.clearAll(true);
373 }
374 }
375
376//-----------------------------------------------------------------------------
377
379 {
380 if (fragViewerTmplViewerCard != null)
381 {
382 ((CardLayout) fragViewerCardHolder.getLayout()).
383 removeLayoutComponent(fragViewerTmplViewerCard);
386 }
387 }
388
389//-----------------------------------------------------------------------------
390
395 public void clearCurrentSystem()
396 {
397 dnGraph = null;
401 }
402
403//-----------------------------------------------------------------------------
404
408 public void clearVertexViewer()
409 {
410 // We lease data in the viewer to increase speed of execution, but the
411 // leftover is outdated! This is the meaning of 'true'
412 fragViewer.clearAll(true);
414 }
415
416//-----------------------------------------------------------------------------
417
422 {
423 // We lease data in the viewer to increase speed of execution, but the
424 // leftover is outdated! This is the meaning of 'true'
425 molViewer.clearAll(true);
427 }
428
429//-----------------------------------------------------------------------------
430
435 private class NodeClickedListener implements PropertyChangeListener
436 {
437 @Override
438 public void propertyChange(PropertyChangeEvent evt)
439 {
440 // null is used to trigger cleanup
441 if (evt.getNewValue() == null)
442 {
444 return;
445 }
446 JVertex jv = (JVertex) evt.getNewValue();
448 }
449 }
450
451//------------------------------------------------------------------------------
452
459 {
460 Vertex bb = v.clone();
461 if (bb instanceof Fragment) {
462 removeNestedGraphViewer(); //Just is case we still have it
463 Fragment frag = (Fragment) bb;
466 } else if (bb instanceof Template) {
467 Template t = (Template) bb;
468
469 // We lease data in the viewer to increase speed of execution, but the
470 // leftover is outdated! This is the meaning of 'true'
471 fragViewer.clearAll(true);
473
474 //NB: this setting of the size is needed to allow generation
475 // of the graph layout.
476 Dimension d = new Dimension();
477 d.height = (int) fragViewerCardHolder.getSize().height;
478 d.width = (int) (fragViewerCardHolder.getSize().width*0.5);
480
484 fragViewerCardHolder.getSize());
485
487 t.getIAtomContainer(), false);
488
490 fragViewerTmplViewerCard.setDividerLocation(DEFDIVLOC);
491 } else if (bb instanceof EmptyVertex) {
492 removeNestedGraphViewer(); //Just is case we still have it
493
494 //TODO
495 System.out.println("WARNING: Visualization of "
496 + "EmptyVertex is not implemented yet");
497
498 // We lease data in the viewer to increase speed of execution, but the
499 // leftover is outdated! This is the meaning of 'true'
500 fragViewer.clearAll(true);
502 }
503 }
504
505//------------------------------------------------------------------------------
506
511 private class MouseModeChoiceListener implements PropertyChangeListener
512 {
513
514 @Override
515 public void propertyChange(PropertyChangeEvent evt)
516 {
517 switch ((Integer)evt.getNewValue())
518 {
519 case 0:
520 setMouseMode(ModalGraphMouse.Mode.PICKING);
521 break;
522
523 case 1:
524 setMouseMode(ModalGraphMouse.Mode.TRANSFORMING);
525 break;
526
527 default:
528 System.out.println("WARNING: invalid mouse mode request!");
529 }
530 }
531 }
532
533//-----------------------------------------------------------------------------
534
540 {
541 setDividerLocation(defDivLoc);
542 }
543
544//-----------------------------------------------------------------------------
545
549 public boolean hasSelectedNodes()
550 {
551 return graphViewer.hasSelected();
552 }
553
554//-----------------------------------------------------------------------------
555
562 public void alterLabels(LabelType labelName, boolean show)
563 {
564 graphViewer.alterLabels(labelName, show);
565 }
566
567//-----------------------------------------------------------------------------
568
574 public ArrayList<AttachmentPoint> getAPsSelectedInViewer()
575 {
576 ArrayList<AttachmentPoint> aps =
577 new ArrayList<AttachmentPoint>();
579 {
580 if (jv.vtype == JVertexType.AP)
581 {
582 aps.add(jv.ap);
583 }
584 }
585 return aps;
586 }
587
588//-----------------------------------------------------------------------------
589
594 public ArrayList<Vertex> getSelectedNodesInViewer()
595 {
596 ArrayList<Vertex> selected = new ArrayList<Vertex>();
598 {
599 if (jv.vtype == JVertexType.AP)
600 {
601 continue;
602 }
603 selected.add(jv.dnpVertex);
604 }
605 return selected;
606 }
607
608//-----------------------------------------------------------------------------
609
619 public void bringCardToTopOfVertexViewer(String cardName)
620 {
621 ((CardLayout) fragViewerCardHolder.getLayout()).show(
622 fragViewerCardHolder, cardName);
623 }
624
625//-----------------------------------------------------------------------------
626
635 public void bringCardToTopOfMolViewer(String cardName)
636 {
637 ((CardLayout) molViewerCardHolder.getLayout()).show(
638 molViewerCardHolder, cardName);
639 }
640
641//-----------------------------------------------------------------------------
642
643 /*
644 * This is needed to stop GraphStream and Jmol threads upon closure of this
645 * gui card.
646 */
647 public void dispose()
648 {
652 if (fragViewerTmplViewerCard != null)
653 {
655 }
656 }
657
658//-----------------------------------------------------------------------------
659
664 public void setMouseMode(ModalGraphMouse.Mode mode)
665 {
667 }
668
669//-----------------------------------------------------------------------------
670
671}
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
Vertex getVertexAtPosition(int pos)
Returns the vertex that is in the given position of the list of vertices belonging to this graph.
Definition: DGraph.java:2514
boolean containsAtoms()
Returns true if this graph has any vertex that contains atoms.
Definition: DGraph.java:3935
An empty vertex has the behaviors of a vertex, but has no molecular structure.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
IAtomContainer getIAtomContainer()
The molecular representation, if any, is generated by this method and stored until further changes in...
Definition: Template.java:715
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
abstract Vertex clone()
Returns a deep-copy of this vertex.
A panel with a molecular viewer and attachment point table.
void clearAll(boolean dataIsComing)
Removes the currently visualized molecule and AP table.
void loadFragmentToViewer(Fragment frag)
Loads the given fragments to this viewer.
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
static final String GUILOGGER
Name of logger for the GUI.
Definition: GUI.java:91
Listener for identifying the node on which the user has clicked and load the corresponding fragment i...
Listener for identifying the node on which the user has clicked and load the corresponding fragment i...
A panel that collects three viewers:
void bringCardToTopOfVertexViewer(String cardName)
Allows to show the given card in the vertex viewer panel.
JUNGGraphSnapshot oldGSStatus
The snapshot of the old (removed) visualized GraphStrem system.
DGraph dnGraph
The unsaved version of the currently loaded graph.
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 visualizeVertexInNestedViewer(Vertex v)
Makes a clone of the given vertex and loads that clone into the nested visualization frame.
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 initialize()
Initialize the panel and add buttons.
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 clearVertexViewer()
Clears the molecular viewer and hides it behind the empty card.
void renderMolVieverToNeedUpdate()
Triggers the generation of the molecular representation of the loaded graph.
void loadDnGraphToViewer(DGraph dnGraph, boolean keepLabels)
Loads the given graph into the graph viewer.
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.
Vertex dnpVertex
The reference to the corresponding Vertex or null.
A Panel that holds the JUNG representation of a graph.
void loadGraphToViewer(DGraph dnGraph)
Load the given DGraph to this graph viewer.
JUNGGraphSnapshot getGraphStatusSnapshot()
Returns a copy of the graph loaded into the viewer.
void cleanup()
Removes the currently loaded graph viewer.
Set< JVertex > getSelectedNodes()
Finds selected nodes from the viewer.
void setMouseMode(ModalGraphMouse.Mode mode)
static final String PROPERTYMOUSEMODE
static final String PROPERTYNODECLICKED
void alterLabels(LabelType labelType, boolean show)
Adds or removes labels from the elements selected in the graph view.
boolean hasSelected()
Check is there is any node selected in the viewer.
This class collects information on how a graph was displayed in a JUNG visialisation server (i....
A panel with a molecular viewer and data table.
void enablePartialData(boolean enable)
Sets the behavior in case of request to visualize partial data.
void clearAll(boolean dataIsComing)
Removes the currently visualized molecule and AP table.
void loadChemicalStructure(IAtomContainer mol)
Loads a structure in the Jmol viewer.
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.
Utilities for molecule conversion.
static void removeUsedRCA(IAtomContainer mol, DGraph graph, Logger logger)
Replace used RCAs (i.e., those involved in Rings) while adding the ring closing bonds.