2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.datamodel.SequenceI;
24 import jalview.ext.varna.JalviewVarnaBinding;
25 import jalview.structure.AtomSpec;
26 import jalview.util.MessageManager;
28 import java.awt.BorderLayout;
29 import java.awt.Color;
30 import java.awt.Component;
31 import java.awt.Dimension;
32 import java.awt.datatransfer.DataFlavor;
33 import java.awt.datatransfer.Transferable;
34 import java.awt.dnd.DnDConstants;
35 import java.awt.dnd.DropTarget;
36 import java.awt.dnd.DropTargetAdapter;
37 import java.awt.dnd.DropTargetDropEvent;
38 import java.awt.event.ComponentEvent;
39 import java.awt.event.MouseAdapter;
40 import java.awt.event.MouseEvent;
42 import java.io.IOException;
43 import java.util.ArrayList;
44 import java.util.Collection;
45 import java.util.List;
47 import javax.swing.DefaultListModel;
48 import javax.swing.DefaultListSelectionModel;
49 import javax.swing.JLabel;
50 import javax.swing.JList;
51 import javax.swing.JPanel;
52 import javax.swing.JScrollPane;
53 import javax.swing.ListModel;
54 import javax.swing.ListSelectionModel;
55 import javax.swing.event.ListSelectionEvent;
56 import javax.swing.event.ListSelectionListener;
58 import fr.orsay.lri.varna.VARNAPanel;
59 import fr.orsay.lri.varna.components.ReorderableJList;
60 import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
61 import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
62 import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
63 import fr.orsay.lri.varna.models.FullBackup;
64 import fr.orsay.lri.varna.models.VARNAConfig;
65 import fr.orsay.lri.varna.models.rna.RNA;
67 public class AppVarnaBinding extends JalviewVarnaBinding
71 protected JPanel _listPanel = new JPanel();
73 private ReorderableJList _sideList = null;
75 private final static String errorOpt = "error";
77 @SuppressWarnings("unused")
78 private boolean _error;
80 private Color _backgroundColor = Color.white;
82 private static int _nextID = 1;
84 @SuppressWarnings("unused")
85 private int _algoCode;
87 private BackupHolder _rnaList;
92 public AppVarnaBinding()
98 * Constructs the VARNAPanel and an (empty) selection list of structures to
103 DefaultListModel<FullBackup> dlm = new DefaultListModel<>();
105 int marginTools = 40;
107 DefaultListSelectionModel m = new DefaultListSelectionModel();
108 m.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
109 m.setLeadAnchorNotificationEnabled(false);
111 _sideList = new ReorderableJList();
112 _sideList.setModel(dlm);
113 _sideList.addMouseListener(new MouseAdapter()
116 public void mouseClicked(MouseEvent e)
118 AppVarnaBinding.this.mouseClicked(e);
121 _sideList.setSelectionModel(m);
122 _sideList.setPreferredSize(new Dimension(100, 0));
123 _sideList.addListSelectionListener(new ListSelectionListener()
126 public void valueChanged(ListSelectionEvent evt)
128 changeSelectedStructure_actionPerformed(evt);
131 _rnaList = new BackupHolder(dlm, _sideList);
135 vp = new VARNAPanel("0", ".");
136 } catch (ExceptionNonEqualLength e)
140 vp.setPreferredSize(new Dimension(400, 400));
142 JScrollPane listScroller = new JScrollPane(_sideList);
143 listScroller.setPreferredSize(new Dimension(150, 0));
145 vp.setBackground(_backgroundColor);
147 JLabel j = new JLabel(
148 MessageManager.getString("label.structures_manager"),
150 _listPanel.setLayout(new BorderLayout());
152 _listPanel.add(j, BorderLayout.NORTH);
153 _listPanel.add(listScroller, BorderLayout.CENTER);
155 new DropTarget(vp, new DropTargetAdapter()
158 public void drop(DropTargetDropEvent dtde)
160 AppVarnaBinding.this.drop(dtde);
165 public JPanel getListPanel()
171 * Returns the currently selected RNA, or null if none selected
175 public RNA getSelectedRNA()
177 int selectedIndex = _sideList.getSelectedIndex();
178 if (selectedIndex < 0)
182 FullBackup selected = _rnaList.getElementAt(selectedIndex);
187 * Substitute currently selected RNA with the edited one
191 public void updateSelectedRNA(RNA rnaEdit)
197 public static String generateDefaultName()
199 return "User file #" + _nextID++;
202 public String[][] getParameterInfo()
205 // Parameter Name Kind of Value Description,
206 { "sequenceDBN", "String", "A raw RNA sequence" },
207 { "structureDBN", "String",
208 "An RNA structure in dot bracket notation (DBN)" },
209 { errorOpt, "boolean", "To show errors" }, };
213 @SuppressWarnings("unused")
214 private Color getSafeColor(String col, Color def)
219 result = Color.decode(col);
220 } catch (Exception e)
224 result = Color.getColor(col, def);
225 } catch (Exception e2)
233 public VARNAPanel get_varnaPanel()
238 public void set_varnaPanel(VARNAPanel surface)
243 public void drop(DropTargetDropEvent dtde)
247 Transferable tr = dtde.getTransferable();
248 DataFlavor[] flavors = tr.getTransferDataFlavors();
249 for (int i = 0; i < flavors.length; i++)
251 if (flavors[i].isFlavorJavaFileListType())
253 dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
254 Object ob = tr.getTransferData(flavors[i]);
255 if (ob instanceof List)
257 List list = (List) ob;
258 for (int j = 0; j < list.size(); j++)
260 Object o = list.get(j);
262 if (dtde.getSource() instanceof DropTarget)
264 DropTarget dt = (DropTarget) dtde.getSource();
265 Component c = dt.getComponent();
266 if (c instanceof VARNAPanel)
268 String path = o.toString();
269 VARNAPanel varnaPanel = (VARNAPanel) c;
272 FullBackup bck = VARNAPanel.importSession(path);
273 _rnaList.add(bck.config, bck.rna, bck.name, true);
274 } catch (ExceptionLoadingFailed e3)
277 Collection<RNA> mdls = fr.orsay.lri.varna.factories.RNAFactory
281 r.drawRNA(varnaPanel.getConfig());
282 String name = r.getName();
285 name = path.substring(
286 path.lastIndexOf(File.separatorChar) + 1);
290 name += " (Model " + mn++ + ")";
292 _rnaList.add(varnaPanel.getConfig().clone(), r, name,
294 // BH 2018 SwingJS clone of varnaPanel or its config will be the object itself, not a clone
301 // If we made it this far, everything worked.
302 dtde.dropComplete(true);
306 // Hmm, the user must not have dropped a file list
308 } catch (Exception e)
316 private class BackupHolder
318 private DefaultListModel<FullBackup> _rnalist;
320 private List<RNA> _rnas = new ArrayList<>();
324 public BackupHolder(DefaultListModel<FullBackup> rnaList, JList l)
330 public void add(VARNAConfig c, RNA r, String name)
332 add(c, r, name, false);
336 * Adds an entry to the end of the selection list and (optionally) sets it
344 public void add(VARNAConfig c, RNA r, String name, boolean select)
348 _l.removeSelectionInterval(0, _rnalist.size());
352 name = generateDefaultName();
354 FullBackup bck = new FullBackup(c, r, name);
356 _rnalist.addElement(bck);
359 _l.setSelectedIndex(0);
363 public FullBackup getElementAt(int i)
365 return _rnalist.getElementAt(i);
369 public void mouseClicked(MouseEvent e)
371 if (e.getClickCount() == 2)
373 int index = _sideList.locationToIndex(e.getPoint());
374 ListModel<FullBackup> dlm = _sideList.getModel();
375 // FullBackup item = dlm.getElementAt(index);
377 _sideList.ensureIndexIsVisible(index);
379 * TODO Object newName = JvOptionPane.showInputDialog( this,
380 * "Specify a new name for this RNA", "Rename RNA",
381 * JvOptionPane.QUESTION_MESSAGE, (Icon)null, null, item.toString()); if
382 * (newName!=null) { item.name = newName.toString();
383 * this._sideList.repaint(); }
389 public String[] getStructureFiles()
395 public void releaseReferences(Object svl)
400 public void updateColours(Object source)
405 public void componentHidden(ComponentEvent e)
410 public void componentMoved(ComponentEvent e)
415 public void componentResized(ComponentEvent e)
420 public void componentShown(ComponentEvent e)
425 public void highlightAtoms(List<AtomSpec> atoms)
430 public boolean isListeningFor(SequenceI seq)
436 * Returns the path to a temporary file containing a representation of the
437 * state of the Varna display, or null on any error
444 public String getStateInfo(RNA rna)
452 * we have to show the RNA we want to save in the viewer; get the currently
453 * displayed model first so we can restore it
455 FullBackup sel = (FullBackup) _sideList.getSelectedValue();
457 FullBackup model = null;
458 ListModel models = _sideList.getModel();
459 for (int i = 0; i < models.getSize(); i++)
461 model = (FullBackup) models.getElementAt(i);
462 if (model.rna == rna)
475 vp.showRNA(model.rna, model.config);
480 temp = File.createTempFile("varna", null);
482 String filePath = temp.getAbsolutePath();
486 * restore the previous display
488 vp.showRNA(sel.rna, sel.config);
491 } catch (IOException e)
497 public int getSelectedIndex()
499 return _sideList.getSelectedIndex();
503 * Switch the Varna display to the structure selected in the left hand panel
507 protected void changeSelectedStructure_actionPerformed(
508 ListSelectionEvent evt)
510 if (!evt.getValueIsAdjusting())
512 showSelectedStructure();
519 protected void showSelectedStructure()
521 FullBackup sel = (FullBackup) _sideList.getSelectedValue();
524 vp.showRNA(sel.rna, sel.config);
529 * Set and display the selected item in the list of structures
533 public void setSelectedIndex(final int selectedRna)
536 * note this does nothing if, say, selecting item 3 when only 1 has been
539 _sideList.setSelectedIndex(selectedRna);
540 // TODO ? need a worker thread to get this to happen properly
544 * Add an RNA structure to the selection list
548 public void addStructure(RNA rna)
550 VARNAConfig config = vp.getConfig().clone(); // BH 2018 this will NOT be a clone in SwingJS
551 addStructure(rna, config);
558 protected void addStructure(final RNA rna, final VARNAConfig config)
560 drawRna(rna, config);
561 _rnaList.add(config, rna, rna.getName());
568 protected void drawRna(final RNA rna, final VARNAConfig config)
572 rna.drawRNA(rna.getDrawMode(), config);
573 } catch (ExceptionNAViewAlgorithm e)
575 // only throwable for draw mode = 3 NAView
576 System.err.println("Error drawing RNA: " + e.getMessage());