21import java.awt.BorderLayout;
23import java.awt.Component;
24import java.awt.Cursor;
25import java.awt.Dimension;
26import java.awt.event.ActionEvent;
27import java.awt.event.ActionListener;
28import java.beans.PropertyChangeEvent;
29import java.beans.PropertyChangeListener;
30import java.io.BufferedReader;
32import java.io.InputStreamReader;
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.HashSet;
39import java.util.concurrent.atomic.AtomicInteger;
41import javax.swing.BoxLayout;
42import javax.swing.DefaultListModel;
43import javax.swing.GroupLayout;
44import javax.swing.JButton;
45import javax.swing.JComponent;
46import javax.swing.JLabel;
47import javax.swing.JList;
48import javax.swing.JOptionPane;
49import javax.swing.JPanel;
50import javax.swing.JScrollPane;
51import javax.swing.JSeparator;
52import javax.swing.JSpinner;
53import javax.swing.JSpinner.DefaultEditor;
54import javax.swing.ListSelectionModel;
55import javax.swing.SpinnerNumberModel;
56import javax.swing.SwingConstants;
57import javax.swing.UIManager;
58import javax.swing.event.ChangeEvent;
59import javax.swing.event.ChangeListener;
60import javax.swing.table.DefaultTableModel;
61import javax.vecmath.Point3d;
63import org.openscience.cdk.interfaces.IAtom;
64import org.openscience.cdk.interfaces.IAtomContainer;
65import org.openscience.cdk.interfaces.IBond;
67import denoptim.constants.DENOPTIMConstants;
68import denoptim.exception.DENOPTIMException;
69import denoptim.files.FileAndFormat;
70import denoptim.files.FileUtils;
71import denoptim.fragmenter.FragmenterTools;
72import denoptim.graph.APClass;
73import denoptim.graph.AttachmentPoint;
74import denoptim.graph.DGraph;
75import denoptim.graph.Edge.BondType;
76import denoptim.graph.EmptyVertex;
77import denoptim.graph.Fragment;
78import denoptim.graph.Vertex;
79import denoptim.graph.Vertex.BBType;
80import denoptim.io.DenoptimIO;
81import denoptim.programs.fragmenter.CuttingRule;
82import denoptim.programs.fragmenter.FragmenterParameters;
83import denoptim.utils.DummyAtomHandler;
84import denoptim.utils.MoleculeUtils;
177 super.setLayout(
new BorderLayout());
189 this.setLayout(
new BorderLayout());
200 new PropertyChangeListener() {
202 public void propertyChange(PropertyChangeEvent evt) {
220 JLabel navigationLabel1 =
new JLabel(
"Vertex # ");
221 JLabel navigationLabel2 =
new JLabel(
"Current library size: ");
224 navigSpinner =
new JSpinner(
new SpinnerNumberModel(0, 0, 0, 1));
225 navigSpinner.setToolTipText(
"Move to vertex number # in the currently loaded library.");
237 btnAddVrtx.setToolTipText(
"Append vertices taken from a file.");
238 btnAddVrtx.addActionListener(
new ActionListener() {
239 public void actionPerformed(ActionEvent e) {
241 if (inFile ==
null || inFile.getAbsolutePath().equals(
""))
246 ArrayList<Vertex> vrtxLib =
new ArrayList<>();
249 }
catch (Exception e1) {
250 e1.printStackTrace();
252 "<html>Could not read building blocks from file"
253 +
"<br>'" + inFile +
"'"
254 +
"<br>Hint on cause: " + e1.getMessage()
257 JOptionPane.ERROR_MESSAGE,
258 UIManager.getIcon(
"OptionPane.errorIcon"));
262 if (vrtxLib.size() == 0)
265 "<html>No building blocks in file"
266 +
"<br>'" + inFile +
"'</html>",
268 JOptionPane.ERROR_MESSAGE,
269 UIManager.getIcon(
"OptionPane.errorIcon"));
273 if (vrtxLib.size() == 1)
279 String[] options =
new String[]{
"All",
282 String txt =
"<html><body width='%1s'>Do you want to "
283 +
"append all building blocks or only selected ones?"
285 int res = JOptionPane.showOptionDialog(
btnAddVrtx,
286 String.format(txt,200),
287 "Append Building Blocks",
288 JOptionPane.DEFAULT_OPTION,
289 JOptionPane.QUESTION_MESSAGE,
290 UIManager.getIcon(
"OptionPane.warningIcon"),
306 ArrayList<Vertex> selectedVrtxs =
307 new ArrayList<Vertex>();
311 vrtxSelector.
load(vrtxLib, 0);
314 if (selected !=
null)
316 @SuppressWarnings(
"unchecked")
317 ArrayList<ArrayList<Integer>> selList =
318 (ArrayList<ArrayList<Integer>>) selected;
319 for (ArrayList<Integer> pair : selList)
321 selectedVrtxs.add(vrtxLib.get(pair.get(0)));
333 btnDelVrtx.setToolTipText(
"Remove the present building block from the "
335 btnDelVrtx.addActionListener(
new ActionListener() {
336 public void actionPerformed(ActionEvent e) {
340 System.out.println(
"Exception while removing the current "
341 +
"building block:");
342 e1.printStackTrace();
354 JLabel lblImportStruct =
new JLabel(
"Import a structure from");
356 btnOpenMol.setToolTipText(
"Imports a chemical system"
358 btnOpenMol.addActionListener(
new ActionListener() {
359 public void actionPerformed(ActionEvent e) {
361 if (inFile ==
null || inFile.getAbsolutePath().equals(
""))
372 +
" from SMILES string.<br>The conversion of SMILES "
373 +
"to 3D structure requires"
374 +
"<br> an internet connection.</html>");
376 public void actionPerformed(ActionEvent e) {
378 "Please input SMILES: ");
379 if (smiles !=
null && !smiles.trim().equals(
""))
387 lyoImportStructure.setAutoCreateGaps(
true);
388 lyoImportStructure.setAutoCreateContainerGaps(
true);
389 lyoImportStructure.setHorizontalGroup(lyoImportStructure.createParallelGroup(
390 GroupLayout.Alignment.CENTER)
391 .addComponent(lblImportStruct)
392 .addGroup(lyoImportStructure.createSequentialGroup()
395 lyoImportStructure.setVerticalGroup(lyoImportStructure.createSequentialGroup()
396 .addComponent(lblImportStruct)
397 .addGroup(lyoImportStructure.createParallelGroup()
406 btnEmptFrag.setToolTipText(
"<html>Creates an empty vertex:<br>a vertex "
407 +
"that contains no molecular structure.<html>");
408 btnEmptFrag.addActionListener(
new ActionListener() {
409 public void actionPerformed(ActionEvent e) {
412 makeEmptyVertexDialog.pack();
413 Object ev = makeEmptyVertexDialog.
showDialog();
418 ArrayList<Vertex> lst =
new ArrayList<Vertex>(1);
422 fragSelector.
load(lst, 0);
423 fragSelector.
btnDone.setText(
"Confirm");
424 fragSelector.
ctrlPane.setVisible(
false);
427 if (selected ==
null)
441 btnAtmToAP.setToolTipText(
"<html>Replaces the selected atoms with "
442 +
"attachment points.<br>Click on atoms to select"
443 +
" them. Click again to unselect.<br>"
444 +
"<br><b>WARNING:</b> this action cannot be undone!<html>");
445 btnAtmToAP.addActionListener(
new ActionListener() {
446 public void actionPerformed(ActionEvent e) {
449 ArrayList<IAtom> selectedAtms =
452 if (selectedAtms.size() == 0)
455 "<html>No atom selected! Click on atoms to select"
456 +
" them.<br>Click again to unselect.</html>",
458 JOptionPane.ERROR_MESSAGE,
459 UIManager.getIcon(
"OptionPane.errorIcon"));
468 if (selectedAPCs.size() == 0)
473 String apClass = selectedAPCs.get(0).toString();
475 ArrayList<IAtom> failed =
new ArrayList<IAtom>();
476 for (IAtom atm : selectedAtms)
483 for (IAtom atm : failed)
485 selectedAtms.remove(atm);
487 if (selectedAtms.size() == 0)
505 String bndToApLabel =
"Bond to AP Pair";
508 +
"pairs of attachment points. "
509 +
"</br>Click on this button to start the selection of atoms that define the bonds to break."
510 +
"<br><b>WARNING:</b> this action cannot be undone!<html>");
512 public void actionPerformed(ActionEvent e) {
517 Object firstSelected = firstAtomSelectionDialog.
showDialog();
518 if (firstSelected ==
null)
522 List<IAtom> firstSelAtoms = (List<IAtom>) firstSelected;
526 Object secondSelected = secondAtomSelectionDialog.
showDialog();
527 if (secondSelected ==
null)
531 List<IAtom> secondSelAtoms = (List<IAtom>) secondSelected;
533 List<List<List<IAtom>>> atomPairs =
new ArrayList<>();
534 if (firstSelAtoms.size() == secondSelAtoms.size())
537 for (
int i = 0; i < firstSelAtoms.size(); i++)
539 if (firstSelAtoms.get(i).getBond(secondSelAtoms.get(i)) ==
null)
541 String[] options =
new String[]{
"Ignore bonds",
"Cancel"};
542 String txt =
"<html>Atom "
544 +
" is not bound to "
546 +
". Proceed the creation of AP pairs irrespective of the bonds?</html>";
548 String.format(txt,200),
550 JOptionPane.DEFAULT_OPTION,
551 JOptionPane.QUESTION_MESSAGE,
552 UIManager.getIcon(
"OptionPane.warningIcon"),
560 atomPairs.add(Arrays.asList(Arrays.asList(firstSelAtoms.get(i)),
561 Arrays.asList(secondSelAtoms.get(i))));
564 String[] options =
new String[]{
"Multihaptic bond",
565 "Multidentate bonds",
567 String txt =
"<html>Unequal number of atoms in the two sets. Bonds may "
568 +
"be treated as:<ul>"
569 +
"<li> multihapto bond (create a single AP pair)</li>"
570 +
"<li> multiple multidentate bonds (create multiple AP pairs)</li>"
572 +
"<br>How to threat the selected atoms?</html>";
574 String.format(txt,200),
575 "Multihaptic or Multidentate?",
576 JOptionPane.DEFAULT_OPTION,
577 JOptionPane.QUESTION_MESSAGE,
578 UIManager.getIcon(
"OptionPane.warningIcon"),
585 if (firstSelAtoms.size() < secondSelAtoms.size())
587 Set<IAtom> assignedSecondAtoms =
new HashSet<>();
588 for (
int i = 0; i < firstSelAtoms.size(); i++)
590 IAtom firstAtom = firstSelAtoms.get(i);
591 List<IAtom> secondAtomsConnectedToFirstAtom =
new ArrayList<>();
592 for (
int j = 0; j < secondSelAtoms.size(); j++)
594 IAtom secondAtom = secondSelAtoms.get(j);
595 if (firstAtom.getBond(secondAtom) !=
null)
597 if (i>0 && assignedSecondAtoms.contains(secondSelAtoms.get(j)))
604 +
" but is already assigned to another atom. "
605 +
"<br>Aborting: you'll have to break bonds involving "
607 +
" one at the time.</html>",
609 JOptionPane.ERROR_MESSAGE,
610 UIManager.getIcon(
"OptionPane.errorIcon"));
613 assignedSecondAtoms.add(secondAtom);
614 secondAtomsConnectedToFirstAtom.add(secondAtom);
617 if (secondAtomsConnectedToFirstAtom.size() == 0)
620 "<html>No atoms in the second set is connected to atom "
622 +
". Aborting.</html>",
624 JOptionPane.ERROR_MESSAGE,
625 UIManager.getIcon(
"OptionPane.errorIcon"));
628 atomPairs.add(Arrays.asList(Arrays.asList(firstAtom), secondAtomsConnectedToFirstAtom));
631 Set<IAtom> assignedFirstAtoms =
new HashSet<>();
632 for (
int i = 0; i < secondSelAtoms.size(); i++)
634 IAtom secondAtom = secondSelAtoms.get(i);
635 List<IAtom> firstAtomsConnectedToSecondAtom =
new ArrayList<>();
636 for (
int j = 0; j < firstSelAtoms.size(); j++)
638 IAtom firstAtom = firstSelAtoms.get(j);
639 if (firstAtom.getBond(secondAtom) !=
null)
641 if (i>0 && assignedFirstAtoms.contains(firstSelAtoms.get(j)))
648 +
" but is already assigned to another atom. "
649 +
"<br>Aborting: you'll have to break bonds involving "
651 +
" one at the time.</html>",
653 JOptionPane.ERROR_MESSAGE,
654 UIManager.getIcon(
"OptionPane.errorIcon"));
657 assignedFirstAtoms.add(firstAtom);
658 firstAtomsConnectedToSecondAtom.add(firstAtom);
661 if (firstAtomsConnectedToSecondAtom.size() == 0)
664 "<html>No atoms in the second set is connected to atom "
666 +
". Aborting.</html>",
668 JOptionPane.ERROR_MESSAGE,
669 UIManager.getIcon(
"OptionPane.errorIcon"));
672 atomPairs.add(Arrays.asList(firstAtomsConnectedToSecondAtom, Arrays.asList(secondAtom)));
675 }
else if (answer == 1) {
677 for (IAtom firstAtom : firstSelAtoms)
679 for (IAtom secondAtom : secondSelAtoms)
681 if (firstAtom.getBond(secondAtom) !=
null)
683 atomPairs.add(Arrays.asList(Arrays.asList(firstAtom), Arrays.asList(secondAtom)));
692 List<List<APClass>> apClasses =
new ArrayList<>();
695 if (selectedAPCs.size() == 0)
699 APClass apc0 = selectedAPCs.get(0);
703 if (selectedAPCs.size() == 0)
707 APClass apc1 = selectedAPCs.get(0);
708 for (
int i = 0; i < atomPairs.size(); i++)
710 apClasses.add(Arrays.asList(apc0, apc1));
717 List<Vertex> fragments;
724 }
catch (Throwable t)
726 JOptionPane.showMessageDialog(
btnChop,String.format(
727 "<html><body width='%1s'"
728 +
"Could not complete fragmentation. Hint: "
729 + t.getMessage() +
"</html>", 400),
731 JOptionPane.ERROR_MESSAGE,
732 UIManager.getIcon(
"OptionPane.errorIcon"));
737 for (
Vertex frag : fragments)
744 if (fragments.size() < 1 || (fragments.size() == 1 &&
748 "<html>Fragmentation produced no fragments!</html>",
750 JOptionPane.WARNING_MESSAGE,
751 UIManager.getIcon(
"OptionPane.warningIcon"));
758 String[] options =
new String[]{
"All",
761 String txt =
"<html><body width='%1s'>Fragmentation produced "
762 + fragments.size() +
" fragments. Do you want to "
763 +
"append all or select some?"
765 int answer = JOptionPane.showOptionDialog(
btnAddVrtx,
766 String.format(txt,200),
767 "Append Building Blocks",
768 JOptionPane.DEFAULT_OPTION,
769 JOptionPane.QUESTION_MESSAGE,
770 UIManager.getIcon(
"OptionPane.warningIcon"),
786 List<Vertex> selectedVrtxs =
787 new ArrayList<Vertex>();
791 vrtxSelector.
load(fragments, 0);
794 if (selected !=
null)
796 @SuppressWarnings(
"unchecked")
797 List<ArrayList<Integer>> selList =
798 (ArrayList<ArrayList<Integer>>) selected;
799 for (ArrayList<Integer> pair : selList)
801 selectedVrtxs.add(fragments.get(pair.get(0)));
816 btnChop =
new JButton(
"Chop Structure");
817 btnChop.setToolTipText(String.format(
"<html><body width='%1s'>"
818 +
"Applies cutting rules on "
819 +
"the current structure to generate fragments.</html>", 400));
820 btnChop.addActionListener(
new ActionListener() {
821 public void actionPerformed(ActionEvent event) {
826 JOptionPane.showMessageDialog(
btnChop,
827 "<html>System contains 0 bonds. "
828 +
"Nothing to chop.</html>",
830 JOptionPane.ERROR_MESSAGE,
831 UIManager.getIcon(
"OptionPane.errorIcon"));
838 this.getClass().getClassLoader(),
844 String pathnameLastUsedCutRules =
846 if (pathnameLastUsedCutRules !=
null
847 && !pathnameLastUsedCutRules.isBlank())
849 GUIPreferences.lastCutRulesFile =
850 new File(pathnameLastUsedCutRules);
854 List<Vertex> fragments;
863 JOptionPane.showMessageDialog(
btnChop,String.format(
864 "<html><body width='%1s'"
865 +
"Could not complete fragmentation. Hint: "
866 + e.getMessage() +
"</html>", 400),
868 JOptionPane.ERROR_MESSAGE,
869 UIManager.getIcon(
"OptionPane.errorIcon"));
874 for (
Vertex frag : fragments)
881 if (fragments.size() < 1 || (fragments.size() == 1 &&
885 "<html>Fragmentation produced no fragments!</html>",
887 JOptionPane.WARNING_MESSAGE,
888 UIManager.getIcon(
"OptionPane.warningIcon"));
895 String[] options =
new String[]{
"All",
898 String txt =
"<html><body width='%1s'>Fragmentation produced "
899 + fragments.size() +
" fragments. Do you want to "
900 +
"append all or select some?"
902 int answer = JOptionPane.showOptionDialog(
btnAddVrtx,
903 String.format(txt,200),
904 "Append Building Blocks",
905 JOptionPane.DEFAULT_OPTION,
906 JOptionPane.QUESTION_MESSAGE,
907 UIManager.getIcon(
"OptionPane.warningIcon"),
923 List<Vertex> selectedVrtxs =
924 new ArrayList<Vertex>();
928 vrtxSelector.
load(fragments, 0);
931 if (selected !=
null)
933 @SuppressWarnings(
"unchecked")
934 List<ArrayList<Integer>> selList =
935 (ArrayList<ArrayList<Integer>>) selected;
936 for (ArrayList<Integer> pair : selList)
938 selectedVrtxs.add(fragments.get(pair.get(0)));
954 btnTmplBldChop.setToolTipText(String.format(
"<html><body width='%1s'>"
955 +
"Chops the current structure according to a given graph template expected to be a substructure of the current structure.</html>", 400));
957 public void actionPerformed(ActionEvent event) {
966 if (inFile ==
null || inFile.getAbsolutePath().equals(
""))
971 List<DGraph> fragmentationTmpls =
new ArrayList<>();
975 }
catch (Throwable e)
978 "<html><body width='%1s'"
979 +
"Could not read template file. Hint: "
980 + e.getMessage() +
"</html>", 400),
982 JOptionPane.ERROR_MESSAGE,
983 UIManager.getIcon(
"OptionPane.errorIcon"));
987 if (fragmentationTmpls.size() == 0)
990 "<html>No graphs found in file '"
991 + inFile +
"'.</html>",
993 JOptionPane.ERROR_MESSAGE,
994 UIManager.getIcon(
"OptionPane.errorIcon"));
1002 List<Vertex> fragments;
1012 JOptionPane.showMessageDialog(
btnChop,String.format(
1013 "<html><body width='%1s'"
1014 +
"Could not complete fragmentation. Hint: "
1015 + e.getMessage() +
"</html>", 400),
1017 JOptionPane.ERROR_MESSAGE,
1018 UIManager.getIcon(
"OptionPane.errorIcon"));
1023 for (
Vertex frag : fragments)
1030 if (fragments.size() < 1 || (fragments.size() == 1 &&
1034 "<html>Fragmentation produced no fragments!</html>",
1036 JOptionPane.WARNING_MESSAGE,
1037 UIManager.getIcon(
"OptionPane.warningIcon"));
1044 String[] options =
new String[]{
"All",
1047 String txt =
"<html><body width='%1s'>Fragmentation produced "
1048 + fragments.size() +
" fragments. Do you want to "
1049 +
"append all or select some?"
1051 int answer = JOptionPane.showOptionDialog(
btnAddVrtx,
1052 String.format(txt,200),
1053 "Append Building Blocks",
1054 JOptionPane.DEFAULT_OPTION,
1055 JOptionPane.QUESTION_MESSAGE,
1056 UIManager.getIcon(
"OptionPane.warningIcon"),
1072 List<Vertex> selectedVrtxs =
1073 new ArrayList<Vertex>();
1077 vrtxSelector.
load(fragments, 0);
1080 if (selected !=
null)
1082 @SuppressWarnings(
"unchecked")
1083 List<ArrayList<Integer>> selList =
1084 (ArrayList<ArrayList<Integer>>) selected;
1085 for (ArrayList<Integer> pair : selList)
1087 selectedVrtxs.add(fragments.get(pair.get(0)));
1102 btnDelSel =
new JButton(
"Remove Atoms");
1103 btnDelSel.setToolTipText(
"<html>Removes all selected atoms from the "
1104 +
"system.<br><br><b>WARNING:</b> this action cannot be "
1106 btnDelSel.addActionListener(
new ActionListener() {
1107 public void actionPerformed(ActionEvent e) {
1108 ArrayList<IAtom> selectedAtms =
1111 if (selectedAtms.size() == 0)
1113 JOptionPane.showMessageDialog(
btnDelSel,
1114 "<html>No atom selected! Click on atoms to select"
1115 +
" them.<br>Click again to unselect.</html>",
1117 JOptionPane.ERROR_MESSAGE,
1118 UIManager.getIcon(
"OptionPane.errorIcon"));
1141 btnSaveEdits.setToolTipText(
"<html>Save the current system replacing"
1142 +
" <br>the original one in the loaded library.</html>");
1144 public void actionPerformed(ActionEvent e) {
1150 this.add(
ctrlPane, BorderLayout.EAST);
1155 super.add(commandsPane, BorderLayout.SOUTH);
1157 btnOpenVrtxs =
new JButton(
"Load Library of Building Blocks");
1158 btnOpenVrtxs.setToolTipText(
"Reads building blocks or structures from "
1161 public void actionPerformed(ActionEvent e) {
1163 if (inFile ==
null || inFile.getAbsolutePath().equals(
""))
1167 ArrayList<Vertex> vrtxLib =
new ArrayList<>();
1170 }
catch (Exception e1) {
1171 e1.printStackTrace();
1173 "<html>Could not read building blocks from file"
1174 +
"<br>'" + inFile +
"'"
1175 +
"<br>Hint on cause: " + e1.getMessage()
1178 JOptionPane.ERROR_MESSAGE,
1179 UIManager.getIcon(
"OptionPane.errorIcon"));
1183 if (vrtxLib.size() == 0)
1186 "<html>No building blocks in file"
1187 +
"<br>'" + inFile +
"'</html>",
1189 JOptionPane.ERROR_MESSAGE,
1190 UIManager.getIcon(
"OptionPane.errorIcon"));
1198 JButton btnSaveVrtxs =
new JButton(
"Save Library of Building Blocks");
1199 btnSaveVrtxs.setToolTipText(
"Write all building blocks to a file.");
1200 btnSaveVrtxs.addActionListener(
new ActionListener() {
1201 public void actionPerformed(ActionEvent e) {
1204 if (fileAndFormat ==
null)
1208 File outFile = fileAndFormat.
file;
1217 catch (Exception ex)
1219 ex.printStackTrace();
1220 JOptionPane.showMessageDialog(btnSaveVrtxs,
1221 "Could not write to '" + outFile +
"'! "
1222 +
"Hint: "+ex.getMessage(),
1224 JOptionPane.PLAIN_MESSAGE,
1225 UIManager.getIcon(
"OptionPane.errorIcon"));
1235 commandsPane.
add(btnSaveVrtxs);
1237 JButton btnCanc =
new JButton(
"Close Tab");
1238 btnCanc.setToolTipText(
"Closes this tab.");
1240 commandsPane.
add(btnCanc);
1242 JButton btnHelp =
new JButton(
"?");
1243 btnHelp.setToolTipText(
"<html>Hover over the buttons and fields "
1244 +
"to get a tip.</html>");
1245 btnHelp.addActionListener(
new ActionListener() {
1246 public void actionPerformed(ActionEvent e) {
1247 String txt =
"<html><body width='%1s'>"
1248 +
"<p>This tab allows to create, inspect, and edit "
1249 +
"building blocks and "
1250 +
"three-dimensional molecular fragments.</p>"
1251 +
"<p>New fragments can be created starting from any "
1252 +
"chemical structure that can be loaded from file or "
1253 +
"generated from SMILES (SMILES-to-3D conversion "
1254 +
"requires an Internet connection).</p>"
1255 +
"<p>Any terminal atom (i.e., atoms that have only "
1256 +
"one connected neighbor) can be transformed into "
1257 +
"on attachment point (AP). Click on the atom to "
1258 +
"select it, and press <code><b>Atom to AP</b></code>."
1260 +
"<p>Attachment points are depicted in the molecular "
1261 +
"viewer as yellow arrows in the 3D space, and their "
1262 +
"attachment point class (APClass) is specified in "
1263 +
"the table below the viewer. Double-click on a "
1264 +
"specific APClass field to change its value.</p>"
1266 +
"<p>Hover over buttons get a tip.</p>"
1268 +
"<p>Right-click on the Jmol viewer will open the "
1269 +
"Jmol menu. However, since Jmol cannot handle the "
1270 +
"attachment points data. Therefore, Jmol "
1271 +
"functionality should only be used on systems "
1272 +
"that have no attachment points, or for alterations "
1273 +
"of the molecular structure that do not change the "
1274 +
"list of atoms au to the last atom decorated with an "
1275 +
"attachment point.</p></html>";
1276 JOptionPane.showMessageDialog(btnHelp,
1277 String.format(txt, 400),
1279 JOptionPane.PLAIN_MESSAGE);
1282 commandsPane.
add(btnHelp);
1300 boolean setMolToGraphSettings)
1304 List<CuttingRule> defaultCuttingRules =
new ArrayList<CuttingRule>();
1308 }
catch (Exception e )
1310 e.printStackTrace();
1311 JOptionPane.showMessageDialog(parent,String.format(
1312 "<html><body width='%1s'>"
1313 +
"Could not read default cutting rules from "
1316 + e.getMessage() +
"</html>", 400),
1318 JOptionPane.ERROR_MESSAGE,
1319 UIManager.getIcon(
"OptionPane.errorIcon"));
1324 List<CuttingRule> customCuttingRules =
new ArrayList<CuttingRule>();
1325 boolean useDefaultCuttingRules =
true;
1332 customCuttingRules);
1333 useDefaultCuttingRules =
false;
1337 JOptionPane.showMessageDialog(parent,String.format(
1338 "<html><body width='%1s'"
1339 +
"Could not read last-used cutting rules from '"
1342 + e.getMessage() +
"</html>", 400),
1344 JOptionPane.ERROR_MESSAGE,
1345 UIManager.getIcon(
"OptionPane.errorIcon"));
1352 if (setMolToGraphSettings)
1355 defaultCuttingRules, customCuttingRules,
1356 useDefaultCuttingRules, parent, settings);
1359 defaultCuttingRules, customCuttingRules,
1360 useDefaultCuttingRules, parent, settings);
1363 crs.setVisible(
true);
1369 if (pathnameLastUsedCutRules !=
null
1370 && !pathnameLastUsedCutRules.isBlank())
1372 GUIPreferences.lastCutRulesFile =
new File(pathnameLastUsedCutRules);
1382 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1411 }
catch (Exception e) {
1412 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1413 e.printStackTrace();
1414 JOptionPane.showMessageDialog(
this,
1415 "<html>Could not read file '" + file.getAbsolutePath()
1416 +
"'!<br>Hint about reason: " + e.getCause() +
"</html>",
1418 JOptionPane.PLAIN_MESSAGE,
1419 UIManager.getIcon(
"OptionPane.errorIcon"));
1422 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1435 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1443 }
catch (Exception e) {
1444 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1464 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1475 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1477 ArrayList<Vertex> vrtxLib =
new ArrayList<>();
1480 }
catch (Exception e1) {
1481 e1.printStackTrace();
1483 "<html>Could not read building blocks from file"
1484 +
"<br>'" + file +
"'"
1485 +
"<br>Hint on cause: " + e1.getMessage()
1488 JOptionPane.ERROR_MESSAGE,
1489 UIManager.getIcon(
"OptionPane.errorIcon"));
1493 if (vrtxLib.size() == 0)
1496 "<html>No building blocks in file"
1497 +
"<br>'" + file +
"'</html>",
1499 JOptionPane.ERROR_MESSAGE,
1500 UIManager.getIcon(
"OptionPane.errorIcon"));
1504 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1515 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1518 boolean libFromScrtch =
false;
1521 libFromScrtch =
true;
1529 boolean addedOne =
false;
1530 if (fragments.size() > 0)
1549 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1550 JOptionPane.showMessageDialog(
this,
1551 "<html>No vertices to import from the given list.</html>",
1553 JOptionPane.PLAIN_MESSAGE,
1554 UIManager.getIcon(
"OptionPane.errorIcon"));
1556 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1573 JOptionPane.showMessageDialog(
this,
1574 "No list of building blocks loaded.",
1576 JOptionPane.PLAIN_MESSAGE,
1577 UIManager.getIcon(
"OptionPane.errorIcon"));
1639 str = str +
" " + atm.getSymbol()
1642 System.out.println(
"Connected atoms: "+str);
1644 JOptionPane.showMessageDialog(
this,
1645 "<html>Atom "+ trgAtm.getSymbol()
1647 +
" has zero or more than one neighbour.<br>I can only "
1649 +
" that have one and only one neighbour.</html>",
1651 JOptionPane.ERROR_MESSAGE,
1652 UIManager.getIcon(
"OptionPane.errorIcon"));
1658 srcAtm.getBond(trgAtm).getOrder().toString());
1662 Point3d vector =
new Point3d();
1663 vector.x = srcP3d.x + (trgP3d.x - srcP3d.x);
1664 vector.y = srcP3d.y + (trgP3d.y - srcP3d.y);
1665 vector.z = srcP3d.z + (trgP3d.z - srcP3d.z);
1668 String[] parts = ruleAndSubClass.split(
1674 Integer.parseInt(parts[1]), bt), vector);
1676 e.printStackTrace();
1677 JOptionPane.showMessageDialog(
this,
1678 "<html>Could not make AP.<br>Possible cause: "
1679 + e.getMessage() +
"</html>",
1681 JOptionPane.ERROR_MESSAGE,
1682 UIManager.getIcon(
"OptionPane.errorIcon"));
1697 ArrayList<IBond> bnsToDel =
new ArrayList<IBond>();
1698 for (IAtom atm : atmsToDels)
1700 for (IBond bnd : frag.
bonds())
1702 if (bnd.contains(atm))
1708 for (IBond bnd : bnsToDel)
1712 for (IAtom atm : atmsToDels)
1740 this.inEnabled = var;
1783 .getTextField().setEditable(
true);
1785 .getTextField().setForeground(Color.BLACK);
1808 .getTextField().setEditable(
false);
1810 .getTextField().setForeground(Color.GRAY);
1830 String[] options =
new String[]{
"Yes",
"No"};
1831 int res = JOptionPane.showOptionDialog(
this,
1832 "<html>Removing unsaved vertex?",
1834 JOptionPane.DEFAULT_OPTION,
1835 JOptionPane.QUESTION_MESSAGE,
1836 UIManager.getIcon(
"OptionPane.warningIcon"),
1868 navigSpinner.setModel(
new SpinnerNumberModel(0,0,0,1));
1887 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1893 for (
int i=0; i<tabModel.getRowCount(); i++)
1895 int apId = ((Integer) tabModel.getValueAt(i, 0)).intValue();
1896 String currApClass = tabModel.getValueAt(i, 1).toString();
1901 apcDefiner.setTitle(
"Confirm APClass on AP #"+i);
1906 Object[] pair = (Object[]) chosen;
1907 currApClass = pair[0].toString();
1909 currApClass =
"dafaultAPClass:0";
1912 Map<Integer, AttachmentPoint> mapAPs =
1915 if (mapAPs.containsKey(apId))
1917 String origApClass = mapAPs.get(apId).getAPClass().toString();
1918 if (!origApClass.equals(currApClass))
1921 mapAPs.get(apId).setAPClass(currApClass);
1925 e.printStackTrace();
1927 "<html>Could not save due to errors setting a "
1928 +
"new APClass.<br>Please report this to the "
1929 +
"DENOPTIM team.</html>",
1931 JOptionPane.PLAIN_MESSAGE,
1932 UIManager.getIcon(
"OptionPane.errorIcon"));
1940 "<html>Could not save due to mistmatch between AP "
1941 +
"table and map.<br>Please report this to the "
1942 +
"DENOPTIM team.</html>",
1944 JOptionPane.PLAIN_MESSAGE,
1945 UIManager.getIcon(
"OptionPane.errorIcon"));
1958 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1967 }
catch (Throwable t) {
1978 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1992 boolean singleSelection)
2009 boolean singleSelection, String title)
2012 DefaultListModel<String> apClassLstModel =
2013 new DefaultListModel<String>();
2014 JList<String> apClassList =
new JList<String>(apClassLstModel);
2017 apClassLstModel.addElement(apc);
2020 apClassLstModel.addElement(
2021 "<html><b><i>Define a new APClass...<i></b></html>");
2022 if (singleSelection)
2024 apClassList.setSelectionMode(
2025 ListSelectionModel.SINGLE_SELECTION);
2027 apClassList.setSelectionMode(
2028 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
2030 if (apClassList.getModel().getSize() == 1)
2032 apClassList.setSelectedIndex(0);
2034 apClassList.setSelectedIndex(apClassLstModel.getSize()-1);
2038 JPanel chooseApPanel =
new JPanel();
2039 JLabel header =
new JLabel(
"Choose APClass:");
2040 JScrollPane apClassScroll =
new JScrollPane(apClassList);
2041 chooseApPanel.add(header);
2042 chooseApPanel.add(apClassScroll);
2044 int res = JOptionPane.showConfirmDialog(parent,
2047 JOptionPane.OK_CANCEL_OPTION,
2048 JOptionPane.PLAIN_MESSAGE,
2050 if (res != JOptionPane.OK_OPTION)
2052 return new ArrayList<APClass>();
2056 ArrayList<APClass> selectedSPCs =
new ArrayList<APClass>();
2057 int[] selectedIds = apClassList.getSelectedIndices();
2058 if (selectedIds.length > 0)
2060 for (
int ii=0; ii<selectedIds.length; ii++)
2063 Integer idAPC = selectedIds[ii];
2066 if (idAPC.intValue() == (apClassLstModel.size()-1))
2074 Object[] pair = (Object[]) chosen;
2079 apc =
APClass.
make(apClassLstModel.getElementAt(idAPC));
2081 }
catch (Exception e1) {
2085 selectedSPCs.add(apc);
2088 return selectedSPCs;
2102 String title,
boolean mustReply, JComponent parent)
2108 if (currApRule !=
"")
2110 preStr =
"APRule '" + currApRule +
"' is not valid!<br>"
2111 +
"The valid syntax for APClass is:<br><br><code>APRule"
2112 + DENOPTIMConstants.SEPARATORAPPROPSCL
2113 +
"subClass</code><br><br> where "
2114 +
"<ul><li><code>APRule</code>"
2115 +
" is the string you should provide now, and is "
2116 +
"typically any string with no spaces,</li>"
2117 +
"<li><code>subClass</code> is an integer.</ul>";
2120 currApRule = JOptionPane.showInputDialog(parent,String.format(
2121 "<html><body width='%1s'>" + preStr
2122 +
" Please, provide a valid APClass rule string: </html>",
2125 JOptionPane.PLAIN_MESSAGE);
2127 if (currApRule ==
null)
General set of constants used in DENOPTIM.
static final String ATMPROPAPS
String tag of Atom property used to store attachment points.
static final String APSTAG
SDF tag defining attachment points.
static final String SEPARATORAPPROPSCL
Separator between APClass and APSubClass and coordinates.
static void addToRecentFiles(String fileName, FileFormat ff)
Appends an entry to the list of recent files.
static List< String > getAllAPClassesAsString()
Returns the list of the names of all APClasses.
static boolean isValidAPRuleString(String s)
Evaluates the given string as a candidate attachment point rule, i.e., as name of a fragmentation rul...
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
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.
IBond removeBond(int position)
List< IAtom > getConnectedAtomsList(IAtom atom)
AttachmentPoint addAPOnAtom(IAtom srcAtm, APClass apc, Point3d vector)
Add an attachment point to the specifies atom.
List< AttachmentPoint > getAttachmentPoints()
ArrayList< AttachmentPoint > getAPsFromAtom(IAtom srcAtm)
void removeAtom(IAtom atom)
void updateAPs()
Changes the properties of each APs as to reflect the current atom list.
Iterable< IBond > bonds()
int getConnectedAtomsCount(IAtom atom)
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
abstract IAtomContainer getIAtomContainer()
A modal dialog to define parameters for fragmentation and fragment filtering.
void setPreDefinedAPClass(String text)
Sets the content of the text field with the given predefined text.
A dialog window meant only to select atoms one or multiple times.
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)
GUI component to provide pathname where to save stuff.
static FileAndFormat pickFileForSavingVertexes(Component parent)
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 result
The result to be returned once the dialog is closed.
Object showDialog()
Shows the dialog and restrains the modality to it, until the dialog gets closed.
The collection of tunable preferences.
static File lastCutRulesFile
File with last used cutting rules.
void setEnabled(boolean var)
Enables/disable the listener.
void stateChanged(ChangeEvent event)
A panel with a viewer capable of visualising DENOPTIM fragments and allows to create and edit fragmen...
void updateVrtxListSpinner()
void clearCurrentSystem()
static String ensureGoodAPRuleString(String currApRule, String title, boolean mustReply, JComponent parent)
Forces the user to specify a properly formatted APRule, i.e., the first component of an APClass.
void saveUnsavedChanges()
ArrayList< Vertex > verticesLibrary
The currently loaded list of fragments.
final VrtxSpinnerChangeEvent vrtxSpinnerListener
Vertex vertex
The currently loaded vertex.
void importStructureFromSMILES(String smiles)
Imports the given SMILES into the viewer.
void deprotectEditedSystem()
static AtomicInteger prepVrtxTabUID
Unique identified for instances of this inspector.
void importVerticesFromFile(File file)
Imports fragments from a file.
VertexViewPanel vertexViewer
void importVertices(List< Vertex > fragments)
Imports vertices.
boolean convertAtomToAP(IAtom trgAtm, String ruleAndSubClass)
Removes an atom and replaces it with an attachment point.
boolean unsavedChanges
Flag signaling that loaded data has changes since last save.
void importStructureFromFile(File file)
int currVrtxIdx
The index of the currently loaded fragment [0–(n-1)}.
boolean hasUnsavedChanges()
Check whether there are unsaved changes.
static List< APClass > choseOrCreateNewAPClass(JComponent parent, boolean singleSelection)
Runs a dialog aimed at selecting an existing APClass or defining a new one.
GUIVertexInspector(GUIMainPanel mainPanel)
Constructor.
void initialize()
Initialize the panel and add buttons.
void protectEditedSystem()
void loadCurrentVrtxIdxToViewer()
Loads the fragments corresponding to the field index.
void removeAtoms(ArrayList< IAtom > atmsToDels)
static final long serialVersionUID
Version UID.
static boolean dialogToDefineCuttingRules(FragmenterParameters settings, ClassLoader classLoader, Component parent, boolean setMolToGraphSettings)
Starts a dialog to define the on-the-fly fragmentation settings.
static List< APClass > choseOrCreateNewAPClass(JComponent parent, boolean singleSelection, String title)
Runs a dialog aimed at selecting an existing APClass or defining a new one.
void activateTabEditsListener(boolean var)
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 ...
A panel for visualizing vertices.
void clearCurrentSystem()
Removes the currently visualized molecule and AP table.
boolean hasUnsavedAPEdits()
Check for unsaved edits to the AP data.
DefaultTableModel getAPTableModel()
void activateTabEditsListener(boolean var)
Allows to activate and deactivate the listener.
Map< Integer, AttachmentPoint > getActiveMapAPs()
Returns the map of attachment points in the currently active viewer.
void deprotectEdits()
Overrides the flag signaling unsaved edits to saying that there are no altered data.
void loadVertexToViewer(Vertex v)
Loads the given vertex to this viewer.
Vertex getLoadedStructure()
Returns the currently loaded vertex.
void loadPlainStructure(IAtomContainer mol)
Loads a structure in the Jmol viewer.
boolean loadSMILES(String smiles)
Loads a molecule build from a smiles string.
void setSwitchable(boolean switchable)
Enable/disable switch-able view.
ArrayList< IAtom > getAtomsSelectedFromJMol()
Identifies the atoms that are selected in the Jmol viewer.
void clearMolecularViewer(boolean dataIsComing)
Clears the molecular viewer.
Utility methods for input/output.
static File writeVertexesToFile(File file, FileFormat format, List< Vertex > vertexes)
Writes vertexes to file.
static void readCuttingRules(BufferedReader reader, List< CuttingRule > cutRules, String source)
Read cutting rules from a stream.
static ArrayList< DGraph > readDENOPTIMGraphsFromFile(File inFile)
Reads a list of DGraphs from file.
static ArrayList< Vertex > readVertexes(File file, Vertex.BBType bbt)
Reads Vertexes from any file that can contain such items.
static List< IAtomContainer > readAllAtomContainers(File file)
Returns a single collection with all atom containers found in a file of any format.
Logger getLogger()
Get the name of the program specific logger.
Logger startConsoleLogger(String loggerIdentifier)
Starts a program-specific logger that prints to System.err stream.
Randomizer getRandomizer()
Returns the current program-specific randomizer.
Parameters controlling execution of the fragmenter.
double getLinearAngleLimit()
String getCuttingRulesFilePathname()
void setFragmentationTmpls(List< DGraph > fragmentationTmpls)
Sets the list of graph templates for fragmentation.
List< DGraph > getFragmentationTmpls()
List< CuttingRule > getCuttingRules()
int getMaxBufferShellSize()
List< CuttingRule > getDefaultCuttingRules()
Get default cutting rules from the class loader of the current class.
Toll to add/remove dummy atoms from linearities or multi-hapto sites.
static void addDummiesOnLinearities(Fragment frag, double angLim)
Append dummy atoms on otherwise linear arrangements of atoms.
Utilities for molecule conversion.
static String getAtomRef(IAtom atm, IAtomContainer mol)
static Point3d getPoint3d(IAtom atm)
Return the 3D coordinates, if present.
Possible chemical bond types an edge can represent.
The type of building block.
Interface for all vertex viewers that intend to allow selection of attachment points.
final String APDATACHANGEEVENT