$darkmode
DENOPTIM
GUIEmptyVertexMaker.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.Component;
23import java.awt.Dimension;
24import java.awt.FlowLayout;
25import java.awt.GridLayout;
26import java.awt.event.ActionEvent;
27import java.awt.event.ActionListener;
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.List;
31
32import javax.swing.BoxLayout;
33import javax.swing.DefaultComboBoxModel;
34import javax.swing.GroupLayout;
35import javax.swing.JButton;
36import javax.swing.JComboBox;
37import javax.swing.JLabel;
38import javax.swing.JOptionPane;
39import javax.swing.JPanel;
40import javax.swing.JRadioButton;
41import javax.swing.JScrollPane;
42import javax.swing.JTable;
43import javax.swing.SwingConstants;
44import javax.swing.UIManager;
45import javax.swing.table.DefaultTableModel;
46import javax.swing.table.JTableHeader;
47
48import denoptim.exception.DENOPTIMException;
49import denoptim.graph.APClass;
50import denoptim.graph.EmptyVertex;
51import denoptim.graph.Vertex.BBType;
52
54{
55
59 private static final long serialVersionUID = 1L;
60
61 private JPanel centralPanel;
62
63 private JPanel lineAPsBtns;
64 private JButton btnAPInsert;
65 private JButton btnAPDelete;
66
67 private JScrollPane apTabPanel;
68 private JTable apTable;
69 private DefaultTableModel apTabModel;
70
71 private JPanel lineBBType;
72 private JComboBox<BBType> cmbBBType;
73
74 private JPanel lineRCV;
75 private JRadioButton rcbIsRCV;
76
77 //TODO: uncomment when properties will be enabled
78 /*
79 private JPanel linePropBtns;
80 private JButton btnPropInsert;
81 private JButton btnPropDelete;
82
83 private JScrollPane propTabPanel;
84 private JTable propTable;
85 private DefaultTableModel propTabModel;
86 */
87
88 private boolean canBeScaffold = true;
89
90
91//------------------------------------------------------------------------------
92
100 public GUIEmptyVertexMaker(Component parent, BBType givenType)
101 {
102 this(parent, false);
103 BBType[] bt = new BBType[1];
104 bt[0] = givenType;
105 cmbBBType.setModel(new DefaultComboBoxModel<BBType>(bt));
106 cmbBBType.setEnabled(false);
107 }
108
109//------------------------------------------------------------------------------
110
116 public GUIEmptyVertexMaker(Component parent)
117 {
118 this(parent, true);
119 }
120
121//------------------------------------------------------------------------------
122
129 @SuppressWarnings("serial")
130 public GUIEmptyVertexMaker(Component refForPlacement, boolean canBeScaffold)
131 {
132 super(refForPlacement);
133 this.canBeScaffold = canBeScaffold;
134 setTitle("Create Empty Vertex");
135 centralPanel = new JPanel();
136 centralPanel.setLayout(new BoxLayout(
137 centralPanel, SwingConstants.VERTICAL));
138
139 JPanel titleAPs = new JPanel(new FlowLayout(FlowLayout.LEFT));
140 titleAPs.add(new JLabel("Attachment Points:"));
141 centralPanel.add(titleAPs);
142
143 apTabModel = new DefaultTableModel() {
144 @Override
145 public boolean isCellEditable(int row, int column) {
146 if (column == 0)
147 {
148 return false;
149 }
150 else
151 {
152 return true;
153 }
154 }
155 };
156 apTabModel.setColumnCount(2);
157 String column_names[]= {"<html><b>AP#</b></html>", "<html><b>APClass</b></html>"};
158 apTabModel.setColumnIdentifiers(column_names);
159 apTable = new JTable(apTabModel);
160 apTable.putClientProperty("terminateEditOnFocusLost", true);
161 apTable.getColumnModel().getColumn(0).setMaxWidth(75);
162 apTable.setGridColor(Color.LIGHT_GRAY);
163 JTableHeader apTabHeader = apTable.getTableHeader();
164 apTabHeader.setPreferredSize(new Dimension(100, 20));
165 apTabPanel = new JScrollPane(apTable);
166 apTabPanel.setMaximumSize(new Dimension(400, 150));
167
168 lineAPsBtns = new JPanel(new GridLayout(2, 2));
169 btnAPInsert = new JButton("Add AP");
170 btnAPInsert.setToolTipText("Click to add an attachment point.");
171 btnAPInsert.addActionListener(new ActionListener(){
172 public void actionPerformed(ActionEvent e){
173 List<APClass> selectedAPCs =
175 false);
176 for (APClass apc : selectedAPCs)
177 {
178 apTabModel.addRow(new Object[]{apTabModel.getRowCount()+1,
179 apc.toString()});
180 }
182 }
183 });
184 btnAPDelete = new JButton("Remove Selected");
185 btnAPDelete.setToolTipText("Remove all selected APs from list.");
186 btnAPDelete.addActionListener(new ActionListener(){
187 public void actionPerformed(ActionEvent e){
188 if (apTable.getRowCount() > 0)
189 {
190 if (apTable.getSelectedRowCount() > 0)
191 {
192 int selectedRowIds[] = apTable.getSelectedRows();
193 Arrays.sort(selectedRowIds);
194 for (int i=(selectedRowIds.length-1); i>-1; i--)
195 {
196 apTabModel.removeRow(selectedRowIds[i]);
197 }
199 }
200 }
201 }
202 });
203 GroupLayout grpLyoAPs = new GroupLayout(lineAPsBtns);
204 lineAPsBtns.setLayout(grpLyoAPs);
205 grpLyoAPs.setAutoCreateGaps(true);
206 grpLyoAPs.setAutoCreateContainerGaps(true);
207 grpLyoAPs.setHorizontalGroup(grpLyoAPs.createSequentialGroup()
208 .addGroup(grpLyoAPs.createParallelGroup()
209 .addGroup(grpLyoAPs.createSequentialGroup()
210 .addComponent(btnAPInsert)
211 .addComponent(btnAPDelete))
212 .addComponent(apTabPanel))
213 );
214 grpLyoAPs.setVerticalGroup(grpLyoAPs.createParallelGroup(
215 GroupLayout.Alignment.CENTER)
216 .addGroup(grpLyoAPs.createSequentialGroup()
217 .addGroup(grpLyoAPs.createParallelGroup()
218 .addComponent(btnAPInsert)
219 .addComponent(btnAPDelete))
220 .addComponent(apTabPanel))
221 );
223
224
225 cmbBBType = new JComboBox<BBType>();
227 cmbBBType.setToolTipText(String.format("<html><body width='%1s'>"
228 + "Speicfy the type of building block of the vertex. This"
229 + "determines, for instance, the type of other vertexes "
230 + "that can be used to replace thi one (if such mutation "
231 + "is permitted).</html>",300));
232 lineBBType = new JPanel(new FlowLayout(FlowLayout.LEFT));
235
236
237 rcbIsRCV = new JRadioButton("ring-closing vertex");
238 rcbIsRCV.setToolTipText("Select to mark this vertex as a ring-closing "
239 + "vertex");
240 lineRCV = new JPanel(new FlowLayout(FlowLayout.LEFT));
241 lineRCV.add(rcbIsRCV);
243
244
245
246
247 //TODO: uncomment when properties will be enables
248 /*
249 JPanel titleProps = new JPanel(new FlowLayout(FlowLayout.LEFT));
250 titleProps.add(new JLabel("Properties:"));
251 titleProps.setToolTipText("Properties represent any general form data "
252 + "contained in the vertex");
253 centralPanel.add(titleProps);
254
255 propTabModel = new DefaultTableModel();
256 propTabModel.setColumnCount(2);
257 String column_names_prop[]= {"<html><b>Name</b></html>",
258 "<html><b>Value</b></html>"};
259 propTabModel.setColumnIdentifiers(column_names_prop);
260 propTable = new JTable(propTabModel);
261 propTable.putClientProperty("terminateEditOnFocusLost", true);
262 propTable.getColumnModel().getColumn(0).setMaxWidth(75);
263 propTable.setGridColor(Color.LIGHT_GRAY);
264 propTable.getTableHeader().setPreferredSize(new Dimension(100, 20));
265 propTabPanel = new JScrollPane(propTable);
266 propTabPanel.setMaximumSize(new Dimension(400, 150));
267
268 linePropBtns = new JPanel(new GridLayout(2, 2));
269 btnPropInsert = new JButton("Add Property");
270 btnPropInsert.setToolTipText("Click to add an property.");
271 btnPropInsert.addActionListener(new ActionListener(){
272 public void actionPerformed(ActionEvent e){
273 String propName = "noName";
274 String propValue = "1.23456";
275 //TODO: launch dialog to provide name and value
276 propTabModel.addRow(new Object[]{propName,propValue});
277 }
278 });
279 btnPropDelete = new JButton("Remove Selected");
280 btnPropDelete.setToolTipText("Remove all selected properties from list.");
281 btnPropDelete.addActionListener(new ActionListener(){
282 public void actionPerformed(ActionEvent e){
283 if (propTable.getRowCount() > 0)
284 {
285 if (propTable.getSelectedRowCount() > 0)
286 {
287 int selectedRowIds[] = propTable.getSelectedRows();
288 Arrays.sort(selectedRowIds);
289 for (int i=(selectedRowIds.length-1); i>-1; i--)
290 {
291 propTabModel.removeRow(selectedRowIds[i]);
292 }
293 }
294 }
295 }
296 });
297 GroupLayout grpLyoProps = new GroupLayout(linePropBtns);
298 linePropBtns.setLayout(grpLyoProps);
299 grpLyoProps.setAutoCreateGaps(true);
300 grpLyoProps.setAutoCreateContainerGaps(true);
301 grpLyoProps.setHorizontalGroup(grpLyoProps.createSequentialGroup()
302 .addGroup(grpLyoProps.createParallelGroup()
303 .addGroup(grpLyoProps.createSequentialGroup()
304 .addComponent(btnPropInsert)
305 .addComponent(btnPropDelete))
306 .addComponent(propTabPanel))
307 );
308 grpLyoProps.setVerticalGroup(grpLyoProps.createParallelGroup(
309 GroupLayout.Alignment.CENTER)
310 .addGroup(grpLyoProps.createSequentialGroup()
311 .addGroup(grpLyoProps.createParallelGroup()
312 .addComponent(btnPropInsert)
313 .addComponent(btnPropDelete))
314 .addComponent(propTabPanel))
315 );
316 centralPanel.add(linePropBtns);
317 */
318
319 this.btnDone.setText("Create");
320 this.btnDone.setToolTipText("<html>Create an empty vertex with the "
321 + "given attachment points<br>and properties</html>");
322 this.btnDone.addActionListener(new ActionListener() {
323
324 @Override
325 public void actionPerformed(ActionEvent e) {
326 EmptyVertex ev = new EmptyVertex(BBType.valueOf(
327 cmbBBType.getSelectedItem().toString()));
328 for (int i=0; i<apTabModel.getRowCount(); i++)
329 {
330 String apClass = apTabModel.getValueAt(i, 1).toString();
331 try
332 {
333 ev.addAP(APClass.make(apClass));
334 } catch (DENOPTIMException e1)
335 {
336 e1.printStackTrace();
337 JOptionPane.showMessageDialog(btnDone,
338 "<html>Could not add attachment point with "
339 + "<br>APClass '" + apClass + "'. "
340 + "<br>Hint on cause: " + e1.getMessage()
341 +"</html>",
342 "Error",
343 JOptionPane.ERROR_MESSAGE,
344 UIManager.getIcon("OptionPane.errorIcon"));
345 }
346 }
347
348 //TODO : add props
349
350 ev.setAsRCV(rcbIsRCV.isSelected());
351
352 result = ev;
353 close();
354 }
355 });
356
357 this.btnCanc.setEnabled(true);
358 this.btnCanc.setVisible(true);
359
360 super.addToCentralPane(centralPanel);
361 }
362
363//------------------------------------------------------------------------------
364
366 {
367 List<BBType> collection = new ArrayList<BBType>();
368
369 if (canBeScaffold)
370 {
371 collection.add(BBType.SCAFFOLD);
372 for (int i=0; i<BBType.values().length; i++)
373 if (!collection.contains(BBType.values()[i]))
374 collection.add(BBType.values()[i]);
375 } else {
376 switch (apTabModel.getRowCount())
377 {
378 case 0:
379 collection.add(BBType.UNDEFINED);
380 break;
381
382 case 1:
383 collection.add(BBType.CAP);
384 for (int i=0; i<BBType.values().length; i++)
385 {
386 BBType cand = BBType.values()[i];
387 if (!collection.contains(cand)
388 && !cand.equals(BBType.SCAFFOLD))
389 collection.add(cand);
390 }
391 break;
392
393 default:
394 collection.add(BBType.FRAGMENT);
395 for (int i=0; i<BBType.values().length; i++)
396 {
397 BBType cand = BBType.values()[i];
398 if (!collection.contains(cand)
399 && !cand.equals(BBType.SCAFFOLD)
400 && !cand.equals(BBType.CAP))
401 collection.add(cand);
402 }
403 break;
404
405 }
406 }
407 BBType[] types = new BBType[collection.size()];
408 for (int i=0; i<collection.size(); i++)
409 {
410 types[i] = collection.get(i);
411 }new DefaultComboBoxModel<BBType>(types);
412 cmbBBType.setModel(new DefaultComboBoxModel<BBType>(types));
413 }
414
415//------------------------------------------------------------------------------
416
417}
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
Definition: APClass.java:136
An empty vertex has the behaviors of a vertex, but has no molecular structure.
void addAP()
Adds an attachment point with no APClass or other attribute.
void setAsRCV(boolean isRCV)
Definition: Vertex.java:254
static final long serialVersionUID
Version UID.
GUIEmptyVertexMaker(Component parent)
Constructs a maker that can make empty vertexes freely.
GUIEmptyVertexMaker(Component parent, BBType givenType)
Constructs a maker that can make empty vertexes on a specific BBType and does not allow to change suc...
JButton btnCanc
The button that is used to close the dialog without processing any input.
JButton btnDone
The button that is used to launch the processing of the data given to the open dialog,...
Object result
The result to be returned once the dialog is closed.
void close()
Closes the dialog window.
A panel with a viewer capable of visualising DENOPTIM fragments and allows to create and edit fragmen...
static List< APClass > choseOrCreateNewAPClass(JComponent parent, boolean singleSelection)
Runs a dialog aimed at selecting an existing APClass or defining a new one.
The type of building block.
Definition: Vertex.java:86