$darkmode
DENOPTIM
VertexAsGraphViewPanel.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2020 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.gui;
20
21import java.awt.Color;
22import java.awt.Dimension;
23import java.util.ArrayList;
24import java.util.HashMap;
25import java.util.List;
26import java.util.Map;
27
28import javax.swing.JScrollPane;
29import javax.swing.JSplitPane;
30import javax.swing.JTable;
31import javax.swing.event.TableModelEvent;
32import javax.swing.event.TableModelListener;
33import javax.swing.table.DefaultTableModel;
34import javax.swing.table.JTableHeader;
35
36import denoptim.exception.DENOPTIMException;
37import denoptim.graph.AttachmentPoint;
38import denoptim.graph.DGraph;
39import denoptim.graph.EmptyVertex;
40import denoptim.graph.Fragment;
41import denoptim.graph.Template;
42import denoptim.graph.Vertex;
43
44
52public class VertexAsGraphViewPanel extends JSplitPane implements IVertexAPSelection
53{
57 private static final long serialVersionUID = 1L;
58
62 private Vertex vertex;
63
67 protected Map<Integer,AttachmentPoint> mapAPs = null;
68
72 public boolean alteredAPData = false;
73
75 private JScrollPane tabPanel;
76 protected DefaultTableModel apTabModel;
77 protected JTable apTable;
78
79 // This is a global property of this instance
80 private boolean editableAPTable = false;
81 // this is vertex-specific, it does not overwrite editableAPTable, which is
82 // more general. The overall editablility is given by general && local.
83 private boolean vertexSpecificAPTabEditable = true;
84
85//-----------------------------------------------------------------------------
86
92 public VertexAsGraphViewPanel(boolean editableTable)
93 {
94 this(editableTable,340);
95 }
96
97//-----------------------------------------------------------------------------
98
106 public VertexAsGraphViewPanel(boolean editableTable,
107 int dividerPosition)
108 {
109 editableAPTable = editableTable;
110 initialize(dividerPosition);
111 }
112
113//-----------------------------------------------------------------------------
114
115 @SuppressWarnings("serial")
116 private void initialize(int dividerPosition)
117 {
118 this.setOrientation(JSplitPane.VERTICAL_SPLIT);
119 this.setOneTouchExpandable(true);
120 this.setDividerLocation(dividerPosition);
121 this.setResizeWeight(0.5);
122
123 // Graph Viewer
125 this.setTopComponent(graphViewer);
126
127 // List of attachment points
128 apTabModel = new DefaultTableModel() {
129 @Override
130 public boolean isCellEditable(int row, int column) {
131 if (column == 0)
132 {
133 return false;
134 }
135 else
136 {
138 }
139 }
140 };
141 apTabModel.setColumnCount(2);
142 String column_names[]= {"<html><b>AP#</b></html>",
143 "<html><b>APClass</b></html>"};
144 apTabModel.setColumnIdentifiers(column_names);
145 apTable = new JTable(apTabModel);
146 apTable.putClientProperty("terminateEditOnFocusLost", true);
147 apTable.getColumnModel().getColumn(0).setMaxWidth(75);
148 apTable.setGridColor(Color.LIGHT_GRAY);
149 apTable.setPreferredScrollableViewportSize(apTable.getPreferredSize());
150 JTableHeader apTabHeader = apTable.getTableHeader();
151 apTabHeader.setPreferredSize(new Dimension(100, 20));
152 apTabModel.addTableModelListener(new PausableTableModelListener());
153 tabPanel = new JScrollPane(apTable);
154 this.setBottomComponent(tabPanel);
155 }
156
157//-----------------------------------------------------------------------------
158
159 public void setVertexSpecificEditableAPTable(boolean editable)
160 {
162 }
163
164//-----------------------------------------------------------------------------
165
167 {
169 clearAPTable();
170 vertex = v;
173 preSelectAPs();
174 }
175
176//-----------------------------------------------------------------------------
177
178 /*
179 * Structure here means the single-node-graph-like visual depiction of the
180 */
181 private void loadVertexStructure()
182 {
183 if ((vertex instanceof EmptyVertex)
184 || (vertex instanceof Fragment))
185 {
186 //We plot the empty vertex as a single-node graph
187 DGraph dnGraph = new DGraph();
188 try
189 {
190 dnGraph.addVertex(vertex.clone()); //Clone avoids setting owner
191 } catch (DENOPTIMException e)
192 {
193 //This will never happen because this is a one-vertex graph
194 }
197 } else {
198 Template tmpl = ((Template) vertex);
201 }
202 }
203
204//-----------------------------------------------------------------------------
205
210 public boolean hasUnsavedAPEdits()
211 {
212 return alteredAPData;
213 }
214
215//-----------------------------------------------------------------------------
216
221 public void deprotectEdits()
222 {
223 alteredAPData = false;
224 }
225
226//-----------------------------------------------------------------------------
227
232 private void updateAPsMapAndTable()
233 {
234 clearAPTable();
235 mapAPs = new HashMap<Integer,AttachmentPoint>();
236
237 List<AttachmentPoint> lstAPs = vertex.getAttachmentPoints();
238 if (lstAPs.size() == 0)
239 {
240 return;
241 }
242
244 int arrId = 0;
245 for (AttachmentPoint ap : lstAPs)
246 {
247 arrId++;
248 apTabModel.addRow(new Object[]{arrId, ap.getAPClass()});
249 mapAPs.put(arrId,ap);
250 }
252 }
253
254//-----------------------------------------------------------------------------
255
256 private void preSelectAPs()
257 {
258 String PRESELPROP = GUIVertexSelector.PRESELECTEDAPSFIELD;
259 String PRESELPROPSEP = GUIVertexSelector.PRESELECTEDAPSFIELDSEP;
260
261 if (vertex.getProperty(PRESELPROP) == null)
262 {
263 return;
264 }
265
266 String prop = vertex.getProperty(PRESELPROP).toString();
267 String[] parts =prop.split(PRESELPROPSEP);
268
270 for (int i=0; i<parts.length; i++)
271 {
272 int apId = Integer.parseInt(parts[i]); //0-based
273 apTable.getSelectionModel().addSelectionInterval(apId, apId);
274 }
276 }
277
278//-----------------------------------------------------------------------------
279
283 public void clearAll()
284 {
285 clearAPTable();
286 }
287
288//-----------------------------------------------------------------------------
289
293 public void clearAPTable()
294 {
296 int initRowCount = apTabModel.getRowCount();
297 for (int i=0; i<initRowCount; i++)
298 {
299 //Always remove the first to avoid dealing with changing row ids
300 apTabModel.removeRow(0);
301 }
303 }
304
305//-----------------------------------------------------------------------------
306
311 public ArrayList<AttachmentPoint> getSelectedAPs()
312 {
313 ArrayList<AttachmentPoint> selected =
314 new ArrayList<AttachmentPoint>();
315
316 for (int rowId : apTable.getSelectedRows())
317 {
318 selected.add(mapAPs.get(apTable.getValueAt(rowId, 0)));
319 }
320 return selected;
321 }
322
323//-----------------------------------------------------------------------------
324
329 public ArrayList<Integer> getSelectedAPIDs()
330 {
331 ArrayList<Integer> selected = new ArrayList<Integer>();
332 for (int rowId : apTable.getSelectedRows())
333 {
334 selected.add(rowId);
335 }
336 return selected;
337 }
338
339//-----------------------------------------------------------------------------
340
341 private class PausableTableModelListener implements TableModelListener
342 {
343 private boolean isActive = false;
344
346 {};
347
348 @Override
349 public void tableChanged(TableModelEvent e)
350 {
351 if (isActive && !alteredAPData
352 && e.getType() == TableModelEvent.UPDATE)
353 {
354 alteredAPData = true;
355 firePropertyChange(IVertexAPSelection.APDATACHANGEEVENT, false,
356 true);
357 }
358 }
359
360 public void setActive(boolean var)
361 {
362 isActive = var;
363 }
364 }
365
366//-----------------------------------------------------------------------------
367
372 public void activateTabEditsListener(boolean var)
373 {
374 try
375 {
377 apTabModel.getTableModelListeners()[0];
378 l.setActive(var);
379 } catch (Throwable t) {
380 //t.printStackTrace();
381 System.out.println("Bad attempt to contro listener: "
382 + t.getMessage());
383 System.out.println(t.getCause());
384 }
385 }
386
387//-----------------------------------------------------------------------------
388
389 public void dispose()
390 {
392 }
393
394//-----------------------------------------------------------------------------
395
396 @Override
397 public Map<Integer, AttachmentPoint> getMapOfAPsInTable()
398 {
399 return mapAPs;
400 }
401
402//-----------------------------------------------------------------------------
403
404 @Override
405 public DefaultTableModel getAPTableModel()
406 {
407 return apTabModel;
408 }
409
410//-----------------------------------------------------------------------------
411
412}
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1097
An empty vertex has the behaviors of a vertex, but has no molecular structure.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
abstract Vertex clone()
Returns a deep-copy of this vertex.
abstract List< AttachmentPoint > getAttachmentPoints()
Object getProperty(Object property)
Definition: Vertex.java:1136
A modal dialog with a viewer that understands the different types of DENOPTIM vertex and allows to se...
static final String PRESELECTEDAPSFIELD
Property used to pre-select APs.
static final String PRESELECTEDAPSFIELDSEP
Separator in property used to pre-select APs.
A Panel that holds the JUNG representation of a graph.
void loadGraphToViewer(DGraph dnGraph)
Load the given DGraph to this graph viewer.
void cleanup()
Removes the currently loaded graph viewer.
A panel to visualize a vertex as a graph component with attachment point table.
static final long serialVersionUID
Version UID.
VertexAsGraphViewPanel(boolean editableTable)
Constructor that allows to specify whether the AP table is editable or not.
boolean alteredAPData
Flag signalling that data about APs has been changed in the GUI.
ArrayList< AttachmentPoint > getSelectedAPs()
Identifies which attachment points are selected in the visualized table.
void setVertexSpecificEditableAPTable(boolean editable)
void deprotectEdits()
Overrides the flag signaling unsaved edits to saying that there are no altered data.
ArrayList< Integer > getSelectedAPIDs()
Identifies which attachment points are selected in the visualized table.
void activateTabEditsListener(boolean var)
Allows to activate and deactivate the listener.
Map< Integer, AttachmentPoint > getMapOfAPsInTable()
Vertex vertex
The currently loaded fragment.
void clearAll()
Removes the currently visualized molecule and AP table.
VertexAsGraphViewPanel(boolean editableTable, int dividerPosition)
Constructor that allows to specify whether the AP table is editable or not.
Map< Integer, AttachmentPoint > mapAPs
Temporary list of attachment points of the current fragment.
void updateAPsMapAndTable()
Uses the AP of the Fragment to create a new map and table of APs.
boolean hasUnsavedAPEdits()
Check for unsaved edits to the AP data.
void clearAPTable()
Clears the table of attachment points.
Interface for all vertex viewers that intend to allow selection of attachment points.