From 0b00b079074351ec4318357b9657e07c4af01af7 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 1 Oct 2024 16:37:25 -0400 Subject: [PATCH 01/28] Trick to display different properties panels for the same SpeciesContextSpec object --- .../desktop/biomodel/BioModelEditor.java | 9 ++---- .../mapping/gui/InitialConditionsPanel.java | 2 +- .../gui/SpeciesContextSpecsTableModel.java | 30 ++++++++++++------- .../gui/MolecularStructuresPanel.java | 2 +- .../mapping/LangevinSpeciesContextSpec.java | 14 +++++++++ 5 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java diff --git a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java index d03bc4d481..70485bbd1a 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java +++ b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java @@ -24,6 +24,7 @@ import javax.swing.JComponent; import javax.swing.ListSelectionModel; +import cbit.vcell.mapping.*; import org.vcell.model.rbm.MolecularType; import org.vcell.model.rbm.SpeciesPattern; import org.vcell.pathway.BioPaxObject; @@ -56,15 +57,9 @@ import cbit.vcell.geometry.CSGObject; import cbit.vcell.geometry.GeometryInfo; import cbit.vcell.geometry.gui.CSGObjectPropertiesPanel; -import cbit.vcell.mapping.BioEvent; -import cbit.vcell.mapping.MathMappingCallbackTaskAdapter; -import cbit.vcell.mapping.ReactionRuleSpec; -import cbit.vcell.mapping.ReactionSpec; -import cbit.vcell.mapping.SimulationContext; import cbit.vcell.mapping.SimulationContext.Application; import cbit.vcell.mapping.SimulationContext.MathMappingCallback; import cbit.vcell.mapping.SimulationContext.NetworkGenerationRequirements; -import cbit.vcell.mapping.SpeciesContextSpec; import cbit.vcell.mapping.gui.DataSymbolsSpecPanel; import cbit.vcell.mapping.gui.ReactionRuleSpecPropertiesPanel; import cbit.vcell.mapping.gui.SpatialObjectPropertyPanel; @@ -768,6 +763,8 @@ protected void setRightBottomPanelOnSelection(Object[] selections) { } else if (singleSelection instanceof GeometryInfo) { bShowInDatabaseProperties = true; bottomComponent = geometryMetaDataPanel; + } else if (singleSelection instanceof LangevinSpeciesContextSpec) { + bottomComponent = getSpeciesContextSpecPanel(); } else if (singleSelection instanceof SpeciesContextSpec) { bottomComponent = getSpeciesContextSpecPanel(); } else if (singleSelection instanceof ReactionSpec) { diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java index 1fb19ea247..06bd23ec97 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java @@ -440,7 +440,7 @@ private JSortTable getScrollPaneTable() { try { table = new JSortTable(); table.setName("spceciesContextSpecsTable"); - tableModel = new SpeciesContextSpecsTableModel(table); + tableModel = new SpeciesContextSpecsTableModel(table, this); table.setModel(tableModel); table.setScrollTableActionManager(new InternalScrollTableActionManager(table)); table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java index f44b9fac4a..8656391673 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java @@ -14,10 +14,11 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; -import java.util.TreeSet; -import cbit.vcell.model.Membrane; +import cbit.vcell.client.desktop.biomodel.DocumentEditorSubPanel; +import cbit.vcell.mapping.*; import org.vcell.model.rbm.SpeciesPattern; +import org.vcell.model.springsalad.gui.MolecularStructuresPanel; import org.vcell.util.Displayable; import org.vcell.util.gui.GuiUtils; import org.vcell.util.gui.ScrollTable; @@ -25,19 +26,12 @@ import cbit.gui.ScopedExpression; import cbit.vcell.client.PopupGenerator; import cbit.vcell.client.desktop.biomodel.VCellSortTableModel; -import cbit.vcell.mapping.AssignmentRule; -import cbit.vcell.mapping.GeometryContext; -import cbit.vcell.mapping.RateRule; -import cbit.vcell.mapping.ReactionContext; -import cbit.vcell.mapping.SimulationContext; -import cbit.vcell.mapping.SpeciesContextSpec; import cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter; import cbit.vcell.model.Parameter; import cbit.vcell.model.SpeciesContext; import cbit.vcell.model.Structure; import cbit.vcell.parser.AutoCompleteSymbolFilter; import cbit.vcell.parser.Expression; -import cbit.vcell.parser.ExpressionBindingException; import cbit.vcell.parser.ExpressionException; import cbit.vcell.parser.SymbolTableEntry; /** @@ -86,12 +80,14 @@ private ColumnType(String label){ private AutoCompleteSymbolFilter autoCompleteSymbolFilter = null; private boolean bEditable = true; // this.isCellEditable() decides + private final DocumentEditorSubPanel owner; /** * ReactionSpecsTableModel constructor comment. */ -public SpeciesContextSpecsTableModel(ScrollTable table) { +public SpeciesContextSpecsTableModel(ScrollTable table, DocumentEditorSubPanel owner) { super(table); + this.owner = owner; refreshColumns(); } @@ -284,6 +280,18 @@ public Object getValueAt(int row, int col) { } } +@Override +public SpeciesContextSpec getValueAt(int row) { + if(owner instanceof MolecularStructuresPanel) { + SpeciesContextSpec scs = super.getValueAt(row); + if(scs != null) { + LangevinSpeciesContextSpec lscs = new LangevinSpeciesContextSpec(scs, scs.getSimulationContext()); + return lscs; + } + } + return super.getValueAt(row); +} + /** * Insert the method's description here. * Creation date: (2/24/01 12:27:46 AM) @@ -671,7 +679,7 @@ private void updateListenersReactionContext(ReactionContext reactionContext,bool public Comparator getComparator(final int col, final boolean ascending) { - return new Comparator() { + return new Comparator<>() { /** * Compares its two arguments for order. Returns a negative integer, * zero, or a positive integer as the first argument is less than, equal diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 3606f71825..5b3d1f5168 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -659,7 +659,7 @@ private EditorScrollTable getSpeciesContextSpecsTable() { try { speciesContextSpecsTable = new EditorScrollTable(); speciesContextSpecsTable.setName("spceciesContextSpecsTable"); - speciesContextSpecsTableModel = new SpeciesContextSpecsTableModel(speciesContextSpecsTable); + speciesContextSpecsTableModel = new SpeciesContextSpecsTableModel(speciesContextSpecsTable, this); speciesContextSpecsTableModel.setEditable(false); speciesContextSpecsTable.setModel(speciesContextSpecsTableModel); // speciesContextSpecsTable.setScrollTableActionManager(new InternalScrollTableActionManager(speciesContextSpecsTable)); diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java new file mode 100644 index 0000000000..2fd8f0c3a0 --- /dev/null +++ b/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java @@ -0,0 +1,14 @@ +package cbit.vcell.mapping; + +import cbit.vcell.model.SpeciesContext; + +public class LangevinSpeciesContextSpec extends SpeciesContextSpec { + + public LangevinSpeciesContextSpec(SpeciesContextSpec speciesContextSpec, SimulationContext argSimulationContext) { + super(speciesContextSpec, argSimulationContext); + } + + public LangevinSpeciesContextSpec(SpeciesContext speciesContext, SimulationContext argSimulationContext) { + super(speciesContext, argSimulationContext); + } +} From 00c216b30582a2334984b7cd14d4b2b968d64fab Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 1 Oct 2024 16:40:48 -0400 Subject: [PATCH 02/28] WIP fixing errors --- .../cbit/vcell/client/desktop/biomodel/BioModelEditor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java index 70485bbd1a..449e3f349c 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java +++ b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java @@ -1003,7 +1003,6 @@ private BioModelEditorApplicationsPanel getBioModelEditorApplicationsPanel() { /** * Sets the bioModel property (cbit.vcell.biomodel.BioModel) value. * @param bioModel The new value for the property. - * @see #getBioModel */ public void setBioModel(BioModel bioModel) { if (this.bioModel == bioModel) { @@ -1038,7 +1037,7 @@ public void setBioModel(BioModel bioModel) { /** * Insert the method's description here. * Creation date: (5/7/2004 5:40:13 PM) - * @param newBioModelWindowManager cbit.vcell.client.desktop.BioModelWindowManager + * @param bioModelWindowManager cbit.vcell.client.desktop.BioModelWindowManager */ public void setBioModelWindowManager(BioModelWindowManager bioModelWindowManager) { if (this.bioModelWindowManager == bioModelWindowManager) { From e294a61cf15b16a9fb925352c15f53bbf6607321 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 3 Oct 2024 17:14:50 -0400 Subject: [PATCH 03/28] Manage tricky selection for LangevinSpeciesContext step class, stub for Molecular structures properties panel --- .../desktop/biomodel/BioModelEditor.java | 22 +- .../vcell/graph/gui/SsldLargeShapePanel.java | 77 ++++++ .../MolecularStructuresPropertiesPanel.java | 226 ++++++++++++++++++ .../mapping/gui/SpeciesContextSpecPanel.java | 4 +- .../gui/MolecularStructuresPanel.java | 8 +- .../mapping/LangevinSpeciesContextSpec.java | 8 +- 6 files changed, 335 insertions(+), 10 deletions(-) create mode 100644 vcell-client/src/main/java/cbit/vcell/graph/gui/SsldLargeShapePanel.java create mode 100644 vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java diff --git a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java index 449e3f349c..e9c0a376f4 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java +++ b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java @@ -25,6 +25,7 @@ import javax.swing.ListSelectionModel; import cbit.vcell.mapping.*; +import cbit.vcell.mapping.gui.*; import org.vcell.model.rbm.MolecularType; import org.vcell.model.rbm.SpeciesPattern; import org.vcell.pathway.BioPaxObject; @@ -60,11 +61,6 @@ import cbit.vcell.mapping.SimulationContext.Application; import cbit.vcell.mapping.SimulationContext.MathMappingCallback; import cbit.vcell.mapping.SimulationContext.NetworkGenerationRequirements; -import cbit.vcell.mapping.gui.DataSymbolsSpecPanel; -import cbit.vcell.mapping.gui.ReactionRuleSpecPropertiesPanel; -import cbit.vcell.mapping.gui.SpatialObjectPropertyPanel; -import cbit.vcell.mapping.gui.SpatialProcessPropertyPanel; -import cbit.vcell.mapping.gui.SpeciesContextSpecPanel; import cbit.vcell.mapping.spatial.SpatialObject; import cbit.vcell.mapping.spatial.processes.SpatialProcess; import cbit.vcell.model.Model; @@ -127,6 +123,7 @@ public class BioModelEditor extends DocumentEditor { private ReactionParticipantPropertiesPanel reactionParticipantPropertiesPanel = null; private ApplicationPropertiesPanel applicationPropertiesPanel = null; private SpeciesContextSpecPanel speciesContextSpecPanel = null; + private MolecularStructuresPropertiesPanel molecularStructuresPropertiesPanel = null; private KineticsTypeTemplatePanel kineticsTypeTemplatePanel = null; private ReactionRuleSpecPropertiesPanel reactionRuleSpecPropertiesPanel = null; private SimulationSummaryPanel simulationSummaryPanel = null; @@ -626,6 +623,17 @@ private SpeciesContextSpecPanel getSpeciesContextSpecPanel() { } return speciesContextSpecPanel; } + private MolecularStructuresPropertiesPanel getMolecularStructuresPropertiesPanel() { + if (molecularStructuresPropertiesPanel == null) { + try { + molecularStructuresPropertiesPanel = new MolecularStructuresPropertiesPanel(); + molecularStructuresPropertiesPanel.setName("MolecularStructuresPropertiesPanel"); + } catch (java.lang.Throwable ivjExc) { + handleException(ivjExc); + } + } + return molecularStructuresPropertiesPanel; + } private void initialize() { try { @@ -676,6 +684,7 @@ private void initialize() { getReactionRulePropertiesPanel().setSelectionManager(selectionManager); getReactionPropertiesPanel().setSelectionManager(selectionManager); getSpeciesContextSpecPanel().setSelectionManager(selectionManager); + getMolecularStructuresPropertiesPanel().setSelectionManager(selectionManager); getReactionRuleSpecPropertiesPanel().setSelectionManager(selectionManager); getSpatialObjectPropertyPanel().setSelectionManager(selectionManager); getSpatialProcessPropertyPanel().setSelectionManager(selectionManager); @@ -764,7 +773,7 @@ protected void setRightBottomPanelOnSelection(Object[] selections) { bShowInDatabaseProperties = true; bottomComponent = geometryMetaDataPanel; } else if (singleSelection instanceof LangevinSpeciesContextSpec) { - bottomComponent = getSpeciesContextSpecPanel(); + bottomComponent = getMolecularStructuresPropertiesPanel(); } else if (singleSelection instanceof SpeciesContextSpec) { bottomComponent = getSpeciesContextSpecPanel(); } else if (singleSelection instanceof ReactionSpec) { @@ -1012,6 +1021,7 @@ public void setBioModel(BioModel bioModel) { bioModelEditorModelPanel.setBioModel(bioModel); getBioModelEditorApplicationsPanel().setBioModel(bioModel); getSpeciesContextSpecPanel().setBioModel(bioModel); + getMolecularStructuresPropertiesPanel().setBioModel(bioModel); getReactionRuleSpecPropertiesPanel().setBioModel(bioModel); getScriptingPanel().setBioModel(bioModel); getBioModelEditorPathwayPanel().setBioModel(bioModel); diff --git a/vcell-client/src/main/java/cbit/vcell/graph/gui/SsldLargeShapePanel.java b/vcell-client/src/main/java/cbit/vcell/graph/gui/SsldLargeShapePanel.java new file mode 100644 index 0000000000..ae0dc342aa --- /dev/null +++ b/vcell-client/src/main/java/cbit/vcell/graph/gui/SsldLargeShapePanel.java @@ -0,0 +1,77 @@ +package cbit.vcell.graph.gui; + +import javax.swing.*; + +public class SsldLargeShapePanel extends JPanel { + +// private boolean showDifferencesOnly = false; +// private boolean bShowMoleculeColor = false; +// private boolean bShowNonTrivialOnly = false; + + + // zooming the shape, 0 means normal size, a negative number means smaller shape + private static final int SmallestZoomFactor = -7; // -7 is the smallest where the shapes scale decently well + private static final int DefaultZoomFactor = 0; + private static final int LargestZoomFactor = 0; + private int zoomFactor = DefaultZoomFactor; + + // by default the shapes are editable and their border and text is black / gray, aso + // otherwise they are a shade of brown, very much alike the DefaultScrollTableCellRenderer.uneditableForeground + private boolean editable = true; + + + +// public void setShowMoleculeColor(boolean bShowMoleculeColor) { +// this.bShowMoleculeColor = bShowMoleculeColor; +// } +// public void setShowNonTrivialOnly(boolean bShowNonTrivialOnly) { +// this.bShowNonTrivialOnly = bShowNonTrivialOnly; +// } + + + public boolean zoomLarger() { // returns false when upper limit was reached + zoomFactor++; + if(zoomFactor >= LargestZoomFactor) { + zoomFactor = LargestZoomFactor; + System.out.println("MAX. Factor is " + zoomFactor); + return false; + } else { + System.out.println("Up. Factor is " + zoomFactor); + return true; + } + } + public void setZoomFactor(int newZoomFactor) { + if(newZoomFactor > LargestZoomFactor || newZoomFactor < SmallestZoomFactor) { + throw new RuntimeException("Large Shape Panel zoom factor is out of bounds"); + } + zoomFactor = newZoomFactor; + } + public boolean zoomSmaller() { // returns false when lower limit was reached + zoomFactor--; + if(zoomFactor <= SmallestZoomFactor) { + zoomFactor = SmallestZoomFactor; + System.out.println("MIN. Factor is " + zoomFactor); + return false; + } else { + System.out.println("Down. Factor is " + zoomFactor); + return true; + } + } + public boolean isLargestZoomFactor() { + return zoomFactor >= LargestZoomFactor ? true : false; + } + public boolean isSmallestZoomFactor() { + return zoomFactor <= SmallestZoomFactor ? true : false; + } + public int getZoomFactor() { + return zoomFactor; + } + + public void setEditable(boolean editable) { + this.editable = editable; + } + public boolean isEditable() { + return editable; + } + +} diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java new file mode 100644 index 0000000000..c2dbab6315 --- /dev/null +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -0,0 +1,226 @@ +package cbit.vcell.mapping.gui; + +import cbit.vcell.biomodel.BioModel; +import cbit.vcell.client.desktop.biomodel.DocumentEditorSubPanel; +import cbit.vcell.graph.PointLocationInShapeContext; +import cbit.vcell.graph.SpeciesPatternLargeShape; +import cbit.vcell.graph.gui.LargeShapePanel; +import cbit.vcell.graph.gui.SsldLargeShapePanel; +import cbit.vcell.graph.gui.ZoomShapeIcon; +import cbit.vcell.mapping.LangevinSpeciesContextSpec; +import cbit.vcell.mapping.SpeciesContextSpec; +import cbit.vcell.model.Model; +import cbit.vcell.model.SpeciesContext; +import cbit.vcell.parser.ExpressionException; +import org.vcell.model.rbm.SpeciesPattern; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +public class MolecularStructuresPropertiesPanel extends DocumentEditorSubPanel { + + private BioModel bioModel = null; + private SpeciesContext speciesContext = null; + private EventHandler eventHandler = new EventHandler(); + + private JScrollPane scrollPane; // shapePanel lives inside this + private SpeciesPatternLargeShape spls; // make the real thing + private SsldLargeShapePanel shapePanel = null; + + + private JButton zoomLargerButton = null; + private JButton zoomSmallerButton = null; + + + private class EventHandler implements ActionListener { + public void actionPerformed(java.awt.event.ActionEvent e) { + if (e.getSource() == getZoomLargerButton()) { + boolean ret = shapePanel.zoomLarger(); + getZoomLargerButton().setEnabled(ret); + getZoomSmallerButton().setEnabled(true); + updateShape(); + } else if (e.getSource() == getZoomSmallerButton()) { + boolean ret = shapePanel.zoomSmaller(); + getZoomLargerButton().setEnabled(true); + getZoomSmallerButton().setEnabled(ret); + updateShape(); + } + } + } + + + public MolecularStructuresPropertiesPanel() { + super(); + initialize(); + } + + private void handleException(Throwable exception) { + /* Uncomment the following lines to print uncaught exceptions to stdout */ + if (exception instanceof ExpressionException){ + javax.swing.JOptionPane.showMessageDialog(this, exception.getMessage(), "Error", javax.swing.JOptionPane.ERROR_MESSAGE); + } + System.out.println("--------- UNCAUGHT EXCEPTION --------- in SpeciesContextSpecPanel"); + exception.printStackTrace(System.out); + } + + private void initialize() { + try { + shapePanel = new SsldLargeShapePanel() { // glyph (shape) panel + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + if (spls != null) { + spls.paintSelf(g); + } + } + + + }; + shapePanel.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent e) { + Point overWhat = e.getPoint(); + PointLocationInShapeContext locationContext = new PointLocationInShapeContext(overWhat); + spls.contains(locationContext); + shapePanel.setToolTipText("View-Only panel"); + } + }); + shapePanel.setBackground(new Color(0xe0e0e0)); + shapePanel.setZoomFactor(-2); + shapePanel.setEditable(false); + + scrollPane = new JScrollPane(shapePanel); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + + // ----------------------------------------------------------------------------------------- + + JPanel optionsPanel = new JPanel(); // ------- left panel with zoom buttons + optionsPanel.setLayout(new GridBagLayout()); + + getZoomSmallerButton().setEnabled(true); + getZoomLargerButton().setEnabled(true); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.insets = new Insets(4,4,0,10); + gbc.anchor = GridBagConstraints.WEST; + optionsPanel.add(getZoomLargerButton(), gbc); + + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 1; + gbc.insets = new Insets(4,4,4,10); + gbc.anchor = GridBagConstraints.WEST; + optionsPanel.add(getZoomSmallerButton(), gbc); + + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 2; + gbc.weightx = 1; + gbc.weighty = 1; // fake cell used for filling all the vertical empty space + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(4, 4, 4, 10); + optionsPanel.add(new JLabel(""), gbc); + + + // ------------------------------------------------------------------------------------------ + JPanel containerOfScrollPanel = new JPanel(); + containerOfScrollPanel.setLayout(new BorderLayout()); + containerOfScrollPanel.add(optionsPanel, BorderLayout.WEST); + containerOfScrollPanel.add(scrollPane, BorderLayout.CENTER); + + setLayout(new BorderLayout()); + add(containerOfScrollPanel, BorderLayout.CENTER); + setBackground(Color.white); + setName("MolecularStructuresPropertiesPanel"); + + + + } catch (java.lang.Throwable ivjExc) { + handleException(ivjExc); + } + } + + private void updateInterface() { + if(speciesContext == null) { + return; + } + updateShape(); + } + + public static final int xOffsetInitial = 20; + public static final int yOffsetInitial = 10; + private void updateShape() { + if(speciesContext == null) { + return; + } + SpeciesPattern sp = speciesContext.getSpeciesPattern(); +// spls = new SpeciesPatternLargeShape(xOffsetInitial, yOffsetInitial, -1, sp, shapePanel, speciesContext, issueManager); +// +// Dimension preferredSize = new Dimension(spls.getRightEnd()+40, yOffsetInitial+80); +// shapePanel.setPreferredSize(preferredSize); +// shapePanel.repaint(); + } + + public void setSpeciesContextSpec(SpeciesContextSpec scSpec) { + if(scSpec == null) { + this.speciesContext = null; + } else { + this.speciesContext = scSpec.getSpeciesContext(); + } +// getSpeciesContextSpecParameterTableModel().setSpeciesContextSpec(scSpec); + updateInterface(); + } + public void setBioModel(BioModel newValue) { + if (bioModel == newValue) { + return; + } + bioModel = newValue; + if(bioModel == null) { + return; + } + Model model = bioModel.getModel(); + if(model != null & model.getRbmModelContainer().getMolecularTypeList().size() > 0) { +// splitPaneHorizontal.setDividerLocation(165); + } else { + // since we have no molecular types we initialize a much smaller shape panel + // because we can only show a trivial shape (circle) +// splitPaneHorizontal.setDividerLocation(195); + } + } + + + @Override + protected void onSelectedObjectsChange(Object[] selectedObjects) { + SpeciesContextSpec speciesContextSpec = null; + if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof LangevinSpeciesContextSpec) { + LangevinSpeciesContextSpec lscs = (LangevinSpeciesContextSpec)selectedObjects[0]; + speciesContextSpec = lscs.getTheSpeciesContextSpec(); + } + setSpeciesContextSpec(speciesContextSpec); + + } + + private JButton getZoomLargerButton() { + if (zoomLargerButton == null) { + zoomLargerButton = new JButton(); // "+" +// ResizeCanvasShape.setCanvasNormalMod(zoomLargerButton, ResizeCanvasShape.Sign.expand); + ZoomShapeIcon.setZoomMod(zoomLargerButton, ZoomShapeIcon.Sign.plus); + zoomLargerButton.addActionListener(eventHandler); + } + return zoomLargerButton; + } + private JButton getZoomSmallerButton() { + if (zoomSmallerButton == null) { + zoomSmallerButton = new JButton(); // - +// ResizeCanvasShape.setCanvasNormalMod(zoomSmallerButton, ResizeCanvasShape.Sign.shrink); + ZoomShapeIcon.setZoomMod(zoomSmallerButton, ZoomShapeIcon.Sign.minus); + zoomSmallerButton.addActionListener(eventHandler); + } + return zoomSmallerButton; + } +} diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java index e21539bae0..d7d204116b 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java @@ -28,6 +28,7 @@ import javax.swing.JScrollPane; import javax.swing.JSplitPane; +import cbit.vcell.mapping.LangevinSpeciesContextSpec; import org.vcell.model.rbm.MolecularComponentPattern; import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; @@ -307,7 +308,8 @@ public void setBioModel(BioModel newValue) { @Override protected void onSelectedObjectsChange(Object[] selectedObjects) { SpeciesContextSpec speciesContextSpec = null; - if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof SpeciesContextSpec) { + if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof SpeciesContextSpec + && !(selectedObjects[0] instanceof LangevinSpeciesContextSpec)) { speciesContextSpec = (SpeciesContextSpec) selectedObjects[0]; } setSpeciesContextSpec(speciesContextSpec); diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 5b3d1f5168..1b71cdca24 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -164,7 +164,13 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { setSelectedObjectsFromTable(getSpeciesContextSpecsTable(), speciesContextSpecsTableModel); int row = getSpeciesContextSpecsTable().getSelectedRow(); SpeciesContextSpec scsSelected = speciesContextSpecsTableModel.getValueAt(row); - setSpeciesContextSpec(scsSelected); + if(scsSelected instanceof LangevinSpeciesContextSpec) { + LangevinSpeciesContextSpec lscs = (LangevinSpeciesContextSpec)scsSelected; + SpeciesContextSpec theSpeciesContextStep = lscs.getTheSpeciesContextSpec(); + setSpeciesContextSpec(theSpeciesContextStep); + } else { + setSpeciesContextSpec(scsSelected); + } } if (e.getSource() == getMolecularTypeSpecsTable().getSelectionModel()) { int row = getMolecularTypeSpecsTable().getSelectedRow(); diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java index 2fd8f0c3a0..cd48e28ecb 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java @@ -4,11 +4,15 @@ public class LangevinSpeciesContextSpec extends SpeciesContextSpec { + private final SpeciesContextSpec theSpeciesContextSpec; + public LangevinSpeciesContextSpec(SpeciesContextSpec speciesContextSpec, SimulationContext argSimulationContext) { super(speciesContextSpec, argSimulationContext); + this.theSpeciesContextSpec = speciesContextSpec; } - public LangevinSpeciesContextSpec(SpeciesContext speciesContext, SimulationContext argSimulationContext) { - super(speciesContext, argSimulationContext); + public SpeciesContextSpec getTheSpeciesContextSpec() { + return theSpeciesContextSpec; } + } From d5d3400be2f6a33a2597da8a84259d4f83c7d5ea Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Fri, 4 Oct 2024 17:07:32 -0400 Subject: [PATCH 04/28] Use existing large shape panel, new Anchor issues, bug fixing --- .../MolecularStructuresPropertiesPanel.java | 51 +++++- .../cbit/vcell/mapping/ReactionRuleSpec.java | 159 ++++++++++-------- 2 files changed, 137 insertions(+), 73 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index c2dbab6315..c11f0036c5 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -3,15 +3,20 @@ import cbit.vcell.biomodel.BioModel; import cbit.vcell.client.desktop.biomodel.DocumentEditorSubPanel; import cbit.vcell.graph.PointLocationInShapeContext; +import cbit.vcell.graph.ReactionCartoon; import cbit.vcell.graph.SpeciesPatternLargeShape; import cbit.vcell.graph.gui.LargeShapePanel; import cbit.vcell.graph.gui.SsldLargeShapePanel; import cbit.vcell.graph.gui.ZoomShapeIcon; import cbit.vcell.mapping.LangevinSpeciesContextSpec; import cbit.vcell.mapping.SpeciesContextSpec; +import cbit.vcell.model.GroupingCriteria; import cbit.vcell.model.Model; +import cbit.vcell.model.RuleParticipantSignature; import cbit.vcell.model.SpeciesContext; import cbit.vcell.parser.ExpressionException; +import org.vcell.model.rbm.MolecularComponentPattern; +import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; import javax.swing.*; @@ -28,7 +33,7 @@ public class MolecularStructuresPropertiesPanel extends DocumentEditorSubPanel { private JScrollPane scrollPane; // shapePanel lives inside this private SpeciesPatternLargeShape spls; // make the real thing - private SsldLargeShapePanel shapePanel = null; + private LargeShapePanel shapePanel = null; private JButton zoomLargerButton = null; @@ -68,7 +73,7 @@ private void handleException(Throwable exception) { private void initialize() { try { - shapePanel = new SsldLargeShapePanel() { // glyph (shape) panel + shapePanel = new LargeShapePanel() { // glyph (shape) panel @Override public void paintComponent(Graphics g) { super.paintComponent(g); @@ -76,8 +81,46 @@ public void paintComponent(Graphics g) { spls.paintSelf(g); } } - - + @Override + public DisplayMode getDisplayMode() { + return DisplayMode.other; + } + @Override + public ReactionCartoon.RuleAnalysisChanged hasStateChanged(String reactionRuleName, MolecularComponentPattern molecularComponentPattern) { + return ReactionCartoon.RuleAnalysisChanged.UNCHANGED; + } + @Override + public ReactionCartoon.RuleAnalysisChanged hasStateChanged(MolecularComponentPattern molecularComponentPattern) { + return ReactionCartoon.RuleAnalysisChanged.UNCHANGED; + } + @Override + public ReactionCartoon.RuleAnalysisChanged hasBondChanged(String reactionRuleName, MolecularComponentPattern molecularComponentPattern) { + return ReactionCartoon.RuleAnalysisChanged.UNCHANGED; + } + @Override + public ReactionCartoon.RuleAnalysisChanged hasBondChanged(MolecularComponentPattern molecularComponentPattern) { + return ReactionCartoon.RuleAnalysisChanged.UNCHANGED; + } + @Override + public ReactionCartoon.RuleAnalysisChanged hasNoMatch(String reactionRuleName, MolecularTypePattern mtp) { + return ReactionCartoon.RuleAnalysisChanged.UNCHANGED; + } + @Override + public ReactionCartoon.RuleAnalysisChanged hasNoMatch(MolecularTypePattern molecularTypePattern) { + return ReactionCartoon.RuleAnalysisChanged.UNCHANGED; + } + @Override + public RuleParticipantSignature getSignature() { + return null; + } + @Override + public GroupingCriteria getCriteria() { + return null; + } + @Override + public boolean isViewSingleRow() { + return true; + } }; shapePanel.addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent e) { diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java index 75ce1d0756..e43cfd4df2 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java @@ -638,6 +638,20 @@ private boolean isBindingReaction(Map analysisResults) { if(ret == null) { return false; } + for(ReactionRuleParticipant rrp : reactionRule.getReactionRuleParticipants()) { + SpeciesPattern sp = rrp.getSpeciesPattern(); + for(MolecularTypePattern mtp : sp.getMolecularTypePatterns()) { + for(MolecularComponentPattern mcp : mtp.getComponentPatternList()) { + BondType bt = mcp.getBondType(); + ComponentStatePattern csp = mcp.getComponentStatePattern(); + if(!csp.isAny() && BondType.Possible == bt) { + // all the sites not binding must be in Any state + return false; + } + } + } + } + int bindingTransitions = (int)ret; if(bindingTransitions == 2) { return true; // one binding reaction produces 2 binding transitions @@ -867,9 +881,9 @@ public SpeciesContext getDestroyedSpecies(SpeciesContextSpec[] speciesContextSpe */ private final static String GenericTip = "Please edit the reaction so that it matches a SpringSaLaD subtype or disable it in this table"; private final static String SpringSaLaDMsgAtLeastOne = "At least one reactant and one product are required."; -private final static String SpringSaLaDMsgReactionsCannotBe = "SpringSaLaD reactions cannot be located on the Membrane."; -private final static String SpringSaLaDMsgEachReactionMust = "SpringSaLaD requires that each reaction and all its participants must be in the same Structure"; -private final static String SpringSaLaDMsgAnchorCannotBePart = "The reserved site 'Anchor' cannot be part of a non-membrane reactant pattern."; +private final static String SpringSaLaDMsgAnchorReactionMustMembrane = "SpringSaLaD reactions must be located on the Membrane if one reactant is on Membrane."; +private final static String SpringSaLaDMsgEachReactionMust = "SpringSaLaD requires that each compartmental reaction and all its participants must be in the same compartment"; +private final static String SpringSaLaDMsgAnchorCannotBePart = "The reserved site 'Anchor' can only be part of a membrane reactant pattern."; private final static String SpringSaLaDMsgAnchorCannotBeTarget = "The reserved site 'Anchor' cannot be the target of any SpringSaLaD reaction."; private final static String SpringSaLaDMsgOnlyAcceptsOneProduct = "SpringSaLaD only accepts one Product."; private final static String SpringSaLaDMsgOnlyAcceptsTwo = "SpringSaLaD only accepts 2 Reactants for the binding reactions and 1 Reactant for the other subtypes."; @@ -943,79 +957,86 @@ public void gatherIssues(IssueContext issueContext, List issueList, React return; } + // if at least one reactant is on a membrane, the reaction must be on a membrane + for(ReactantPattern rp : rpList) { + if(SpringStructureEnum.Membrane.columnName.equals(rp.getStructure().getName())) { + if(!(SpringStructureEnum.Membrane.columnName.equals(reactionRule.getStructure().getName()))) { + String msg = SpringSaLaDMsgAnchorReactionMustMembrane; + String tip = msg; + issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); + return; + } + } + } + // all compartmental reactions must have all reactants, all products and the reaction located in the same compartment + Set participantStructureSet = new LinkedHashSet<>(); + for(ReactionRuleParticipant rrp : reactionRule.getReactionRuleParticipants()) { + if(SpringStructureEnum.Membrane.columnName.equals(rrp.getStructure().getName())) { + break; // we deal with membrane participants reactions separately + } + participantStructureSet.add(rrp.getStructure()); + } + if(participantStructureSet.size() > 1) { + String msg = SpringSaLaDMsgEachReactionMust; + String tip = msg; + issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); + return; + } else if(participantStructureSet.size() == 1) { // reaction must also be here + if(!participantStructureSet.contains(reactionRule.getStructure())) { + String msg = SpringSaLaDMsgEachReactionMust; + String tip = msg; + issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); + return; + } + } - // no reaction can be on the membrane - // dan 7/31/24 correction: a reaction involving a Membrane molecule can be on a membrane -// String reactionStructure = reactionRule.getStructure().getName(); -// if(SpringStructureEnum.Membrane.columnName.equals(reactionStructure)) { -// String msg = SpringSaLaDMsgReactionsCannotBe; -// String tip = msg; -// issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); -// return; -// } - - // the reaction and its participants must all be in the same Structure. - // TODO: this has to be refined, actually reactants bound to a membrane may have sites in the right compartment - // Also, some conditional transition or allosteric reaction may have their condition molecule located in a different - // compartment (can they? TODO check with springsalad !!!) -// List reactionRuleParticipants = reactionRule.getReactionRuleParticipants(); -// for(ReactionRuleParticipant rrp : reactionRuleParticipants) { -// if(!reactionStructure.equals(rrp.getStructure().getName())) { -// String msg = SpringSaLaDMsgEachReactionMust; -// String tip = msg; -// issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); -// return; -// } -// } - // the reserved site 'Anchor' must be not present in any reactant pattern that is not situated on a membrane // note that we do a similar check for seed species, but this is also needed // (we can have a bad reactant pattern even though the seed species may be missing) - // TODO:we'll change the Anchor paradigm but this check should still be present some way or another -// for(ReactantPattern rp : rpList) { -// if(!SpringStructureEnum.Membrane.columnName.equals(rp.getStructure().getName())) { -// SpeciesPattern spReactant = rp.getSpeciesPattern(); -// List mtpReactantList = spReactant.getMolecularTypePatterns(); -// for(MolecularTypePattern mtpReactant : mtpReactantList) { -// List mcpReactantList = mtpReactant.getComponentPatternList(); -// for(MolecularComponentPattern mcpReactant : mcpReactantList) { -// MolecularComponent mcReactant = mcpReactant.getMolecularComponent(); -// if(SpeciesContextSpec.AnchorSiteString.equals(mcReactant.getName())) { -// String msg = SpringSaLaDMsgAnchorCannotBePart; -// String tip = msg; -// issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); -// return; -// } -// } -// } -// } -// } + for(ReactantPattern rp : rpList) { + if(!SpringStructureEnum.Membrane.columnName.equals(rp.getStructure().getName())) { + SpeciesPattern spReactant = rp.getSpeciesPattern(); + List mtpReactantList = spReactant.getMolecularTypePatterns(); + for(MolecularTypePattern mtpReactant : mtpReactantList) { + List mcpReactantList = mtpReactant.getComponentPatternList(); + for(MolecularComponentPattern mcpReactant : mcpReactantList) { + MolecularComponent mcReactant = mcpReactant.getMolecularComponent(); + if(SpeciesContextSpec.AnchorSiteString.equals(mcReactant.getName())) { + String msg = SpringSaLaDMsgAnchorCannotBePart; + String tip = msg; + issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); + return; + } + } + } + } + } // the reserved site 'Anchor' must not be part of any reaction - // TODO: deal with this once the Anchor is being refactored -// for(ReactantPattern rp : rpList) { -// if(!SpringStructureEnum.Membrane.columnName.equals(rp.getStructure().getName())) { -// continue; // we don't have anchors if it's not a membrane molecule -// } -// SpeciesPattern spReactant = rp.getSpeciesPattern(); -// List mtpReactantList = spReactant.getMolecularTypePatterns(); -// for(MolecularTypePattern mtpReactant : mtpReactantList) { -// List mcpReactantList = mtpReactant.getComponentPatternList(); -// for(MolecularComponentPattern mcpReactant : mcpReactantList) { -// MolecularComponent mcReactant = mcpReactant.getMolecularComponent(); -// if(!SpeciesContextSpec.AnchorSiteString.equals(mcReactant.getName())) { -// continue; -// } -// if(BondType.Possible != mcpReactant.getBondType() || !mcpReactant.getComponentStatePattern().isAny()) { -// String msg = SpringSaLaDMsgAnchorCannotBeTarget; -// String tip = msg; -// issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); -// return; -// } -// } -// } -// } + for(ReactantPattern rp : rpList) { + if(!SpringStructureEnum.Membrane.columnName.equals(rp.getStructure().getName())) { + continue; // we don't have anchors if it's not a membrane molecule + } + SpeciesPattern spReactant = rp.getSpeciesPattern(); + List mtpReactantList = spReactant.getMolecularTypePatterns(); + for(MolecularTypePattern mtpReactant : mtpReactantList) { + List mcpReactantList = mtpReactant.getComponentPatternList(); + for(MolecularComponentPattern mcpReactant : mcpReactantList) { + MolecularComponent mcReactant = mcpReactant.getMolecularComponent(); + if(!SpeciesContextSpec.AnchorSiteString.equals(mcReactant.getName())) { + continue; + } + if(BondType.Possible != mcpReactant.getBondType() || !mcpReactant.getComponentStatePattern().isAny()) { + String msg = SpringSaLaDMsgAnchorCannotBeTarget; + String tip = msg; + issueList.add(new Issue(r, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR)); + return; + } + } + } + } + // ------------------------------------------------------------------------------------------------------------------------ Map analysisResults = new LinkedHashMap<> (); From 53060dabd7eea7e55522fa51736e16699e6dcbaf Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 8 Oct 2024 16:39:23 -0400 Subject: [PATCH 05/28] Site location initialization for membrane molecules --- .../vcell/mapping/SpeciesContextSpec.java | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java index a84f4ccaac..180fed64f1 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java @@ -69,6 +69,7 @@ public class SpeciesContextSpec implements Matchable, ScopedSymbolTable, Seriali public static final String PARAMETER_NAME_PROXY_PARAMETERS = "proxyParameters"; private static final String PROPERTY_NAME_WELL_MIXED = "wellMixed"; private static final String PROPERTY_NAME_FORCECONTINUOUS = "forceContinuous"; + private static final int INITIAL_YZ_SITE_OFFSET = 4; public static final boolean TrackClusters = true; // SpringSaLaD specific public static final boolean InitialLocationRandom = true; @@ -754,24 +755,62 @@ public void initializeForSpringSaLaD(MolecularType molecularType) { oldMcpSet.clear(); // step 3.4: we add any new instance of authoritative mcp not there yet, and we initialize with default sas - int componentCount = 0; - for (MolecularComponent mc : componentList) { + boolean isMmembraneMolecule = false; + boolean hasAnchor = false; + int anchorIndex = 0; + if(getSpeciesContext().getStructure().getName().equals(Structure.SpringStructureEnum.Membrane.columnName)) { + isMmembraneMolecule = true; + // in a membrane molecule, we arrange Sites left to the anchor as located in Extracellular, + // the Anchor site is on the Membrane, + // the sites right to the anchor are to be initialized as located in Intracellular + for (int count = 0; count anchorIndex) { // Intracellular + Structure struct = getSimulationContext().getModel().getStructure(Structure.SpringStructureEnum.Intracellular.columnName); + sas = new SiteAttributesSpec(this, mcp, struct); + } else { // Anchor, the only site located on the Membrane + Structure struct = getSimulationContext().getModel().getStructure(Structure.SpringStructureEnum.Membrane.columnName); + sas = new SiteAttributesSpec(this, mcp, struct); + } + } else { sas = new SiteAttributesSpec(this, mcp, getSpeciesContext().getStructure()); - if(initialPass == true) { - Coordinate coordinate = new Coordinate(0, 0, (componentCount+1)*4); - sas.setCoordinate(coordinate); - NamedColor nextColor = Colors.COLORARRAY[componentCount]; - sas.setColor(nextColor); + } + if(initialPass == true) { + Coordinate coordinate = new Coordinate(0, INITIAL_YZ_SITE_OFFSET, INITIAL_YZ_SITE_OFFSET + (componentCount * 4)); + sas.setCoordinate(coordinate); + NamedColor nextColor; + if(componentCount == anchorIndex) { + nextColor = Colors.DARKGRAY; + } else { + nextColor = Colors.COLORARRAY[componentCount]; } - siteAttributesMap.put(mcp, sas); + sas.setColor(nextColor); + } else { // if this is a new site added to an existing molecule, the existing sites already have + ; // attributes (like coordinates, diffusion rates, colors) and links. + // We cannot guess how the user will want to deal with the new site. } - componentCount++; + siteAttributesMap.put(mcp, sas); } // at this point the siteAttributesMap should be fully reconstructed From d8a86a6a879d1a903d08b27c0dd8c64259267f85 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Wed, 9 Oct 2024 13:38:27 -0400 Subject: [PATCH 06/28] Implemented the correct Transition Condition FREE - meaning that the transitioning site must be Unbound --- .../cbit/vcell/mapping/ReactionRuleSpec.java | 59 +++++++++++++------ .../model/rbm/MolecularComponentPattern.java | 8 +-- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java index e43cfd4df2..6a17295974 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java @@ -99,17 +99,20 @@ public static Subtype fromName(String nameCandidate) { return null; } } - // transition site is bond Possible and in explicit state - // all the other sites are unbound AND in "Any" state - // ==> TransitionCondition.NONE; // condition is "None" - // - // transition site is bond Possible and in explicit state - // all the other sites are bond Possible AND in "Any" state - // ==> TransitionCondition.FREE; // transition reaction condition is "Free" public enum TransitionCondition { // everywhere internally in vcell we use RBM bond type naming conventions - NONE("Unbound", "None"), // MolecularComponentPattern.BondType.None (-) - FREE("Any", "Free"), // MolecularComponentPattern.BondType.Possible (?) - BOUND("Bound", "Bound"); // MolecularComponentPattern.BondType.Exists (+) + /* + public enum MolecularComponentPattern.BondType { + Specified(""), // numbers // explicit (in springsalad this is TransitionCondition.BOUND) + Exists("+"), // "+" // bound (this one doesn't exist in springsalad) + Possible("?"), // "?" // any (in springsalad this is TransitionCondition.NONE) + None("-"); // unbound (in springsalad this is TransitionCondition.FREE) + As you see, terminology is very confusing: + BondType.None means TransitionCondition.Free (no bond, in other words condition must be no bond), while + BondType.Possible means TransitionCondition.None (bond can be anything, in other words no condition) + */ + NONE("Any", "None"), // BondType.Possible (?) transitioning site bond can be anything (springsalad condition is NONE (no condition)) + FREE("Unbound", "Free"), // BondType.None (-) transitioning site must be unbound, no bond (springsalad condition is FREE(condition is that there is no bond) + BOUND("Bound", "Bound"); // BondType.Exists (+) transitioning site has explicit bond to site of another molecule final public String vcellName; final public String lngvName; @@ -414,16 +417,20 @@ public TransitionCondition getTransitionCondition(Map analysisRe int numBondsPossible = 0; int numBondsUnbound = 0; MolecularTypePattern mtpReactant = mtpReactantList.get(0); + MolecularComponentPattern mcpTransitionReactant = (MolecularComponentPattern)analysisResults.get(McpReactantState + "1"); + if(mcpTransitionReactant == null) { + return null; // we must have a reactant that's transitioning + } for(MolecularComponentPattern mcpReactant : mtpReactant.getComponentPatternList()) { ComponentStatePattern cspReactant = mcpReactant.getComponentStatePattern(); BondType bondTypeReactant = mcpReactant.getBondType(); if(cspReactant == null) { return null; // all sites must have at least one state } - if(!cspReactant.isAny() && BondType.Possible != bondTypeReactant) { - // this is the transition site, bond must be "Possible" - return null; - } +// if(!cspReactant.isAny() && BondType.Possible != bondTypeReactant) { +// // this is the transition site, bond must be "Possible" +// return null; +// } if(!cspReactant.isAny()) { ; } else { @@ -437,15 +444,33 @@ public TransitionCondition getTransitionCondition(Map analysisRe return null; // all bonds must be either none or possible } } + /* + public enum MolecularComponentPattern.BondType { + Specified(""), // numbers // Explicit (in springsalad this is TransitionCondition.BOUND) + Exists("+"), // "+" // Bound to some other (unspecified) site (this one doesn't exist in springsalad) + Possible("?"), // "?" // Any bonding situation (in springsalad this is TransitionCondition.NONE) + None("-"); // "-" // Unbound (in springsalad this is TransitionCondition.FREE) + + As you see, terminology is very confusing: + BondType.None means TransitionCondition.FREE (no bond, in other words condition must be no bond), while + BondType.Possible means TransitionCondition.NONE (bond can be anything, in other words no condition) + + public enum TransitionCondition { // everywhere internally in vcell we use RBM bond type naming conventions + NONE("Any", "None"), // BondType.Possible (?) transitioning site bond can be anything (springsalad condition is NONE (no condition)) + FREE("Unbound", "Free"), // BondType.None (-) transitioning site must be unbound, no bond (springsalad condition is FREE(condition is that there is no bond) + BOUND("Bound", "Bound"); // BondType.Exists (+) transitioning site has explicit bond to site of another molecule + */ int numSites = mtpReactant.getComponentPatternList().size(); - if(numBondsUnbound > 0 && numBondsPossible == 1 && numBondsUnbound == numSites-1 && numAnyStates == numSites-1) { + if(numBondsUnbound == 1 && numBondsPossible == numSites-1 ) { // transition site is bond Possible and in explicit state // all the other sites are unbound AND in "Any" state - return TransitionCondition.NONE; // condition is "None" + if(mcpTransitionReactant.getBondType() == BondType.None) { + return TransitionCondition.FREE; // condition is "Free" (Unbound) + } } else if(numBondsUnbound == 0 && numBondsPossible == numSites && numAnyStates == numSites-1) { // transition site is bond Possible and in explicit state // all the other sites are bond Possible AND in "Any" state - return TransitionCondition.FREE; // transition reaction condition is "Free" + return TransitionCondition.NONE; // transition reaction condition is "None" (bond can be anything, BondType is possible) } return null; } else if(mtpReactantList.size() == 2 && mtpProductList.size() == 2) { // we look for transition with "Bound" condition, means 2 molecules diff --git a/vcell-core/src/main/java/org/vcell/model/rbm/MolecularComponentPattern.java b/vcell-core/src/main/java/org/vcell/model/rbm/MolecularComponentPattern.java index 5810adf1b1..48f4036f9b 100644 --- a/vcell-core/src/main/java/org/vcell/model/rbm/MolecularComponentPattern.java +++ b/vcell-core/src/main/java/org/vcell/model/rbm/MolecularComponentPattern.java @@ -36,10 +36,10 @@ public class MolecularComponentPattern extends RbmElementAbstract implements Mat private transient boolean bHighlighted = false; public enum BondType { - Specified(""), // numbers // explicit - Exists("+"), // "+" // bound - Possible("?"), // "?" // any - None("-"); // unbound + Specified(""), // numbers // Explicit (in springsalad this is TransitionCondition.BOUND) + Exists("+"), // "+" // Bound to some other (unspecified) site (this one doesn't exist in springsalad) + Possible("?"), // "?" // Any bonding situation (in springsalad this is TransitionCondition.NONE) + None("-"); // "-" // Unbound (in springsalad this is TransitionCondition.FREE) public String symbol; BondType(String s) { From 72c9b93e3a1cc510667bbab6b2594b990ce7d7ca Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 10 Oct 2024 15:14:17 -0400 Subject: [PATCH 07/28] Fixed import and export for Transition Condition FREE --- .../cbit/vcell/mapping/ReactionRuleSpec.java | 13 ++++-------- .../java/org/vcell/model/ssld/SsldUtils.java | 20 +++++-------------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java index 6a17295974..9b3e13a0b2 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java @@ -737,16 +737,11 @@ private void writeTransitionData(StringBuilder sb, Subtype subtype, Map rpList = reactionRule.getReactantPatterns(); // we already know that this list is not empty List mtpReactantList = rpList.get(0).getSpeciesPattern().getMolecularTypePatterns(); - TransitionCondition transitionCondition = TransitionCondition.FREE; // molecules with just one site belong to free + TransitionCondition transitionCondition = TransitionCondition.NONE; // no restriction if(mtpReactantList.size() == 1) { // transition reaction condition "None" or "Free" - for(MolecularComponentPattern mcpOtherReactant : mtpTransitionReactant.getComponentPatternList()) { - if(mcpOtherReactant != mcpTransitionReactant) { - if(BondType.None == mcpOtherReactant.getBondType()) { - // transition "None" has the bond types of all sites set to "None" (except the transitioning site which is "Possible") - transitionCondition = TransitionCondition.NONE; - break; - } - } + if(BondType.None == mcpTransitionReactant.getBondType()) { + // transition "FREE" has the bond types of all sites set to "Possible" (except the transitioning site which is Unbound) + transitionCondition = TransitionCondition.FREE; } } else if(mtpReactantList.size() == 2) { // transition reaction condition "Bound" transitionCondition = TransitionCondition.BOUND; diff --git a/vcell-core/src/main/java/org/vcell/model/ssld/SsldUtils.java b/vcell-core/src/main/java/org/vcell/model/ssld/SsldUtils.java index 6314d45fdd..e811cf692c 100644 --- a/vcell-core/src/main/java/org/vcell/model/ssld/SsldUtils.java +++ b/vcell-core/src/main/java/org/vcell/model/ssld/SsldUtils.java @@ -991,14 +991,9 @@ private void adjustTransitionReactionSites(TransitionReaction ssldReaction, Mapp ComponentStatePattern cspTransitionReactant = new ComponentStatePattern(csdInitial); mcpTransitionReactant.setComponentStatePattern(cspTransitionReactant); // bond is already set to Any - if(ssldReaction.getCondition().equals(TransitionReaction.NO_CONDITION)) { - for(MolecularComponentPattern mcp : mtpTransitionReactant.getComponentPatternList()) { - if(mcp == mcpTransitionReactant) { - continue; - } - mcp.setBondType(MolecularComponentPattern.BondType.None); - } - } else if(ssldReaction.getCondition().equals(TransitionReaction.BOUND_CONDITION)) { + if(ssldReaction.getCondition().equals(TransitionReaction.FREE_CONDITION)) { + mcpTransitionReactant.setBondType(MolecularComponentPattern.BondType.None); + } else if(ssldReaction.getCondition().equals(TransitionReaction.BOUND_CONDITION)) { // we know for sure that this is the only explicit bond in each of the 2 molecular type patterns of the reactant int bondId = 1; // correct would be: sp.nextBondId(); mcpConditionReactant.setBondId(bondId); // this also sets the BondType to Specified @@ -1016,13 +1011,8 @@ private void adjustTransitionReactionSites(TransitionReaction ssldReaction, Mapp ComponentStatePattern cspTransitionProduct = new ComponentStatePattern(csdFinal); mcpTransitionProduct.setComponentStatePattern(cspTransitionProduct); System.out.println(" " + ssldReaction.getCondition()); - if(ssldReaction.getCondition().equals(TransitionReaction.NO_CONDITION)) { - for(MolecularComponentPattern mcp : mtpTransitionProduct.getComponentPatternList()) { - if(mcp == mcpTransitionProduct) { - continue; - } - mcp.setBondType(MolecularComponentPattern.BondType.None); - } + if(ssldReaction.getCondition().equals(TransitionReaction.FREE_CONDITION)) { + mcpTransitionProduct.setBondType(MolecularComponentPattern.BondType.None); } else if(ssldReaction.getCondition().equals(TransitionReaction.BOUND_CONDITION)) { // we know for sure that this is the only explicit bond in each of the 2 molecular type patterns of the product int bondId = 1; // correct would be: sp.nextBondId(); From e86e50ee7ae7c728e1bc28a1aed6b4adb19bd29d Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Fri, 11 Oct 2024 15:29:18 -0400 Subject: [PATCH 08/28] WIP: painting the shapes of the sites --- .../MolecularStructuresPropertiesPanel.java | 32 ++-- .../graph/SpeciesContextSpecLargeShape.java | 146 ++++++++++++++++++ .../cbit/vcell/mapping/ReactionRuleSpec.java | 4 + .../SpringSaLaDGoodReactionsTest.java | 8 +- 4 files changed, 171 insertions(+), 19 deletions(-) create mode 100644 vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index c11f0036c5..299f6e7dd6 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -4,6 +4,7 @@ import cbit.vcell.client.desktop.biomodel.DocumentEditorSubPanel; import cbit.vcell.graph.PointLocationInShapeContext; import cbit.vcell.graph.ReactionCartoon; +import cbit.vcell.graph.SpeciesContextSpecLargeShape; import cbit.vcell.graph.SpeciesPatternLargeShape; import cbit.vcell.graph.gui.LargeShapePanel; import cbit.vcell.graph.gui.SsldLargeShapePanel; @@ -28,12 +29,12 @@ public class MolecularStructuresPropertiesPanel extends DocumentEditorSubPanel { private BioModel bioModel = null; - private SpeciesContext speciesContext = null; + private SpeciesContextSpec speciesContextSpec = null; private EventHandler eventHandler = new EventHandler(); - private JScrollPane scrollPane; // shapePanel lives inside this - private SpeciesPatternLargeShape spls; // make the real thing + private JScrollPane scrollPane; // shapePanel lives inside this private LargeShapePanel shapePanel = null; + private SpeciesContextSpecLargeShape scsls; // the real thing private JButton zoomLargerButton = null; @@ -77,8 +78,8 @@ private void initialize() { @Override public void paintComponent(Graphics g) { super.paintComponent(g); - if (spls != null) { - spls.paintSelf(g); + if (scsls != null) { + scsls.paintSelf(g); } } @Override @@ -125,9 +126,9 @@ public boolean isViewSingleRow() { shapePanel.addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent e) { Point overWhat = e.getPoint(); - PointLocationInShapeContext locationContext = new PointLocationInShapeContext(overWhat); - spls.contains(locationContext); - shapePanel.setToolTipText("View-Only panel"); +// PointLocationInShapeContext locationContext = new PointLocationInShapeContext(overWhat); +// spls.contains(locationContext); +// shapePanel.setToolTipText("View-Only panel"); } }); shapePanel.setBackground(new Color(0xe0e0e0)); @@ -189,7 +190,7 @@ public void mouseMoved(MouseEvent e) { } private void updateInterface() { - if(speciesContext == null) { + if(speciesContextSpec == null || speciesContextSpec.getSpeciesContext() == null) { return; } updateShape(); @@ -198,22 +199,23 @@ private void updateInterface() { public static final int xOffsetInitial = 20; public static final int yOffsetInitial = 10; private void updateShape() { - if(speciesContext == null) { + if(speciesContextSpec == null || speciesContextSpec.getSpeciesContext() == null) { return; } - SpeciesPattern sp = speciesContext.getSpeciesPattern(); -// spls = new SpeciesPatternLargeShape(xOffsetInitial, yOffsetInitial, -1, sp, shapePanel, speciesContext, issueManager); + SpeciesPattern sp = speciesContextSpec.getSpeciesContext().getSpeciesPattern(); + System.out.println(sp.getNameShort()); + scsls = new SpeciesContextSpecLargeShape(xOffsetInitial, yOffsetInitial, -1, speciesContextSpec, shapePanel, speciesContextSpec, issueManager); // // Dimension preferredSize = new Dimension(spls.getRightEnd()+40, yOffsetInitial+80); // shapePanel.setPreferredSize(preferredSize); -// shapePanel.repaint(); + shapePanel.repaint(); } public void setSpeciesContextSpec(SpeciesContextSpec scSpec) { if(scSpec == null) { - this.speciesContext = null; + this.speciesContextSpec = null; } else { - this.speciesContext = scSpec.getSpeciesContext(); + this.speciesContextSpec = scSpec; } // getSpeciesContextSpecParameterTableModel().setSpeciesContextSpec(scSpec); updateInterface(); diff --git a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java new file mode 100644 index 0000000000..f1779417b6 --- /dev/null +++ b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java @@ -0,0 +1,146 @@ +package cbit.vcell.graph; + +import cbit.vcell.mapping.SiteAttributesSpec; +import cbit.vcell.mapping.SpeciesContextSpec; +import cbit.vcell.model.SpeciesContext; +import org.vcell.model.rbm.MolecularComponentPattern; +import org.vcell.model.rbm.MolecularTypePattern; +import org.vcell.model.rbm.SpeciesPattern; +import org.vcell.util.Coordinate; +import org.vcell.util.Displayable; + +import java.awt.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class SpeciesContextSpecLargeShape extends AbstractComponentShape implements HighlightableShapeInterface { + + + private int xPos = 0; + private int yPos = 0; // y position where we draw the shape + private int nameOffset = 0; // offset upwards from yPos where we may write some text, like the expression of the sp + private int height = -1; // -1 means it doesn't matter or that we can compute it from the shape + "tallest" bond + + final LargeShapeCanvas shapePanel; + + private Displayable owner; // it's the same scs + + private SpeciesContextSpec scs; + private SpeciesContext sc = null; + private SpeciesPattern sp = null; + private MolecularTypePattern mtp = null; + + boolean isPlanarYZ = true; // we only show entities that are 2D in the YZ plane + + + + public SpeciesContextSpecLargeShape(int xPos, int yPos, int height, SpeciesContextSpec scs, + LargeShapeCanvas shapePanel, Displayable owner, IssueListProvider issueListProvider) { + super(issueListProvider); + + this.owner = owner; + this.scs = scs; + this.xPos = xPos; + this.yPos = yPos; + this.height = height; + this.shapePanel = shapePanel; + + if(scs != null) { + this.sc = scs.getSpeciesContext(); + } + if(this.sc != null) { + this.sp = this.sc.getSpeciesPattern(); + } + if(this.sp != null) { + if(this.sp.getMolecularTypePatterns().size() != 1) { + throw new RuntimeException("Number of Molecules must be exactly 1"); + } + this.mtp = this.sp.getMolecularTypePatterns().get(0); + } + + + + } + + + private void paintDummy(Graphics g, int xPos, int yPos) { + return; // implement later + } + private void paintCompartments(Graphics g) { + return; // implement later + } + private void paintAxes(Graphics g) { + return; // implement later + } + public void drawCenteredCircle(Graphics2D g, int x, int y, int r) { + x = x-(r/2); + y = y-(r/2); + g.fillOval(x,y,r,r); + + Color oldColor = g.getColor(); + g.setColor(Color.black); + g.drawOval(x, y, r, r); + g.setColor(oldColor); + } + public void paintSelf(Graphics g, boolean bPaintContour) { + + if(!isPlanarYZ) { + return; + } + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Color oldColor = g.getColor(); + + paintCompartments(g); + paintAxes(g); + if(mtp == null || mtp.getComponentPatternList().size() == 0) { // paint empty dummy + paintDummy(g, xPos, yPos); + } + + Map siteAttributesMap = scs.getSiteAttributesMap(); + for(Map.Entry entry : siteAttributesMap.entrySet()) { + MolecularComponentPattern mcp = entry.getKey(); + SiteAttributesSpec sas = entry.getValue(); + Coordinate coord = sas.getCoordinate(); + double radius = sas.getRadius(); + Color color = sas.getColor().getColor(); + g.setColor(color); + drawCenteredCircle((Graphics2D)g, 10*(int)coord.getZ(), 10*(int)coord.getY(), 10*(int)radius); + } + g.setColor(oldColor); + } + + + + @Override + public void paintSelf(Graphics g) { + paintSelf(g, true); + } + + @Override + public boolean isHighlighted() { + return false; + } + + @Override + public void setHighlight(boolean highlight, boolean param) { + + } + + @Override + public void turnHighlightOffRecursive(Graphics g) { + + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getDisplayType() { + return null; + } +} diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java index 9b3e13a0b2..242439df4f 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java @@ -1161,6 +1161,10 @@ public void gatherIssues(IssueContext issueContext, List issueList, React // TODO: to be very strict, we should also check if we have a seed species with the right site / state combination // needed for the transition reactant, or another transition (or creation?) reaction that would produce it break; + case ALLOSTERIC: + // We check elsewhere that Allosteric cannot have the Anchor as transitioning or allosteric site + // Nothing to do here + break; default: break; } diff --git a/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java b/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java index ccd194c299..a1f606724a 100644 --- a/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java +++ b/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java @@ -48,7 +48,7 @@ @Tag("Fast") public class SpringSaLaDGoodReactionsTest { - private static final String reactionTestString = "'r0' :: 'MT0' : 'Site1' : 'state0' --> 'state1' Rate 50.0 Condition Free"; + private static final String reactionTestString = "'r0' :: 'MT0' : 'Site1' : 'state0' --> 'state1' Rate 50.0 Condition None"; private static final String L_x = "L_x: 0.1"; private static final String molecule = "MOLECULE: \"MT0\" Intracellular Number 10 Site_Types 2 Total_Sites 2 Total_Links 1 is2D false"; private static final String analyticExpressionIntra = "(z < 0.09)"; @@ -147,7 +147,7 @@ public void test_springsalad_bad_reactions() throws IOException, XmlParseExcepti simContext.gatherIssues(issueContext, issueList, true); // bIgnoreMathDescription == true int numErrors = checkIssuesBySeverity(issueList, Issue.Severity.ERROR); int numWarnings = checkIssuesBySeverity(issueList, Issue.Severity.WARNING); - assertTrue((numErrors == 0 && numWarnings == 14) ? true : false, "expecting 1 errors and 14 warning issues"); + assertTrue((numErrors == 2 && numWarnings == 14) ? true : false, "expecting 1 errors and 14 warning issues"); } /* ------------------------------------------------------------------------------------------------------------------------- @@ -180,7 +180,7 @@ public void test_springsalad_good_reactions() throws IOException, XmlParseExcept assertTrue((numErrors == 0) ? true : false, "expecting no Application error issues"); // 2 conditional bound transition reactions are syntactically correct, but there are // no binding reactions to make them possible - assertTrue((numWarnings == 2) ? true : false, "expecting 2 Application warning issues"); + assertTrue((numWarnings == 3) ? true : false, "expecting 2 Application warning issues"); // WARNING!! Debug configuration for this JUnit test required System property "vcell.installDir" // ex: -Dvcell.installDir=C:\dan\jprojects\git\vcell @@ -199,7 +199,7 @@ public void test_springsalad_good_reactions() throws IOException, XmlParseExcept List particleJumpProcesses = compartmentSubDomain.getParticleJumpProcesses(); List reactionRuleList = bioModel.getModel().getRbmModelContainer().getReactionRuleList(); assertTrue(reactionRuleList.size() == 9 ? true : false, "expecting 9 ReactionRule entities"); - assertTrue(particleJumpProcesses.size() == 10 ? true : false, "expecting 10 ParticleJumpProcess entities"); + assertTrue(particleJumpProcesses.size() == 9 ? true : false, "expecting 10 ParticleJumpProcess entities"); MathType mathType = mathDescription.getMathType(); assertTrue((mathType != null && mathType == SpringSaLaD) ? true : false, "expecting SpringSaLaD math type"); From 5ded0115c47f0ac62e65a1e9b118dd7447be39b8 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Wed, 16 Oct 2024 16:31:13 -0400 Subject: [PATCH 09/28] WIP: painting the shapes of the sites --- .../graph/SpeciesContextSpecLargeShape.java | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java index f1779417b6..33d793dc14 100644 --- a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java +++ b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java @@ -1,22 +1,21 @@ package cbit.vcell.graph; +import cbit.vcell.mapping.MolecularInternalLinkSpec; import cbit.vcell.mapping.SiteAttributesSpec; import cbit.vcell.mapping.SpeciesContextSpec; import cbit.vcell.model.SpeciesContext; -import org.vcell.model.rbm.MolecularComponentPattern; -import org.vcell.model.rbm.MolecularTypePattern; -import org.vcell.model.rbm.SpeciesPattern; +import cbit.vcell.model.Structure; +import org.vcell.model.rbm.*; import org.vcell.util.Coordinate; import org.vcell.util.Displayable; import java.awt.*; -import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.util.*; import java.util.List; -import java.util.Map; public class SpeciesContextSpecLargeShape extends AbstractComponentShape implements HighlightableShapeInterface { + private static final double nmToPixelRatio = 10; private int xPos = 0; private int yPos = 0; // y position where we draw the shape @@ -32,7 +31,11 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape impleme private SpeciesPattern sp = null; private MolecularTypePattern mtp = null; - boolean isPlanarYZ = true; // we only show entities that are 2D in the YZ plane + private boolean hasAnchor = false; + private MolecularComponentPattern mcpAnchor = null; + private boolean hasExtracellularSite = false; + private boolean hasMembraneSite = false; + private boolean hasIntracellularSite = false; @@ -59,9 +62,28 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, int height, SpeciesConte } this.mtp = this.sp.getMolecularTypePatterns().get(0); } + Map sasMap = scs.getSiteAttributesMap(); + Set ilSet = scs.getInternalLinkSet(); + MolecularType mt = mtp.getMolecularType(); + for(MolecularComponentPattern mcp : mtp.getComponentPatternList()) { + MolecularComponent mc = mcp.getMolecularComponent(); + SiteAttributesSpec sas = sasMap.get(mcp); + Structure structure = sas.getLocation(); + if(structure.getName().equals(Structure.SpringStructureEnum.Extracellular.columnName)) { + hasExtracellularSite = true; + } else if(structure.getName().equals(Structure.SpringStructureEnum.Intracellular.columnName)) { + hasIntracellularSite = true; + } + if(mc.getName().equals(SpeciesContextSpec.AnchorSiteString)) { + hasAnchor = true; + mcpAnchor = mcp; + hasMembraneSite = true; + } + } + } - - + private boolean isPlanarYZ() { // we only show entities that are 2D in the YZ plane + return true; // TODO: check } @@ -86,7 +108,7 @@ public void drawCenteredCircle(Graphics2D g, int x, int y, int r) { } public void paintSelf(Graphics g, boolean bPaintContour) { - if(!isPlanarYZ) { + if(isPlanarYZ() == false) { return; } Graphics2D g2 = (Graphics2D) g; @@ -99,15 +121,22 @@ public void paintSelf(Graphics g, boolean bPaintContour) { paintDummy(g, xPos, yPos); } - Map siteAttributesMap = scs.getSiteAttributesMap(); - for(Map.Entry entry : siteAttributesMap.entrySet()) { - MolecularComponentPattern mcp = entry.getKey(); - SiteAttributesSpec sas = entry.getValue(); + Map sasMap = scs.getSiteAttributesMap(); + MolecularType mt = mtp.getMolecularType(); + for(MolecularComponentPattern mcp : mtp.getComponentPatternList()) { +// for(Map.Entry entry : siteAttributesMap.entrySet()) { +// MolecularComponentPattern mcp = entry.getKey(); +// SiteAttributesSpec sas = entry.getValue(); + MolecularComponent mc = mcp.getMolecularComponent(); + SiteAttributesSpec sas = sasMap.get(mcp); Coordinate coord = sas.getCoordinate(); double radius = sas.getRadius(); Color color = sas.getColor().getColor(); g.setColor(color); - drawCenteredCircle((Graphics2D)g, 10*(int)coord.getZ(), 10*(int)coord.getY(), 10*(int)radius); + drawCenteredCircle((Graphics2D)g, + (int)(nmToPixelRatio * coord.getZ()), // transform nm to pixels + (int)(nmToPixelRatio * coord.getY()), + (int)(nmToPixelRatio * radius)); } g.setColor(oldColor); } From 98e431c571abc6b6d44b3ee1bf457ef36c277443 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Fri, 18 Oct 2024 14:58:14 -0400 Subject: [PATCH 10/28] WIP: painting the shapes of the sites --- .../gui/SpeciesContextSpecsTableModel.java | 6 ++- .../graph/SpeciesContextSpecLargeShape.java | 39 ++++++++++++++++--- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java index 8656391673..eb90c755c4 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java @@ -226,8 +226,8 @@ private void refreshData() { * getValueAt method comment. */ public Object getValueAt(int row, int col) { - try { - SpeciesContextSpec scSpec = getValueAt(row); + try { + SpeciesContextSpec scSpec = getValueAt(row); // TODO: if it's LangevinSpeciesContextSpec use super.getValueAt(row) ColumnType columnType = columns.get(col); switch (columnType){ case COLUMN_SPECIESCONTEXT:{ @@ -300,6 +300,7 @@ public SpeciesContextSpec getValueAt(int row) { * @param columnIndex int */ public boolean isCellEditable(int rowIndex, int columnIndex) { + // TODO: if it's LangevinSpeciesContextSpec use the super.getValueAt(row) !!! SpeciesContextSpec speciesContextSpec = getValueAt(rowIndex); ColumnType columnType = columns.get(columnIndex); switch (columnType){ @@ -565,6 +566,7 @@ public void setSimulationContext(SimulationContext simulationContext) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + // TODO: if it's LangevinSpeciesContextSpec use super.getValueAt(row) SpeciesContextSpec scSpec = getValueAt(rowIndex); ColumnType columnType = columns.get(columnIndex); switch (columnType){ diff --git a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java index 33d793dc14..64c62e58a8 100644 --- a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java +++ b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java @@ -17,10 +17,10 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape impleme private static final double nmToPixelRatio = 10; - private int xPos = 0; - private int yPos = 0; // y position where we draw the shape - private int nameOffset = 0; // offset upwards from yPos where we may write some text, like the expression of the sp - private int height = -1; // -1 means it doesn't matter or that we can compute it from the shape + "tallest" bond + private int xPos = 0; // TODO: we may not need these since we compute aitomatically offset, to nicely center the molecule + private int yPos = 0; // y position where we draw the shape (pixels from top and left of painting area) + +// private int nameOffset = 0; // offset upwards from yPos where we may write some text, like the expression of the sp final LargeShapeCanvas shapePanel; @@ -37,9 +37,16 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape impleme private boolean hasMembraneSite = false; private boolean hasIntracellularSite = false; + // we use these to compute some offset from top and left, so that the molecule will look nicely centered on screen + private double minX = 0; // coodrdinate of the leftmost site + private MolecularComponentPattern leftmostSite = null; + private double minY = 0; // coordinate of the topmost site + private MolecularComponentPattern topmostSite = null; // if more sites qualify we just keep the first we find - public SpeciesContextSpecLargeShape(int xPos, int yPos, int height, SpeciesContextSpec scs, + public SpeciesContextSpecLargeShape(int xPos, int yPos, + int height, // we may not need this + SpeciesContextSpec scs, LargeShapeCanvas shapePanel, Displayable owner, IssueListProvider issueListProvider) { super(issueListProvider); @@ -47,7 +54,7 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, int height, SpeciesConte this.scs = scs; this.xPos = xPos; this.yPos = yPos; - this.height = height; +// this.height = height; this.shapePanel = shapePanel; if(scs != null) { @@ -65,6 +72,7 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, int height, SpeciesConte Map sasMap = scs.getSiteAttributesMap(); Set ilSet = scs.getInternalLinkSet(); MolecularType mt = mtp.getMolecularType(); + int counter = 0; // site counter for(MolecularComponentPattern mcp : mtp.getComponentPatternList()) { MolecularComponent mc = mcp.getMolecularComponent(); SiteAttributesSpec sas = sasMap.get(mcp); @@ -79,6 +87,25 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, int height, SpeciesConte mcpAnchor = mcp; hasMembraneSite = true; } + Coordinate coordinate = sas.getCoordinate(); + double x = coordinate.getZ(); + double y = coordinate.getY(); + if(counter == 0) { + minX = x; + minY = y; + leftmostSite = mcp; + topmostSite = mcp; + } else { + if(x < minX) { + minX = x; + leftmostSite = mcp; + } + if(y < minY) { + minY = y; + topmostSite = mcp; + } + } + counter++; } } From cf4323383078761d8a2a0c5b3d03c4831db21b42 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Mon, 21 Oct 2024 14:05:39 -0400 Subject: [PATCH 11/28] WIP: painting the shapes of the sites --- .../desktop/biomodel/BioModelEditor.java | 16 ++++++++--- .../mapping/gui/InitialConditionsPanel.java | 12 +++++++-- .../MolecularStructuresPropertiesPanel.java | 10 +++---- .../mapping/gui/SpeciesContextSpecPanel.java | 14 +++++++--- .../gui/SpeciesContextSpecsTableModel.java | 23 +++++++++------- .../gui/MolecularStructuresPanel.java | 27 ++++++++++--------- .../mapping/LangevinSpeciesContextSpec.java | 2 ++ .../vcell/mapping/SpeciesContextSpec.java | 17 ++++++++++++ 8 files changed, 86 insertions(+), 35 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java index e9c0a376f4..fae673d24d 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java +++ b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/BioModelEditor.java @@ -772,10 +772,20 @@ protected void setRightBottomPanelOnSelection(Object[] selections) { } else if (singleSelection instanceof GeometryInfo) { bShowInDatabaseProperties = true; bottomComponent = geometryMetaDataPanel; - } else if (singleSelection instanceof LangevinSpeciesContextSpec) { - bottomComponent = getMolecularStructuresPropertiesPanel(); } else if (singleSelection instanceof SpeciesContextSpec) { - bottomComponent = getSpeciesContextSpecPanel(); + SpeciesContextSpec scs = (SpeciesContextSpec)singleSelection; + switch(scs.provenance) { + case LangevinSpecs: + bottomComponent = getMolecularStructuresPropertiesPanel(); + break; + case LangevinInitialConditions: // TODO: we'll have here a simplified SpeciesContextSpecPanel + bottomComponent = getSpeciesContextSpecPanel(); + break; + case GeneralInitialConditions: + default: + bottomComponent = getSpeciesContextSpecPanel(); + break; + } } else if (singleSelection instanceof ReactionSpec) { bottomComponent = getKineticsTypeTemplatePanel(); } else if (singleSelection instanceof ReactionRuleSpec) { // diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java index 06bd23ec97..3380d3f446 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/InitialConditionsPanel.java @@ -15,6 +15,7 @@ import java.awt.Component; import java.awt.FlowLayout; import java.awt.Graphics; +import java.util.ArrayList; import java.util.Hashtable; import java.util.Vector; @@ -157,8 +158,15 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } - if (e.getSource() == getScrollPaneTable().getSelectionModel()) - setSelectedObjectsFromTable(getScrollPaneTable(), tableModel); + if (e.getSource() == getScrollPaneTable().getSelectionModel()) { + + int row = getScrollPaneTable().getSelectedRow(); + SpeciesContextSpec scsSelected = tableModel.getValueAt(row); + + ArrayList selectedObjects = new ArrayList(); + selectedObjects.add(scsSelected); + selectionManager.setSelectedObjects(selectedObjects.toArray()); + } } ; diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index 299f6e7dd6..077bbb3c7f 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -9,7 +9,6 @@ import cbit.vcell.graph.gui.LargeShapePanel; import cbit.vcell.graph.gui.SsldLargeShapePanel; import cbit.vcell.graph.gui.ZoomShapeIcon; -import cbit.vcell.mapping.LangevinSpeciesContextSpec; import cbit.vcell.mapping.SpeciesContextSpec; import cbit.vcell.model.GroupingCriteria; import cbit.vcell.model.Model; @@ -242,12 +241,13 @@ public void setBioModel(BioModel newValue) { @Override protected void onSelectedObjectsChange(Object[] selectedObjects) { SpeciesContextSpec speciesContextSpec = null; - if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof LangevinSpeciesContextSpec) { - LangevinSpeciesContextSpec lscs = (LangevinSpeciesContextSpec)selectedObjects[0]; - speciesContextSpec = lscs.getTheSpeciesContextSpec(); + if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof SpeciesContextSpec) { + speciesContextSpec = (SpeciesContextSpec) selectedObjects[0]; + if(speciesContextSpec.provenance != SpeciesContextSpec.Provenance.LangevinSpecs) { + return; + } } setSpeciesContextSpec(speciesContextSpec); - } private JButton getZoomLargerButton() { diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java index d7d204116b..39e6d2bd49 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java @@ -28,7 +28,6 @@ import javax.swing.JScrollPane; import javax.swing.JSplitPane; -import cbit.vcell.mapping.LangevinSpeciesContextSpec; import org.vcell.model.rbm.MolecularComponentPattern; import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; @@ -270,6 +269,9 @@ private void updateShape() { if(speciesContext == null) { return; } + if(shapePanel.getGraphics() == null) { + return; + } SpeciesPattern sp = speciesContext.getSpeciesPattern(); spls = new SpeciesPatternLargeShape(xOffsetInitial, yOffsetInitial, -1, sp, shapePanel, speciesContext, issueManager); @@ -308,11 +310,15 @@ public void setBioModel(BioModel newValue) { @Override protected void onSelectedObjectsChange(Object[] selectedObjects) { SpeciesContextSpec speciesContextSpec = null; - if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof SpeciesContextSpec - && !(selectedObjects[0] instanceof LangevinSpeciesContextSpec)) { + if (selectedObjects != null && selectedObjects.length == 1 && selectedObjects[0] instanceof SpeciesContextSpec) { speciesContextSpec = (SpeciesContextSpec) selectedObjects[0]; + // TODO: we'll need to be more specific here in the future, we also return for LangevinInitialConditions + if(speciesContextSpec.provenance == SpeciesContextSpec.Provenance.LangevinSpecs) { + setSpeciesContextSpec(null); + } } - setSpeciesContextSpec(speciesContextSpec); + // TODO: eventually we'll do this only for GeneralInitialConditions + setSpeciesContextSpec(speciesContextSpec); } private JButton getZoomLargerButton() { diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java index eb90c755c4..be2be507cc 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecsTableModel.java @@ -227,7 +227,7 @@ private void refreshData() { */ public Object getValueAt(int row, int col) { try { - SpeciesContextSpec scSpec = getValueAt(row); // TODO: if it's LangevinSpeciesContextSpec use super.getValueAt(row) + SpeciesContextSpec scSpec = getValueAt(row); ColumnType columnType = columns.get(col); switch (columnType){ case COLUMN_SPECIESCONTEXT:{ @@ -282,14 +282,21 @@ public Object getValueAt(int row, int col) { @Override public SpeciesContextSpec getValueAt(int row) { - if(owner instanceof MolecularStructuresPanel) { - SpeciesContextSpec scs = super.getValueAt(row); - if(scs != null) { - LangevinSpeciesContextSpec lscs = new LangevinSpeciesContextSpec(scs, scs.getSimulationContext()); - return lscs; + SpeciesContextSpec scs = super.getValueAt(row); + if(scs == null) { + return null; + } + SimulationContext sc = getSimulationContext(); + if(getSimulationContext().getApplicationType() == SimulationContext.Application.SPRINGSALAD) { + if(owner instanceof MolecularStructuresPanel) { + scs.provenance = SpeciesContextSpec.Provenance.LangevinSpecs; + } else { + scs.provenance = SpeciesContextSpec.Provenance.LangevinInitialConditions; } + } else { + scs.provenance = SpeciesContextSpec.Provenance.GeneralInitialConditions; } - return super.getValueAt(row); + return scs; } /** @@ -300,7 +307,6 @@ public SpeciesContextSpec getValueAt(int row) { * @param columnIndex int */ public boolean isCellEditable(int rowIndex, int columnIndex) { - // TODO: if it's LangevinSpeciesContextSpec use the super.getValueAt(row) !!! SpeciesContextSpec speciesContextSpec = getValueAt(rowIndex); ColumnType columnType = columns.get(columnIndex); switch (columnType){ @@ -566,7 +572,6 @@ public void setSimulationContext(SimulationContext simulationContext) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - // TODO: if it's LangevinSpeciesContextSpec use super.getValueAt(row) SpeciesContextSpec scSpec = getValueAt(rowIndex); ColumnType columnType = columns.get(columnIndex); switch (columnType){ diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 1b71cdca24..4721df11fe 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -47,6 +47,7 @@ import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.beans.PropertyChangeListener; +import java.util.ArrayList; // we should use WindowBuilder Plugin (add it to Eclipse IDE) to speed up panel design // can choose absolute layout and place everything exactly as we see fit @@ -135,6 +136,7 @@ public void focusGained(FocusEvent e) { public void focusLost(FocusEvent e) { Object source = e.getSource(); if (source == siteXField || source == siteYField || source == siteZField) { + // TODO: are these even needed? we already call changePosition() on actionPerformed() changePosition((JTextField)source); } else if(source == linkLengthField) { // TODO: do NOT call here changeLinkLength(), it will modified the newly selected link instead the old one @@ -161,25 +163,26 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { return; } if (e.getSource() == getSpeciesContextSpecsTable().getSelectionModel()) { - setSelectedObjectsFromTable(getSpeciesContextSpecsTable(), speciesContextSpecsTableModel); + System.out.println("valueChanged: speciesContextSpecsTableModel"); int row = getSpeciesContextSpecsTable().getSelectedRow(); SpeciesContextSpec scsSelected = speciesContextSpecsTableModel.getValueAt(row); - if(scsSelected instanceof LangevinSpeciesContextSpec) { - LangevinSpeciesContextSpec lscs = (LangevinSpeciesContextSpec)scsSelected; - SpeciesContextSpec theSpeciesContextStep = lscs.getTheSpeciesContextSpec(); - setSpeciesContextSpec(theSpeciesContextStep); - } else { - setSpeciesContextSpec(scsSelected); - } - } - if (e.getSource() == getMolecularTypeSpecsTable().getSelectionModel()) { + setSpeciesContextSpec(scsSelected); + + ArrayList selectedObjects = new ArrayList(); + selectedObjects.add(scsSelected); + selectionManager.setSelectedObjects(selectedObjects.toArray()); + + } else if (e.getSource() == getMolecularTypeSpecsTable().getSelectionModel()) { + System.out.println("valueChanged: molecularTypeSpecsTableModel"); int row = getMolecularTypeSpecsTable().getSelectedRow(); MolecularComponentPattern mcmSelected = molecularTypeSpecsTableModel.getValueAt(row); setMolecularComponentPattern(mcmSelected); - } - if(e.getSource() == siteLinksList) { + + } else if(e.getSource() == siteLinksList) { + System.out.println("valueChanged: siteLinksList"); showLinkLength(siteLinksList.getSelectedValue()); } + // for siteXField, siteYField, siteZField we have actionPerformed() } } diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java index cd48e28ecb..f348238126 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/LangevinSpeciesContextSpec.java @@ -2,6 +2,8 @@ import cbit.vcell.model.SpeciesContext; + +@Deprecated public class LangevinSpeciesContextSpec extends SpeciesContextSpec { private final SpeciesContextSpec theSpeciesContextSpec; diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java index 180fed64f1..68d79daaa1 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java @@ -457,6 +457,23 @@ public void targetPropertyChange(PropertyChangeEvent evt){ // TODO: add getIs2DSQL() and readIs2DSQL(), similar to getSiteAttributesSQL(), readSiteAttributesSQL private boolean is2D = false; + // We implement Provenance as a means to use different PropertiesPanels when viewing SpeciesContextSpec properties + // we want the general SCS panel for non-springsalad applications, and 2 special panels for + // initial conditions - simplified initial conditions panel without the parameters table which make no sense for springsalad + // site specifications properties panel = for springsalad site attributes (will contain the viewer) + public transient Provenance provenance = Provenance.GeneralInitialConditions; + public enum Provenance { // SpringSaLaD specific + GeneralInitialConditions, + LangevinInitialConditions, + LangevinSpecs; +// +// final public String columnName; +// private SpringStructureEnum(String columnName) { +// this.columnName = columnName; +// } + } + + protected transient java.beans.VetoableChangeSupport vetoPropertyChange; private SpeciesContextSpecParameter[] fieldParameters = null; private SpeciesContextSpecProxyParameter[] fieldProxyParameters = new SpeciesContextSpecProxyParameter[0]; From 85cef01ce9c1c9eb7253254affaffcb350e22de1 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Wed, 23 Oct 2024 09:45:29 -0400 Subject: [PATCH 12/28] WIP: painting the scompartments --- .../MolecularStructuresPropertiesPanel.java | 2 + .../graph/SpeciesContextSpecLargeShape.java | 88 ++++++++++++++++--- 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index 077bbb3c7f..b4e2dfd0ae 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -43,11 +43,13 @@ public class MolecularStructuresPropertiesPanel extends DocumentEditorSubPanel { private class EventHandler implements ActionListener { public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getSource() == getZoomLargerButton()) { + System.out.println("Zoom to larger (Zoom In)"); boolean ret = shapePanel.zoomLarger(); getZoomLargerButton().setEnabled(ret); getZoomSmallerButton().setEnabled(true); updateShape(); } else if (e.getSource() == getZoomSmallerButton()) { + System.out.println("Zoom to smaller (Zoom Out)"); boolean ret = shapePanel.zoomSmaller(); getZoomLargerButton().setEnabled(true); getZoomSmallerButton().setEnabled(ret); diff --git a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java index 64c62e58a8..a3eb0fb1d9 100644 --- a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java +++ b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java @@ -15,10 +15,15 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape implements HighlightableShapeInterface { - private static final double nmToPixelRatio = 10; + private static final double nmToPixelRatio = 20; + private static final double DEFAULT_UPPER_CORNER = 4; // default screen coordinates where we want to display the first site + private static final double DEFAULT_LEFT_CORNER = 10; // in nm - private int xPos = 0; // TODO: we may not need these since we compute aitomatically offset, to nicely center the molecule - private int yPos = 0; // y position where we draw the shape (pixels from top and left of painting area) + // x, y positions where we want to begin drawing the shape (pixels from top and left of painting area) + private int xPos = 0; // we use these and the sites coordinates to compute offset, to nicely center the molecule + private int yPos = 0; + private double x_offset; + private double y_offset; // private int nameOffset = 0; // offset upwards from yPos where we may write some text, like the expression of the sp @@ -30,9 +35,13 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape impleme private SpeciesContext sc = null; private SpeciesPattern sp = null; private MolecularTypePattern mtp = null; + private Structure structure = null; private boolean hasAnchor = false; private MolecularComponentPattern mcpAnchor = null; + private double membraneX = 0; + private double membraneY = 0; + private double membraneRadius = 0; private boolean hasExtracellularSite = false; private boolean hasMembraneSite = false; private boolean hasIntracellularSite = false; @@ -60,15 +69,17 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, if(scs != null) { this.sc = scs.getSpeciesContext(); } - if(this.sc != null) { - this.sp = this.sc.getSpeciesPattern(); + if(sc != null) { + this.sp = sc.getSpeciesPattern(); + this.structure = sc.getStructure(); } - if(this.sp != null) { - if(this.sp.getMolecularTypePatterns().size() != 1) { + if(sp != null) { + if(sp.getMolecularTypePatterns().size() != 1) { throw new RuntimeException("Number of Molecules must be exactly 1"); } - this.mtp = this.sp.getMolecularTypePatterns().get(0); + this.mtp = sp.getMolecularTypePatterns().get(0); } + Map sasMap = scs.getSiteAttributesMap(); Set ilSet = scs.getInternalLinkSet(); MolecularType mt = mtp.getMolecularType(); @@ -86,6 +97,9 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, hasAnchor = true; mcpAnchor = mcp; hasMembraneSite = true; + membraneX = sasMap.get(mcp).getZ(); + membraneY = sasMap.get(mcp).getY(); + membraneRadius = sasMap.get(mcp).getRadius(); } Coordinate coordinate = sas.getCoordinate(); double x = coordinate.getZ(); @@ -107,6 +121,10 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, } counter++; } + // now compute the offsets, we want the sites nicely centered on screen + // UPPER_CORNER, LEFT_CORNER + x_offset = DEFAULT_LEFT_CORNER - minX; + y_offset = DEFAULT_UPPER_CORNER - minY; } private boolean isPlanarYZ() { // we only show entities that are 2D in the YZ plane @@ -118,6 +136,52 @@ private void paintDummy(Graphics g, int xPos, int yPos) { return; // implement later } private void paintCompartments(Graphics g) { + Graphics2D g2 = (Graphics2D)g; + Color colorOld = g2.getColor(); + Paint paintOld = g2.getPaint(); + Font fontOld = g2.getFont(); + + Font font; + int w; // width of compartment shape, adjusted continuously based on zoom factor + String name = structure.getName(); + int z = shapePanel.getZoomFactor(); + if(z > -3) { + font = fontOld.deriveFont(Font.BOLD); + g.setFont(font); + } else { + font = fontOld; + g.setFont(font); + } + + g.setColor(Color.black); + if(!hasMembraneSite) { + double x = minX+x_offset; + double y = 1; + g2.drawString(name, (int)(nmToPixelRatio * x), (int)(nmToPixelRatio * y)); + } else { + double x = membraneX+x_offset-5; + double y = 1; + g2.drawString("Extracellular", (int)(nmToPixelRatio * x), (int)(nmToPixelRatio * y)); + + x = membraneX+x_offset; + y = 1; + g2.drawString("Membrane Intracellular", + (int)(nmToPixelRatio * (x-membraneRadius)), // move it slightly to the left + (int)(nmToPixelRatio * y)); + + g2.setColor(Color.gray); + g2.drawLine((int)(nmToPixelRatio * x), // centered on the Anchor + (int)(nmToPixelRatio * (y+1)), + (int)(nmToPixelRatio * x), + (int)(nmToPixelRatio * (y+6))); + + } + + + g2.setFont(fontOld); + g2.setPaint(paintOld); + g2.setColor(colorOld); + return; // implement later } private void paintAxes(Graphics g) { @@ -144,6 +208,7 @@ public void paintSelf(Graphics g, boolean bPaintContour) { paintCompartments(g); paintAxes(g); + if(mtp == null || mtp.getComponentPatternList().size() == 0) { // paint empty dummy paintDummy(g, xPos, yPos); } @@ -160,9 +225,12 @@ public void paintSelf(Graphics g, boolean bPaintContour) { double radius = sas.getRadius(); Color color = sas.getColor().getColor(); g.setColor(color); + double x = x_offset + coord.getZ(); + double y = y_offset + coord.getY(); + System.out.println("Painting site at " + x + ", " + y + " (nm)"); drawCenteredCircle((Graphics2D)g, - (int)(nmToPixelRatio * coord.getZ()), // transform nm to pixels - (int)(nmToPixelRatio * coord.getY()), + (int)(nmToPixelRatio * x), // transform nm to pixels + (int)(nmToPixelRatio * y), (int)(nmToPixelRatio * radius)); } g.setColor(oldColor); From 9ed923d94817f2d97541b23e75f28348df3951a7 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 24 Oct 2024 10:25:33 -0400 Subject: [PATCH 13/28] Utilities: graph continuity, color management --- .../util/springsalad/GraphContinuity.java | 96 +++++++++++++++++++ .../vcell/util/springsalad/NamedColor.java | 14 +++ 2 files changed, 110 insertions(+) create mode 100644 vcell-core/src/main/java/org/vcell/util/springsalad/GraphContinuity.java diff --git a/vcell-core/src/main/java/org/vcell/util/springsalad/GraphContinuity.java b/vcell-core/src/main/java/org/vcell/util/springsalad/GraphContinuity.java new file mode 100644 index 0000000000..d5fd5d2699 --- /dev/null +++ b/vcell-core/src/main/java/org/vcell/util/springsalad/GraphContinuity.java @@ -0,0 +1,96 @@ +package org.vcell.util.springsalad; + +import java.util.*; + +/* + * test graph continuity + * for undirected graph + */ +public class GraphContinuity { + + public enum Algorithm { + DFS, + BFS + } + + public static class Graph { + private int nodes; + private LinkedList[] adjList; + + public Graph(int nodes) { + this.nodes = nodes; + adjList = new LinkedList[nodes]; + for (int i = 0; i < nodes; i++) { + adjList[i] = new LinkedList<>(); + } + } + + // add an edge to the graph + public void addEdge(int source, int destination) { + adjList[source].add(destination); + adjList[destination].add(source); // for undirected graph + } + + public boolean isConnected(Algorithm algorithm) { + if(Algorithm.DFS == algorithm) { + return isConnectedDFS(); + } else { + return isConnectedBFS(); + } + } + + private boolean isConnectedDFS() { // ------------ check continuity using DFS + boolean[] visited = new boolean[nodes]; // array to track visited nodes + DFS(0, visited); // start from node 0 + for (boolean nodeVisited : visited) { // check if all nodes are visited + if (!nodeVisited) { + return false; // if any node is not visited, graph is disconnected + } + } + return true; + } + private void DFS(int node, boolean[] visited) { // depth-first search (DFS) algorithm + visited[node] = true; // mark the current node as visited + for (int adjacent : adjList[node]) { // visit all adjacent nodes + if (!visited[adjacent]) { + DFS(adjacent, visited); // recursively visit unvisited adjacent nodes + } + } + } + + private boolean isConnectedBFS() { // ------------ check continuity using BFS + boolean[] visited = new boolean[nodes]; + BFS(0, visited); + for (boolean nodeVisited : visited) { + if (!nodeVisited) { + return false; + } + } + return true; + } + private void BFS(int startNode, boolean[] visited) { // breadth-first search (BFS) algorithm + Queue queue = new LinkedList<>(); + queue.add(startNode); // add start node to the queue + visited[startNode] = true; // mark it as visited + while (!queue.isEmpty()) { + int node = queue.poll(); // remove the node from the queue + for (int adjacent : adjList[node]) { // visit all adjacent nodes + if (!visited[adjacent]) { + queue.add(adjacent); // add unvisited adjacent nodes to the queue + visited[adjacent] = true; // mark them as visited + } + } + } + } + } + + public static void main(String[] args) { + Graph graph = new Graph(5); + graph.addEdge(0, 1); + graph.addEdge(1, 2); + graph.addEdge(2, 3); + graph.addEdge(3, 4); + System.out.println("DFS: the graph is " + (graph.isConnected(Algorithm.DFS) ? "connected" : "disconnected")); + System.out.println("BFS: the graph is " + (graph.isConnected(Algorithm.BFS) ? "connected" : "disconnected")); + } +} diff --git a/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java b/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java index 0de30a1194..5cb2cd1d1c 100644 --- a/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java +++ b/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java @@ -34,4 +34,18 @@ public String toString() { return name; } + public Color darker(double factor) { + return new Color(Math.max((int)(color.getRed()*factor), 0), + Math.max((int)(color.getGreen()*factor), 0), + Math.max((int)(color.getBlue() *factor), 0), + color.getAlpha()); + } + + public static Color darker(Color color, double factor) { + return new Color(Math.max((int)(color.getRed()*factor), 0), + Math.max((int)(color.getGreen()*factor), 0), + Math.max((int)(color.getBlue() *factor), 0), + color.getAlpha()); + } + } From 16eda45fdb5e115572fd64ee2af3332fd5c671b7 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 24 Oct 2024 13:03:23 -0400 Subject: [PATCH 14/28] molecular details: compartments, axes, links, zoom --- .../MolecularStructuresPropertiesPanel.java | 29 +-- .../graph/SpeciesContextSpecLargeShape.java | 242 +++++++++++++----- .../vcell/mapping/SpeciesContextSpec.java | 32 ++- 3 files changed, 219 insertions(+), 84 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index b4e2dfd0ae..0c05dc7955 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -79,9 +79,12 @@ private void initialize() { @Override public void paintComponent(Graphics g) { super.paintComponent(g); - if (scsls != null) { - scsls.paintSelf(g); + if (speciesContextSpec == null || speciesContextSpec.getSpeciesContext() == null) { + return; } + System.out.println(speciesContextSpec.getSpeciesContext().getName() + ": painting shape"); + scsls = new SpeciesContextSpecLargeShape(speciesContextSpec, shapePanel, speciesContextSpec, issueManager); + scsls.paintSelf(g); } @Override public DisplayMode getDisplayMode() { @@ -132,13 +135,14 @@ public void mouseMoved(MouseEvent e) { // shapePanel.setToolTipText("View-Only panel"); } }); + shapePanel.setPreferredSize(new Dimension(2000, 800)); shapePanel.setBackground(new Color(0xe0e0e0)); shapePanel.setZoomFactor(-2); shapePanel.setEditable(false); scrollPane = new JScrollPane(shapePanel); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); // ----------------------------------------------------------------------------------------- @@ -171,7 +175,6 @@ public void mouseMoved(MouseEvent e) { gbc.insets = new Insets(4, 4, 4, 10); optionsPanel.add(new JLabel(""), gbc); - // ------------------------------------------------------------------------------------------ JPanel containerOfScrollPanel = new JPanel(); containerOfScrollPanel.setLayout(new BorderLayout()); @@ -182,9 +185,6 @@ public void mouseMoved(MouseEvent e) { add(containerOfScrollPanel, BorderLayout.CENTER); setBackground(Color.white); setName("MolecularStructuresPropertiesPanel"); - - - } catch (java.lang.Throwable ivjExc) { handleException(ivjExc); } @@ -197,18 +197,15 @@ private void updateInterface() { updateShape(); } - public static final int xOffsetInitial = 20; - public static final int yOffsetInitial = 10; private void updateShape() { if(speciesContextSpec == null || speciesContextSpec.getSpeciesContext() == null) { return; } - SpeciesPattern sp = speciesContextSpec.getSpeciesContext().getSpeciesPattern(); - System.out.println(sp.getNameShort()); - scsls = new SpeciesContextSpecLargeShape(xOffsetInitial, yOffsetInitial, -1, speciesContextSpec, shapePanel, speciesContextSpec, issueManager); -// -// Dimension preferredSize = new Dimension(spls.getRightEnd()+40, yOffsetInitial+80); -// shapePanel.setPreferredSize(preferredSize); + System.out.println(speciesContextSpec.getSpeciesContext().getName() + ": painting shape"); + scsls = new SpeciesContextSpecLargeShape(speciesContextSpec, shapePanel, speciesContextSpec, issueManager); + +// shapePanel.setPreferredSize(scsls.getMaxSize()); + shapePanel.repaint(); } diff --git a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java index a3eb0fb1d9..f2460cf660 100644 --- a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java +++ b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java @@ -8,6 +8,8 @@ import org.vcell.model.rbm.*; import org.vcell.util.Coordinate; import org.vcell.util.Displayable; +import org.vcell.util.Pair; +import org.vcell.util.springsalad.NamedColor; import java.awt.*; import java.util.*; @@ -15,15 +17,14 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape implements HighlightableShapeInterface { - private static final double nmToPixelRatio = 20; - private static final double DEFAULT_UPPER_CORNER = 4; // default screen coordinates where we want to display the first site + private static final double NmToPixelRatio = 25; + private static final double DEFAULT_UPPER_CORNER = 3; // default screen coordinates where we want to display the first site private static final double DEFAULT_LEFT_CORNER = 10; // in nm - // x, y positions where we want to begin drawing the shape (pixels from top and left of painting area) - private int xPos = 0; // we use these and the sites coordinates to compute offset, to nicely center the molecule - private int yPos = 0; - private double x_offset; - private double y_offset; + // x, y positions where we want to begin drawing the shape (nm from top and left of painting area) + private double x_offset = DEFAULT_LEFT_CORNER; + private double y_offset = DEFAULT_UPPER_CORNER; + private double nmToPixelRatio = NmToPixelRatio; // private int nameOffset = 0; // offset upwards from yPos where we may write some text, like the expression of the sp @@ -47,23 +48,19 @@ public class SpeciesContextSpecLargeShape extends AbstractComponentShape impleme private boolean hasIntracellularSite = false; // we use these to compute some offset from top and left, so that the molecule will look nicely centered on screen - private double minX = 0; // coodrdinate of the leftmost site + private double minX = 0; // coordinate of the leftmost site private MolecularComponentPattern leftmostSite = null; private double minY = 0; // coordinate of the topmost site private MolecularComponentPattern topmostSite = null; // if more sites qualify we just keep the first we find + private double maxX = 0; // coordinate of the rightmost site + private double maxY = 0; // coordinate of the bottommost site - - public SpeciesContextSpecLargeShape(int xPos, int yPos, - int height, // we may not need this - SpeciesContextSpec scs, - LargeShapeCanvas shapePanel, Displayable owner, IssueListProvider issueListProvider) { + public SpeciesContextSpecLargeShape(SpeciesContextSpec scs, LargeShapeCanvas shapePanel, + Displayable owner, IssueListProvider issueListProvider) { super(issueListProvider); this.owner = owner; this.scs = scs; - this.xPos = xPos; - this.yPos = yPos; -// this.height = height; this.shapePanel = shapePanel; if(scs != null) { @@ -75,9 +72,11 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, } if(sp != null) { if(sp.getMolecularTypePatterns().size() != 1) { - throw new RuntimeException("Number of Molecules must be exactly 1"); + return; } this.mtp = sp.getMolecularTypePatterns().get(0); + } else { + return; } Map sasMap = scs.getSiteAttributesMap(); @@ -109,6 +108,8 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, minY = y; leftmostSite = mcp; topmostSite = mcp; + maxX = x; + maxY = y; } else { if(x < minX) { minX = x; @@ -118,6 +119,12 @@ public SpeciesContextSpecLargeShape(int xPos, int yPos, minY = y; topmostSite = mcp; } + if(x > maxX) { + maxX = x; + } + if(y > maxY) { + maxY = y; + } } counter++; } @@ -131,23 +138,36 @@ private boolean isPlanarYZ() { // we only show entities that are 2D in the YZ return true; // TODO: check } + public Dimension getMaxSize() { + int z = shapePanel.getZoomFactor(); + nmToPixelRatio = NmToPixelRatio + z; + int width = (int) (nmToPixelRatio * (x_offset+maxX+10)); + int height = (int) (nmToPixelRatio * (y_offset+maxY+6)); + return new Dimension(width, height); + } - private void paintDummy(Graphics g, int xPos, int yPos) { + private void paintDummy(Graphics g) { return; // implement later } private void paintCompartments(Graphics g) { + Graphics2D g2 = (Graphics2D)g; Color colorOld = g2.getColor(); Paint paintOld = g2.getPaint(); Font fontOld = g2.getFont(); + RenderingHints hintsOld = g2.getRenderingHints(); + Stroke strokeOld = g2.getStroke(); Font font; - int w; // width of compartment shape, adjusted continuously based on zoom factor - String name = structure.getName(); int z = shapePanel.getZoomFactor(); + nmToPixelRatio = NmToPixelRatio + z; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + String name = structure.getName(); if(z > -3) { font = fontOld.deriveFont(Font.BOLD); g.setFont(font); + } else { font = fontOld; g.setFont(font); @@ -166,105 +186,201 @@ private void paintCompartments(Graphics g) { x = membraneX+x_offset; y = 1; g2.drawString("Membrane Intracellular", - (int)(nmToPixelRatio * (x-membraneRadius)), // move it slightly to the left + (int)(nmToPixelRatio * x), +// (int)(nmToPixelRatio * (x-membraneRadius)), // move it slightly to the left (int)(nmToPixelRatio * y)); - g2.setColor(Color.gray); + g2.setColor(NamedColor.darker(Color.orange, 0.8)); + float thickness = 4.0f; + g2.setStroke(new BasicStroke(thickness)); g2.drawLine((int)(nmToPixelRatio * x), // centered on the Anchor (int)(nmToPixelRatio * (y+1)), (int)(nmToPixelRatio * x), - (int)(nmToPixelRatio * (y+6))); - + (int)(nmToPixelRatio * (maxY+y_offset+6))); } - - + g2.setStroke(strokeOld); + g2.setRenderingHints(hintsOld); g2.setFont(fontOld); g2.setPaint(paintOld); g2.setColor(colorOld); - - return; // implement later } + private void paintAxes(Graphics g) { - return; // implement later + + Graphics2D g2 = (Graphics2D) g; + Color colorOld = g2.getColor(); + Paint paintOld = g2.getPaint(); + Font fontOld = g2.getFont(); + RenderingHints hintsOld = g2.getRenderingHints(); + Stroke strokeOld = g2.getStroke(); + + Font font; + int z = shapePanel.getZoomFactor(); + nmToPixelRatio = NmToPixelRatio + z; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + if(z > -3) { + font = fontOld.deriveFont(Font.BOLD); + g.setFont(font); + } else { + font = fontOld; + g.setFont(font); + } + + int startX = 15; // coordinates for the arrow line (z-axis) + int startY = 15; + int endX = 60; + int endY = 15; + g2.setColor(Color.black); + g2.drawString("Z", endX+5, endY+3); // coord name + g2.setColor(Color.gray); + g2.drawLine(startX, startY, endX, endY); // draw the arrow line + int arrowSize = 10; // draw the arrow head + int[] xPoints = {endX, endX - arrowSize, endX - arrowSize}; + int[] yPoints = {endY, endY - arrowSize, endY + arrowSize}; + g2.fillPolygon(xPoints, yPoints, 3); + + startX = 15; // coordinates for the arrow line (Y-axis) + startY = 15; + endX = 15; + endY = 60; + g2.setColor(Color.black); + g2.drawString("Y", endX-2, endY+12); + g2.setColor(Color.gray); + g2.drawLine(startX, startY, endX, endY); + int[] xPoints2 = {endX, endX - arrowSize, endX + arrowSize}; + int[] yPoints2 = {endY, endY - arrowSize, endY - arrowSize}; + g2.fillPolygon(xPoints2, yPoints2, 3); + + startX = 15; // coordinates for the arrow line (Y-axis) + startY = 100; + endX = 15 + (int)nmToPixelRatio; + int offset = 3; + g2.setColor(Color.black); + float thickness = 2.0f; + g2.setStroke(new BasicStroke(thickness)); + g2.drawLine(startX, startY, endX, startY); + g2.drawLine(startX, startY-offset, startX, startY+offset); + g2.drawLine(endX, startY-offset, endX, startY+offset); + g2.setStroke(strokeOld); + g2.drawString("1 nm", endX+10, startY+offset); + + g2.setStroke(strokeOld); + g2.setRenderingHints(hintsOld); + g2.setFont(fontOld); + g2.setPaint(paintOld); + g2.setColor(colorOld); } - public void drawCenteredCircle(Graphics2D g, int x, int y, int r) { - x = x-(r/2); - y = y-(r/2); - g.fillOval(x,y,r,r); + public void drawCenteredCircle(Graphics g, NamedColor namedColor, double xd, double yd, double rd) { + + Graphics2D g2 = (Graphics2D)g; Color oldColor = g.getColor(); + RenderingHints hintsOld = g2.getRenderingHints(); + + int z = shapePanel.getZoomFactor(); + nmToPixelRatio = NmToPixelRatio + z; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + xd = xd-(rd/2); + yd = yd-(rd/2); + + int x = (int)(nmToPixelRatio * xd); + int y = (int)(nmToPixelRatio * yd); + int r = (int)(nmToPixelRatio * rd); + +// g.setColor(namedColor.darker(0.9)); + g.setColor(namedColor.getColor()); + g.fillOval(x,y,r,r); // colored circle + g.setColor(Color.black); - g.drawOval(x, y, r, r); + g.drawOval(x, y, r, r); // black contour + + g2.setRenderingHints(hintsOld); + g.setColor(oldColor); + } + + public void drawLink(Graphics g, double x1d, double y1d, double x2d, double y2d) { + + Graphics2D g2 = (Graphics2D)g; + Color oldColor = g.getColor(); + RenderingHints hintsOld = g2.getRenderingHints(); + Stroke strokeOld = g2.getStroke(); + + int z = shapePanel.getZoomFactor(); + nmToPixelRatio = NmToPixelRatio + z; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + int x1 = (int)(nmToPixelRatio * x1d); + int y1 = (int)(nmToPixelRatio * y1d); + int x2 = (int)(nmToPixelRatio * x2d); + int y2 = (int)(nmToPixelRatio * y2d); + + g.setColor(Color.gray); + float thickness = 1.4f; + g2.setStroke(new BasicStroke(thickness)); + g2.drawLine(x1, y1, x2, y2); + + g2.setStroke(strokeOld); + g2.setRenderingHints(hintsOld); g.setColor(oldColor); } - public void paintSelf(Graphics g, boolean bPaintContour) { + public void paintSelf(Graphics g, boolean bPaintContour) { if(isPlanarYZ() == false) { return; } - Graphics2D g2 = (Graphics2D) g; - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - Color oldColor = g.getColor(); - paintCompartments(g); paintAxes(g); - if(mtp == null || mtp.getComponentPatternList().size() == 0) { // paint empty dummy - paintDummy(g, xPos, yPos); + paintDummy(g); + return; } - Map sasMap = scs.getSiteAttributesMap(); - MolecularType mt = mtp.getMolecularType(); + Set internalLinkSet = scs.getInternalLinkSet(); + for(MolecularInternalLinkSpec mils : internalLinkSet) { + Pair link = mils.getLink(); + SiteAttributesSpec sas1 = sasMap.get(link.one); + SiteAttributesSpec sas2 = sasMap.get(link.two); + double x1 = x_offset + sas1.getCoordinate().getZ(); + double x2 = x_offset + sas2.getCoordinate().getZ(); + double y1 = y_offset + sas1.getCoordinate().getY(); + double y2 = y_offset + sas2.getCoordinate().getY(); + drawLink(g, x1, y1, x2, y2); + } for(MolecularComponentPattern mcp : mtp.getComponentPatternList()) { -// for(Map.Entry entry : siteAttributesMap.entrySet()) { -// MolecularComponentPattern mcp = entry.getKey(); -// SiteAttributesSpec sas = entry.getValue(); - MolecularComponent mc = mcp.getMolecularComponent(); SiteAttributesSpec sas = sasMap.get(mcp); Coordinate coord = sas.getCoordinate(); double radius = sas.getRadius(); - Color color = sas.getColor().getColor(); - g.setColor(color); + NamedColor color = sas.getColor(); double x = x_offset + coord.getZ(); double y = y_offset + coord.getY(); - System.out.println("Painting site at " + x + ", " + y + " (nm)"); - drawCenteredCircle((Graphics2D)g, - (int)(nmToPixelRatio * x), // transform nm to pixels - (int)(nmToPixelRatio * y), - (int)(nmToPixelRatio * radius)); + drawCenteredCircle(g, color, x, y, radius); } - g.setColor(oldColor); } - - @Override public void paintSelf(Graphics g) { paintSelf(g, true); } - @Override public boolean isHighlighted() { return false; } - @Override public void setHighlight(boolean highlight, boolean param) { - } - @Override public void turnHighlightOffRecursive(Graphics g) { - } @Override public String getDisplayName() { return null; } - @Override public String getDisplayType() { return null; } + } diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java index 68d79daaa1..440cdb1400 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java @@ -59,6 +59,7 @@ import net.sourceforge.interval.ia_math.RealInterval; import org.vcell.util.springsalad.Colors; import org.vcell.util.springsalad.NamedColor; +import org.vcell.util.springsalad.GraphContinuity; @SuppressWarnings("serial") public class SpeciesContextSpec implements Matchable, ScopedSymbolTable, Serializable, SimulationContextEntity, IssueSource, @@ -1298,12 +1299,33 @@ public void gatherIssues(IssueContext issueContext, List issueVector){ return; } } - if(mcpList.size() > 1 && mcpList.size() > getInternalLinkSet().size() + 1){ - String msg = "Link chain within the molecule has at least one discontinuity."; - String tip = "One or more links are missing"; - issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); - return; + if(mcpList.size() > 1 && getInternalLinkSet().size() > 0) { + GraphContinuity.Graph graph = new GraphContinuity.Graph(mcpList.size()); + Map mcpMap = new LinkedHashMap<> (); + for(int i=0; i link = mils.getLink(); + int one = mcpMap.get(link.one); + int two = mcpMap.get(link.two); + graph.addEdge(one, two); + } + if(!graph.isConnected(GraphContinuity.Algorithm.DFS)) { // let's use DFS! + String msg = "Link chain within the molecule has at least one discontinuity."; + String tip = "One or more links are missing"; + issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); + return; + } } +// old way, imprecise! use graph above +// if(mcpList.size() > 1 && mcpList.size() > getInternalLinkSet().size() + 1){ +// String msg = "Link chain within the molecule has at least one discontinuity."; +// String tip = "One or more links are missing"; +// issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); +// return; +// } for(MolecularInternalLinkSpec candidate : getInternalLinkSet()){ for(MolecularInternalLinkSpec other : getInternalLinkSet()){ if(candidate == other){ From 089fbdc84e3e4d3a956931e289f81678a1e96bd6 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Fri, 25 Oct 2024 14:13:55 -0400 Subject: [PATCH 15/28] molecular details: NamedColor combobox, editor, renderer --- .../gui/MolecularTypeSpecsTableModel.java | 69 +++++++-- .../gui/MolecularStructuresPanel.java | 133 ++++++++++-------- 2 files changed, 138 insertions(+), 64 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index 7e6a273c48..ec3bfb1c96 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -10,7 +10,7 @@ package cbit.vcell.mapping.gui; -import java.awt.Component; +import java.awt.*; import java.beans.PropertyChangeEvent; import java.util.ArrayList; import java.util.Arrays; @@ -18,12 +18,8 @@ import java.util.List; import java.util.Map; -import javax.swing.DefaultCellEditor; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListCellRenderer; -import javax.swing.JComboBox; -import javax.swing.JList; -import javax.swing.SwingConstants; +import javax.swing.*; +import javax.swing.table.TableCellRenderer; import org.vcell.model.rbm.ComponentStatePattern; import org.vcell.model.rbm.MolecularComponent; @@ -31,6 +27,7 @@ import org.vcell.model.rbm.MolecularType; import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; +import org.vcell.util.gui.ColorIcon; import org.vcell.util.gui.GuiUtils; import org.vcell.util.gui.ScrollTable; @@ -44,6 +41,8 @@ import cbit.vcell.model.SpeciesContext; import cbit.vcell.model.Structure; import cbit.vcell.parser.Expression; +import org.vcell.util.springsalad.Colors; +import org.vcell.util.springsalad.NamedColor; /** * Insert the type's description here. @@ -63,7 +62,8 @@ private enum ColumnType { COLUMN_STRUCTURE("Location"), COLUMN_STATE("Initial State"), COLUMN_RADIUS("Radius (nm)"), - COLUMN_DIFFUSION("Diffusion Rate (um^2/s)"); + COLUMN_DIFFUSION("Diff. Rate (um^2/s)"), + COLUMN_COLOR("Color"); public final String label; private ColumnType(String label){ @@ -95,6 +95,8 @@ public Class getColumnClass(int column) { case COLUMN_RADIUS: case COLUMN_DIFFUSION: return Expression.class; + case COLUMN_COLOR: + return NamedColor.class; default: return Object.class; } @@ -151,6 +153,11 @@ public Object getValueAt(int row, int col) { return null; } return sas.getDiffusionRate(); // um^2/s + case COLUMN_COLOR: + if(sas == null) { + return null; + } + return sas.getColor(); default: return null; } @@ -204,6 +211,16 @@ public void setValueAt(Object aValue, int row, int col) { sas.setDiffusionRate(result); return; } + case COLUMN_COLOR: + if (aValue instanceof NamedColor) { + NamedColor namedColor = (NamedColor)aValue; + SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); + if(sas == null) { + sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + } + sas.setColor(namedColor); + return; + } default: return; } @@ -227,6 +244,7 @@ public boolean isCellEditable(int row, int col) { case COLUMN_STRUCTURE: case COLUMN_RADIUS: case COLUMN_DIFFUSION: + case COLUMN_COLOR: return true; default: return false; @@ -251,6 +269,7 @@ public int compare(MolecularComponentPattern mcp1, MolecularComponentPattern mcp case COLUMN_STATE: case COLUMN_RADIUS: case COLUMN_DIFFUSION: + case COLUMN_COLOR: default: return 1; } @@ -381,8 +400,40 @@ private void refreshData() { GuiUtils.flexResizeTableColumns(ownerTable); updateLocationComboBox(); + updateColorComboBox(); } - + + + + private void updateColorComboBox() { + if(fieldSimulationContext == null) { + return; + } + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); + for(NamedColor namedColor : Colors.COLORARRAY) { + model.addElement(namedColor); + } + JComboBox colorComboBox = new JComboBox<>(); + colorComboBox.setRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setHorizontalTextPosition(SwingConstants.LEFT); + if (value instanceof NamedColor) { + NamedColor namedColor = (NamedColor)value; + setText(namedColor.getName()); + Icon icon = new ColorIcon(10,10,namedColor.getColor(), true); // small square icon with subdomain color + setHorizontalTextPosition(SwingConstants.RIGHT); + setIcon(icon); + } + return this; + } + }); + colorComboBox.setModel(model); + ownerTable.getColumnModel().getColumn(ColumnType.COLUMN_COLOR.ordinal()).setCellEditor(new DefaultCellEditor(colorComboBox)); + } + private void updateLocationComboBox() { if(fieldSimulationContext == null) { return; diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 4721df11fe..f42aa9bfe5 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -26,6 +26,7 @@ import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; import org.vcell.util.Coordinate; +import org.vcell.util.gui.ColorIcon; import org.vcell.util.gui.DefaultScrollTableCellRenderer; import org.vcell.util.gui.EditorScrollTable; import org.vcell.util.gui.ScrollTable.ScrollTableBooleanCellRenderer; @@ -66,7 +67,7 @@ public class MolecularStructuresPanel extends DocumentEditorSubPanel implements private EditorScrollTable molecularTypeSpecsTable = null; private MolecularTypeSpecsTableModel molecularTypeSpecsTableModel = null; - private JComboBox siteColorComboBox = null; +// private JComboBox siteColorComboBox = null; private JTextField siteXField = null; private JTextField siteYField = null; private JTextField siteZField = null; @@ -127,8 +128,8 @@ public void actionPerformed(ActionEvent e) { } else if(source == deleteLinkButton) { deleteLinkActionPerformed(); refreshSiteLinksList(); - } else if(source == getSiteColorComboBox()) { - updateSiteColor(); +// } else if(source == getSiteColorComboBox()) { +// updateSiteColor(); } } public void focusGained(FocusEvent e) { @@ -217,7 +218,7 @@ private void initConnections() throws java.lang.Exception { // listeners here! addLinkButton.addActionListener(eventHandler); deleteLinkButton.addActionListener(eventHandler); - getSiteColorComboBox().addActionListener(eventHandler); +// getSiteColorComboBox().addActionListener(eventHandler); ListSelectionModel lsm = getSpeciesContextSpecsTable().getSelectionModel(); if(lsm instanceof DefaultListSelectionModel) { @@ -509,7 +510,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole gbc = new GridBagConstraints(); gbc.gridx = 3; gbc.gridy = 0; - gbc.weightx = 0.5; + gbc.weightx = 0.1; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(3, 2, 2, 3); @@ -528,8 +529,34 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole gbc.fill = GridBagConstraints.BOTH; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets = new Insets(2, 3, 3, 4); - sitesPanel.add(pb, gbc); - + sitesPanel.add(pb, gbc); // MolecularTypeSpecsTable + + // The NamedColor combobox cell renderer in the MolecularTypeSpecsTable + DefaultScrollTableCellRenderer namedColorTableCellRenderer = new DefaultScrollTableCellRenderer() { + final Color lightBlueBackground = new Color(214, 234, 248); + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, + int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (table.getModel() instanceof MolecularTypeSpecsTableModel) { + if (value instanceof NamedColor) { + System.out.println("NamedColor table cell"); + NamedColor namedColor = (NamedColor)value; + setText(namedColor.getName()); + Icon icon = new ColorIcon(10,10,namedColor.getColor(), true); // small square icon with subdomain color + setHorizontalTextPosition(SwingConstants.RIGHT); + setIcon(icon); + } + } + return this; + } + }; + + getMolecularTypeSpecsTable().setDefaultRenderer(String.class, new DefaultScrollTableCellRenderer()); + getMolecularTypeSpecsTable().setDefaultRenderer(Structure.class, structuresTableCellRenderer); // The Structures combobox cell renderer + getMolecularTypeSpecsTable().setDefaultRenderer(NamedColor.class, namedColorTableCellRenderer); // NamedColor combobox cell renderer + + gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 5; @@ -578,21 +605,21 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole gbc.insets = new Insets(2, 2, 2, 2); sitesPanel.add(siteZField, gbc); - gbc = new GridBagConstraints(); - gbc.gridx = 6; - gbc.gridy = 5; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(new JLabel(" Color "), gbc); - - gbc = new GridBagConstraints(); - gbc.gridx = 7; - gbc.gridy = 5; - gbc.weightx = 1.0; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(getSiteColorComboBox(), gbc); +// gbc = new GridBagConstraints(); +// gbc.gridx = 6; +// gbc.gridy = 5; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(new JLabel(" Color "), gbc); + +// gbc = new GridBagConstraints(); +// gbc.gridx = 7; +// gbc.gridy = 5; +// gbc.weightx = 1.0; +// gbc.fill = GridBagConstraints.HORIZONTAL; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(getSiteColorComboBox(), gbc); // // --- links ----------------------------------------------- linksPanel.setLayout(new GridBagLayout()); @@ -637,10 +664,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole gbc.insets = new Insets(5, 2, 2, 3); linksPanel.add(deleteLinkButton, gbc); - getMolecularTypeSpecsTable().setDefaultRenderer(String.class, new DefaultScrollTableCellRenderer()); - getMolecularTypeSpecsTable().setDefaultRenderer(Structure.class, structuresTableCellRenderer); // The Structures combobox cell renderer - - initConnections(); // adding listeners } catch(Throwable e) { @@ -681,33 +704,33 @@ private EditorScrollTable getSpeciesContextSpecsTable() { } // siteColorComboBox - private JComboBox getSiteColorComboBox() { - if (siteColorComboBox == null) { - siteColorComboBox = new JComboBox(); - siteColorComboBox.setName("JComboBox1"); - - DefaultComboBoxModel model = new DefaultComboBoxModel<>(); - for(NamedColor namedColor : Colors.COLORARRAY) { - model.addElement(namedColor.getName()); - } - siteColorComboBox.setModel(model); -// siteColorComboBox.setRenderer(new DefaultListCellRenderer() { -// see ReactionRuleKineticsPropertiesPanel.getKineticsTypeComboBox() for complex renderer -// }); - } - return siteColorComboBox; - } - private void updateSiteColor() { - String colorName = (String)getSiteColorComboBox().getSelectedItem(); - if(colorName == null) { - return; - } - NamedColor namedColor = Colors.getColorByName(colorName); - SiteAttributesSpec sas = fieldSpeciesContextSpec.getSiteAttributesMap().get(fieldMolecularComponentPattern); - if(namedColor != null && namedColor != sas.getColor()) { - sas.setColor(namedColor); - } - } +// private JComboBox getSiteColorComboBox() { +// if (siteColorComboBox == null) { +// siteColorComboBox = new JComboBox(); +// siteColorComboBox.setName("JComboBox1"); +// +// DefaultComboBoxModel model = new DefaultComboBoxModel<>(); +// for(NamedColor namedColor : Colors.COLORARRAY) { +// model.addElement(namedColor.getName()); +// } +// siteColorComboBox.setModel(model); +//// siteColorComboBox.setRenderer(new DefaultListCellRenderer() { +//// see ReactionRuleKineticsPropertiesPanel.getKineticsTypeComboBox() for complex renderer +//// }); +// } +// return siteColorComboBox; +// } +// private void updateSiteColor() { +// String colorName = (String)getSiteColorComboBox().getSelectedItem(); +// if(colorName == null) { +// return; +// } +// NamedColor namedColor = Colors.getColorByName(colorName); +// SiteAttributesSpec sas = fieldSpeciesContextSpec.getSiteAttributesMap().get(fieldMolecularComponentPattern); +// if(namedColor != null && namedColor != sas.getColor()) { +// sas.setColor(namedColor); +// } +// } private void handleException(Throwable exception) { System.out.println("--------- UNCAUGHT EXCEPTION --------- in cbit.vcell.mapping.InitialConditionPanel"); @@ -805,7 +828,7 @@ private void updateInterface() { siteXField.setText(sas.getCoordinate().getX()+""); siteYField.setText(sas.getCoordinate().getY()+""); siteZField.setText(sas.getCoordinate().getZ()+""); - getSiteColorComboBox().setSelectedItem(sas.getColor().getName()); +// getSiteColorComboBox().setSelectedItem(sas.getColor().getName()); } else { siteXField.setEditable(false); siteYField.setEditable(false); @@ -813,7 +836,7 @@ private void updateInterface() { siteXField.setText(null); siteYField.setText(null); siteZField.setText(null); - getSiteColorComboBox().setSelectedItem(null); +// getSiteColorComboBox().setSelectedItem(null); } } From 1bc16326fd4fa6a91ba513de0d5aca3202e616c1 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 29 Oct 2024 17:46:17 -0400 Subject: [PATCH 16/28] molecular details: NamedColor combobox, editor, renderer --- .../gui/MolecularTypeSpecsTableModel.java | 6 ++-- .../gui/MolecularStructuresPanel.java | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index ec3bfb1c96..454610545e 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -56,13 +56,13 @@ public class MolecularTypeSpecsTableModel extends VCellSortTableModel [nm]"; + setText(text); + } else { + setText(value + " [nm]"); + } + } else if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_DIFFUSION.ordinal() == column) { + if(!isSelected) { + String darkRed = "#8B0000"; + String text = "" + value + " [um^2/s]"; + setText(text); + } else { + setText(value + " [um^2/s"); + } + } + } + } + return this; + } + }; getMolecularTypeSpecsTable().setDefaultRenderer(String.class, new DefaultScrollTableCellRenderer()); getMolecularTypeSpecsTable().setDefaultRenderer(Structure.class, structuresTableCellRenderer); // The Structures combobox cell renderer + getMolecularTypeSpecsTable().setDefaultRenderer(Expression.class, expressionTableCellRenderer); // Expression field cell renderer getMolecularTypeSpecsTable().setDefaultRenderer(NamedColor.class, namedColorTableCellRenderer); // NamedColor combobox cell renderer From 5d7bf8fa035f57c5f2d665d482756078d6f9ebd5 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 31 Oct 2024 13:17:56 -0400 Subject: [PATCH 17/28] WIP: molecular structure panel, renderer --- .../vcell/mapping/gui/MolecularTypeSpecsTableModel.java | 2 +- .../model/springsalad/gui/MolecularStructuresPanel.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index 454610545e..9ceeb3fa4c 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -60,7 +60,7 @@ public enum ColumnType { COLUMN_SITE("Site"), COLUMN_MOLECULE("Molecule"), COLUMN_STRUCTURE("Location"), - COLUMN_STATE("Initial State"), + COLUMN_STATE("State"), COLUMN_RADIUS("Radius"), COLUMN_DIFFUSION("Diff. Rate"), COLUMN_COLOR("Color"); diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 55140b24af..6756f46f6b 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -554,6 +554,8 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole }; // The Expression cell renderer in the MolecularTypeSpecsTable DefaultScrollTableCellRenderer expressionTableCellRenderer = new DefaultScrollTableCellRenderer() { + final String darkRed = "#8B0000"; + final String brown = "#A52A2A"; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { @@ -564,15 +566,13 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole String columnName = model.getColumnName(column); if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_RADIUS.ordinal() == column) { if(!isSelected) { - String brown = "#A52A2A"; - String text = "" + value + " [nm]"; + String text = "" + value + " [nm]"; setText(text); } else { setText(value + " [nm]"); } } else if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_DIFFUSION.ordinal() == column) { if(!isSelected) { - String darkRed = "#8B0000"; String text = "" + value + " [um^2/s]"; setText(text); } else { From f2356e4551cb592199b5f8abbecff008f8b80bd7 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 31 Oct 2024 15:06:29 -0400 Subject: [PATCH 18/28] WIP: molecular structure panel, renderer --- .../gui/MolecularStructuresPanel.java | 5 +-- .../vcell/util/springsalad/NamedColor.java | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 6756f46f6b..e244ab5095 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -8,6 +8,7 @@ import cbit.vcell.client.desktop.biomodel.IssueManager; import cbit.vcell.client.desktop.biomodel.SelectionManager.ActiveViewID; import cbit.vcell.client.desktop.biomodel.VCellSortTableModel; +import cbit.vcell.graph.GraphConstants; import cbit.vcell.graph.SmallShapeManager; import cbit.vcell.graph.SpeciesPatternSmallShape; import cbit.vcell.mapping.*; @@ -554,8 +555,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole }; // The Expression cell renderer in the MolecularTypeSpecsTable DefaultScrollTableCellRenderer expressionTableCellRenderer = new DefaultScrollTableCellRenderer() { - final String darkRed = "#8B0000"; - final String brown = "#A52A2A"; + String darkRed = NamedColor.getHex(GraphConstants.darkred); // "#8B0000" @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { @@ -563,7 +563,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole if (table.getModel() instanceof MolecularTypeSpecsTableModel) { MolecularTypeSpecsTableModel model = (MolecularTypeSpecsTableModel)table.getModel(); if (value instanceof Double) { - String columnName = model.getColumnName(column); if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_RADIUS.ordinal() == column) { if(!isSelected) { String text = "" + value + " [nm]"; diff --git a/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java b/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java index 5cb2cd1d1c..2a30a296c0 100644 --- a/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java +++ b/vcell-core/src/main/java/org/vcell/util/springsalad/NamedColor.java @@ -10,11 +10,19 @@ package org.vcell.util.springsalad; +import cbit.vcell.graph.GraphConstants; + import java.awt.Color; import java.io.Serializable; +/* + * Springsalad-style colors. + * See also Colors + * For vcell-style colors see GraphConstants + */ @SuppressWarnings("serial") public class NamedColor implements Serializable { + private final Color color; private final String name; @@ -48,4 +56,34 @@ public static Color darker(Color color, double factor) { color.getAlpha()); } + public String getHex() { + Color c = getColor(); + String hex = getHex(c); + return hex; + } + public static String getHex(Color c) { + String hex = String.format("#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue()); + return hex; + } + + public static void main(String[] args) { + + Color red = Color.decode("#FF0000"); + Color red1 = new Color(255, 0, 0, 32); + Color red2 = new Color(255, 0, 0, 127); + Color red3 = new Color(255, 0, 0, 255); // plain red + + // some alpha manipulation + Color darkred = GraphConstants.darkred; // #8b0000 + Color darkred1 = new Color(139, 0, 0, 32); + Color darkred2 = new Color(139, 0, 0, 127); + Color darkred3 = new Color(139, 0, 0, 255); // plain darkred + + Color brown = Color.decode("#A52A2A"); + Color brown1 = new Color(165, 42, 42, 32); + Color brown2 = new Color(165, 42, 42, 127); + Color brown3 = new Color(165, 42, 42, 255); // plain brown + + } + } From 264aaf97f24f70f4a18fb33f2a27b66d6f2e58c9 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 31 Oct 2024 15:13:57 -0400 Subject: [PATCH 19/28] fix test --- .../java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java b/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java index a1f606724a..50a85271e8 100644 --- a/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java +++ b/vcell-core/src/test/java/cbit/vcell/biomodel/SpringSaLaDGoodReactionsTest.java @@ -100,7 +100,7 @@ public void test_springsalad_model_bad() throws IOException, XmlParseException, simContext.gatherIssues(issueContext, issueList, true); // bIgnoreMathDescription == true int numErrors = checkIssuesBySeverity(issueList, Issue.Severity.ERROR); int numWarnings = checkIssuesBySeverity(issueList, Issue.Severity.WARNING); - assertTrue((numErrors == 2 && numWarnings == 8) ? true : false, "expecting 2 errors and 8 warnings for this model"); + assertTrue((numErrors == 2 && numWarnings == 7) ? true : false, "expecting 2 errors and 8 warnings for this model"); /* We should detect the following: @@ -111,7 +111,6 @@ public void test_springsalad_model_bad() throws IOException, XmlParseException, s1: Each Site must have at least one State. s2: Internal Links are possible only when the Molecule has at least 2 sites. s2: The Species and the Molecular Type must share the same name. - MT2: Link chain within the molecule has at least one discontinuity. Sink: SpringSaLaD reserved Molecules 'Source' and 'Sink' must not have any sites defined s5: There must be a biunivocal correspondence between the Species and the associated MolecularType. s6: There must be a biunivocal correspondence between the Species and the associated MolecularType. From 2b5acbe991a6f85e501cf98feeadcd0ddaa64784 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Fri, 1 Nov 2024 14:33:52 -0400 Subject: [PATCH 20/28] taking the units out of the table, they will only show in the cell tooltip instead --- .../gui/MolecularTypeSpecsTableModel.java | 95 ++++++- .../gui/MolecularStructuresPanel.java | 246 ++++++++++-------- 2 files changed, 229 insertions(+), 112 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index 9ceeb3fa4c..211f012783 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -27,6 +27,7 @@ import org.vcell.model.rbm.MolecularType; import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; +import org.vcell.util.Coordinate; import org.vcell.util.gui.ColorIcon; import org.vcell.util.gui.GuiUtils; import org.vcell.util.gui.ScrollTable; @@ -61,6 +62,9 @@ public enum ColumnType { COLUMN_MOLECULE("Molecule"), COLUMN_STRUCTURE("Location"), COLUMN_STATE("State"), + COLUMN_X(" X "), + COLUMN_Y(" Y "), + COLUMN_Z(" Z "), COLUMN_RADIUS("Radius"), COLUMN_DIFFUSION("Diff. Rate"), COLUMN_COLOR("Color"); @@ -92,6 +96,9 @@ public Class getColumnClass(int column) { return Structure.class; case COLUMN_STATE: return ComponentStatePattern.class; + case COLUMN_X: + case COLUMN_Y: + case COLUMN_Z: case COLUMN_RADIUS: case COLUMN_DIFFUSION: return Expression.class; @@ -143,11 +150,26 @@ public Object getValueAt(int row, int col) { } String name = csp.getComponentStateDefinition().getName(); return name; + case COLUMN_X: + if(sas == null) { + return null; + } + return sas.getCoordinate().getX(); // nm + case COLUMN_Y: + if(sas == null) { + return null; + } + return sas.getCoordinate().getY(); // nm + case COLUMN_Z: + if(sas == null) { + return null; + } + return sas.getCoordinate().getZ(); // nm case COLUMN_RADIUS: if(sas == null) { return null; } - return sas.getRadius(); // nm + return sas.getRadius(); // nm case COLUMN_DIFFUSION: if(sas == null) { return null; @@ -189,6 +211,66 @@ public void setValueAt(Object aValue, int row, int col) { } } return; + case COLUMN_X: + if (aValue instanceof String) { + SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); + if(sas == null) { + sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + } + String newExpressionString = (String)aValue; + double res = 0.0; + try { + res = Double.parseDouble(newExpressionString); + } catch(NumberFormatException e) { + return; + } + Coordinate c = sas.getCoordinate(); + if(c.getX() != res) { + c = new Coordinate(res, c.getY(), c.getZ()); + sas.setCoordinate(c); + } + } + return; + case COLUMN_Y: + if (aValue instanceof String) { + SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); + if(sas == null) { + sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + } + String newExpressionString = (String)aValue; + double res = 0.0; + try { + res = Double.parseDouble(newExpressionString); + } catch(NumberFormatException e) { + return; + } + Coordinate c = sas.getCoordinate(); + if(c.getX() != res) { + c = new Coordinate(c.getX(), res, c.getZ()); + sas.setCoordinate(c); + } + } + return; + case COLUMN_Z: + if (aValue instanceof String) { + SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); + if(sas == null) { + sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + } + String newExpressionString = (String)aValue; + double res = 0.0; + try { + res = Double.parseDouble(newExpressionString); + } catch(NumberFormatException e) { + return; + } + Coordinate c = sas.getCoordinate(); + if(c.getX() != res) { + c = new Coordinate(c.getX(), c.getY(), res); + sas.setCoordinate(c); + } + } + return; case COLUMN_RADIUS: if (aValue instanceof String) { String newExpressionString = (String)aValue; @@ -242,6 +324,9 @@ public boolean isCellEditable(int row, int col) { case COLUMN_STATE: return false; case COLUMN_STRUCTURE: + case COLUMN_X: + case COLUMN_Y: + case COLUMN_Z: case COLUMN_RADIUS: case COLUMN_DIFFUSION: case COLUMN_COLOR: @@ -267,6 +352,9 @@ public int compare(MolecularComponentPattern mcp1, MolecularComponentPattern mcp case COLUMN_MOLECULE: case COLUMN_STRUCTURE: case COLUMN_STATE: + case COLUMN_X: + case COLUMN_Y: + case COLUMN_Z: case COLUMN_RADIUS: case COLUMN_DIFFUSION: case COLUMN_COLOR: @@ -496,11 +584,6 @@ protected List computeData() { // return parameterList; } - - - - - @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getSource() instanceof ReactionContext && evt.getPropertyName().equals("speciesContextSpecs")) { diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index e244ab5095..0e52502883 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -70,9 +70,9 @@ public class MolecularStructuresPanel extends DocumentEditorSubPanel implements private MolecularTypeSpecsTableModel molecularTypeSpecsTableModel = null; // private JComboBox siteColorComboBox = null; - private JTextField siteXField = null; - private JTextField siteYField = null; - private JTextField siteZField = null; +// private JTextField siteXField = null; +// private JTextField siteYField = null; +// private JTextField siteZField = null; private JTextField linkLengthField = null; private JButton addLinkButton = null; @@ -120,9 +120,10 @@ private class EventHandler implements FocusListener, ActionListener, PropertyCha public void actionPerformed(ActionEvent e) { Object source = e.getSource(); - if (source == siteXField || source == siteYField || source == siteZField) { - changePosition((JTextField)source); - } else if(source == linkLengthField) { +// if (source == siteXField || source == siteYField || source == siteZField) { +// changePosition((JTextField)source); +// } else + if(source == linkLengthField) { changeLinkLength(); } else if(source == addLinkButton) { addLinkActionPerformed(); @@ -138,10 +139,11 @@ public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { Object source = e.getSource(); - if (source == siteXField || source == siteYField || source == siteZField) { - // TODO: are these even needed? we already call changePosition() on actionPerformed() - changePosition((JTextField)source); - } else if(source == linkLengthField) { +// if (source == siteXField || source == siteYField || source == siteZField) { +// // TODO: are these even needed? we already call changePosition() on actionPerformed() +// changePosition((JTextField)source); +// } else + if(source == linkLengthField) { // TODO: do NOT call here changeLinkLength(), it will modified the newly selected link instead the old one // changeLinkLength(); } @@ -205,13 +207,13 @@ public void setSearchText(String s) { } private void initConnections() throws java.lang.Exception { // listeners here! - siteXField.addFocusListener(eventHandler); - siteYField.addFocusListener(eventHandler); - siteZField.addFocusListener(eventHandler); +// siteXField.addFocusListener(eventHandler); +// siteYField.addFocusListener(eventHandler); +// siteZField.addFocusListener(eventHandler); linkLengthField.addFocusListener(eventHandler); - siteXField.addActionListener(eventHandler); - siteYField.addActionListener(eventHandler); - siteZField.addActionListener(eventHandler); +// siteXField.addActionListener(eventHandler); +// siteYField.addActionListener(eventHandler); +// siteZField.addActionListener(eventHandler); siteLinksList.addListSelectionListener(eventHandler); siteLinksList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); @@ -240,17 +242,17 @@ private void initConnections() throws java.lang.Exception { // listeners here! private void initialize() { try { // labels / button / combos / lists initialization - siteXField = new JTextField(); - siteYField = new JTextField(); - siteZField = new JTextField(); +// siteXField = new JTextField(); +// siteYField = new JTextField(); +// siteZField = new JTextField(); siteLinksList = new JList(siteLinksListModel); siteLinksList.setCellRenderer(siteLinksCellRenderer); linkLengthField = new JTextField(""); addLinkButton = new JButton("Add Link"); deleteLinkButton = new JButton("Delete Link"); - siteXField.setEditable(false); - siteYField.setEditable(false); - siteZField.setEditable(false); +// siteXField.setEditable(false); +// siteYField.setEditable(false); +// siteZField.setEditable(false); linkLengthField.setEditable(false); deleteLinkButton.setEnabled(false); @@ -297,7 +299,7 @@ private void initialize() { gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 1.0; - gbc.weighty = 0.8; + gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(3, 0, 0, 0); // top, left, bottom, right thePanel.add(top, gbc); @@ -307,7 +309,7 @@ private void initialize() { gbc.gridy = 1; gbc.weightx = 1.0; gbc.weighty = 1.0; - gbc.gridheight = 2; +// gbc.gridheight = 2; gbc.insets = new Insets(1, 0, 0, 0); gbc.fill = GridBagConstraints.BOTH; thePanel.add(bottom, gbc); @@ -545,6 +547,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole System.out.println("NamedColor table cell"); NamedColor namedColor = (NamedColor)value; setText(namedColor.getName()); +// setText(""); // we may want to just display the icon and no text Icon icon = new ColorIcon(10,10,namedColor.getColor(), true); // small square icon with subdomain color setHorizontalTextPosition(SwingConstants.RIGHT); setIcon(icon); @@ -563,21 +566,52 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole if (table.getModel() instanceof MolecularTypeSpecsTableModel) { MolecularTypeSpecsTableModel model = (MolecularTypeSpecsTableModel)table.getModel(); if (value instanceof Double) { - if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_RADIUS.ordinal() == column) { - if(!isSelected) { - String text = "" + value + " [nm]"; - setText(text); - } else { - setText(value + " [nm]"); - } - } else if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_DIFFUSION.ordinal() == column) { - if(!isSelected) { - String text = "" + value + " [um^2/s]"; - setText(text); - } else { - setText(value + " [um^2/s"); - } + MolecularTypeSpecsTableModel.ColumnType columnType = MolecularTypeSpecsTableModel.ColumnType.values()[column]; + switch(columnType) { + case COLUMN_X: + case COLUMN_Y: + case COLUMN_Z: + case COLUMN_RADIUS: + setText(value+""); + setToolTipText(value + " [nm]"); + break; +// case COLUMN_RADIUS: // good looking but too busy +// if(!isSelected) { +// String text = "" + value + " [nm]"; +// setText(text); +// } else { +// setText(value + " [nm]"); +// } +// setToolTipText(value + " [nm]"); +// break; + case COLUMN_DIFFUSION: +// if(!isSelected) { +// String text = "" + value + " [um^2/s]"; +// setText(text); +// } else { +// setText(value + " [um^2/s]"); +// } + setText(value + ""); + setToolTipText(value + " [um^2/s]"); + break; + default: + break; } +// if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_RADIUS.ordinal() == column) { +// if(!isSelected) { +// String text = "" + value + " [nm]"; +// setText(text); +// } else { +// setText(value + " [nm]"); +// } +// } else if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_DIFFUSION.ordinal() == column) { +// if(!isSelected) { +// String text = "" + value + " [um^2/s]"; +// setText(text); +// } else { +// setText(value + " [um^2/s"); +// } +// } } } return this; @@ -590,54 +624,54 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole getMolecularTypeSpecsTable().setDefaultRenderer(NamedColor.class, namedColorTableCellRenderer); // NamedColor combobox cell renderer - gbc = new GridBagConstraints(); - gbc.gridx = 0; - gbc.gridy = 5; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(new JLabel(" X (nm) "), gbc); - - gbc = new GridBagConstraints(); - gbc.gridx = 1; - gbc.gridy = 5; - gbc.weightx = 1.0; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(siteXField, gbc); // - - gbc = new GridBagConstraints(); - gbc.gridx = 2; - gbc.gridy = 5; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(new JLabel(" Y (nm) "), gbc); - - gbc = new GridBagConstraints(); - gbc.gridx = 3; - gbc.gridy = 5; - gbc.weightx = 1.0; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(siteYField, gbc); - - gbc = new GridBagConstraints(); - gbc.gridx = 4; - gbc.gridy = 5; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(new JLabel(" Z (nm) "), gbc); - - gbc = new GridBagConstraints(); - gbc.gridx = 5; - gbc.gridy = 5; - gbc.weightx = 1.0; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.anchor = GridBagConstraints.SOUTH; - gbc.insets = new Insets(2, 2, 2, 2); - sitesPanel.add(siteZField, gbc); - +// gbc = new GridBagConstraints(); +// gbc.gridx = 0; +// gbc.gridy = 5; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(new JLabel(" X (nm) "), gbc); +// +// gbc = new GridBagConstraints(); +// gbc.gridx = 1; +// gbc.gridy = 5; +// gbc.weightx = 1.0; +// gbc.fill = GridBagConstraints.HORIZONTAL; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(siteXField, gbc); // +// +// gbc = new GridBagConstraints(); +// gbc.gridx = 2; +// gbc.gridy = 5; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(new JLabel(" Y (nm) "), gbc); +// +// gbc = new GridBagConstraints(); +// gbc.gridx = 3; +// gbc.gridy = 5; +// gbc.weightx = 1.0; +// gbc.fill = GridBagConstraints.HORIZONTAL; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(siteYField, gbc); +// +// gbc = new GridBagConstraints(); +// gbc.gridx = 4; +// gbc.gridy = 5; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(new JLabel(" Z (nm) "), gbc); +// +// gbc = new GridBagConstraints(); +// gbc.gridx = 5; +// gbc.gridy = 5; +// gbc.weightx = 1.0; +// gbc.fill = GridBagConstraints.HORIZONTAL; +// gbc.anchor = GridBagConstraints.SOUTH; +// gbc.insets = new Insets(2, 2, 2, 2); +// sitesPanel.add(siteZField, gbc); +// // gbc = new GridBagConstraints(); // gbc.gridx = 6; // gbc.gridy = 5; @@ -855,20 +889,20 @@ private void updateInterface() { if(bNonNullMolecularComponentPattern) { SiteAttributesSpec sas = fieldSpeciesContextSpec.getSiteAttributesMap().get(fieldMolecularComponentPattern); - siteXField.setEditable(true); - siteYField.setEditable(true); - siteZField.setEditable(true); - siteXField.setText(sas.getCoordinate().getX()+""); - siteYField.setText(sas.getCoordinate().getY()+""); - siteZField.setText(sas.getCoordinate().getZ()+""); +// siteXField.setEditable(true); +// siteYField.setEditable(true); +// siteZField.setEditable(true); +// siteXField.setText(sas.getCoordinate().getX()+""); +// siteYField.setText(sas.getCoordinate().getY()+""); +// siteZField.setText(sas.getCoordinate().getZ()+""); // getSiteColorComboBox().setSelectedItem(sas.getColor().getName()); } else { - siteXField.setEditable(false); - siteYField.setEditable(false); - siteZField.setEditable(false); - siteXField.setText(null); - siteYField.setText(null); - siteZField.setText(null); +// siteXField.setEditable(false); +// siteYField.setEditable(false); +// siteZField.setEditable(false); +// siteXField.setText(null); +// siteYField.setText(null); +// siteZField.setText(null); // getSiteColorComboBox().setSelectedItem(null); } } @@ -910,14 +944,14 @@ private void changePosition(JTextField source) { return; } - if(siteXField == source && c.getX() != res) { - c = new Coordinate(res, c.getY(), c.getZ()); - } else if(siteYField == source && c.getY() != res) { - c = new Coordinate(c.getX(), res, c.getZ()); - } else if(siteZField == source && c.getZ() != res) { - c = new Coordinate(c.getX(), c.getY(), res); - } - sas.setCoordinate(c); +// if(siteXField == source && c.getX() != res) { +// c = new Coordinate(res, c.getY(), c.getZ()); +// } else if(siteYField == source && c.getY() != res) { +// c = new Coordinate(c.getX(), res, c.getZ()); +// } else if(siteZField == source && c.getZ() != res) { +// c = new Coordinate(c.getX(), c.getY(), res); +// } +// sas.setCoordinate(c); recalculateLinkLengths(); } From 1cb32fa3b71421fcf44c0fa7cd900f9f8d640fb3 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Mon, 4 Nov 2024 15:54:59 -0500 Subject: [PATCH 21/28] WIP: refactoring all Specifications subpanels for Springsalad --- .../desktop/biomodel/AnnotationsPanel.java | 2 - .../MolecularStructuresPropertiesPanel.java | 2 - .../gui/MolecularTypeSpecsTableModel.java | 13 +- .../gui/ReactionRuleSpecPropertiesPanel.java | 7 +- .../mapping/gui/SpeciesContextSpecPanel.java | 5 +- .../gui/MolecularStructuresPanel.java | 126 +++++------------- .../cbit/vcell/mapping/ReactionRuleSpec.java | 2 +- .../vcell/mapping/SpeciesContextSpec.java | 34 +++++ 8 files changed, 82 insertions(+), 109 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/AnnotationsPanel.java b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/AnnotationsPanel.java index 445d736582..2e095aba76 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/AnnotationsPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/desktop/biomodel/AnnotationsPanel.java @@ -517,7 +517,6 @@ public JComboBox getJComboBoxURI() { @Override public void actionPerformed(ActionEvent e) { VCMetaDataDataType mdt = (VCMetaDataDataType)jComboBoxURI.getSelectedItem(); - System.out.println("aici"); if(mdt != null && mdt.isSearchable()) { getJButtonSearchRef().setEnabled(true); } else { @@ -939,7 +938,6 @@ protected void onSelectedObjectsChange(Object[] selectedObjects) { } if(selectedObjects[0] instanceof Identifiable && selectedObjects[0] instanceof Displayable) { selectedObject = (Identifiable)selectedObjects[0]; - System.out.println("AnnotationsPanel: class: " + selectedObject.getClass().getSimpleName() + ", selected object: " + ((Displayable)selectedObject).getDisplayName()); } else { selectedObject = null; System.out.println("Unsupported or null entity"); diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index 0c05dc7955..b0b14ca193 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -82,7 +82,6 @@ public void paintComponent(Graphics g) { if (speciesContextSpec == null || speciesContextSpec.getSpeciesContext() == null) { return; } - System.out.println(speciesContextSpec.getSpeciesContext().getName() + ": painting shape"); scsls = new SpeciesContextSpecLargeShape(speciesContextSpec, shapePanel, speciesContextSpec, issueManager); scsls.paintSelf(g); } @@ -201,7 +200,6 @@ private void updateShape() { if(speciesContextSpec == null || speciesContextSpec.getSpeciesContext() == null) { return; } - System.out.println(speciesContextSpec.getSpeciesContext().getName() + ": painting shape"); scsls = new SpeciesContextSpecLargeShape(speciesContextSpec, shapePanel, speciesContextSpec, issueManager); // shapePanel.setPreferredSize(scsls.getMaxSize()); diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index 211f012783..46f87d9d4f 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -53,9 +53,7 @@ @SuppressWarnings("serial") public class MolecularTypeSpecsTableModel extends VCellSortTableModel implements java.beans.PropertyChangeListener { - // TODO: sas is null for molecules added late (after the application is created) - // TODO: add is2D flag here as a checkbox (var is SpeciesContextSpec) - membrane species may have it set to true, for compartment species is always false - // TODO: math is wrong for a model with a membrane species, saving model fails, see model aaa-SS-membrane, see issue #1097 + // TODO: the is2D flag here (a checkbox, var is SpeciesContextSpec) - membrane species may have it set to true, for compartment species is always false public enum ColumnType { COLUMN_SITE("Site"), @@ -212,6 +210,9 @@ public void setValueAt(Object aValue, int row, int col) { } return; case COLUMN_X: + if(getSpeciesContextSpec() == null) { + return; + } if (aValue instanceof String) { SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { @@ -232,6 +233,9 @@ public void setValueAt(Object aValue, int row, int col) { } return; case COLUMN_Y: + if(getSpeciesContextSpec() == null) { + return; + } if (aValue instanceof String) { SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { @@ -253,6 +257,9 @@ public void setValueAt(Object aValue, int row, int col) { return; case COLUMN_Z: if (aValue instanceof String) { + if(getSpeciesContextSpec() == null) { + return; + } SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java index d358ce2e8a..6cd49ad9a1 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java @@ -135,8 +135,8 @@ public void mouseMoved(MouseEvent e) { shapePanel.setEditable(false); // colored with a shade of brown, close to DefaultScrollTableCellRenderer.uneditableForeground shapePanel.setViewSingleRow(true); shapePanel.setShowMoleculeColor(false); - shapePanel.setShowNonTrivialOnly(false); -// shapePanel.setShowDifferencesOnly(true); + shapePanel.setShowNonTrivialOnly(true); + shapePanel.setShowDifferencesOnly(true); // ---------------------------------------------------------------------------------- JPanel upperPanel = new JPanel(); @@ -239,7 +239,7 @@ public void mouseMoved(MouseEvent e) { splitPaneHorizontal.setTopComponent(upperPanel); splitPaneHorizontal.setBottomComponent(containerOfScrollPanel); splitPaneHorizontal.setOneTouchExpandable(true); - splitPaneHorizontal.setDividerLocation(125); + splitPaneHorizontal.setDividerLocation(110); splitPaneHorizontal.setResizeWeight(1); setLayout(new BorderLayout()); @@ -305,6 +305,7 @@ public void setReactionRule(ReactionRuleSpec rrSpec) { ReactionRule rr = rrSpec.getReactionRule(); this.reactionRule = rr; } + shapePanel.setReactionRule(reactionRule); getReactionRulePropertiesTableModel().setReactionRule(reactionRule); updateInterface(); } diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java index 39e6d2bd49..fa4f7d15df 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/SpeciesContextSpecPanel.java @@ -28,6 +28,7 @@ import javax.swing.JScrollPane; import javax.swing.JSplitPane; +import cbit.vcell.mapping.SimulationContext; import org.vcell.model.rbm.MolecularComponentPattern; import org.vcell.model.rbm.MolecularTypePattern; import org.vcell.model.rbm.SpeciesPattern; @@ -243,7 +244,7 @@ public void mouseMoved(MouseEvent e) { splitPaneHorizontal.setTopComponent(upperPanel); splitPaneHorizontal.setBottomComponent(containerOfScrollPanel); splitPaneHorizontal.setOneTouchExpandable(true); - splitPaneHorizontal.setDividerLocation(165); // upper panel is 165 pixel height + splitPaneHorizontal.setDividerLocation(115); // upper panel is 115 pixel height splitPaneHorizontal.setResizeWeight(1); setLayout(new BorderLayout()); @@ -299,7 +300,7 @@ public void setBioModel(BioModel newValue) { } Model model = bioModel.getModel(); if(model != null & model.getRbmModelContainer().getMolecularTypeList().size() > 0) { - splitPaneHorizontal.setDividerLocation(165); + splitPaneHorizontal.setDividerLocation(115); } else { // since we have no molecular types we initialize a much smaller shape panel // because we can only show a trivial shape (circle) diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 0e52502883..0243add71d 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -168,7 +168,7 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { return; } if (e.getSource() == getSpeciesContextSpecsTable().getSelectionModel()) { - System.out.println("valueChanged: speciesContextSpecsTableModel"); +// System.out.println("valueChanged: speciesContextSpecsTableModel"); int row = getSpeciesContextSpecsTable().getSelectedRow(); SpeciesContextSpec scsSelected = speciesContextSpecsTableModel.getValueAt(row); setSpeciesContextSpec(scsSelected); @@ -178,13 +178,13 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { selectionManager.setSelectedObjects(selectedObjects.toArray()); } else if (e.getSource() == getMolecularTypeSpecsTable().getSelectionModel()) { - System.out.println("valueChanged: molecularTypeSpecsTableModel"); +// System.out.println("valueChanged: molecularTypeSpecsTableModel"); int row = getMolecularTypeSpecsTable().getSelectedRow(); MolecularComponentPattern mcmSelected = molecularTypeSpecsTableModel.getValueAt(row); setMolecularComponentPattern(mcmSelected); } else if(e.getSource() == siteLinksList) { - System.out.println("valueChanged: siteLinksList"); +// System.out.println("valueChanged: siteLinksList"); showLinkLength(siteLinksList.getSelectedValue()); } // for siteXField, siteYField, siteZField we have actionPerformed() @@ -293,13 +293,15 @@ private void initialize() { top.setBorder(titleTop); sitesPanel.setBorder(titleSites); linksPanel.setBorder(titleLinks); + + top.setMinimumSize(new Dimension(0, 100)); thePanel.setLayout(new GridBagLayout()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 1.0; - gbc.weighty = 1.0; + gbc.weighty = 0.4; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(3, 0, 0, 0); // top, left, bottom, right thePanel.add(top, gbc); @@ -308,10 +310,10 @@ private void initialize() { gbc.gridx = 0; gbc.gridy = 1; gbc.weightx = 1.0; - gbc.weighty = 1.0; + gbc.weighty = 0.6; // gbc.gridheight = 2; - gbc.insets = new Insets(1, 0, 0, 0); gbc.fill = GridBagConstraints.BOTH; + gbc.insets = new Insets(1, 0, 0, 0); thePanel.add(bottom, gbc); // we may want to use a scroll pane whose viewing area is the JTable to provide similar look with NetGen Console @@ -412,61 +414,6 @@ public void paintComponent(Graphics g) { } }; - // renderer for the rules column (reaction rules / assignment rules) - // TODO: rules not compatible with springsalad, must create issue if present - DefaultScrollTableCellRenderer rulesTableCellRenderer = new DefaultScrollTableCellRenderer() { - final Color lightBlueBackground = new Color(214, 234, 248); - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, - int row, int column) { - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - - if (table.getModel() instanceof SpeciesContextSpecsTableModel) { - Icon icon = VCellIcons.issueGoodIcon; - Object selectedObject = null; - if (table.getModel() == speciesContextSpecsTableModel) { - selectedObject = speciesContextSpecsTableModel.getValueAt(row); - } - if (selectedObject != null) { - if(isSelected) { - setBackground(lightBlueBackground); - } - if(selectedObject instanceof SpeciesContextSpec) { - SpeciesContextSpec scs = (SpeciesContextSpec)selectedObject; - SpeciesContext sc = scs.getSpeciesContext(); - - boolean foundRuleMatch = false; - if(fieldSimulationContext.getRateRules() != null && fieldSimulationContext.getRateRules().length > 0) { - for(RateRule rr : fieldSimulationContext.getRateRules()) { - if(rr.getRateRuleVar() == null) { - continue; - } - if(sc.getName().equals(rr.getRateRuleVar().getName())) { - foundRuleMatch = true; - icon = VCellIcons.ruleRateIcon; - break; - } - } - } - if(!foundRuleMatch && fieldSimulationContext.getAssignmentRules() != null && fieldSimulationContext.getAssignmentRules().length > 0) { - for(AssignmentRule rr : fieldSimulationContext.getAssignmentRules()) { - if(rr.getAssignmentRuleVar() == null) { - continue; - } - if(sc.getName().equals(rr.getAssignmentRuleVar().getName())) { - icon = VCellIcons.ruleAssignIcon; - break; - } - } - } - } - } - setIcon(icon); - } - return this; - } - }; - // The Structures combobox cell renderer in the MolecularTypeSpecsTable DefaultScrollTableCellRenderer structuresTableCellRenderer = new DefaultScrollTableCellRenderer() { final Color lightBlueBackground = new Color(214, 234, 248); @@ -496,7 +443,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole getSpeciesContextSpecsTable().setDefaultRenderer(Species.class, renderer); getSpeciesContextSpecsTable().setDefaultRenderer(ScopedExpression.class, renderer); getSpeciesContextSpecsTable().setDefaultRenderer(Boolean.class, new ScrollTableBooleanCellRenderer()); - getSpeciesContextSpecsTable().setDefaultRenderer(SpeciesContextSpecsTableModel.RulesProvenance.class, rulesTableCellRenderer); // icons for assignment and rate rules // --------------------------------------------------------------------------------------------- @@ -544,7 +490,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (table.getModel() instanceof MolecularTypeSpecsTableModel) { if (value instanceof NamedColor) { - System.out.println("NamedColor table cell"); NamedColor namedColor = (NamedColor)value; setText(namedColor.getName()); // setText(""); // we may want to just display the icon and no text @@ -567,51 +512,40 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole MolecularTypeSpecsTableModel model = (MolecularTypeSpecsTableModel)table.getModel(); if (value instanceof Double) { MolecularTypeSpecsTableModel.ColumnType columnType = MolecularTypeSpecsTableModel.ColumnType.values()[column]; + int cellWidth = table.getColumnModel().getColumn(column).getWidth(); switch(columnType) { case COLUMN_X: case COLUMN_Y: case COLUMN_Z: case COLUMN_RADIUS: - setText(value+""); + if(cellWidth > 70) { + if(!isSelected) { + String text = "" + value + " [nm]"; + setText(text); + } else { + setText(value + " [nm]"); + } + } else { + setText(value + ""); + } setToolTipText(value + " [nm]"); break; -// case COLUMN_RADIUS: // good looking but too busy -// if(!isSelected) { -// String text = "" + value + " [nm]"; -// setText(text); -// } else { -// setText(value + " [nm]"); -// } -// setToolTipText(value + " [nm]"); -// break; case COLUMN_DIFFUSION: -// if(!isSelected) { -// String text = "" + value + " [um^2/s]"; -// setText(text); -// } else { -// setText(value + " [um^2/s]"); -// } - setText(value + ""); - setToolTipText(value + " [um^2/s]"); + if(cellWidth > 70) { + if(!isSelected) { + String text = "" + value + " [μm^2/s]"; + setText(text); + } else { + setText(value + " [μm^2/s]"); // μ is html for greek mu + } + } else { + setText(value + ""); + } + setToolTipText(value + " [\u03BCm^2/s]"); // "\u03BC" is unicode for greek mu break; default: break; } -// if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_RADIUS.ordinal() == column) { -// if(!isSelected) { -// String text = "" + value + " [nm]"; -// setText(text); -// } else { -// setText(value + " [nm]"); -// } -// } else if(MolecularTypeSpecsTableModel.ColumnType.COLUMN_DIFFUSION.ordinal() == column) { -// if(!isSelected) { -// String text = "" + value + " [um^2/s]"; -// setText(text); -// } else { -// setText(value + " [um^2/s"); -// } -// } } } return this; diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java index 242439df4f..ef88d012c2 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/ReactionRuleSpec.java @@ -669,7 +669,7 @@ private boolean isBindingReaction(Map analysisResults) { for(MolecularComponentPattern mcp : mtp.getComponentPatternList()) { BondType bt = mcp.getBondType(); ComponentStatePattern csp = mcp.getComponentStatePattern(); - if(!csp.isAny() && BondType.Possible == bt) { + if(csp == null || (!csp.isAny() && BondType.Possible == bt)) { // all the sites not binding must be in Any state return false; } diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java index 440cdb1400..47877c426c 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java @@ -1455,6 +1455,37 @@ public void gatherIssues(IssueContext issueContext, List issueVector){ issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); return; } + + // rate rules and assignment rules are not permitted + // normally it is not possible to create RateRule or AssignmentRule using the vcell UI, the Protocols subpanels are disabled + // we check this just in case the user is very crafty and finds a way + boolean foundRuleMatch = false; + if(simulationContext.getRateRules() != null && simulationContext.getRateRules().length > 0) { + for(RateRule rr : simulationContext.getRateRules()) { + if(rr.getRateRuleVar() == null) { + continue; + } + if(sc.getName().equals(rr.getRateRuleVar().getName())) { + String msg = "SpringSaLaD applications do not accept Rate Rules."; + String tip = msg; + issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); + return; + } + } + } + if(!foundRuleMatch && simulationContext.getAssignmentRules() != null && simulationContext.getAssignmentRules().length > 0) { + for(AssignmentRule rr : simulationContext.getAssignmentRules()) { + if(rr.getAssignmentRuleVar() == null) { + continue; + } + if(sc.getName().equals(rr.getAssignmentRuleVar().getName())) { + String msg = "SpringSaLaD applications do not accept Assignment Rules."; + String tip = msg; + issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); + return; + } + } + } } else { String msg = "SpringSaLaD requires all Species to be associated with a MolecularType."; String tip = "Associate a MolecularType to the Species in Physiology / Species panel."; @@ -2336,6 +2367,9 @@ public boolean hasTransport(){ public List computeApplicableParameterList(){ List speciesContextSpecParameterList = new ArrayList(); speciesContextSpecParameterList.add(getInitialConditionParameter()); + if(getSimulationContext().getApplicationType() == Application.SPRINGSALAD) { + return speciesContextSpecParameterList; + } int dimension = simulationContext.getGeometry().getDimension(); if(!isConstant() && !isWellMixed() && dimension > 0){ // diffusion From f6325e669d0d8e62a45e52fd8f5cb966f4cf23cb Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 5 Nov 2024 15:57:48 -0500 Subject: [PATCH 22/28] WIP: refactoring Springsalad panels, navigation, issues --- .../gui/MolecularTypeSpecsTableModel.java | 2 +- .../gui/ReactionRuleSpecPropertiesPanel.java | 2 +- .../gui/MolecularStructuresPanel.java | 23 ++++---- .../graph/SpeciesContextSpecLargeShape.java | 21 ++++++- .../vcell/mapping/SpeciesContextSpec.java | 58 ++++++++++++++++--- 5 files changed, 83 insertions(+), 23 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index 46f87d9d4f..087f50ab21 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -420,8 +420,8 @@ public void setSpeciesContextSpec(SpeciesContextSpec speciesContextSpec) { } if (speciesContextSpec != null) { speciesContextSpec.addPropertyChangeListener(this); - refreshData(); } + refreshData(); } private SpeciesContextSpec getSpeciesContextSpec() { return fieldSpeciesContextSpec; diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java index 6cd49ad9a1..9bee8b1fa4 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/ReactionRuleSpecPropertiesPanel.java @@ -131,7 +131,7 @@ public void mouseMoved(MouseEvent e) { } }); shapePanel.setBackground(new Color(0xe0e0e0)); - shapePanel.setZoomFactor(-2); + shapePanel.setZoomFactor(-3); shapePanel.setEditable(false); // colored with a shade of brown, close to DefaultScrollTableCellRenderer.uneditableForeground shapePanel.setViewSingleRow(true); shapePanel.setShowMoleculeColor(false); diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 0243add71d..84ba361fd2 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -136,6 +136,7 @@ public void actionPerformed(ActionEvent e) { } } public void focusGained(FocusEvent e) { + ; } public void focusLost(FocusEvent e) { Object source = e.getSource(); @@ -518,17 +519,17 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole case COLUMN_Y: case COLUMN_Z: case COLUMN_RADIUS: - if(cellWidth > 70) { - if(!isSelected) { - String text = "" + value + " [nm]"; - setText(text); - } else { - setText(value + " [nm]"); - } + if(cellWidth > 70) { // we show units only if there's enough space + if(!isSelected) { + String text = "" + value + " [nm]"; + setText(text); + } else { + setText(value + " [nm]"); + } } else { - setText(value + ""); + setText(value + ""); // if it's too busy, just show the numbers } - setToolTipText(value + " [nm]"); + setToolTipText(value + " [nm]"); // we always show the units in the tooltip break; case COLUMN_DIFFUSION: if(cellWidth > 70) { @@ -536,7 +537,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole String text = "" + value + " [μm^2/s]"; setText(text); } else { - setText(value + " [μm^2/s]"); // μ is html for greek mu + setText(value + " [\u03BCm^2/s]"); // μ is html for greek mu } } else { setText(value + ""); @@ -860,7 +861,7 @@ protected void onSelectedObjectsChange(Object[] selectedObjects) { * before the newly selected SpeciesContextStep becomes current */ private void changeSpeciesContextSpec() { - + ; } private void changePosition(JTextField source) { diff --git a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java index f2460cf660..205e312b7a 100644 --- a/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java +++ b/vcell-core/src/main/java/cbit/vcell/graph/SpeciesContextSpecLargeShape.java @@ -135,7 +135,26 @@ public SpeciesContextSpecLargeShape(SpeciesContextSpec scs, LargeShapeCanvas sha } private boolean isPlanarYZ() { // we only show entities that are 2D in the YZ plane - return true; // TODO: check + Map sasMap = scs.getSiteAttributesMap(); + // here we could either iterate through the sasMap, or through the components of the mtp + // we use the second method because it provides a sanity check between the components in the sasMap (application level) + // and the physiology (which is authoritative) + double oldX = 0; // dummy value to indulge the compiler + for(int i=0; i< mtp.getComponentPatternList().size(); i++) { + MolecularComponentPattern mcp = mtp.getComponentPatternList().get(i); + SiteAttributesSpec sas = sasMap.get(mcp); + Structure structure = sas.getLocation(); + Coordinate coordinate = sas.getCoordinate(); + // to be planar in YZ, the X coordinates of all sites must be equal + double x = coordinate.getX(); // here x means x + if(i==0) { + oldX = x; // first pass + } + if(oldX != x) { + return false; + } + } + return true; } public Dimension getMaxSize() { diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java index 47877c426c..fc583b2c95 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java @@ -1319,13 +1319,6 @@ public void gatherIssues(IssueContext issueContext, List issueVector){ return; } } -// old way, imprecise! use graph above -// if(mcpList.size() > 1 && mcpList.size() > getInternalLinkSet().size() + 1){ -// String msg = "Link chain within the molecule has at least one discontinuity."; -// String tip = "One or more links are missing"; -// issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); -// return; -// } for(MolecularInternalLinkSpec candidate : getInternalLinkSet()){ for(MolecularInternalLinkSpec other : getInternalLinkSet()){ if(candidate == other){ @@ -1386,14 +1379,28 @@ public void gatherIssues(IssueContext issueContext, List issueVector){ } } else { // all the other sites of a membrane species must not be on the membrane SiteAttributesSpec sas = getSiteAttributesMap().get(mcp); - if(sas.getLocation() instanceof Membrane){ + if(sas.getLocation() instanceof Membrane) { String msg = "All the Sites of a Membrane species, other than the 'Anchor', must NOT be located on a Membrane."; - String tip = msg; + String tip = "Relocate the site '" + mc.getName() + "' inside a compartment, or rename it to 'Anchor'"; issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); return; } } } + // make sure that only one site is on the membrane + int numSitesOnMembrane = 0; + for(MolecularComponentPattern mcp : mcpList) { + SiteAttributesSpec sas = getSiteAttributesMap().get(mcp); + if(sas.getLocation() instanceof Membrane) { + numSitesOnMembrane++; + } + if(numSitesOnMembrane > 1) { + String msg = "Species localized on a membrane must have only one site on the membrane"; + String tip = msg; + issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); + return; + } + } if(anchorExists == false){ String msg = "Species localized on a membrane require a reserved site named 'Anchor'"; String tip = msg; @@ -1416,6 +1423,39 @@ public void gatherIssues(IssueContext issueContext, List issueVector){ return; } } + if(anchorExists == true) { + // sites at the "left" of the anchor (site z < anchor z) must be located in 'Extracellular' + // sites at the 'right' of the anchor (site z > anchor z) must be located in 'Intracellular' + boolean foundSomething = false; + SiteAttributesSpec sasAnchor = getSiteAttributesMap().get(mcpAnchor); + double zAnchor = sasAnchor.getCoordinate().getZ(); + for(MolecularComponentPattern mcp : mcpList) { + MolecularComponent mc = mcp.getMolecularComponent(); + SiteAttributesSpec sasCandidate = getSiteAttributesMap().get(mcp); + if(sasCandidate.getLocation() instanceof Membrane) { + continue; // we skip self + } + double zCandidate = sasCandidate.getCoordinate().getZ(); + if(sasCandidate.getLocation().getName().equals(Structure.SpringStructureEnum.Extracellular.columnName)) { + if(!(zCandidate < zAnchor)) { + String msg = "Sites located in the 'Extracellular' structure must have their z-coordinate smaller that the one of the 'Anchor' site"; + String tip = "Relocate the site '" + mc.getName() + "' inside 'Intracellular', or decrease its 'z' coordinate to less than " + zAnchor; + issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); + foundSomething = true; + } + } else if(sasCandidate.getLocation().getName().equals(Structure.SpringStructureEnum.Intracellular.columnName)){ + if(!(zCandidate > zAnchor)) { + String msg = "Sites located in the 'Intracellular' structure must have their z-coordinate larger that the one of the 'Anchor' site"; + String tip = "Relocate the site '" + mc.getName() + "' inside 'Extracellular', or increase its 'z' coordinate to more than " + zAnchor; + issueVector.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING)); + foundSomething = true; + } + } + } + if(foundSomething == true) { + return; // we show more than the 1st in this category, otherwise it'll be confusing + } + } } else { // a species inside a Feature must NOT have a site named Anchor for(MolecularComponentPattern mcp : mcpList){ MolecularComponent mc = mcp.getMolecularComponent(); From b2fe0a96108fcca78c7038e27839315a2885bb35 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Thu, 7 Nov 2024 14:20:44 -0500 Subject: [PATCH 23/28] WIP: table for MolecularInternalLinkSpec display, rendering for superscript 2 --- .../mapping/gui/LinkSpecsTableModel.java | 270 ++++++++++++++++++ .../gui/MolecularStructuresPanel.java | 8 +- 2 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java new file mode 100644 index 0000000000..578ac05332 --- /dev/null +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java @@ -0,0 +1,270 @@ +package cbit.vcell.mapping.gui; + +import cbit.vcell.client.desktop.biomodel.VCellSortTableModel; +import cbit.vcell.mapping.*; +import cbit.vcell.model.Parameter; +import cbit.vcell.model.SpeciesContext; +import cbit.vcell.model.Structure; +import cbit.vcell.parser.Expression; +import org.vcell.model.rbm.*; +import org.vcell.util.gui.GuiUtils; +import org.vcell.util.gui.ScrollTable; +import org.vcell.util.springsalad.NamedColor; + +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public class LinkSpecsTableModel extends VCellSortTableModel implements java.beans.PropertyChangeListener { + + public enum ColumnType { + COLUMN_LINK("Link"), + COLUMN_LENGTH("Length"); + + public final String label; + private ColumnType(String label){ + this.label = label; + } + } + + ArrayList columns = new ArrayList<>(); + private SimulationContext fieldSimulationContext = null; + private SpeciesContextSpec fieldSpeciesContextSpec = null; + + public LinkSpecsTableModel(ScrollTable table) { + super(table); + refreshColumns(); + } + + + + + + + @Override + public Class getColumnClass(int column) { + ColumnType columnType = columns.get(column); + switch (columnType) { + case COLUMN_LINK: + return MolecularInternalLinkSpec.class; + case COLUMN_LENGTH: + return Expression.class; + default: + return Object.class; + } + } + @Override + public String getColumnName(int columnIndex){ + return columns.get(columnIndex).label; + } + @Override + public int getColumnCount() { + return columns.size(); + } + + @Override + public Object getValueAt(int row, int col) { + try { + if (getSpeciesContextSpec() == null) { + return null; + } + + ColumnType columnType = columns.get(col); + switch (columnType) { + case COLUMN_LINK: + + return null; + case COLUMN_LENGTH: + + return null; + default: + return null; + } + + } catch(Exception e) { + return null; + } + } + @Override + public void setValueAt(Object aValue, int row, int col) { + MolecularInternalLinkSpec mils = getValueAt(row); + ColumnType columnType = columns.get(col); + switch (columnType) { + case COLUMN_LINK: + + return; + case COLUMN_LENGTH: + + return; + default: + return; + } + } + @Override + public boolean isCellEditable(int row, int col) { + ColumnType columnType = columns.get(col); + switch (columnType) { + case COLUMN_LINK: + case COLUMN_LENGTH: + return false; + default: + return false; + } + } + + @Override + protected Comparator getComparator(int col, boolean ascending) { + return new Comparator() { + /** + * Compares its two arguments for order. Returns a negative integer, + * zero, or a positive integer as the first argument is less than, equal + * to, or greater than the second.

+ */ + public int compare(MolecularInternalLinkSpec mils1, MolecularInternalLinkSpec mils2) { + + ColumnType columnType = columns.get(col); + switch (columnType) { + case COLUMN_LINK: + case COLUMN_LENGTH: + default: + return 1; + } + } + }; + } + + + + + public void setSimulationContext(SimulationContext simulationContext) { + SimulationContext oldValue = fieldSimulationContext; + int oldColumnCount = getColumnCount(); + if (oldValue != null) { + oldValue.removePropertyChangeListener(this); + oldValue.getGeometryContext().removePropertyChangeListener(this); + updateListenersReactionContext(oldValue.getReactionContext(),true); + } + fieldSimulationContext = simulationContext; + refreshColumns(); + int newColumnCount = getColumnCount(); + if (oldColumnCount != newColumnCount) { + fireTableStructureChanged(); + } + if (simulationContext != null) { + simulationContext.addPropertyChangeListener(this); + simulationContext.getGeometryContext().addPropertyChangeListener(this); + updateListenersReactionContext(simulationContext.getReactionContext(),false); + +// autoCompleteSymbolFilter = simulationContext.getAutoCompleteSymbolFilter(); + refreshData(); + } + } + private SimulationContext getSimulationContext() { + return fieldSimulationContext; + } + + public void setSpeciesContextSpec(SpeciesContextSpec speciesContextSpec) { + SpeciesContextSpec oldValue = fieldSpeciesContextSpec; + int oldColumnCount = getColumnCount(); + if (oldValue != null) { + oldValue.removePropertyChangeListener(this); + } + fieldSpeciesContextSpec = speciesContextSpec; + refreshColumns(); + int newColumnCount = getColumnCount(); + if (oldColumnCount != newColumnCount) { + fireTableStructureChanged(); + } + if (speciesContextSpec != null) { + speciesContextSpec.addPropertyChangeListener(this); + } + refreshData(); + } + private SpeciesContextSpec getSpeciesContextSpec() { + return fieldSpeciesContextSpec; + } + + private void updateListenersReactionContext(ReactionContext reactionContext,boolean bRemove) { + + if(bRemove) { + reactionContext.removePropertyChangeListener(this); + SpeciesContextSpec oldSpecs[] = reactionContext.getSpeciesContextSpecs(); + for (int i=0;i molecularInternalLinkSpecList = computeData(); + setData(molecularInternalLinkSpecList); + GuiUtils.flexResizeTableColumns(ownerTable); + } + protected List computeData() { + ArrayList allParameterList = new ArrayList(); +// if(fieldSpeciesContextSpec != null && fieldSpeciesContextSpec.getSpeciesContext() != null) { +// SpeciesPattern sp = fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern(); +// if(sp == null) { +// return null; +// } +// MolecularTypePattern mtp = sp.getMolecularTypePatterns().get(0); +// MolecularType mt = mtp.getMolecularType(); +// List componentList = mt.getComponentList(); +// for(MolecularComponent mc : componentList) { +// MolecularComponentPattern mcp = mtp.getMolecularComponentPattern(mc); +// allParameterList.add(mcp); +// } +// } else { +// return null; +// } + return allParameterList; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getSource() instanceof ReactionContext && evt.getPropertyName().equals("speciesContextSpecs")) { + refreshData(); + } + if (evt.getSource() instanceof SpeciesContext && evt.getPropertyName().equals("name")) { + fireTableRowsUpdated(0,getRowCount()-1); + } + + if (evt.getSource() instanceof SpeciesContextSpec) { + fireTableRowsUpdated(0,getRowCount()-1); + } + if (evt.getSource() instanceof SpeciesContextSpec.SpeciesContextSpecParameter) { // prolly not needed + fireTableRowsUpdated(0,getRowCount()-1); + } + if (evt.getSource() instanceof GeometryContext) { + refreshColumns(); + fireTableStructureChanged(); + } + + } + + +} diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 84ba361fd2..ad47d11bc3 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -533,16 +533,16 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole break; case COLUMN_DIFFUSION: if(cellWidth > 70) { - if(!isSelected) { - String text = "" + value + " [μm^2/s]"; + if(!isSelected) { // 2 is html for superscript 2 (x^2 for example) + String text = "" + value + " [μm2/s]"; setText(text); } else { - setText(value + " [\u03BCm^2/s]"); // μ is html for greek mu + setText(value + " [\u03BCm\u00B2/s]"); // \u03BC is unicode for greek mu, \u00B2 is unicode for superscript 2 } } else { setText(value + ""); } - setToolTipText(value + " [\u03BCm^2/s]"); // "\u03BC" is unicode for greek mu + setToolTipText(value + " [\u03BCm\u00B2/s]"); break; default: break; From 3487e5744abc3af0f3c50130613baf45cf1dfa4e Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 12 Nov 2024 12:36:56 -0500 Subject: [PATCH 24/28] WIP: table for MolecularInternalLinkSpec display --- .../mapping/gui/LinkSpecsTableModel.java | 47 +++--- .../gui/MolecularStructuresPanel.java | 141 ++++++++++++------ 2 files changed, 116 insertions(+), 72 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java index 578ac05332..899999fbb1 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java @@ -12,10 +12,7 @@ import org.vcell.util.springsalad.NamedColor; import java.beans.PropertyChangeEvent; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; +import java.util.*; public class LinkSpecsTableModel extends VCellSortTableModel implements java.beans.PropertyChangeListener { @@ -70,19 +67,23 @@ public Object getValueAt(int row, int col) { if (getSpeciesContextSpec() == null) { return null; } - + Set ilSet = getSpeciesContextSpec().getInternalLinkSet(); + MolecularInternalLinkSpec mils = getValueAt(row); ColumnType columnType = columns.get(col); switch (columnType) { case COLUMN_LINK: - - return null; + if(mils == null) { + return null; + } + return mils; case COLUMN_LENGTH: - - return null; + if(mils == null) { + return null; + } + return mils.getLinkLength(); default: return null; } - } catch(Exception e) { return null; } @@ -226,21 +227,17 @@ private void refreshData() { // called in setSimulationContext() } protected List computeData() { ArrayList allParameterList = new ArrayList(); -// if(fieldSpeciesContextSpec != null && fieldSpeciesContextSpec.getSpeciesContext() != null) { -// SpeciesPattern sp = fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern(); -// if(sp == null) { -// return null; -// } -// MolecularTypePattern mtp = sp.getMolecularTypePatterns().get(0); -// MolecularType mt = mtp.getMolecularType(); -// List componentList = mt.getComponentList(); -// for(MolecularComponent mc : componentList) { -// MolecularComponentPattern mcp = mtp.getMolecularComponentPattern(mc); -// allParameterList.add(mcp); -// } -// } else { -// return null; -// } + if(fieldSpeciesContextSpec != null && fieldSpeciesContextSpec.getSpeciesContext() != null) { + Set ilSet = fieldSpeciesContextSpec.getInternalLinkSet(); + if (ilSet == null || ilSet.isEmpty()) { + return null; + } + for (MolecularInternalLinkSpec mils : ilSet) { + allParameterList.add(mils); + } + } else { + return null; + } return allParameterList; } diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index ad47d11bc3..e84748cff2 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -13,6 +13,7 @@ import cbit.vcell.graph.SpeciesPatternSmallShape; import cbit.vcell.mapping.*; import cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter; +import cbit.vcell.mapping.gui.LinkSpecsTableModel; import cbit.vcell.mapping.gui.MolecularTypeSpecsTableModel; import cbit.vcell.mapping.gui.SpeciesContextSpecsTableModel; import cbit.vcell.mapping.gui.StructureMappingTableRenderer.TextIcon; @@ -61,13 +62,18 @@ public class MolecularStructuresPanel extends DocumentEditorSubPanel implements private SimulationContext fieldSimulationContext; private SpeciesContextSpec fieldSpeciesContextSpec; private MolecularComponentPattern fieldMolecularComponentPattern; - + private MolecularInternalLinkSpec fieldMolecularInternalLinkSpec; + private EditorScrollTable speciesContextSpecsTable = null; private SpeciesContextSpecsTableModel speciesContextSpecsTableModel = null; private SmallShapeManager shapeManager = new SmallShapeManager(false, false, false, false); private EditorScrollTable molecularTypeSpecsTable = null; private MolecularTypeSpecsTableModel molecularTypeSpecsTableModel = null; + + private EditorScrollTable linkSpecsTable = null; + private LinkSpecsTableModel linkSpecsTableModel = null; + // private JComboBox siteColorComboBox = null; // private JTextField siteXField = null; @@ -127,7 +133,7 @@ public void actionPerformed(ActionEvent e) { changeLinkLength(); } else if(source == addLinkButton) { addLinkActionPerformed(); - refreshSiteLinksList(); + refreshSiteLinksList(); // TODO: table stuff instead of this } else if(source == deleteLinkButton) { deleteLinkActionPerformed(); refreshSiteLinksList(); @@ -169,7 +175,7 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { return; } if (e.getSource() == getSpeciesContextSpecsTable().getSelectionModel()) { -// System.out.println("valueChanged: speciesContextSpecsTableModel"); + System.out.println("valueChanged: speciesContextSpecsTableModel"); int row = getSpeciesContextSpecsTable().getSelectedRow(); SpeciesContextSpec scsSelected = speciesContextSpecsTableModel.getValueAt(row); setSpeciesContextSpec(scsSelected); @@ -179,14 +185,20 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { selectionManager.setSelectedObjects(selectedObjects.toArray()); } else if (e.getSource() == getMolecularTypeSpecsTable().getSelectionModel()) { -// System.out.println("valueChanged: molecularTypeSpecsTableModel"); + System.out.println("valueChanged: molecularTypeSpecsTableModel"); int row = getMolecularTypeSpecsTable().getSelectedRow(); MolecularComponentPattern mcmSelected = molecularTypeSpecsTableModel.getValueAt(row); setMolecularComponentPattern(mcmSelected); + } else if(e.getSource() == getLinkSpecsTable().getSelectionModel()) { // links table + System.out.println("valueChanged: linkSpecsTableModel"); + int row = getLinkSpecsTable().getSelectedRow(); + MolecularInternalLinkSpec milsSelected = linkSpecsTableModel.getValueAt(row); + setMolecularInternalLinkSpec(milsSelected); + } else if(e.getSource() == siteLinksList) { // System.out.println("valueChanged: siteLinksList"); - showLinkLength(siteLinksList.getSelectedValue()); +// showLinkLength(siteLinksList.getSelectedValue()); } // for siteXField, siteYField, siteZField we have actionPerformed() } @@ -216,10 +228,10 @@ private void initConnections() throws java.lang.Exception { // listeners here! // siteYField.addActionListener(eventHandler); // siteZField.addActionListener(eventHandler); - siteLinksList.addListSelectionListener(eventHandler); - siteLinksList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); +// siteLinksList.addListSelectionListener(eventHandler); +// siteLinksList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); +// linkLengthField.addActionListener(eventHandler); - linkLengthField.addActionListener(eventHandler); addLinkButton.addActionListener(eventHandler); deleteLinkButton.addActionListener(eventHandler); @@ -237,6 +249,11 @@ private void initConnections() throws java.lang.Exception { // listeners here! dlsm.addListSelectionListener(eventHandler); } + ListSelectionModel lsm3 = getLinkSpecsTable().getSelectionModel(); + if(lsm3 instanceof DefaultListSelectionModel) { + DefaultListSelectionModel dlsm = (DefaultListSelectionModel)lsm3; + dlsm.addListSelectionListener(eventHandler); + } } @@ -625,7 +642,9 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole // // --- links ----------------------------------------------- linksPanel.setLayout(new GridBagLayout()); - JScrollPane scrollPane1 = new JScrollPane(siteLinksList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + JScrollPane linksScrollPane = new JScrollPane(getLinkSpecsTable()); + linksScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; @@ -634,34 +653,34 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(5, 2, 2, 3); - linksPanel.add(scrollPane1, gbc); - - gbc = new GridBagConstraints(); // ---------------------- - gbc.gridx = 0; - gbc.gridy = 1; - gbc.anchor = GridBagConstraints.EAST; - gbc.insets = new Insets(5, 2, 2, 3); - linksPanel.add(new JLabel("Length (nm): "), gbc); + linksPanel.add(linksScrollPane, gbc); - gbc = new GridBagConstraints(); - gbc.gridx = 1; - gbc.gridy = 1; - gbc.weightx = 1.0; - gbc.gridwidth = 2; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.insets = new Insets(5, 2, 2, 3); // top, left, bottom, right - linksPanel.add(linkLengthField, gbc); +// gbc = new GridBagConstraints(); // ---------------------- +// gbc.gridx = 0; +// gbc.gridy = 1; +// gbc.anchor = GridBagConstraints.EAST; +// gbc.insets = new Insets(5, 2, 2, 3); +// linksPanel.add(new JLabel("Length (nm): "), gbc); +// +// gbc = new GridBagConstraints(); +// gbc.gridx = 1; +// gbc.gridy = 1; +// gbc.weightx = 1.0; +// gbc.gridwidth = 2; +// gbc.fill = GridBagConstraints.HORIZONTAL; +// gbc.insets = new Insets(5, 2, 2, 3); // top, left, bottom, right +// linksPanel.add(linkLengthField, gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; - gbc.gridy = 2; + gbc.gridy = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(5, 2, 2, 3); linksPanel.add(addLinkButton, gbc); gbc = new GridBagConstraints(); gbc.gridx = 1; - gbc.gridy = 2; + gbc.gridy = 1; // gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(5, 2, 2, 3); linksPanel.add(deleteLinkButton, gbc); @@ -672,7 +691,22 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole handleException(e); } } - + + private EditorScrollTable getLinkSpecsTable() { + if (linkSpecsTable == null) { + try { + linkSpecsTable = new EditorScrollTable(); + linkSpecsTable.setName("linkSpecsTable"); + linkSpecsTableModel = new LinkSpecsTableModel(linkSpecsTable); + linkSpecsTable.setModel(linkSpecsTableModel); +// molecularComponentSpecsTable.setScrollTableActionManager(new InternalScrollTableActionManager(table)); + linkSpecsTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); + } catch (java.lang.Throwable ivjExc) { + handleException(ivjExc); + } + } + return linkSpecsTable; + } private EditorScrollTable getMolecularTypeSpecsTable() { if (molecularTypeSpecsTable == null) { try { @@ -756,6 +790,7 @@ public void setSimulationContext(SimulationContext simulationContext) { } speciesContextSpecsTableModel.setSimulationContext(simulationContext); molecularTypeSpecsTableModel.setSimulationContext(simulationContext); + linkSpecsTableModel.setSimulationContext(simulationContext); updateInterface(); } public SimulationContext getSimulationContext() { @@ -778,6 +813,7 @@ void setSpeciesContextSpec(SpeciesContextSpec newValue) { newValue.addPropertyChangeListener(eventHandler); } molecularTypeSpecsTableModel.setSpeciesContextSpec(fieldSpeciesContextSpec); + linkSpecsTableModel.setSpeciesContextSpec(fieldSpeciesContextSpec); updateInterface(); } public SpeciesContextSpec getSpeciesContextSpec() { @@ -788,6 +824,11 @@ void setMolecularComponentPattern(MolecularComponentPattern mcp) { //TODO: stuff updateInterface(); } + void setMolecularInternalLinkSpec(MolecularInternalLinkSpec mils) { + fieldMolecularInternalLinkSpec = mils; + //TODO: stuff + updateInterface(); + } // ============================================================================================ @@ -801,7 +842,8 @@ private void updateInterface() { boolean bNonNullSpeciesPattern = bNonNullSpeciesContextSpec && fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern() != null; boolean bNonNullMolecularTypePattern = bNonNullSpeciesPattern && fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern().getMolecularTypePatterns().get(0) != null; boolean bNonNullMolecularComponentPattern = bNonNullMolecularTypePattern && fieldMolecularComponentPattern != null; - +// boolean bNonNullMolecularInternalLinkSpec = bNonNullMolecularTypePattern && fieldMolecularInternalLinkSpec != null; + MolecularTypePattern mtp = null; if(bNonNullMolecularTypePattern) { mtp = fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern().getMolecularTypePatterns().get(0); @@ -811,16 +853,21 @@ private void updateInterface() { addLinkButton.setEnabled(true); refreshSiteLinksList(); } else { - linkLengthField.setEditable(false); - linkLengthField.setText(null); +// linkLengthField.setEditable(false); +// linkLengthField.setText(null); addLinkButton.setEnabled(false); refreshSiteLinksList(); } - if(!siteLinksListModel.isEmpty() && siteLinksList.getSelectedValue() != null) { // there are links we can delete + if(linkSpecsTableModel.getRowCount() > 0 && fieldMolecularInternalLinkSpec != null) { // there are links we can delete deleteLinkButton.setEnabled(true); } else { deleteLinkButton.setEnabled(false); } +// if(!siteLinksListModel.isEmpty() && siteLinksList.getSelectedValue() != null) { // there are links we can delete +// deleteLinkButton.setEnabled(true); +// } else { +// deleteLinkButton.setEnabled(false); +// } if(bNonNullMolecularComponentPattern) { SiteAttributesSpec sas = fieldSpeciesContextSpec.getSiteAttributesMap().get(fieldMolecularComponentPattern); @@ -906,8 +953,8 @@ private void recalculateLinkLengths() { MolecularInternalLinkSpec mils = siteLinksList.getSelectedValue(); - - showLinkLength(mils); + // TODO: we need to update the table row (maybe??) +// showLinkLength(mils); } private void recalculatePositions() { } @@ -941,18 +988,18 @@ private void deleteLinkActionPerformed() { return; } - private void showLinkLength(MolecularInternalLinkSpec selectedValue) { - if(selectedValue == null) { - System.out.println("showLinkLength: SelectedValue is null"); - deleteLinkButton.setEnabled(false); - linkLengthField.setEditable(false); - linkLengthField.setText(null); - return; // nothing selected - } - System.out.println("showLinkLength(): Selected row is '" + siteLinksList.getSelectedIndex() + "'"); - deleteLinkButton.setEnabled(true); - linkLengthField.setEditable(false); // make it editable here, for now it's a derived value only - linkLengthField.setText(selectedValue.getLinkLength()+""); - }; +// private void showLinkLength(MolecularInternalLinkSpec selectedValue) { +// if(selectedValue == null) { +// System.out.println("showLinkLength: SelectedValue is null"); +// deleteLinkButton.setEnabled(false); +// linkLengthField.setEditable(false); +// linkLengthField.setText(null); +// return; // nothing selected +// } +// System.out.println("showLinkLength(): Selected row is '" + siteLinksList.getSelectedIndex() + "'"); +// deleteLinkButton.setEnabled(true); +// linkLengthField.setEditable(false); // make it editable here, for now it's a derived value only +// linkLengthField.setText(selectedValue.getLinkLength()+""); +// }; } From 1b07ab0d72136470cfce05f8365fa8c806e17f7f Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 12 Nov 2024 13:17:00 -0500 Subject: [PATCH 25/28] WIP: renderers for LinkSpecsTableModel --- .../gui/MolecularStructuresPanel.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index e84748cff2..7edaeaf558 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -565,6 +565,29 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole break; } } + } else if(table.getModel() instanceof LinkSpecsTableModel) { + LinkSpecsTableModel model = (LinkSpecsTableModel)table.getModel(); + if(value instanceof Double) { + LinkSpecsTableModel.ColumnType columnType = LinkSpecsTableModel.ColumnType.values()[column]; + int cellWidth = table.getColumnModel().getColumn(column).getWidth(); + switch(columnType) { + case COLUMN_LENGTH: + if(cellWidth > 70) { + if(!isSelected) { + String text = "" + value + " [nm]"; + setText(text); + } else { + setText(value + " [nm]"); + } + } else { + setText(value + ""); // if it's too busy, just show the numbers + } + setToolTipText(value + " [nm]"); // we always show the units in the tooltip + break; + default: + break; + } + } } return this; } @@ -655,6 +678,30 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole gbc.insets = new Insets(5, 2, 2, 3); linksPanel.add(linksScrollPane, gbc); + DefaultScrollTableCellRenderer linkSpecsTableCellRenderer = new DefaultScrollTableCellRenderer() { + final Color lightBlueBackground = new Color(214, 234, 248); + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, + int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (table.getModel() instanceof LinkSpecsTableModel) { + if (value instanceof MolecularInternalLinkSpec) { + MolecularInternalLinkSpec mils = (MolecularInternalLinkSpec)value; + MolecularComponentPattern firstMcp = mils.getMolecularComponentPatternOne(); + MolecularComponentPattern secondtMcp = mils.getMolecularComponentPatternTwo(); + setText(firstMcp.getMolecularComponent().getName() + " :: " + secondtMcp.getMolecularComponent().getName()); +// Icon icon = new ColorIcon(10,10,namedColor.getColor(), true); // small square icon with subdomain color +// setHorizontalTextPosition(SwingConstants.RIGHT); +// setIcon(icon); + } + } + return this; + } + }; + getLinkSpecsTable().setDefaultRenderer(MolecularInternalLinkSpec.class, linkSpecsTableCellRenderer); // MolecularInternalLinkSpec field cell renderer + getLinkSpecsTable().setDefaultRenderer(Expression.class, expressionTableCellRenderer); // Expression field cell renderer + + // gbc = new GridBagConstraints(); // ---------------------- // gbc.gridx = 0; // gbc.gridy = 1; From a01910455154158854439e9446cd7963666985ac Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Mon, 18 Nov 2024 15:41:01 -0500 Subject: [PATCH 26/28] WIP: add / delete links, keep table in sync --- .../mapping/gui/LinkSpecsTableModel.java | 2 +- .../gui/MolecularStructuresPanel.java | 90 ++++++++++--------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java index 899999fbb1..b676e5a52b 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java @@ -220,7 +220,7 @@ private void refreshColumns() { // called in setSpeciesContextSpec() // TODO: may remove some columns ex: columns.remove(ColumnType.COLUMN_STRUCTURE) } - private void refreshData() { // called in setSimulationContext() + public void refreshData() { // called in setSimulationContext() List molecularInternalLinkSpecList = computeData(); setData(molecularInternalLinkSpecList); GuiUtils.flexResizeTableColumns(ownerTable); diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index 7edaeaf558..f61b36efe6 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -80,27 +80,27 @@ public class MolecularStructuresPanel extends DocumentEditorSubPanel implements // private JTextField siteYField = null; // private JTextField siteZField = null; - private JTextField linkLengthField = null; +// private JTextField linkLengthField = null; private JButton addLinkButton = null; private JButton deleteLinkButton = null; // // TODO: make it possible to use right click menu to delete links // - private JList siteLinksList = null; - private DefaultListModel siteLinksListModel = new DefaultListModel<>(); - private ListCellRenderer siteLinksCellRenderer = new DefaultListCellRenderer(){ - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (value instanceof MolecularInternalLinkSpec && component instanceof JLabel){ - MolecularInternalLinkSpec mils = (MolecularInternalLinkSpec)value; - MolecularComponentPattern firstMcp = mils.getMolecularComponentPatternOne(); - MolecularComponentPattern secondtMcp = mils.getMolecularComponentPatternTwo(); - ((JLabel)component).setText(firstMcp.getMolecularComponent().getName() + " :: " + secondtMcp.getMolecularComponent().getName()); - } - return component; - } - }; +// private JList siteLinksList = null; +// private DefaultListModel siteLinksListModel = new DefaultListModel<>(); +// private ListCellRenderer siteLinksCellRenderer = new DefaultListCellRenderer(){ +// @Override +// public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { +// Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); +// if (value instanceof MolecularInternalLinkSpec && component instanceof JLabel){ +// MolecularInternalLinkSpec mils = (MolecularInternalLinkSpec)value; +// MolecularComponentPattern firstMcp = mils.getMolecularComponentPatternOne(); +// MolecularComponentPattern secondtMcp = mils.getMolecularComponentPatternTwo(); +// ((JLabel)component).setText(firstMcp.getMolecularComponent().getName() + " :: " + secondtMcp.getMolecularComponent().getName()); +// } +// return component; +// } +// }; // TODO: this is for popup menus in the table (instantiated in getMolecularTypeSpecsTable() - uncomment there too) // private class InternalScrollTableActionManager extends DefaultScrollTableActionManager { @@ -129,9 +129,7 @@ public void actionPerformed(ActionEvent e) { // if (source == siteXField || source == siteYField || source == siteZField) { // changePosition((JTextField)source); // } else - if(source == linkLengthField) { - changeLinkLength(); - } else if(source == addLinkButton) { + if(source == addLinkButton) { addLinkActionPerformed(); refreshSiteLinksList(); // TODO: table stuff instead of this } else if(source == deleteLinkButton) { @@ -150,10 +148,10 @@ public void focusLost(FocusEvent e) { // // TODO: are these even needed? we already call changePosition() on actionPerformed() // changePosition((JTextField)source); // } else - if(source == linkLengthField) { - // TODO: do NOT call here changeLinkLength(), it will modified the newly selected link instead the old one - // changeLinkLength(); - } +// if(source == linkLengthField) { +// // TODO: do NOT call here changeLinkLength(), it will modified the newly selected link instead the old one +// // changeLinkLength(); +// } } public void propertyChange(java.beans.PropertyChangeEvent e) { if(e.getSource() instanceof Model && e.getPropertyName().equals(RbmModelContainer.PROPERTY_NAME_MOLECULAR_TYPE_LIST)) { @@ -196,7 +194,7 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { MolecularInternalLinkSpec milsSelected = linkSpecsTableModel.getValueAt(row); setMolecularInternalLinkSpec(milsSelected); - } else if(e.getSource() == siteLinksList) { +// } else if(e.getSource() == siteLinksList) { // System.out.println("valueChanged: siteLinksList"); // showLinkLength(siteLinksList.getSelectedValue()); } @@ -223,7 +221,7 @@ private void initConnections() throws java.lang.Exception { // listeners here! // siteXField.addFocusListener(eventHandler); // siteYField.addFocusListener(eventHandler); // siteZField.addFocusListener(eventHandler); - linkLengthField.addFocusListener(eventHandler); +// linkLengthField.addFocusListener(eventHandler); // siteXField.addActionListener(eventHandler); // siteYField.addActionListener(eventHandler); // siteZField.addActionListener(eventHandler); @@ -263,15 +261,15 @@ private void initialize() { // siteXField = new JTextField(); // siteYField = new JTextField(); // siteZField = new JTextField(); - siteLinksList = new JList(siteLinksListModel); - siteLinksList.setCellRenderer(siteLinksCellRenderer); - linkLengthField = new JTextField(""); +// siteLinksList = new JList(siteLinksListModel); +// siteLinksList.setCellRenderer(siteLinksCellRenderer); +// linkLengthField = new JTextField(""); addLinkButton = new JButton("Add Link"); deleteLinkButton = new JButton("Delete Link"); // siteXField.setEditable(false); // siteYField.setEditable(false); // siteZField.setEditable(false); - linkLengthField.setEditable(false); +// linkLengthField.setEditable(false); deleteLinkButton.setEnabled(false); // ------------------------------------------- The 2 group boxes -------------------------- @@ -898,12 +896,12 @@ private void updateInterface() { if(bNonNullMolecularTypePattern && mtp.getComponentPatternList().size() > 1) { // a link requires 2 sites (components) addLinkButton.setEnabled(true); - refreshSiteLinksList(); +// refreshSiteLinksList(); } else { // linkLengthField.setEditable(false); // linkLengthField.setText(null); addLinkButton.setEnabled(false); - refreshSiteLinksList(); +// refreshSiteLinksList(); } if(linkSpecsTableModel.getRowCount() > 0 && fieldMolecularInternalLinkSpec != null) { // there are links we can delete deleteLinkButton.setEnabled(true); @@ -935,14 +933,21 @@ private void updateInterface() { // getSiteColorComboBox().setSelectedItem(null); } } - + + /* + * Here we refresh the links table when we + */ private void refreshSiteLinksList() { - siteLinksListModel.removeAllElements(); - if(fieldSpeciesContextSpec != null) { - for (MolecularInternalLinkSpec mils : fieldSpeciesContextSpec.getInternalLinkSet()){ - siteLinksListModel.addElement(mils); - } - } + System.out.println("refreshSiteLinksList"); + linkSpecsTableModel.refreshData(); + +// siteLinksListModel.removeAllElements(); +// if(fieldSpeciesContextSpec != null) { +// for (MolecularInternalLinkSpec mils : fieldSpeciesContextSpec.getInternalLinkSet()){ +// siteLinksListModel.addElement(mils); +// +// } +// } } @Override @@ -998,8 +1003,8 @@ private void changeLinkLength() { // when we need it, we compute it private void recalculateLinkLengths() { - MolecularInternalLinkSpec mils = siteLinksList.getSelectedValue(); - +// MolecularInternalLinkSpec mils = siteLinksList.getSelectedValue(); + System.out.println("recalculateLinkLengths"); // TODO: we need to update the table row (maybe??) // showLinkLength(mils); } @@ -1021,6 +1026,7 @@ private void addLinkActionPerformed() { MolecularComponentPattern secondMcp = panel.getSecondSiteList().getSelectedValue(); MolecularInternalLinkSpec mils = new MolecularInternalLinkSpec(fieldSpeciesContextSpec, firstMcp, secondMcp); fieldSpeciesContextSpec.getInternalLinkSet().add(mils); + System.out.println("addLinkActionPerformed"); return; } else { return; @@ -1028,9 +1034,11 @@ private void addLinkActionPerformed() { } private void deleteLinkActionPerformed() { - MolecularInternalLinkSpec selectedValue = siteLinksList.getSelectedValue(); + int row = linkSpecsTable.getSelectedRow(); + MolecularInternalLinkSpec selectedValue = linkSpecsTableModel.getValueAt(row); if(selectedValue != null) { fieldSpeciesContextSpec.getInternalLinkSet().remove(selectedValue); + System.out.println("deleteLinkActionPerformed"); } return; } From 091043f051fad4af34af9b0614c26ac02cb06164 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 19 Nov 2024 13:26:52 -0500 Subject: [PATCH 27/28] PropertyChange event when changing site attributes PropertyChange event to notify LinkSpecsTableModel and MolecularStructures properties panel about molecule attributes when changing site attributes --- .../mapping/gui/LinkSpecsTableModel.java | 13 +++-- .../MolecularStructuresPropertiesPanel.java | 18 ++++++- .../gui/MolecularTypeSpecsTableModel.java | 47 +++++++++---------- .../vcell/mapping/SpeciesContextSpec.java | 1 + 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java index b676e5a52b..25b19bf25d 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/LinkSpecsTableModel.java @@ -17,7 +17,7 @@ public class LinkSpecsTableModel extends VCellSortTableModel implements java.beans.PropertyChangeListener { public enum ColumnType { - COLUMN_LINK("Link"), + COLUMN_LINK(" Link between sites "), COLUMN_LENGTH("Length"); public final String label; @@ -35,11 +35,6 @@ public LinkSpecsTableModel(ScrollTable table) { refreshColumns(); } - - - - - @Override public Class getColumnClass(int column) { ColumnType columnType = columns.get(column); @@ -251,7 +246,11 @@ public void propertyChange(PropertyChangeEvent evt) { } if (evt.getSource() instanceof SpeciesContextSpec) { - fireTableRowsUpdated(0,getRowCount()-1); + if(evt.getPropertyName().equals(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE)) { + refreshData(); + } else { + fireTableRowsUpdated(0, getRowCount() - 1); + } } if (evt.getSource() instanceof SpeciesContextSpec.SpeciesContextSpecParameter) { // prolly not needed fireTableRowsUpdated(0,getRowCount()-1); diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java index b0b14ca193..1b140d9f3d 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularStructuresPropertiesPanel.java @@ -24,6 +24,8 @@ import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; public class MolecularStructuresPropertiesPanel extends DocumentEditorSubPanel { @@ -40,7 +42,9 @@ public class MolecularStructuresPropertiesPanel extends DocumentEditorSubPanel { private JButton zoomSmallerButton = null; - private class EventHandler implements ActionListener { + private class EventHandler implements ActionListener, PropertyChangeListener { + + @Override public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getSource() == getZoomLargerButton()) { System.out.println("Zoom to larger (Zoom In)"); @@ -56,6 +60,13 @@ public void actionPerformed(java.awt.event.ActionEvent e) { updateShape(); } } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if(evt.getSource() instanceof SpeciesContextSpec && evt.getPropertyName().equals(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE)) { + updateShape(); + } + } } @@ -208,10 +219,15 @@ private void updateShape() { } public void setSpeciesContextSpec(SpeciesContextSpec scSpec) { + SpeciesContextSpec oldValue = this.speciesContextSpec; + if(oldValue != null) { + oldValue.removePropertyChangeListener(eventHandler); + } if(scSpec == null) { this.speciesContextSpec = null; } else { this.speciesContextSpec = scSpec; + scSpec.addPropertyChangeListener(eventHandler); } // getSpeciesContextSpecParameterTableModel().setSpeciesContextSpec(scSpec); updateInterface(); diff --git a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java index 087f50ab21..183f97fbdf 100644 --- a/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/mapping/gui/MolecularTypeSpecsTableModel.java @@ -190,6 +190,11 @@ public Object getValueAt(int row, int col) { public void setValueAt(Object aValue, int row, int col) { MolecularComponentPattern mcp = getValueAt(row); ColumnType columnType = columns.get(col); + SpeciesContextSpec scs = getSpeciesContextSpec(); + if(scs == null) { + return; + } + SiteAttributesSpec sas = scs.getSiteAttributesMap().get(mcp); switch (columnType) { case COLUMN_SITE: case COLUMN_MOLECULE: @@ -197,26 +202,19 @@ public void setValueAt(Object aValue, int row, int col) { return; case COLUMN_STRUCTURE: if(aValue instanceof Structure) { - if(getSpeciesContextSpec() == null) { - return; - } Structure structure = (Structure)aValue; - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, structure); + sas = new SiteAttributesSpec(scs, mcp, structure); } else { sas.setLocation(structure); } + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); } return; case COLUMN_X: - if(getSpeciesContextSpec() == null) { - return; - } if (aValue instanceof String) { - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + sas = new SiteAttributesSpec(scs, mcp, scs.getSpeciesContext().getStructure()); } String newExpressionString = (String)aValue; double res = 0.0; @@ -229,17 +227,15 @@ public void setValueAt(Object aValue, int row, int col) { if(c.getX() != res) { c = new Coordinate(res, c.getY(), c.getZ()); sas.setCoordinate(c); + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); } } return; case COLUMN_Y: - if(getSpeciesContextSpec() == null) { - return; - } if (aValue instanceof String) { - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + // TODO: is this necessary? + sas = new SiteAttributesSpec(scs, mcp, scs.getSpeciesContext().getStructure()); } String newExpressionString = (String)aValue; double res = 0.0; @@ -252,17 +248,14 @@ public void setValueAt(Object aValue, int row, int col) { if(c.getX() != res) { c = new Coordinate(c.getX(), res, c.getZ()); sas.setCoordinate(c); + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); } } return; case COLUMN_Z: if (aValue instanceof String) { - if(getSpeciesContextSpec() == null) { - return; - } - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + sas = new SiteAttributesSpec(scs, mcp, scs.getSpeciesContext().getStructure()); } String newExpressionString = (String)aValue; double res = 0.0; @@ -275,6 +268,8 @@ public void setValueAt(Object aValue, int row, int col) { if(c.getX() != res) { c = new Coordinate(c.getX(), c.getY(), res); sas.setCoordinate(c); + // updates the Length in the links table (LinkSpecsTableModel) + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); } } return; @@ -282,32 +277,32 @@ public void setValueAt(Object aValue, int row, int col) { if (aValue instanceof String) { String newExpressionString = (String)aValue; double result = Double.parseDouble(newExpressionString); - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + sas = new SiteAttributesSpec(scs, mcp, scs.getSpeciesContext().getStructure()); } sas.setRadius(result); + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); } return; case COLUMN_DIFFUSION: if (aValue instanceof String) { String newExpressionString = (String)aValue; double result = Double.parseDouble(newExpressionString); - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + sas = new SiteAttributesSpec(scs, mcp, scs.getSpeciesContext().getStructure()); } sas.setDiffusionRate(result); + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); return; } case COLUMN_COLOR: if (aValue instanceof NamedColor) { NamedColor namedColor = (NamedColor)aValue; - SiteAttributesSpec sas = getSpeciesContextSpec().getSiteAttributesMap().get(mcp); if(sas == null) { - sas = new SiteAttributesSpec(fieldSpeciesContextSpec, mcp, getSpeciesContextSpec().getSpeciesContext().getStructure()); + sas = new SiteAttributesSpec(scs, mcp, scs.getSpeciesContext().getStructure()); } sas.setColor(namedColor); + scs.firePropertyChange(SpeciesContextSpec.PROPERTY_NAME_SITE_ATTRIBUTE, null, sas); return; } default: diff --git a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java index fc583b2c95..3fea343932 100644 --- a/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java +++ b/vcell-core/src/main/java/cbit/vcell/mapping/SpeciesContextSpec.java @@ -70,6 +70,7 @@ public class SpeciesContextSpec implements Matchable, ScopedSymbolTable, Seriali public static final String PARAMETER_NAME_PROXY_PARAMETERS = "proxyParameters"; private static final String PROPERTY_NAME_WELL_MIXED = "wellMixed"; private static final String PROPERTY_NAME_FORCECONTINUOUS = "forceContinuous"; + public static final String PROPERTY_NAME_SITE_ATTRIBUTE = "SiteAttributes"; private static final int INITIAL_YZ_SITE_OFFSET = 4; public static final boolean TrackClusters = true; // SpringSaLaD specific From da4ec77797764017ef88755628a6000c73235a33 Mon Sep 17 00:00:00 2001 From: Dan Vasilescu Date: Tue, 19 Nov 2024 15:10:53 -0500 Subject: [PATCH 28/28] Cosmetic fixes --- .../gui/MolecularStructuresPanel.java | 246 +----------------- 1 file changed, 11 insertions(+), 235 deletions(-) diff --git a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java index f61b36efe6..4c98c308ae 100644 --- a/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java +++ b/vcell-client/src/main/java/org/vcell/model/springsalad/gui/MolecularStructuresPanel.java @@ -53,8 +53,7 @@ import java.beans.PropertyChangeListener; import java.util.ArrayList; -// we should use WindowBuilder Plugin (add it to Eclipse IDE) to speed up panel design -// can choose absolute layout and place everything exactly as we see fit + @SuppressWarnings("serial") public class MolecularStructuresPanel extends DocumentEditorSubPanel implements ApplicationSpecificationsPanel.Specifier { @@ -74,18 +73,13 @@ public class MolecularStructuresPanel extends DocumentEditorSubPanel implements private EditorScrollTable linkSpecsTable = null; private LinkSpecsTableModel linkSpecsTableModel = null; - -// private JComboBox siteColorComboBox = null; -// private JTextField siteXField = null; -// private JTextField siteYField = null; -// private JTextField siteZField = null; - -// private JTextField linkLengthField = null; private JButton addLinkButton = null; private JButton deleteLinkButton = null; // // TODO: make it possible to use right click menu to delete links // + + // keep the code below, just in case we need to override a ListCellRenderer // private JList siteLinksList = null; // private DefaultListModel siteLinksListModel = new DefaultListModel<>(); // private ListCellRenderer siteLinksCellRenderer = new DefaultListCellRenderer(){ @@ -102,7 +96,8 @@ public class MolecularStructuresPanel extends DocumentEditorSubPanel implements // } // }; - // TODO: this is for popup menus in the table (instantiated in getMolecularTypeSpecsTable() - uncomment there too) + // TODO: keep this code + // this is for popup menus in the table (instantiated in getMolecularTypeSpecsTable() - uncomment there too) // private class InternalScrollTableActionManager extends DefaultScrollTableActionManager { // InternalScrollTableActionManager(JTable table) { // super(table); @@ -126,38 +121,24 @@ private class EventHandler implements FocusListener, ActionListener, PropertyCha public void actionPerformed(ActionEvent e) { Object source = e.getSource(); -// if (source == siteXField || source == siteYField || source == siteZField) { -// changePosition((JTextField)source); -// } else if(source == addLinkButton) { addLinkActionPerformed(); - refreshSiteLinksList(); // TODO: table stuff instead of this + refreshSiteLinksList(); } else if(source == deleteLinkButton) { deleteLinkActionPerformed(); refreshSiteLinksList(); -// } else if(source == getSiteColorComboBox()) { -// updateSiteColor(); } } public void focusGained(FocusEvent e) { ; } public void focusLost(FocusEvent e) { - Object source = e.getSource(); -// if (source == siteXField || source == siteYField || source == siteZField) { -// // TODO: are these even needed? we already call changePosition() on actionPerformed() -// changePosition((JTextField)source); -// } else -// if(source == linkLengthField) { -// // TODO: do NOT call here changeLinkLength(), it will modified the newly selected link instead the old one -// // changeLinkLength(); -// } + ; } public void propertyChange(java.beans.PropertyChangeEvent e) { if(e.getSource() instanceof Model && e.getPropertyName().equals(RbmModelContainer.PROPERTY_NAME_MOLECULAR_TYPE_LIST)) { updateInterface(); } - // TODO: I think this is not needed // if (e.getSource() == selectionManager) { // System.out.println(e.getPropertyName()); // if (e.getPropertyName().equals(SelectionManager.PROPERTY_NAME_SELECTED_OBJECTS)) { @@ -193,12 +174,7 @@ public void valueChanged(javax.swing.event.ListSelectionEvent e) { int row = getLinkSpecsTable().getSelectedRow(); MolecularInternalLinkSpec milsSelected = linkSpecsTableModel.getValueAt(row); setMolecularInternalLinkSpec(milsSelected); - -// } else if(e.getSource() == siteLinksList) { -// System.out.println("valueChanged: siteLinksList"); -// showLinkLength(siteLinksList.getSelectedValue()); } - // for siteXField, siteYField, siteZField we have actionPerformed() } } @@ -218,23 +194,9 @@ public void setSearchText(String s) { } private void initConnections() throws java.lang.Exception { // listeners here! -// siteXField.addFocusListener(eventHandler); -// siteYField.addFocusListener(eventHandler); -// siteZField.addFocusListener(eventHandler); -// linkLengthField.addFocusListener(eventHandler); -// siteXField.addActionListener(eventHandler); -// siteYField.addActionListener(eventHandler); -// siteZField.addActionListener(eventHandler); - -// siteLinksList.addListSelectionListener(eventHandler); -// siteLinksList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -// linkLengthField.addActionListener(eventHandler); - addLinkButton.addActionListener(eventHandler); deleteLinkButton.addActionListener(eventHandler); - -// getSiteColorComboBox().addActionListener(eventHandler); - + ListSelectionModel lsm = getSpeciesContextSpecsTable().getSelectionModel(); if(lsm instanceof DefaultListSelectionModel) { DefaultListSelectionModel dlsm = (DefaultListSelectionModel)lsm; @@ -257,19 +219,10 @@ private void initConnections() throws java.lang.Exception { // listeners here! private void initialize() { try { - // labels / button / combos / lists initialization -// siteXField = new JTextField(); -// siteYField = new JTextField(); -// siteZField = new JTextField(); -// siteLinksList = new JList(siteLinksListModel); -// siteLinksList.setCellRenderer(siteLinksCellRenderer); -// linkLengthField = new JTextField(""); addLinkButton = new JButton("Add Link"); deleteLinkButton = new JButton("Delete Link"); -// siteXField.setEditable(false); -// siteYField.setEditable(false); -// siteZField.setEditable(false); -// linkLengthField.setEditable(false); + + addLinkButton.setEnabled(true); deleteLinkButton.setEnabled(false); // ------------------------------------------- The 2 group boxes -------------------------- @@ -596,71 +549,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole getMolecularTypeSpecsTable().setDefaultRenderer(Expression.class, expressionTableCellRenderer); // Expression field cell renderer getMolecularTypeSpecsTable().setDefaultRenderer(NamedColor.class, namedColorTableCellRenderer); // NamedColor combobox cell renderer - -// gbc = new GridBagConstraints(); -// gbc.gridx = 0; -// gbc.gridy = 5; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(new JLabel(" X (nm) "), gbc); -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 1; -// gbc.gridy = 5; -// gbc.weightx = 1.0; -// gbc.fill = GridBagConstraints.HORIZONTAL; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(siteXField, gbc); // -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 2; -// gbc.gridy = 5; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(new JLabel(" Y (nm) "), gbc); -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 3; -// gbc.gridy = 5; -// gbc.weightx = 1.0; -// gbc.fill = GridBagConstraints.HORIZONTAL; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(siteYField, gbc); -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 4; -// gbc.gridy = 5; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(new JLabel(" Z (nm) "), gbc); -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 5; -// gbc.gridy = 5; -// gbc.weightx = 1.0; -// gbc.fill = GridBagConstraints.HORIZONTAL; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(siteZField, gbc); -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 6; -// gbc.gridy = 5; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(new JLabel(" Color "), gbc); - -// gbc = new GridBagConstraints(); -// gbc.gridx = 7; -// gbc.gridy = 5; -// gbc.weightx = 1.0; -// gbc.fill = GridBagConstraints.HORIZONTAL; -// gbc.anchor = GridBagConstraints.SOUTH; -// gbc.insets = new Insets(2, 2, 2, 2); -// sitesPanel.add(getSiteColorComboBox(), gbc); - // // --- links ----------------------------------------------- linksPanel.setLayout(new GridBagLayout()); JScrollPane linksScrollPane = new JScrollPane(getLinkSpecsTable()); @@ -699,23 +587,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole getLinkSpecsTable().setDefaultRenderer(MolecularInternalLinkSpec.class, linkSpecsTableCellRenderer); // MolecularInternalLinkSpec field cell renderer getLinkSpecsTable().setDefaultRenderer(Expression.class, expressionTableCellRenderer); // Expression field cell renderer - -// gbc = new GridBagConstraints(); // ---------------------- -// gbc.gridx = 0; -// gbc.gridy = 1; -// gbc.anchor = GridBagConstraints.EAST; -// gbc.insets = new Insets(5, 2, 2, 3); -// linksPanel.add(new JLabel("Length (nm): "), gbc); -// -// gbc = new GridBagConstraints(); -// gbc.gridx = 1; -// gbc.gridy = 1; -// gbc.weightx = 1.0; -// gbc.gridwidth = 2; -// gbc.fill = GridBagConstraints.HORIZONTAL; -// gbc.insets = new Insets(5, 2, 2, 3); // top, left, bottom, right -// linksPanel.add(linkLengthField, gbc); - gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; @@ -784,35 +655,6 @@ private EditorScrollTable getSpeciesContextSpecsTable() { return speciesContextSpecsTable; } - // siteColorComboBox -// private JComboBox getSiteColorComboBox() { -// if (siteColorComboBox == null) { -// siteColorComboBox = new JComboBox(); -// siteColorComboBox.setName("JComboBox1"); -// -// DefaultComboBoxModel model = new DefaultComboBoxModel<>(); -// for(NamedColor namedColor : Colors.COLORARRAY) { -// model.addElement(namedColor.getName()); -// } -// siteColorComboBox.setModel(model); -//// siteColorComboBox.setRenderer(new DefaultListCellRenderer() { -//// see ReactionRuleKineticsPropertiesPanel.getKineticsTypeComboBox() for complex renderer -//// }); -// } -// return siteColorComboBox; -// } -// private void updateSiteColor() { -// String colorName = (String)getSiteColorComboBox().getSelectedItem(); -// if(colorName == null) { -// return; -// } -// NamedColor namedColor = Colors.getColorByName(colorName); -// SiteAttributesSpec sas = fieldSpeciesContextSpec.getSiteAttributesMap().get(fieldMolecularComponentPattern); -// if(namedColor != null && namedColor != sas.getColor()) { -// sas.setColor(namedColor); -// } -// } - private void handleException(Throwable exception) { System.out.println("--------- UNCAUGHT EXCEPTION --------- in cbit.vcell.mapping.InitialConditionPanel"); exception.printStackTrace(System.out); @@ -886,8 +728,6 @@ private void updateInterface() { boolean bNonNullSpeciesContextSpec = fieldSpeciesContextSpec != null && fieldSimulationContext != null; boolean bNonNullSpeciesPattern = bNonNullSpeciesContextSpec && fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern() != null; boolean bNonNullMolecularTypePattern = bNonNullSpeciesPattern && fieldSpeciesContextSpec.getSpeciesContext().getSpeciesPattern().getMolecularTypePatterns().get(0) != null; - boolean bNonNullMolecularComponentPattern = bNonNullMolecularTypePattern && fieldMolecularComponentPattern != null; -// boolean bNonNullMolecularInternalLinkSpec = bNonNullMolecularTypePattern && fieldMolecularInternalLinkSpec != null; MolecularTypePattern mtp = null; if(bNonNullMolecularTypePattern) { @@ -896,58 +736,22 @@ private void updateInterface() { if(bNonNullMolecularTypePattern && mtp.getComponentPatternList().size() > 1) { // a link requires 2 sites (components) addLinkButton.setEnabled(true); -// refreshSiteLinksList(); } else { -// linkLengthField.setEditable(false); -// linkLengthField.setText(null); addLinkButton.setEnabled(false); -// refreshSiteLinksList(); } if(linkSpecsTableModel.getRowCount() > 0 && fieldMolecularInternalLinkSpec != null) { // there are links we can delete deleteLinkButton.setEnabled(true); } else { deleteLinkButton.setEnabled(false); } -// if(!siteLinksListModel.isEmpty() && siteLinksList.getSelectedValue() != null) { // there are links we can delete -// deleteLinkButton.setEnabled(true); -// } else { -// deleteLinkButton.setEnabled(false); -// } - - if(bNonNullMolecularComponentPattern) { - SiteAttributesSpec sas = fieldSpeciesContextSpec.getSiteAttributesMap().get(fieldMolecularComponentPattern); -// siteXField.setEditable(true); -// siteYField.setEditable(true); -// siteZField.setEditable(true); -// siteXField.setText(sas.getCoordinate().getX()+""); -// siteYField.setText(sas.getCoordinate().getY()+""); -// siteZField.setText(sas.getCoordinate().getZ()+""); -// getSiteColorComboBox().setSelectedItem(sas.getColor().getName()); - } else { -// siteXField.setEditable(false); -// siteYField.setEditable(false); -// siteZField.setEditable(false); -// siteXField.setText(null); -// siteYField.setText(null); -// siteZField.setText(null); -// getSiteColorComboBox().setSelectedItem(null); - } } /* - * Here we refresh the links table when we + * Here we refresh the links table when we add or delete a link */ private void refreshSiteLinksList() { System.out.println("refreshSiteLinksList"); linkSpecsTableModel.refreshData(); - -// siteLinksListModel.removeAllElements(); -// if(fieldSpeciesContextSpec != null) { -// for (MolecularInternalLinkSpec mils : fieldSpeciesContextSpec.getInternalLinkSet()){ -// siteLinksListModel.addElement(mils); -// -// } -// } } @Override @@ -955,10 +759,6 @@ protected void onSelectedObjectsChange(Object[] selectedObjects) { setTableSelections(selectedObjects, speciesContextSpecsTable, speciesContextSpecsTableModel); } - /* - * TODO: commit changes to current (old) SpeciesContextStep - * before the newly selected SpeciesContextStep becomes current - */ private void changeSpeciesContextSpec() { ; } @@ -977,16 +777,6 @@ private void changePosition(JTextField source) { } catch(NumberFormatException e) { return; } - -// if(siteXField == source && c.getX() != res) { -// c = new Coordinate(res, c.getY(), c.getZ()); -// } else if(siteYField == source && c.getY() != res) { -// c = new Coordinate(c.getX(), res, c.getZ()); -// } else if(siteZField == source && c.getZ() != res) { -// c = new Coordinate(c.getX(), c.getY(), res); -// } -// sas.setCoordinate(c); - recalculateLinkLengths(); } private void changeLinkLength() { @@ -1043,18 +833,4 @@ private void deleteLinkActionPerformed() { return; } -// private void showLinkLength(MolecularInternalLinkSpec selectedValue) { -// if(selectedValue == null) { -// System.out.println("showLinkLength: SelectedValue is null"); -// deleteLinkButton.setEnabled(false); -// linkLengthField.setEditable(false); -// linkLengthField.setText(null); -// return; // nothing selected -// } -// System.out.println("showLinkLength(): Selected row is '" + siteLinksList.getSelectedIndex() + "'"); -// deleteLinkButton.setEnabled(true); -// linkLengthField.setEditable(false); // make it editable here, for now it's a derived value only -// linkLengthField.setText(selectedValue.getLinkLength()+""); -// }; - }