2 VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3 Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty.
4 electronic mail : Yann.Ponty@lri.fr
5 paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
7 This file is part of VARNA version 3.1.
8 VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16 If not, see http://www.gnu.org/licenses.
18 package fr.orsay.lri.varna.applications.newGUI;
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Component;
23 import java.awt.Dimension;
24 import java.awt.GridLayout;
25 import java.awt.datatransfer.DataFlavor;
26 import java.awt.datatransfer.Transferable;
27 import java.awt.datatransfer.UnsupportedFlavorException;
28 import java.awt.dnd.DropTarget;
29 import java.awt.dnd.DropTargetDragEvent;
30 import java.awt.dnd.DropTargetDropEvent;
31 import java.awt.dnd.DropTargetEvent;
32 import java.awt.dnd.DropTargetListener;
33 import java.awt.event.ActionEvent;
34 import java.awt.event.ActionListener;
35 import java.awt.event.ComponentEvent;
36 import java.awt.event.ComponentListener;
37 import java.awt.event.FocusEvent;
38 import java.awt.event.FocusListener;
39 import java.awt.event.MouseEvent;
40 import java.awt.event.MouseListener;
41 import java.awt.event.WindowEvent;
42 import java.awt.event.WindowListener;
43 import java.io.IOException;
44 import java.util.ArrayList;
46 import javax.swing.BorderFactory;
47 import javax.swing.ButtonGroup;
48 import javax.swing.DefaultListSelectionModel;
49 import javax.swing.JButton;
50 import javax.swing.JComponent;
51 import javax.swing.JFileChooser;
52 import javax.swing.JFrame;
53 import javax.swing.JLabel;
54 import javax.swing.JList;
55 import javax.swing.JOptionPane;
56 import javax.swing.JPanel;
57 import javax.swing.JRadioButton;
58 import javax.swing.JScrollPane;
59 import javax.swing.JSplitPane;
60 import javax.swing.JTextPane;
61 import javax.swing.JToolBar;
62 import javax.swing.JTree;
63 import javax.swing.ListSelectionModel;
64 import javax.swing.TransferHandler;
65 import javax.swing.UIManager;
66 import javax.swing.UIManager.LookAndFeelInfo;
67 import javax.swing.event.TreeModelEvent;
68 import javax.swing.event.TreeModelListener;
69 import javax.swing.tree.DefaultMutableTreeNode;
70 import javax.swing.tree.TreePath;
71 import javax.swing.tree.TreeSelectionModel;
73 import fr.orsay.lri.varna.VARNAPanel;
74 import fr.orsay.lri.varna.applications.BasicINI;
75 import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
78 public class VARNAGUI extends JFrame implements TreeModelListener, MouseListener,DropTargetListener, WindowListener, ComponentListener, ActionListener {
96 private static final long serialVersionUID = -790155708306987257L;
100 private String _INIFilename = "FragSeqUI.ini";
101 private Color _backgroundColor = Color.white;
102 private boolean redrawOnSlide = false;
103 private int dividerWidth = 5;
105 private JPanel _varnaUpperPanels = new JPanel();
106 private JPanel _varnaLowerPanels = new JPanel();
108 private JPanel _listPanel = new JPanel();
109 private JPanel _infoPanel = new JPanel();
110 private VARNAGUITree _sideList = null;
113 private VARNAGUITreeModel _treeModel;
114 private JToolBar _toolbar = new JToolBar();
115 private JFileChooser _choice = new JFileChooser();
117 private JScrollPane _listScroller;
119 private JList _selectedElems;
120 private JSplitPane _splitLeft;
121 private JSplitPane _splitRight;
122 private JSplitPane _splitVARNA;
127 super("VARNA Explorer");
132 private void RNAPanelDemoInit()
134 JFrame.setDefaultLookAndFeelDecorated(true);
135 this.addWindowListener(this);
137 _selectedElems = new JList();
139 // Initializing Custom Tree Model
140 _treeModel = new VARNAGUITreeModel();
141 _treeModel.addTreeModelListener(this);
143 _sideList = new VARNAGUITree(_treeModel);
144 _sideList.addMouseListener(this);
145 _sideList.setLargeModel(true);
146 _sideList.setEditable(true);
147 VARNAGUIRenderer renderer = new VARNAGUIRenderer(_sideList,_treeModel);
148 //_sideList.setUI(new CustomTreeUI());
149 _sideList.setCellRenderer(renderer);
150 _sideList.setCellEditor(new VARNAGUICellEditor(_sideList,renderer,_treeModel));
151 TreeSelectionModel m = _sideList.getSelectionModel();
152 m.setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
153 _sideList.setSelectionModel(m);
154 _sideList.setShowsRootHandles(true);
155 _sideList.setDragEnabled(true);
156 _sideList.setRootVisible(false);
157 _sideList.setTransferHandler(new TransferHandler(null)
159 public int getSourceActions(JComponent c) {
162 protected Transferable createTransferable(JComponent c) {
163 JTree tree = (JTree) c;
164 TreePath tp =tree.getSelectionPath();
167 DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
168 if (node.getUserObject() instanceof VARNAGUIModel) {
169 return new Transferable(){
170 public DataFlavor[] getTransferDataFlavors() {
171 DataFlavor[] dt = {VARNAGUIModel.Flavor};
174 public Object getTransferData(DataFlavor df)
175 throws UnsupportedFlavorException, IOException {
176 if (!isDataFlavorSupported(df))
177 throw new UnsupportedFlavorException(df);
178 DefaultMutableTreeNode node = (DefaultMutableTreeNode) _sideList.getSelectionPath().getLastPathComponent();
179 return node.getUserObject();
181 public boolean isDataFlavorSupported(DataFlavor df) {
182 return VARNAGUIModel.Flavor.equals(df);
194 JButton refreshAllFoldersButton = new JButton("Refresh All");
195 refreshAllFoldersButton.setActionCommand(""+Commands.REFRESH_ALL);
196 refreshAllFoldersButton.addActionListener(this);
197 JButton watchFolderButton = new JButton("Add folder");
198 watchFolderButton.setActionCommand("" +Commands.NEW_FOLDER);
199 watchFolderButton.addActionListener(this);
200 JButton addUpperButton = new JButton("+Up");
201 addUpperButton.setActionCommand(""+Commands.ADD_PANEL_UP);
202 addUpperButton.addActionListener(this);
203 JButton removeUpperButton = new JButton("-Up");
204 removeUpperButton.setActionCommand(""+Commands.REMOVE_PANEL_UP);
205 removeUpperButton.addActionListener(this);
206 JButton addLowerButton = new JButton("+Down");
207 addLowerButton.setActionCommand(""+Commands.ADD_PANEL_DOWN);
208 addLowerButton.addActionListener(this);
209 JButton removeLowerButton = new JButton("-Down");
210 removeLowerButton.setActionCommand(""+Commands.REMOVE_PANEL_DOWN);
211 removeLowerButton.addActionListener(this);
213 _toolbar.setFloatable(false);
214 _toolbar.add(refreshAllFoldersButton);
215 _toolbar.addSeparator();
216 _toolbar.add(addUpperButton);
217 _toolbar.add(removeUpperButton);
218 _toolbar.add(addLowerButton);
219 _toolbar.add(removeLowerButton);
221 // Scroller for File tree
222 _listScroller = new JScrollPane(_sideList,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
223 _listScroller.setPreferredSize(new Dimension(300, 200));
224 _listScroller.addComponentListener(this);
227 _listPanel.setLayout(new BorderLayout());
229 _listPanel.add(_listScroller,BorderLayout.CENTER);
230 _listPanel.add(_selectedElems,BorderLayout.SOUTH);
231 _listPanel.setBorder(BorderFactory.createTitledBorder("Structures"));
232 _listPanel.setPreferredSize(new Dimension(300, 0));
234 _varnaUpperPanels.setLayout(new GridLayout());
235 _varnaUpperPanels.setPreferredSize(new Dimension(800, 600));
237 _varnaLowerPanels.setLayout(new GridLayout());
238 _varnaLowerPanels.setPreferredSize(new Dimension(800, 000));
240 JRadioButton sortFileName = new JRadioButton("Filename");
241 sortFileName.setActionCommand("sortfilename");
242 sortFileName.setSelected(true);
243 sortFileName.setOpaque(false);
244 sortFileName.setActionCommand(""+Commands.SORT_FILENAME);
245 sortFileName.addActionListener(this);
246 JRadioButton sortID = new JRadioButton("ID");
247 sortID.setActionCommand("sortid");
248 sortID.setOpaque(false);
249 sortID.setActionCommand(""+Commands.SORT_ID);
250 sortID.addActionListener(this);
252 ButtonGroup group = new ButtonGroup();
253 group.add(sortFileName);
256 JToolBar listTools = new JToolBar();
257 listTools.setFloatable(false);
258 listTools.add(watchFolderButton);
259 listTools.addSeparator();
260 listTools.add(new JLabel("Sort by"));
261 listTools.add(sortFileName);
262 listTools.add(sortID);
264 JPanel sidePanel = new JPanel();
265 sidePanel.setLayout(new BorderLayout());
266 sidePanel.add(listTools,BorderLayout.NORTH);
267 sidePanel.add(_listPanel,BorderLayout.CENTER);
270 JPanel mainVARNAPanel = new JPanel();
271 mainVARNAPanel.setLayout(new BorderLayout());
272 _splitVARNA = new JSplitPane(JSplitPane.VERTICAL_SPLIT,redrawOnSlide,_varnaUpperPanels,_varnaLowerPanels);
273 _splitVARNA.setDividerSize(dividerWidth);
274 _splitVARNA.setResizeWeight(1.0);
275 _splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,redrawOnSlide,sidePanel,_splitVARNA);
276 _splitLeft.setResizeWeight(0.1);
277 _splitLeft.setDividerSize(dividerWidth);
278 _splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,redrawOnSlide,_splitLeft,_infoPanel);
279 _splitRight.setResizeWeight(0.85);
280 _splitRight.setDividerSize(dividerWidth);
282 _infoPanel.setLayout(new GridLayout(0,1));
284 this.restoreConfig();
285 this.setBackground(_backgroundColor);
286 this.getContentPane().setLayout(new BorderLayout());
287 this.getContentPane().add(_splitRight, BorderLayout.CENTER);
288 this.getContentPane().add(_toolbar, BorderLayout.NORTH);
290 this.setVisible(true);
293 public VARNAGUI getSelf()
298 public VARNAHolder createIntegratedPanel(int height)
300 VARNAHolder vh = new VARNAHolder(this);
301 _varnaPanels.add(vh);
306 public void removeUpperPanel()
308 if (_varnaUpperPanels.getComponentCount()>1)
310 VARNAHolder vh = (VARNAHolder) _varnaUpperPanels.getComponent(_varnaUpperPanels.getComponentCount()-1);
311 _infoPanel.remove(vh.getInfoPane());
312 _varnaUpperPanels.remove(vh);
313 _splitLeft.validate();
314 _splitRight.validate();
318 public void addUpperPanel()
320 VARNAHolder vh = createIntegratedPanel(100);
321 _varnaUpperPanels.add(vh);
322 _infoPanel.add(vh.getInfoPane());
323 _splitRight.validate();
324 _splitLeft.validate();
328 public void removeLowerPanel()
330 if (_varnaLowerPanels.getComponentCount()>0)
332 _varnaLowerPanels.remove(_varnaLowerPanels.getComponentCount()-1);
333 if (_varnaLowerPanels.getComponentCount()==0)
335 _splitVARNA.setDividerLocation(1.0);
336 _splitVARNA.validate();
337 _splitVARNA.repaint();
339 _splitLeft.validate();
343 public void addLowerPanel()
345 if (_varnaLowerPanels.getComponentCount()==0)
347 _splitVARNA.setDividerLocation(0.7);
348 _splitVARNA.validate();
350 _varnaLowerPanels.add(createIntegratedPanel(400));
351 _splitLeft.validate();
354 public static void main(String[] args) {
356 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
357 if ("Nimbus".equals(info.getName())) {
358 UIManager.setLookAndFeel(info.getClassName());
362 } catch (Exception e) {
363 // If Nimbus is not available, you can set the GUI to another look and feel.
365 VARNAGUI d = new VARNAGUI();
366 d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
371 public void treeNodesChanged(TreeModelEvent e) {
372 DefaultMutableTreeNode node;
373 node = (DefaultMutableTreeNode)
374 (e.getTreePath().getLastPathComponent());
377 * If the event lists children, then the changed
378 * node is the child of the node we have already
379 * gotten. Otherwise, the changed node and the
380 * specified node are the same.
383 int index = e.getChildIndices()[0];
384 node = (DefaultMutableTreeNode)
385 (node.getChildAt(index));
386 } catch (NullPointerException exc) {}
393 public void addFolder(String path) {
394 addFolder( path, true);
397 public void addFolder(String path,
398 boolean shouldBeVisible)
400 DefaultMutableTreeNode childNode = _treeModel.addFolder(path);
402 if ((childNode!=null) && shouldBeVisible ) {
403 System.out.println(" Expanding: "+childNode.getUserObject());
404 TreePath tp = new TreePath(childNode.getPath());
405 _sideList.scrollPathToVisible(tp);
406 _sideList.expandRow(_sideList.getRowForPath(tp));
407 _sideList.updateUI();
408 _sideList.validate();
412 public void treeNodesInserted(TreeModelEvent e) {
413 System.out.println(e);
417 public void treeNodesRemoved(TreeModelEvent e) {
418 // TODO Auto-generated method stub
422 public void treeStructureChanged(TreeModelEvent e) {
423 // TODO Auto-generated method stub
427 public void mouseClicked(MouseEvent e) {
428 // TODO Auto-generated method stub
432 public void mousePressed(MouseEvent e) {
438 public void mouseReleased(MouseEvent e) {
439 // TODO Auto-generated method stub
440 if (e.getSource() == this._sideList)
442 if (e.getClickCount() == 2)
444 TreePath t = _sideList.getSelectionPath();
447 DefaultMutableTreeNode node = (DefaultMutableTreeNode) t.getLastPathComponent();
448 if (node.getUserObject() instanceof VARNAGUIModel)
450 VARNAGUIModel model = (VARNAGUIModel) node.getUserObject();
451 int res = index % (_varnaUpperPanels.getComponentCount()+_varnaLowerPanels.getComponentCount());
453 if (res<_varnaUpperPanels.getComponentCount())
455 c = (VARNAHolder)_varnaUpperPanels.getComponent(res);
459 res -= _varnaUpperPanels.getComponentCount();
460 c = (VARNAHolder)_varnaLowerPanels.getComponent(res);
462 if (c instanceof VARNAHolder)
464 VARNAHolder h = (VARNAHolder) c;
477 class VARNAHolder extends JPanel
483 public VARNAHolder(DropTargetListener f)
486 vp = new VARNAPanel();
487 vp.addFocusListener(new FocusListener(){
488 public void focusGained(FocusEvent e) {
491 public void focusLost(FocusEvent e) {
493 vp.setPreferredSize(new Dimension(800, 400));
494 vp.setBackground(_backgroundColor);
496 _infoTxt = new JTextPane();
497 _infoTxt.setPreferredSize(new Dimension(200,0));
498 _infoTxt.setContentType("text/html");
500 JScrollPane scroll = new JScrollPane(_infoTxt,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
502 _infoPanel = new JPanel();
503 _infoPanel.setLayout(new BorderLayout());
504 _infoPanel.setPreferredSize(new Dimension(200,0));
505 _infoPanel.setBorder(BorderFactory.createTitledBorder("Info"));
506 _infoPanel.add(scroll,BorderLayout.CENTER);
507 _infoPanel.validate();
509 this.setLayout(new BorderLayout());
510 this.setPreferredSize(new Dimension(300,600));
511 this.setBorder(BorderFactory.createTitledBorder("None"));
512 this.add(vp, BorderLayout.CENTER);
514 DropTarget dt = new DropTarget(vp, f);
517 VARNAPanel getVARNAPanel()
521 void setModel(VARNAGUIModel m)
524 vp.showRNAInterpolated(m.getRNA());
525 setBorder(BorderFactory.createTitledBorder(m.toString()));
526 _infoTxt.setText(m.getRNA().getHTMLDescription());
527 _infoPanel.setBorder(BorderFactory.createTitledBorder("Info ("+_m+")"));
530 VARNAGUIModel getModel()
532 setBorder(BorderFactory.createTitledBorder(_m.toString()));
535 public void setInfoTxt(String s)
537 _infoTxt.setText(vp.getRNA().getHTMLDescription());
540 public JPanel getInfoPane()
548 private ArrayList<VARNAHolder> _varnaPanels = new ArrayList<VARNAHolder>();
550 private VARNAHolder getHolder(Component vp)
552 if (vp instanceof VARNAHolder)
554 int i= _varnaPanels.indexOf(vp);
557 return _varnaPanels.get(i);
560 if (vp instanceof VARNAPanel)
562 for (VARNAHolder vh: _varnaPanels)
564 if (vh.getVARNAPanel()==vp)
573 public void mouseEntered(MouseEvent e) {
574 // TODO Auto-generated method stub
578 public void mouseExited(MouseEvent e) {
579 // TODO Auto-generated method stub
583 public void dragEnter(DropTargetDragEvent arg0) {
584 // TODO Auto-generated method stub
588 public void dragExit(DropTargetEvent arg0) {
589 // TODO Auto-generated method stub
593 public void dragOver(DropTargetDragEvent arg0) {
597 public void drop(DropTargetDropEvent arg0) {
600 DropTarget o = (DropTarget)arg0.getSource();
601 if (o.getComponent() instanceof VARNAPanel)
603 VARNAHolder h = getHolder(o.getComponent());
606 h.setModel((VARNAGUIModel) arg0.getTransferable().getTransferData(VARNAGUIModel.Flavor));
609 } catch (UnsupportedFlavorException e) {
610 // TODO Auto-generated catch block
612 } catch (IOException e) {
613 // TODO Auto-generated catch block
618 public void dropActionChanged(DropTargetDragEvent arg0) {
619 // TODO Auto-generated method stub
623 public void windowOpened(WindowEvent e) {
624 // TODO Auto-generated method stub
628 public void windowClosing(WindowEvent e) {
633 public void windowClosed(WindowEvent e) {
634 // TODO Auto-generated method stub
638 public void windowIconified(WindowEvent e) {
639 // TODO Auto-generated method stub
643 public void windowDeiconified(WindowEvent e) {
644 // TODO Auto-generated method stub
648 public void windowActivated(WindowEvent e) {
649 // TODO Auto-generated method stub
653 public void windowDeactivated(WindowEvent e) {
654 // TODO Auto-generated method stub
658 private void restoreConfig()
660 BasicINI config = BasicINI.loadINI(_INIFilename);
661 ArrayList<String> vals = config.getItemList("folders");
662 System.out.print("[C]"+vals);
664 for(String path:vals)
666 System.out.println("Loading folder "+path);
669 _sideList.validate();
670 _listScroller.validate();
673 private void saveConfig()
675 BasicINI data = new BasicINI();
677 for (String folderPath: _treeModel.getFolders())
679 data.addItem("folders", "val"+i, folderPath);
682 BasicINI.saveINI(data, _INIFilename);
686 public void componentResized(ComponentEvent e) {
687 _sideList.validate();
691 public void componentMoved(ComponentEvent e) {
692 // TODO Auto-generated method stub
697 public void componentShown(ComponentEvent e) {
698 // TODO Auto-generated method stub
703 public void componentHidden(ComponentEvent e) {
704 // TODO Auto-generated method stub
709 public void actionPerformed(ActionEvent e) {
710 String cmd = e.getActionCommand();
711 System.out.println(cmd);
712 if (cmd.equals(""+Commands.NEW_FOLDER))
714 _choice.setDialogTitle("Watch new folder...");
715 _choice.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
716 _choice.setAcceptAllFileFilterUsed(false);
718 if (_choice.showOpenDialog(getSelf()) == JFileChooser.APPROVE_OPTION) {
719 addFolder(_choice.getSelectedFile().getCanonicalPath());
722 System.out.println("No Selection ");
724 } catch (IOException e1) {
725 e1.printStackTrace();
728 else if (cmd.equals(""+Commands.ADD_PANEL_DOWN))
732 else if (cmd.equals(""+Commands.ADD_PANEL_UP))
736 else if (cmd.equals(""+Commands.REMOVE_PANEL_DOWN))
740 else if (cmd.equals(""+Commands.REMOVE_PANEL_UP))
746 JOptionPane.showMessageDialog(this, "Command '"+cmd+"' not implemented yet.");