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 static jalview.util.UrlConstants.EMBLEBI_STRING;
24 import static jalview.util.UrlConstants.SEQUENCE_ID;
26 import jalview.api.AlignViewportI;
27 import jalview.api.AlignmentViewPanel;
28 import jalview.bin.Cache;
29 import jalview.bin.Jalview;
30 import jalview.io.DataSourceType;
31 import jalview.io.FileFormat;
32 import jalview.io.FileFormatException;
33 import jalview.io.FileFormatI;
34 import jalview.io.FileLoader;
35 import jalview.io.IdentifyFile;
36 import jalview.io.JalviewFileChooser;
37 import jalview.io.JalviewFileView;
38 import jalview.jbgui.GSplitFrame;
39 import jalview.jbgui.GStructureViewer;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.util.ImageMaker;
42 import jalview.util.MessageManager;
43 import jalview.util.Platform;
44 import jalview.viewmodel.AlignmentViewport;
45 import jalview.ws.params.ParamManager;
47 import java.awt.BorderLayout;
48 import java.awt.Color;
49 import java.awt.Dimension;
50 import java.awt.FontMetrics;
51 import java.awt.Graphics;
52 import java.awt.GridLayout;
53 import java.awt.Point;
54 import java.awt.Rectangle;
55 import java.awt.Toolkit;
56 import java.awt.Window;
57 import java.awt.datatransfer.Clipboard;
58 import java.awt.datatransfer.ClipboardOwner;
59 import java.awt.datatransfer.DataFlavor;
60 import java.awt.datatransfer.Transferable;
61 import java.awt.dnd.DnDConstants;
62 import java.awt.dnd.DropTargetDragEvent;
63 import java.awt.dnd.DropTargetDropEvent;
64 import java.awt.dnd.DropTargetEvent;
65 import java.awt.dnd.DropTargetListener;
66 import java.awt.event.ActionEvent;
67 import java.awt.event.ActionListener;
68 import java.awt.event.FocusEvent;
69 import java.awt.event.FocusListener;
70 import java.awt.event.KeyEvent;
71 import java.awt.event.MouseAdapter;
72 import java.awt.event.MouseEvent;
73 import java.awt.event.WindowAdapter;
74 import java.awt.event.WindowEvent;
75 import java.beans.PropertyChangeEvent;
76 import java.beans.PropertyChangeListener;
77 import java.io.BufferedInputStream;
79 import java.io.FileOutputStream;
81 import java.util.ArrayList;
82 import java.util.Hashtable;
83 import java.util.List;
84 import java.util.ListIterator;
85 import java.util.StringTokenizer;
86 import java.util.Vector;
87 import java.util.concurrent.ExecutorService;
88 import java.util.concurrent.Executors;
89 import java.util.concurrent.Semaphore;
91 import javax.swing.AbstractAction;
92 import javax.swing.Box;
93 import javax.swing.BoxLayout;
94 import javax.swing.DefaultDesktopManager;
95 import javax.swing.DesktopManager;
96 import javax.swing.JButton;
97 import javax.swing.JCheckBox;
98 import javax.swing.JComboBox;
99 import javax.swing.JComponent;
100 import javax.swing.JDesktopPane;
101 import javax.swing.JFrame;
102 import javax.swing.JInternalFrame;
103 import javax.swing.JLabel;
104 import javax.swing.JMenuItem;
105 import javax.swing.JPanel;
106 import javax.swing.JPopupMenu;
107 import javax.swing.JProgressBar;
108 import javax.swing.KeyStroke;
109 import javax.swing.SwingUtilities;
110 import javax.swing.event.HyperlinkEvent;
111 import javax.swing.event.HyperlinkEvent.EventType;
112 import javax.swing.event.InternalFrameAdapter;
113 import javax.swing.event.InternalFrameEvent;
114 import javax.swing.event.MenuEvent;
115 import javax.swing.event.MenuListener;
122 * @version $Revision: 1.155 $
124 public class Desktop extends jalview.jbgui.GDesktop implements
125 DropTargetListener, ClipboardOwner, IProgressIndicator,
126 jalview.api.StructureSelectionManagerProvider
129 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
132 * news reader - null if it was never started.
134 private BlogReader jvnews = null;
136 private File projectFile;
140 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
142 public void addJalviewPropertyChangeListener(
143 PropertyChangeListener listener)
145 changeSupport.addJalviewPropertyChangeListener(listener);
149 * @param propertyName
151 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
152 * java.beans.PropertyChangeListener)
154 public void addJalviewPropertyChangeListener(String propertyName,
155 PropertyChangeListener listener)
157 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
161 * @param propertyName
163 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
164 * java.beans.PropertyChangeListener)
166 public void removeJalviewPropertyChangeListener(String propertyName,
167 PropertyChangeListener listener)
169 changeSupport.removeJalviewPropertyChangeListener(propertyName,
173 /** Singleton Desktop instance */
174 public static Desktop instance;
176 public static MyDesktopPane desktop;
178 static int openFrameCount = 0;
180 static final int xOffset = 30;
182 static final int yOffset = 30;
184 public static jalview.ws.jws1.Discoverer discoverer;
186 public static Object[] jalviewClipboard;
188 public static boolean internalCopy = false;
190 static int fileLoadingCount = 0;
192 class MyDesktopManager implements DesktopManager
195 private DesktopManager delegate;
197 public MyDesktopManager(DesktopManager delegate)
199 this.delegate = delegate;
203 public void activateFrame(JInternalFrame f)
207 delegate.activateFrame(f);
208 } catch (NullPointerException npe)
210 Point p = getMousePosition();
211 instance.showPasteMenu(p.x, p.y);
216 public void beginDraggingFrame(JComponent f)
218 delegate.beginDraggingFrame(f);
222 public void beginResizingFrame(JComponent f, int direction)
224 delegate.beginResizingFrame(f, direction);
228 public void closeFrame(JInternalFrame f)
230 delegate.closeFrame(f);
234 public void deactivateFrame(JInternalFrame f)
236 delegate.deactivateFrame(f);
240 public void deiconifyFrame(JInternalFrame f)
242 delegate.deiconifyFrame(f);
246 public void dragFrame(JComponent f, int newX, int newY)
252 delegate.dragFrame(f, newX, newY);
256 public void endDraggingFrame(JComponent f)
258 delegate.endDraggingFrame(f);
262 public void endResizingFrame(JComponent f)
264 delegate.endResizingFrame(f);
268 public void iconifyFrame(JInternalFrame f)
270 delegate.iconifyFrame(f);
274 public void maximizeFrame(JInternalFrame f)
276 delegate.maximizeFrame(f);
280 public void minimizeFrame(JInternalFrame f)
282 delegate.minimizeFrame(f);
286 public void openFrame(JInternalFrame f)
288 delegate.openFrame(f);
292 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
299 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
303 public void setBoundsForFrame(JComponent f, int newX, int newY,
304 int newWidth, int newHeight)
306 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
309 // All other methods, simply delegate
314 * Creates a new Desktop object.
319 * A note to implementors. It is ESSENTIAL that any activities that might
320 * block are spawned off as threads rather than waited for during this
324 doVamsasClientCheck();
326 groovyShell = new JMenuItem();
327 groovyShell.setText(MessageManager.getString("label.groovy_console"));
328 groovyShell.addActionListener(new ActionListener()
331 public void actionPerformed(ActionEvent e)
333 groovyShell_actionPerformed();
336 toolsMenu.add(groovyShell);
337 groovyShell.setVisible(true);
339 doConfigureStructurePrefs();
340 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
341 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
342 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
344 boolean showjconsole = jalview.bin.Cache.getDefault(
345 "SHOW_JAVA_CONSOLE", false);
346 desktop = new MyDesktopPane(selmemusage);
347 if (Platform.isAMac())
349 desktop.setDoubleBuffered(false);
351 showMemusage.setSelected(selmemusage);
352 desktop.setBackground(Color.white);
353 getContentPane().setLayout(new BorderLayout());
354 // alternate config - have scrollbars - see notes in JAL-153
355 // JScrollPane sp = new JScrollPane();
356 // sp.getViewport().setView(desktop);
357 // getContentPane().add(sp, BorderLayout.CENTER);
358 getContentPane().add(desktop, BorderLayout.CENTER);
359 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
361 // This line prevents Windows Look&Feel resizing all new windows to maximum
362 // if previous window was maximised
363 desktop.setDesktopManager(new MyDesktopManager(
364 new DefaultDesktopManager()));
366 Rectangle dims = getLastKnownDimensions("");
373 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
374 setBounds((screenSize.width - 900) / 2,
375 (screenSize.height - 650) / 2, 900, 650);
377 jconsole = new Console(this, showjconsole);
378 // add essential build information
379 jconsole.setHeader("Jalview Version: "
380 + jalview.bin.Cache.getProperty("VERSION") + "\n"
381 + "Jalview Installation: "
382 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
383 + "\n" + "Build Date: "
384 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
385 + "Java version: " + System.getProperty("java.version") + "\n"
386 + System.getProperty("os.arch") + " "
387 + System.getProperty("os.name") + " "
388 + System.getProperty("os.version"));
390 showConsole(showjconsole);
392 showNews.setVisible(false);
396 this.addWindowListener(new WindowAdapter()
399 public void windowClosing(WindowEvent evt)
406 this.addMouseListener(ma = new MouseAdapter()
409 public void mousePressed(MouseEvent evt)
411 if (evt.isPopupTrigger()) // Mac
413 showPasteMenu(evt.getX(), evt.getY());
418 public void mouseReleased(MouseEvent evt)
420 if (evt.isPopupTrigger()) // Windows
422 showPasteMenu(evt.getX(), evt.getY());
426 desktop.addMouseListener(ma);
428 this.addFocusListener(new FocusListener()
432 public void focusLost(FocusEvent e)
434 // TODO Auto-generated method stub
439 public void focusGained(FocusEvent e)
441 Cache.log.debug("Relaying windows after focus gain");
442 // make sure that we sort windows properly after we gain focus
443 instance.relayerWindows();
446 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
447 // Spawn a thread that shows the splashscreen
448 SwingUtilities.invokeLater(new Runnable()
457 // Thread off a new instance of the file chooser - this reduces the time it
458 // takes to open it later on.
459 new Thread(new Runnable()
464 Cache.log.debug("Filechooser init thread started.");
465 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
466 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
468 Cache.log.debug("Filechooser init thread finished.");
471 // Add the service change listener
472 changeSupport.addJalviewPropertyChangeListener("services",
473 new PropertyChangeListener()
477 public void propertyChange(PropertyChangeEvent evt)
479 Cache.log.debug("Firing service changed event for "
480 + evt.getNewValue());
481 JalviewServicesChanged(evt);
487 public void doConfigureStructurePrefs()
489 // configure services
490 StructureSelectionManager ssm = StructureSelectionManager
491 .getStructureSelectionManager(this);
492 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
494 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
495 Preferences.ADD_TEMPFACT_ANN, true));
496 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
497 Preferences.STRUCT_FROM_PDB, true));
498 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
499 Preferences.USE_RNAVIEW, true));
503 ssm.setAddTempFacAnnot(false);
504 ssm.setProcessSecondaryStructure(false);
505 ssm.setSecStructServices(false);
509 public void checkForNews()
511 final Desktop me = this;
512 // Thread off the news reader, in case there are connection problems.
513 addDialogThread(new Runnable()
518 Cache.log.debug("Starting news thread.");
520 jvnews = new BlogReader(me);
521 showNews.setVisible(true);
522 Cache.log.debug("Completed news thread.");
528 protected void showNews_actionPerformed(ActionEvent e)
530 showNews(showNews.isSelected());
533 void showNews(boolean visible)
536 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
537 showNews.setSelected(visible);
538 if (visible && !jvnews.isVisible())
540 new Thread(new Runnable()
545 long now = System.currentTimeMillis();
546 Desktop.instance.setProgressBar(
547 MessageManager.getString("status.refreshing_news"), now);
548 jvnews.refreshNews();
549 Desktop.instance.setProgressBar(null, now);
558 * recover the last known dimensions for a jalview window
561 * - empty string is desktop, all other windows have unique prefix
562 * @return null or last known dimensions scaled to current geometry (if last
563 * window geom was known)
565 Rectangle getLastKnownDimensions(String windowName)
567 // TODO: lock aspect ratio for scaling desktop Bug #0058199
568 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
569 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
570 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
571 String width = jalview.bin.Cache.getProperty(windowName
573 String height = jalview.bin.Cache.getProperty(windowName
575 if ((x != null) && (y != null) && (width != null) && (height != null))
577 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
578 .parseInt(width), ih = Integer.parseInt(height);
579 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
581 // attempt #1 - try to cope with change in screen geometry - this
582 // version doesn't preserve original jv aspect ratio.
583 // take ratio of current screen size vs original screen size.
584 double sw = ((1f * screenSize.width) / (1f * Integer
585 .parseInt(jalview.bin.Cache
586 .getProperty("SCREENGEOMETRY_WIDTH"))));
587 double sh = ((1f * screenSize.height) / (1f * Integer
588 .parseInt(jalview.bin.Cache
589 .getProperty("SCREENGEOMETRY_HEIGHT"))));
590 // rescale the bounds depending upon the current screen geometry.
591 ix = (int) (ix * sw);
592 iw = (int) (iw * sw);
593 iy = (int) (iy * sh);
594 ih = (int) (ih * sh);
595 while (ix >= screenSize.width)
597 jalview.bin.Cache.log
598 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
599 ix -= screenSize.width;
601 while (iy >= screenSize.height)
603 jalview.bin.Cache.log
604 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
605 iy -= screenSize.height;
607 jalview.bin.Cache.log.debug("Got last known dimensions for "
608 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
611 // return dimensions for new instance
612 return new Rectangle(ix, iy, iw, ih);
617 private void doVamsasClientCheck()
619 if (jalview.bin.Cache.vamsasJarsPresent())
621 setupVamsasDisconnectedGui();
622 VamsasMenu.setVisible(true);
623 final Desktop us = this;
624 VamsasMenu.addMenuListener(new MenuListener()
626 // this listener remembers when the menu was first selected, and
627 // doesn't rebuild the session list until it has been cleared and
629 boolean refresh = true;
632 public void menuCanceled(MenuEvent e)
638 public void menuDeselected(MenuEvent e)
644 public void menuSelected(MenuEvent e)
648 us.buildVamsasStMenu();
653 vamsasStart.setVisible(true);
657 void showPasteMenu(int x, int y)
659 JPopupMenu popup = new JPopupMenu();
660 JMenuItem item = new JMenuItem(
661 MessageManager.getString("label.paste_new_window"));
662 item.addActionListener(new ActionListener()
665 public void actionPerformed(ActionEvent evt)
672 popup.show(this, x, y);
679 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
680 Transferable contents = c.getContents(this);
682 if (contents != null)
684 String file = (String) contents
685 .getTransferData(DataFlavor.stringFlavor);
687 FileFormatI format = new IdentifyFile().identify(file,
688 DataSourceType.PASTE);
690 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
693 } catch (Exception ex)
696 .println("Unable to paste alignment from system clipboard:\n"
702 * Adds and opens the given frame to the desktop
713 public static synchronized void addInternalFrame(
714 final JInternalFrame frame, String title, int w, int h)
716 addInternalFrame(frame, title, true, w, h, true);
720 * Add an internal frame to the Jalview desktop
727 * When true, display frame immediately, otherwise, caller must call
728 * setVisible themselves.
734 public static synchronized void addInternalFrame(
735 final JInternalFrame frame, String title, boolean makeVisible,
738 addInternalFrame(frame, title, makeVisible, w, h, true);
742 * Add an internal frame to the Jalview desktop and make it visible
755 public static synchronized void addInternalFrame(
756 final JInternalFrame frame, String title, int w, int h,
759 addInternalFrame(frame, title, true, w, h, resizable);
763 * Add an internal frame to the Jalview desktop
770 * When true, display frame immediately, otherwise, caller must call
771 * setVisible themselves.
779 public static synchronized void addInternalFrame(
780 final JInternalFrame frame, String title, boolean makeVisible,
781 int w, int h, boolean resizable)
784 // TODO: allow callers to determine X and Y position of frame (eg. via
786 // TODO: consider fixing method to update entries in the window submenu with
787 // the current window title
789 frame.setTitle(title);
790 if (frame.getWidth() < 1 || frame.getHeight() < 1)
794 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
795 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
796 // IF JALVIEW IS RUNNING HEADLESS
797 // ///////////////////////////////////////////////
799 || (System.getProperty("java.awt.headless") != null && System
800 .getProperty("java.awt.headless").equals("true")))
807 frame.setVisible(makeVisible);
808 frame.setClosable(true);
809 frame.setResizable(resizable);
810 frame.setMaximizable(resizable);
811 frame.setIconifiable(resizable);
812 if (Platform.isAMac())
814 frame.setIconifiable(false);
815 frame.setFrameIcon(null);
816 // frame.setDesktopIcon(null);
817 frame.setDoubleBuffered(false);
819 if (frame.getX() < 1 && frame.getY() < 1)
821 frame.setLocation(xOffset * openFrameCount, yOffset
822 * ((openFrameCount - 1) % 10) + yOffset);
826 * add an entry for the new frame in the Window menu
827 * (and remove it when the frame is closed)
829 final JMenuItem menuItem = new JMenuItem(title);
830 frame.addInternalFrameListener(new InternalFrameAdapter()
833 public void internalFrameActivated(InternalFrameEvent evt)
835 JInternalFrame itf = desktop.getSelectedFrame();
843 public void internalFrameClosed(InternalFrameEvent evt)
845 PaintRefresher.RemoveComponent(frame);
848 * defensive check to prevent frames being
849 * added half off the window
851 if (openFrameCount > 0)
857 * ensure no reference to alignFrame retained by menu item listener
859 if (menuItem.getActionListeners().length > 0)
861 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
863 windowMenu.remove(menuItem);
864 JInternalFrame itf = desktop.getSelectedFrame();
868 if (itf instanceof AlignFrame)
870 Jalview.setCurrentAlignFrame((AlignFrame) itf);
877 menuItem.addActionListener(new ActionListener()
880 public void actionPerformed(ActionEvent e)
884 frame.setSelected(true);
885 frame.setIcon(false);
886 } catch (java.beans.PropertyVetoException ex)
893 windowMenu.add(menuItem);
899 frame.setSelected(true);
900 frame.requestFocus();
901 } catch (java.beans.PropertyVetoException ve)
903 } catch (java.lang.ClassCastException cex)
906 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
912 public void lostOwnership(Clipboard clipboard, Transferable contents)
916 Desktop.jalviewClipboard = null;
919 internalCopy = false;
923 public void dragEnter(DropTargetDragEvent evt)
928 public void dragExit(DropTargetEvent evt)
933 public void dragOver(DropTargetDragEvent evt)
938 public void dropActionChanged(DropTargetDragEvent evt)
949 public void drop(DropTargetDropEvent evt)
951 boolean success = true;
952 // JAL-1552 - acceptDrop required before getTransferable call for
953 // Java's Transferable for native dnd
954 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
955 Transferable t = evt.getTransferable();
956 List<String> files = new ArrayList<String>();
957 List<DataSourceType> protocols = new ArrayList<DataSourceType>();
961 Desktop.transferFromDropTarget(files, protocols, evt, t);
962 } catch (Exception e)
972 for (int i = 0; i < files.size(); i++)
974 String file = files.get(i).toString();
975 DataSourceType protocol = (protocols == null) ? DataSourceType.FILE
977 FileFormatI format = null;
979 if (file.endsWith(".jar"))
981 format = FileFormat.Jalview;
986 format = new IdentifyFile().identify(file, protocol);
989 new FileLoader().LoadFile(file, protocol, format);
992 } catch (Exception ex)
997 evt.dropComplete(success); // need this to ensure input focus is properly
998 // transfered to any new windows created
1008 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1010 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1011 JalviewFileChooser chooser = JalviewFileChooser.forRead(
1012 Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1014 chooser.setFileView(new JalviewFileView());
1015 chooser.setDialogTitle(MessageManager
1016 .getString("label.open_local_file"));
1017 chooser.setToolTipText(MessageManager.getString("action.open"));
1019 int value = chooser.showOpenDialog(this);
1021 if (value == JalviewFileChooser.APPROVE_OPTION)
1023 String choice = chooser.getSelectedFile().getPath();
1024 Cache.setProperty("LAST_DIRECTORY", chooser
1025 .getSelectedFile().getParent());
1027 FileFormatI format = null;
1028 FileFormatI selectedFormat = chooser.getSelectedFormat();
1029 if (FileFormat.Jalview.equals(selectedFormat))
1031 format = FileFormat.Jalview;
1037 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1038 } catch (FileFormatException e)
1044 if (viewport != null)
1046 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1051 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1063 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1065 // This construct allows us to have a wider textfield
1067 JLabel label = new JLabel(
1068 MessageManager.getString("label.input_file_url"));
1069 final JComboBox history = new JComboBox();
1071 JPanel panel = new JPanel(new GridLayout(2, 1));
1074 history.setPreferredSize(new Dimension(400, 20));
1075 history.setEditable(true);
1076 history.addItem("http://www.");
1078 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1082 if (historyItems != null)
1084 st = new StringTokenizer(historyItems, "\t");
1086 while (st.hasMoreTokens())
1088 history.addItem(st.nextElement());
1092 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1093 MessageManager.getString("label.input_alignment_from_url"),
1094 JvOptionPane.OK_CANCEL_OPTION);
1096 if (reply != JvOptionPane.OK_OPTION)
1101 String url = history.getSelectedItem().toString();
1103 if (url.toLowerCase().endsWith(".jar"))
1105 if (viewport != null)
1107 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1108 FileFormat.Jalview);
1112 new FileLoader().LoadFile(url, DataSourceType.URL,
1113 FileFormat.Jalview);
1118 FileFormatI format = null;
1121 format = new IdentifyFile().identify(url, DataSourceType.URL);
1122 } catch (FileFormatException e)
1124 // TODO revise error handling, distinguish between
1125 // URL not found and response not valid
1130 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1131 MessageManager.formatMessage("label.couldnt_locate",
1132 new Object[] { url }), MessageManager
1133 .getString("label.url_not_found"),
1134 JvOptionPane.WARNING_MESSAGE);
1139 if (viewport != null)
1142 .LoadFile(viewport, url, DataSourceType.URL, format);
1146 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1152 * Opens the CutAndPaste window for the user to paste an alignment in to
1155 * - if not null, the pasted alignment is added to the current
1156 * alignment; if null, to a new alignment window
1159 public void inputTextboxMenuItem_actionPerformed(
1160 AlignmentViewPanel viewPanel)
1162 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1163 cap.setForInput(viewPanel);
1164 Desktop.addInternalFrame(cap,
1165 MessageManager.getString("label.cut_paste_alignmen_file"),
1175 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1177 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1178 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1180 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1181 getBounds().y, getWidth(), getHeight()));
1183 if (jconsole != null)
1185 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1186 jconsole.stopConsole();
1190 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1193 if (dialogExecutor != null)
1195 dialogExecutor.shutdownNow();
1197 closeAll_actionPerformed(null);
1199 if (groovyConsole != null)
1201 // suppress a possible repeat prompt to save script
1202 groovyConsole.setDirty(false);
1203 groovyConsole.exit();
1208 private void storeLastKnownDimensions(String string, Rectangle jc)
1210 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1211 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1212 + " height:" + jc.height);
1214 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1215 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1216 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1217 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1227 public void aboutMenuItem_actionPerformed(ActionEvent e)
1229 // StringBuffer message = getAboutMessage(false);
1230 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1232 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1233 new Thread(new Runnable()
1238 new SplashScreen(true);
1243 public StringBuffer getAboutMessage(boolean shortv)
1245 StringBuffer message = new StringBuffer();
1246 message.append("<html>");
1249 message.append("<h1><strong>Version: "
1250 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1251 message.append("<strong>Last Updated: <em>"
1252 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1253 + "</em></strong>");
1259 message.append("<strong>Version "
1260 + jalview.bin.Cache.getProperty("VERSION")
1261 + "; last updated: "
1262 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1265 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1268 message.append("<br>...Checking latest version...</br>");
1270 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1271 .equals(jalview.bin.Cache.getProperty("VERSION")))
1273 boolean red = false;
1274 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1275 .indexOf("automated build") == -1)
1278 // Displayed when code version and jnlp version do not match and code
1279 // version is not a development build
1280 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1283 message.append("<br>!! Version "
1284 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1286 + " is available for download from "
1287 + jalview.bin.Cache.getDefault("www.jalview.org",
1288 "http://www.jalview.org") + " !!");
1291 message.append("</div>");
1294 message.append("<br>Authors: "
1296 .getDefault("AUTHORFNAMES",
1297 "The Jalview Authors (See AUTHORS file for current list)")
1298 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1299 + "<br><br>For help, see the FAQ at <a href=\"http://www.jalview.org/faq\">www.jalview.org/faq</a> and/or join the jalview-discuss@jalview.org mailing list"
1300 + "<br><br>If you use Jalview, please cite:"
1301 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1302 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1303 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1315 public void documentationMenuItem_actionPerformed(ActionEvent e)
1319 Help.showHelpWindow();
1320 } catch (Exception ex)
1326 public void closeAll_actionPerformed(ActionEvent e)
1328 // TODO show a progress bar while closing?
1329 JInternalFrame[] frames = desktop.getAllFrames();
1330 for (int i = 0; i < frames.length; i++)
1334 frames[i].setClosed(true);
1335 } catch (java.beans.PropertyVetoException ex)
1339 Jalview.setCurrentAlignFrame(null);
1340 System.out.println("ALL CLOSED");
1341 if (v_client != null)
1343 // TODO clear binding to vamsas document objects on close_all
1347 * reset state of singleton objects as appropriate (clear down session state
1348 * when all windows are closed)
1350 StructureSelectionManager ssm = StructureSelectionManager
1351 .getStructureSelectionManager(this);
1360 public void raiseRelated_actionPerformed(ActionEvent e)
1362 reorderAssociatedWindows(false, false);
1366 public void minimizeAssociated_actionPerformed(ActionEvent e)
1368 reorderAssociatedWindows(true, false);
1371 void closeAssociatedWindows()
1373 reorderAssociatedWindows(false, true);
1379 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1383 protected void garbageCollect_actionPerformed(ActionEvent e)
1385 // We simply collect the garbage
1386 jalview.bin.Cache.log.debug("Collecting garbage...");
1388 jalview.bin.Cache.log.debug("Finished garbage collection.");
1395 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1399 protected void showMemusage_actionPerformed(ActionEvent e)
1401 desktop.showMemoryUsage(showMemusage.isSelected());
1408 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1412 protected void showConsole_actionPerformed(ActionEvent e)
1414 showConsole(showConsole.isSelected());
1417 Console jconsole = null;
1420 * control whether the java console is visible or not
1424 void showConsole(boolean selected)
1426 showConsole.setSelected(selected);
1427 // TODO: decide if we should update properties file
1428 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1430 jconsole.setVisible(selected);
1433 void reorderAssociatedWindows(boolean minimize, boolean close)
1435 JInternalFrame[] frames = desktop.getAllFrames();
1436 if (frames == null || frames.length < 1)
1441 AlignmentViewport source = null, target = null;
1442 if (frames[0] instanceof AlignFrame)
1444 source = ((AlignFrame) frames[0]).getCurrentView();
1446 else if (frames[0] instanceof TreePanel)
1448 source = ((TreePanel) frames[0]).getViewPort();
1450 else if (frames[0] instanceof PCAPanel)
1452 source = ((PCAPanel) frames[0]).av;
1454 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1456 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1461 for (int i = 0; i < frames.length; i++)
1464 if (frames[i] == null)
1468 if (frames[i] instanceof AlignFrame)
1470 target = ((AlignFrame) frames[i]).getCurrentView();
1472 else if (frames[i] instanceof TreePanel)
1474 target = ((TreePanel) frames[i]).getViewPort();
1476 else if (frames[i] instanceof PCAPanel)
1478 target = ((PCAPanel) frames[i]).av;
1480 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1482 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1485 if (source == target)
1491 frames[i].setClosed(true);
1495 frames[i].setIcon(minimize);
1498 frames[i].toFront();
1502 } catch (java.beans.PropertyVetoException ex)
1517 protected void preferences_actionPerformed(ActionEvent e)
1529 public void saveState_actionPerformed(ActionEvent e)
1531 JalviewFileChooser chooser = new JalviewFileChooser(
1532 Cache.getProperty("LAST_DIRECTORY"), "jvp", "Jalview Project");
1534 chooser.setFileView(new JalviewFileView());
1535 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1537 int value = chooser.showSaveDialog(this);
1539 if (value == JalviewFileChooser.APPROVE_OPTION)
1541 final Desktop me = this;
1542 final java.io.File choice = chooser.getSelectedFile();
1543 setProjectFile(choice);
1545 new Thread(new Runnable()
1550 // TODO: refactor to Jalview desktop session controller action.
1551 setProgressBar(MessageManager.formatMessage(
1552 "label.saving_jalview_project",
1553 new Object[] { choice.getName() }), choice.hashCode());
1554 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1555 choice.getParent());
1556 // TODO catch and handle errors for savestate
1557 // TODO prevent user from messing with the Desktop whilst we're saving
1560 new Jalview2XML().saveState(choice);
1561 } catch (OutOfMemoryError oom)
1563 new OOMWarning("Whilst saving current state to "
1564 + choice.getName(), oom);
1565 } catch (Exception ex)
1568 "Problems whilst trying to save to " + choice.getName(),
1570 JvOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1571 "label.error_whilst_saving_current_state_to",
1572 new Object[] { choice.getName() }), MessageManager
1573 .getString("label.couldnt_save_project"),
1574 JvOptionPane.WARNING_MESSAGE);
1576 setProgressBar(null, choice.hashCode());
1582 private void setProjectFile(File choice)
1584 this.projectFile = choice;
1587 public File getProjectFile()
1589 return this.projectFile;
1599 public void loadState_actionPerformed(ActionEvent e)
1601 JalviewFileChooser chooser = new JalviewFileChooser(
1602 Cache.getProperty("LAST_DIRECTORY"), new String[] {
1603 "jvp", "jar" }, new String[] { "Jalview Project",
1604 "Jalview Project (old)" }, "Jalview Project");
1605 chooser.setFileView(new JalviewFileView());
1606 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1608 int value = chooser.showOpenDialog(this);
1610 if (value == JalviewFileChooser.APPROVE_OPTION)
1612 final File selectedFile = chooser.getSelectedFile();
1613 setProjectFile(selectedFile);
1614 final String choice = selectedFile.getAbsolutePath();
1615 Cache.setProperty("LAST_DIRECTORY",
1616 selectedFile.getParent());
1617 new Thread(new Runnable()
1623 MessageManager.formatMessage(
1624 "label.loading_jalview_project",
1625 new Object[] { choice }), choice.hashCode());
1628 new Jalview2XML().loadJalviewAlign(choice);
1629 } catch (OutOfMemoryError oom)
1631 new OOMWarning("Whilst loading project from " + choice, oom);
1632 } catch (Exception ex)
1634 Cache.log.error("Problems whilst loading project from "
1636 JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1638 "label.error_whilst_loading_project_from",
1639 new Object[] { choice }), MessageManager
1640 .getString("label.couldnt_load_project"),
1641 JvOptionPane.WARNING_MESSAGE);
1643 setProgressBar(null, choice.hashCode());
1650 public void inputSequence_actionPerformed(ActionEvent e)
1652 new SequenceFetcher(this);
1655 JPanel progressPanel;
1657 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1659 public void startLoading(final String fileName)
1661 if (fileLoadingCount == 0)
1663 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1664 "label.loading_file", new Object[] { fileName })));
1669 private JPanel addProgressPanel(String string)
1671 if (progressPanel == null)
1673 progressPanel = new JPanel(new GridLayout(1, 1));
1674 totalProgressCount = 0;
1675 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1677 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1678 JProgressBar progressBar = new JProgressBar();
1679 progressBar.setIndeterminate(true);
1681 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1683 thisprogress.add(progressBar, BorderLayout.CENTER);
1684 progressPanel.add(thisprogress);
1685 ((GridLayout) progressPanel.getLayout())
1686 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1687 ++totalProgressCount;
1688 instance.validate();
1689 return thisprogress;
1692 int totalProgressCount = 0;
1694 private void removeProgressPanel(JPanel progbar)
1696 if (progressPanel != null)
1698 synchronized (progressPanel)
1700 progressPanel.remove(progbar);
1701 GridLayout gl = (GridLayout) progressPanel.getLayout();
1702 gl.setRows(gl.getRows() - 1);
1703 if (--totalProgressCount < 1)
1705 this.getContentPane().remove(progressPanel);
1706 progressPanel = null;
1713 public void stopLoading()
1716 if (fileLoadingCount < 1)
1718 while (fileLoadingPanels.size() > 0)
1720 removeProgressPanel(fileLoadingPanels.remove(0));
1722 fileLoadingPanels.clear();
1723 fileLoadingCount = 0;
1728 public static int getViewCount(String alignmentId)
1730 AlignmentViewport[] aps = getViewports(alignmentId);
1731 return (aps == null) ? 0 : aps.length;
1736 * @param alignmentId
1737 * - if null, all sets are returned
1738 * @return all AlignmentPanels concerning the alignmentId sequence set
1740 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1742 if (Desktop.desktop == null)
1744 // no frames created and in headless mode
1745 // TODO: verify that frames are recoverable when in headless mode
1748 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1749 AlignFrame[] frames = getAlignFrames();
1754 for (AlignFrame af : frames)
1756 for (AlignmentPanel ap : af.alignPanels)
1758 if (alignmentId == null
1759 || alignmentId.equals(ap.av.getSequenceSetId()))
1765 if (aps.size() == 0)
1769 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1774 * get all the viewports on an alignment.
1776 * @param sequenceSetId
1777 * unique alignment id (may be null - all viewports returned in that
1779 * @return all viewports on the alignment bound to sequenceSetId
1781 public static AlignmentViewport[] getViewports(String sequenceSetId)
1783 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1784 if (desktop != null)
1786 AlignFrame[] frames = Desktop.getAlignFrames();
1788 for (AlignFrame afr : frames)
1790 if (sequenceSetId == null
1791 || afr.getViewport().getSequenceSetId()
1792 .equals(sequenceSetId))
1794 if (afr.alignPanels != null)
1796 for (AlignmentPanel ap : afr.alignPanels)
1798 if (sequenceSetId == null
1799 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1807 viewp.add(afr.getViewport());
1811 if (viewp.size() > 0)
1813 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1820 * Explode the views in the given frame into separate AlignFrame
1824 public static void explodeViews(AlignFrame af)
1826 int size = af.alignPanels.size();
1832 for (int i = 0; i < size; i++)
1834 AlignmentPanel ap = af.alignPanels.get(i);
1835 AlignFrame newaf = new AlignFrame(ap);
1838 * Restore the view's last exploded frame geometry if known. Multiple
1839 * views from one exploded frame share and restore the same (frame)
1840 * position and size.
1842 Rectangle geometry = ap.av.getExplodedGeometry();
1843 if (geometry != null)
1845 newaf.setBounds(geometry);
1848 ap.av.setGatherViewsHere(false);
1850 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1851 AlignFrame.DEFAULT_HEIGHT);
1854 af.alignPanels.clear();
1855 af.closeMenuItem_actionPerformed(true);
1860 * Gather expanded views (separate AlignFrame's) with the same sequence set
1861 * identifier back in to this frame as additional views, and close the
1862 * expanded views. Note the expanded frames may themselves have multiple
1863 * views. We take the lot.
1867 public void gatherViews(AlignFrame source)
1869 source.viewport.setGatherViewsHere(true);
1870 source.viewport.setExplodedGeometry(source.getBounds());
1871 JInternalFrame[] frames = desktop.getAllFrames();
1872 String viewId = source.viewport.getSequenceSetId();
1874 for (int t = 0; t < frames.length; t++)
1876 if (frames[t] instanceof AlignFrame && frames[t] != source)
1878 AlignFrame af = (AlignFrame) frames[t];
1879 boolean gatherThis = false;
1880 for (int a = 0; a < af.alignPanels.size(); a++)
1882 AlignmentPanel ap = af.alignPanels.get(a);
1883 if (viewId.equals(ap.av.getSequenceSetId()))
1886 ap.av.setGatherViewsHere(false);
1887 ap.av.setExplodedGeometry(af.getBounds());
1888 source.addAlignmentPanel(ap, false);
1894 af.alignPanels.clear();
1895 af.closeMenuItem_actionPerformed(true);
1902 jalview.gui.VamsasApplication v_client = null;
1905 public void vamsasImport_actionPerformed(ActionEvent e)
1907 if (v_client == null)
1909 // Load and try to start a session.
1910 JalviewFileChooser chooser = new JalviewFileChooser(
1911 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1913 chooser.setFileView(new JalviewFileView());
1914 chooser.setDialogTitle(MessageManager
1915 .getString("label.open_saved_vamsas_session"));
1916 chooser.setToolTipText(MessageManager
1917 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1919 int value = chooser.showOpenDialog(this);
1921 if (value == JalviewFileChooser.APPROVE_OPTION)
1923 String fle = chooser.getSelectedFile().toString();
1924 if (!vamsasImport(chooser.getSelectedFile()))
1927 .showInternalMessageDialog(
1929 MessageManager.formatMessage(
1930 "label.couldnt_import_as_vamsas_session",
1931 new Object[] { fle }),
1933 .getString("label.vamsas_document_import_failed"),
1934 JvOptionPane.ERROR_MESSAGE);
1940 jalview.bin.Cache.log
1941 .error("Implementation error - load session from a running session is not supported.");
1946 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1949 * @return true if import was a success and a session was started.
1951 public boolean vamsasImport(URL url)
1953 // TODO: create progress bar
1954 if (v_client != null)
1957 jalview.bin.Cache.log
1958 .error("Implementation error - load session from a running session is not supported.");
1964 // copy the URL content to a temporary local file
1965 // TODO: be a bit cleverer here with nio (?!)
1966 File file = File.createTempFile("vdocfromurl", ".vdj");
1967 FileOutputStream fos = new FileOutputStream(file);
1968 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1969 byte[] buffer = new byte[2048];
1971 while ((ln = bis.read(buffer)) > -1)
1973 fos.write(buffer, 0, ln);
1977 v_client = new jalview.gui.VamsasApplication(this, file,
1978 url.toExternalForm());
1979 } catch (Exception ex)
1981 jalview.bin.Cache.log.error(
1982 "Failed to create new vamsas session from contents of URL "
1986 setupVamsasConnectedGui();
1987 v_client.initial_update(); // TODO: thread ?
1988 return v_client.inSession();
1992 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1995 * @return true if import was a success and a session was started.
1997 public boolean vamsasImport(File file)
1999 if (v_client != null)
2002 jalview.bin.Cache.log
2003 .error("Implementation error - load session from a running session is not supported.");
2007 setProgressBar(MessageManager.formatMessage(
2008 "status.importing_vamsas_session_from",
2009 new Object[] { file.getName() }), file.hashCode());
2012 v_client = new jalview.gui.VamsasApplication(this, file, null);
2013 } catch (Exception ex)
2015 setProgressBar(MessageManager.formatMessage(
2016 "status.importing_vamsas_session_from",
2017 new Object[] { file.getName() }), file.hashCode());
2018 jalview.bin.Cache.log.error(
2019 "New vamsas session from existing session file failed:", ex);
2022 setupVamsasConnectedGui();
2023 v_client.initial_update(); // TODO: thread ?
2024 setProgressBar(MessageManager.formatMessage(
2025 "status.importing_vamsas_session_from",
2026 new Object[] { file.getName() }), file.hashCode());
2027 return v_client.inSession();
2030 public boolean joinVamsasSession(String mysesid)
2032 if (v_client != null)
2036 .getString("error.try_join_vamsas_session_another"));
2038 if (mysesid == null)
2041 MessageManager.getString("error.invalid_vamsas_session_id"));
2043 v_client = new VamsasApplication(this, mysesid);
2044 setupVamsasConnectedGui();
2045 v_client.initial_update();
2046 return (v_client.inSession());
2050 public void vamsasStart_actionPerformed(ActionEvent e)
2052 if (v_client == null)
2055 // we just start a default session for moment.
2057 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2058 * getProperty("LAST_DIRECTORY"));
2060 * chooser.setFileView(new JalviewFileView());
2061 * chooser.setDialogTitle("Load Vamsas file");
2062 * chooser.setToolTipText("Import");
2064 * int value = chooser.showOpenDialog(this);
2066 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2067 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2069 v_client = new VamsasApplication(this);
2070 setupVamsasConnectedGui();
2071 v_client.initial_update(); // TODO: thread ?
2075 // store current data in session.
2076 v_client.push_update(); // TODO: thread
2080 protected void setupVamsasConnectedGui()
2082 vamsasStart.setText(MessageManager.getString("label.session_update"));
2083 vamsasSave.setVisible(true);
2084 vamsasStop.setVisible(true);
2085 vamsasImport.setVisible(false); // Document import to existing session is
2086 // not possible for vamsas-client-1.0.
2089 protected void setupVamsasDisconnectedGui()
2091 vamsasSave.setVisible(false);
2092 vamsasStop.setVisible(false);
2093 vamsasImport.setVisible(true);
2094 vamsasStart.setText(MessageManager
2095 .getString("label.new_vamsas_session"));
2099 public void vamsasStop_actionPerformed(ActionEvent e)
2101 if (v_client != null)
2103 v_client.end_session();
2105 setupVamsasDisconnectedGui();
2109 protected void buildVamsasStMenu()
2111 if (v_client == null)
2113 String[] sess = null;
2116 sess = VamsasApplication.getSessionList();
2117 } catch (Exception e)
2119 jalview.bin.Cache.log.warn(
2120 "Problem getting current sessions list.", e);
2125 jalview.bin.Cache.log.debug("Got current sessions list: "
2126 + sess.length + " entries.");
2127 VamsasStMenu.removeAll();
2128 for (int i = 0; i < sess.length; i++)
2130 JMenuItem sessit = new JMenuItem();
2131 sessit.setText(sess[i]);
2132 sessit.setToolTipText(MessageManager.formatMessage(
2133 "label.connect_to_session", new Object[] { sess[i] }));
2134 final Desktop dsktp = this;
2135 final String mysesid = sess[i];
2136 sessit.addActionListener(new ActionListener()
2140 public void actionPerformed(ActionEvent e)
2142 if (dsktp.v_client == null)
2144 Thread rthr = new Thread(new Runnable()
2150 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2151 dsktp.setupVamsasConnectedGui();
2152 dsktp.v_client.initial_update();
2160 VamsasStMenu.add(sessit);
2162 // don't show an empty menu.
2163 VamsasStMenu.setVisible(sess.length > 0);
2168 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2169 VamsasStMenu.removeAll();
2170 VamsasStMenu.setVisible(false);
2175 // Not interested in the content. Just hide ourselves.
2176 VamsasStMenu.setVisible(false);
2181 public void vamsasSave_actionPerformed(ActionEvent e)
2183 if (v_client != null)
2185 JalviewFileChooser chooser = new JalviewFileChooser(
2186 Cache.getProperty("LAST_DIRECTORY"), "vdj",// TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2189 chooser.setFileView(new JalviewFileView());
2190 chooser.setDialogTitle(MessageManager
2191 .getString("label.save_vamsas_document_archive"));
2193 int value = chooser.showSaveDialog(this);
2195 if (value == JalviewFileChooser.APPROVE_OPTION)
2197 java.io.File choice = chooser.getSelectedFile();
2198 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2199 "label.saving_vamsas_doc",
2200 new Object[] { choice.getName() }));
2201 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2202 String warnmsg = null;
2203 String warnttl = null;
2206 v_client.vclient.storeDocument(choice);
2209 warnttl = "Serious Problem saving Vamsas Document";
2210 warnmsg = ex.toString();
2211 jalview.bin.Cache.log.error("Error Whilst saving document to "
2214 } catch (Exception ex)
2216 warnttl = "Problem saving Vamsas Document.";
2217 warnmsg = ex.toString();
2218 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2222 removeProgressPanel(progpanel);
2223 if (warnmsg != null)
2225 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2227 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2233 JPanel vamUpdate = null;
2236 * hide vamsas user gui bits when a vamsas document event is being handled.
2239 * true to hide gui, false to reveal gui
2241 public void setVamsasUpdate(boolean b)
2243 Cache.log.debug("Setting gui for Vamsas update "
2244 + (b ? "in progress" : "finished"));
2246 if (vamUpdate != null)
2248 this.removeProgressPanel(vamUpdate);
2252 vamUpdate = this.addProgressPanel(MessageManager
2253 .getString("label.updating_vamsas_session"));
2255 vamsasStart.setVisible(!b);
2256 vamsasStop.setVisible(!b);
2257 vamsasSave.setVisible(!b);
2260 public JInternalFrame[] getAllFrames()
2262 return desktop.getAllFrames();
2266 * Checks the given url to see if it gives a response indicating that the user
2267 * should be informed of a new questionnaire.
2271 public void checkForQuestionnaire(String url)
2273 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2274 // javax.swing.SwingUtilities.invokeLater(jvq);
2275 new Thread(jvq).start();
2278 public void checkURLLinks()
2280 // Thread off the URL link checker
2281 addDialogThread(new Runnable()
2286 if (Cache.getDefault("CHECKURLLINKS", true))
2288 // check what the actual links are - if it's just the default don't
2289 // bother with the warning
2290 Vector<String> links = Preferences.sequenceURLLinks;
2292 // only need to check links if there is one with a
2293 // SEQUENCE_ID which is not the default EMBL_EBI link
2294 ListIterator<String> li = links.listIterator();
2295 boolean check = false;
2296 List<JLabel> urls = new ArrayList<JLabel>();
2297 while (li.hasNext())
2299 String link = li.next();
2300 if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING))
2303 int barPos = link.indexOf("|");
2304 String urlMsg = barPos == -1 ? link : link.substring(0,
2305 barPos) + ": " + link.substring(barPos + 1);
2306 urls.add(new JLabel(urlMsg));
2314 // ask user to check in case URL links use old style tokens
2315 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2316 JPanel msgPanel = new JPanel();
2317 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2318 msgPanel.add(Box.createVerticalGlue());
2319 JLabel msg = new JLabel(
2321 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2322 JLabel msg2 = new JLabel(
2324 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2326 for (JLabel url : urls)
2332 final JCheckBox jcb = new JCheckBox(
2333 MessageManager.getString("label.do_not_display_again"));
2334 jcb.addActionListener(new ActionListener()
2337 public void actionPerformed(ActionEvent e)
2339 // update Cache settings for "don't show this again"
2340 boolean showWarningAgain = !jcb.isSelected();
2341 Cache.setProperty("CHECKURLLINKS",
2342 Boolean.valueOf(showWarningAgain).toString());
2347 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2349 .getString("label.SEQUENCE_ID_no_longer_used"),
2350 JvOptionPane.WARNING_MESSAGE);
2357 * Proxy class for JDesktopPane which optionally displays the current memory
2358 * usage and highlights the desktop area with a red bar if free memory runs
2363 public class MyDesktopPane extends JDesktopPane implements Runnable
2366 private static final float ONE_MB = 1048576f;
2368 boolean showMemoryUsage = false;
2372 java.text.NumberFormat df;
2374 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2377 public MyDesktopPane(boolean showMemoryUsage)
2379 showMemoryUsage(showMemoryUsage);
2382 public void showMemoryUsage(boolean showMemory)
2384 this.showMemoryUsage = showMemory;
2387 Thread worker = new Thread(this);
2392 public boolean isShowMemoryUsage()
2394 return showMemoryUsage;
2400 df = java.text.NumberFormat.getNumberInstance();
2401 df.setMaximumFractionDigits(2);
2402 runtime = Runtime.getRuntime();
2404 while (showMemoryUsage)
2408 maxMemory = runtime.maxMemory() / ONE_MB;
2409 allocatedMemory = runtime.totalMemory() / ONE_MB;
2410 freeMemory = runtime.freeMemory() / ONE_MB;
2411 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2413 percentUsage = (totalFreeMemory / maxMemory) * 100;
2415 // if (percentUsage < 20)
2417 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2419 // instance.set.setBorder(border1);
2422 // sleep after showing usage
2424 } catch (Exception ex)
2426 ex.printStackTrace();
2432 public void paintComponent(Graphics g)
2434 if (showMemoryUsage && g != null && df != null)
2436 if (percentUsage < 20)
2438 g.setColor(Color.red);
2440 FontMetrics fm = g.getFontMetrics();
2443 g.drawString(MessageManager.formatMessage(
2444 "label.memory_stats",
2445 new Object[] { df.format(totalFreeMemory),
2446 df.format(maxMemory), df.format(percentUsage) }), 10,
2447 getHeight() - fm.getHeight());
2454 * fixes stacking order after a modal dialog to ensure windows that should be
2455 * on top actually are
2457 public void relayerWindows()
2462 protected JMenuItem groovyShell;
2465 * Accessor method to quickly get all the AlignmentFrames loaded.
2467 * @return an array of AlignFrame, or null if none found
2469 public static AlignFrame[] getAlignFrames()
2471 if (Jalview.isHeadlessMode())
2473 // Desktop.desktop is null in headless mode
2474 return new AlignFrame[] { Jalview.currentAlignFrame };
2477 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2483 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2485 for (int i = frames.length - 1; i > -1; i--)
2487 if (frames[i] instanceof AlignFrame)
2489 avp.add((AlignFrame) frames[i]);
2491 else if (frames[i] instanceof SplitFrame)
2494 * Also check for a split frame containing an AlignFrame
2496 GSplitFrame sf = (GSplitFrame) frames[i];
2497 if (sf.getTopFrame() instanceof AlignFrame)
2499 avp.add((AlignFrame) sf.getTopFrame());
2501 if (sf.getBottomFrame() instanceof AlignFrame)
2503 avp.add((AlignFrame) sf.getBottomFrame());
2507 if (avp.size() == 0)
2511 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2516 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2520 public GStructureViewer[] getJmols()
2522 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2528 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2530 for (int i = frames.length - 1; i > -1; i--)
2532 if (frames[i] instanceof AppJmol)
2534 GStructureViewer af = (GStructureViewer) frames[i];
2538 if (avp.size() == 0)
2542 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2547 * Add Groovy Support to Jalview
2549 public void groovyShell_actionPerformed()
2553 openGroovyConsole();
2554 } catch (Exception ex)
2556 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2557 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2559 MessageManager.getString("label.couldnt_create_groovy_shell"),
2560 MessageManager.getString("label.groovy_support_failed"),
2561 JvOptionPane.ERROR_MESSAGE);
2566 * Open the Groovy console
2568 void openGroovyConsole()
2570 if (groovyConsole == null)
2572 groovyConsole = new groovy.ui.Console();
2573 groovyConsole.setVariable("Jalview", this);
2574 groovyConsole.run();
2577 * We allow only one console at a time, so that AlignFrame menu option
2578 * 'Calculate | Run Groovy script' is unambiguous.
2579 * Disable 'Groovy Console', and enable 'Run script', when the console is
2580 * opened, and the reverse when it is closed
2582 Window window = (Window) groovyConsole.getFrame();
2583 window.addWindowListener(new WindowAdapter()
2586 public void windowClosed(WindowEvent e)
2589 * rebind CMD-Q from Groovy Console to Jalview Quit
2592 enableExecuteGroovy(false);
2598 * show Groovy console window (after close and reopen)
2600 ((Window) groovyConsole.getFrame()).setVisible(true);
2603 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2604 * and disable opening a second console
2606 enableExecuteGroovy(true);
2610 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2611 * binding when opened
2613 protected void addQuitHandler()
2615 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2616 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2617 .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
2618 getRootPane().getActionMap().put("Quit", new AbstractAction()
2621 public void actionPerformed(ActionEvent e)
2629 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2632 * true if Groovy console is open
2634 public void enableExecuteGroovy(boolean enabled)
2637 * disable opening a second Groovy console
2638 * (or re-enable when the console is closed)
2640 groovyShell.setEnabled(!enabled);
2642 AlignFrame[] alignFrames = getAlignFrames();
2643 if (alignFrames != null)
2645 for (AlignFrame af : alignFrames)
2647 af.setGroovyEnabled(enabled);
2653 * Progress bars managed by the IProgressIndicator method.
2655 private Hashtable<Long, JPanel> progressBars;
2657 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2662 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2665 public void setProgressBar(String message, long id)
2667 if (progressBars == null)
2669 progressBars = new Hashtable<Long, JPanel>();
2670 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2673 if (progressBars.get(new Long(id)) != null)
2675 JPanel panel = progressBars.remove(new Long(id));
2676 if (progressBarHandlers.contains(new Long(id)))
2678 progressBarHandlers.remove(new Long(id));
2680 removeProgressPanel(panel);
2684 progressBars.put(new Long(id), addProgressPanel(message));
2691 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2692 * jalview.gui.IProgressIndicatorHandler)
2695 public void registerHandler(final long id,
2696 final IProgressIndicatorHandler handler)
2698 if (progressBarHandlers == null
2699 || !progressBars.containsKey(new Long(id)))
2703 .getString("error.call_setprogressbar_before_registering_handler"));
2705 progressBarHandlers.put(new Long(id), handler);
2706 final JPanel progressPanel = progressBars.get(new Long(id));
2707 if (handler.canCancel())
2709 JButton cancel = new JButton(
2710 MessageManager.getString("action.cancel"));
2711 final IProgressIndicator us = this;
2712 cancel.addActionListener(new ActionListener()
2716 public void actionPerformed(ActionEvent e)
2718 handler.cancelActivity(id);
2719 us.setProgressBar(MessageManager.formatMessage(
2720 "label.cancelled_params",
2721 new Object[] { ((JLabel) progressPanel.getComponent(0))
2725 progressPanel.add(cancel, BorderLayout.EAST);
2731 * @return true if any progress bars are still active
2734 public boolean operationInProgress()
2736 if (progressBars != null && progressBars.size() > 0)
2744 * This will return the first AlignFrame holding the given viewport instance.
2745 * It will break if there are more than one AlignFrames viewing a particular
2749 * @return alignFrame for viewport
2751 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2753 if (desktop != null)
2755 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2756 for (int panel = 0; aps != null && panel < aps.length; panel++)
2758 if (aps[panel] != null && aps[panel].av == viewport)
2760 return aps[panel].alignFrame;
2767 public VamsasApplication getVamsasApplication()
2774 * flag set if jalview GUI is being operated programmatically
2776 private boolean inBatchMode = false;
2779 * check if jalview GUI is being operated programmatically
2781 * @return inBatchMode
2783 public boolean isInBatchMode()
2789 * set flag if jalview GUI is being operated programmatically
2791 * @param inBatchMode
2793 public void setInBatchMode(boolean inBatchMode)
2795 this.inBatchMode = inBatchMode;
2798 public void startServiceDiscovery()
2800 startServiceDiscovery(false);
2803 public void startServiceDiscovery(boolean blocking)
2805 boolean alive = true;
2806 Thread t0 = null, t1 = null, t2 = null;
2807 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2810 // todo: changesupport handlers need to be transferred
2811 if (discoverer == null)
2813 discoverer = new jalview.ws.jws1.Discoverer();
2814 // register PCS handler for desktop.
2815 discoverer.addPropertyChangeListener(changeSupport);
2817 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2818 // until we phase out completely
2819 (t0 = new Thread(discoverer)).start();
2822 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2824 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2826 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2828 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2834 // TODO: do rest service discovery
2843 } catch (Exception e)
2846 alive = (t1 != null && t1.isAlive())
2847 || (t2 != null && t2.isAlive())
2848 || (t3 != null && t3.isAlive())
2849 || (t0 != null && t0.isAlive());
2855 * called to check if the service discovery process completed successfully.
2859 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2861 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2863 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2864 .getErrorMessages();
2867 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2869 if (serviceChangedDialog == null)
2871 // only run if we aren't already displaying one of these.
2872 addDialogThread(serviceChangedDialog = new Runnable()
2879 * JalviewDialog jd =new JalviewDialog() {
2881 * @Override protected void cancelPressed() { // TODO
2882 * Auto-generated method stub
2884 * }@Override protected void okPressed() { // TODO
2885 * Auto-generated method stub
2887 * }@Override protected void raiseClosed() { // TODO
2888 * Auto-generated method stub
2890 * } }; jd.initDialogFrame(new
2891 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2892 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2893 * + " or mis-configured HTTP proxy settings.<br/>" +
2894 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2896 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2897 * ), true, true, "Web Service Configuration Problem", 450,
2900 * jd.waitForInput();
2906 "<html><table width=\"450\"><tr><td>"
2908 + "</td></tr></table>"
2909 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2910 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2911 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2912 + " Tools->Preferences dialog box to change them.</p></html>"),
2913 "Web Service Configuration Problem",
2914 JvOptionPane.DEFAULT_OPTION,
2915 JvOptionPane.ERROR_MESSAGE);
2916 serviceChangedDialog = null;
2925 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2932 private Runnable serviceChangedDialog = null;
2935 * start a thread to open a URL in the configured browser. Pops up a warning
2936 * dialog to the user if there is an exception when calling out to the browser
2941 public static void showUrl(final String url)
2943 showUrl(url, Desktop.instance);
2947 * Like showUrl but allows progress handler to be specified
2951 * (null) or object implementing IProgressIndicator
2953 public static void showUrl(final String url,
2954 final IProgressIndicator progress)
2956 new Thread(new Runnable()
2963 if (progress != null)
2965 progress.setProgressBar(MessageManager.formatMessage(
2966 "status.opening_params", new Object[] { url }), this
2969 jalview.util.BrowserLauncher.openURL(url);
2970 } catch (Exception ex)
2972 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2974 .getString("label.web_browser_not_found_unix"),
2975 MessageManager.getString("label.web_browser_not_found"),
2976 JvOptionPane.WARNING_MESSAGE);
2978 ex.printStackTrace();
2980 if (progress != null)
2982 progress.setProgressBar(null, this.hashCode());
2988 public static WsParamSetManager wsparamManager = null;
2990 public static ParamManager getUserParameterStore()
2992 if (wsparamManager == null)
2994 wsparamManager = new WsParamSetManager();
2996 return wsparamManager;
3000 * static hyperlink handler proxy method for use by Jalview's internal windows
3004 public static void hyperlinkUpdate(HyperlinkEvent e)
3006 if (e.getEventType() == EventType.ACTIVATED)
3011 url = e.getURL().toString();
3012 Desktop.showUrl(url);
3013 } catch (Exception x)
3017 if (Cache.log != null)
3019 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3023 System.err.println("Couldn't handle string " + url
3027 // ignore any exceptions due to dud links.
3034 * single thread that handles display of dialogs to user.
3036 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3039 * flag indicating if dialogExecutor should try to acquire a permit
3041 private volatile boolean dialogPause = true;
3046 private java.util.concurrent.Semaphore block = new Semaphore(0);
3048 private static groovy.ui.Console groovyConsole;
3051 * add another dialog thread to the queue
3055 public void addDialogThread(final Runnable prompter)
3057 dialogExecutor.submit(new Runnable()
3067 } catch (InterruptedException x)
3072 if (instance == null)
3078 SwingUtilities.invokeAndWait(prompter);
3079 } catch (Exception q)
3081 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3087 public void startDialogQueue()
3089 // set the flag so we don't pause waiting for another permit and semaphore
3090 // the current task to begin
3091 dialogPause = false;
3096 protected void snapShotWindow_actionPerformed(ActionEvent e)
3100 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3101 "View of Desktop", getWidth(), getHeight(), of = new File(
3102 "Jalview_snapshot" + System.currentTimeMillis()
3103 + ".eps"), "View of desktop", null, 0, false);
3106 paintAll(im.getGraphics());
3108 } catch (Exception q)
3110 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3114 Cache.log.info("Successfully written snapshot to file "
3115 + of.getAbsolutePath());
3119 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3120 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3121 * and location last time the view was expanded (if any). However it does not
3122 * remember the split pane divider location - this is set to match the
3123 * 'exploding' frame.
3127 public void explodeViews(SplitFrame sf)
3129 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3130 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3131 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3133 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3135 int viewCount = topPanels.size();
3142 * Processing in reverse order works, forwards order leaves the first panels
3143 * not visible. I don't know why!
3145 for (int i = viewCount - 1; i >= 0; i--)
3148 * Make new top and bottom frames. These take over the respective
3149 * AlignmentPanel objects, including their AlignmentViewports, so the
3150 * cdna/protein relationships between the viewports is carried over to the
3153 * explodedGeometry holds the (x, y) position of the previously exploded
3154 * SplitFrame, and the (width, height) of the AlignFrame component
3156 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3157 AlignFrame newTopFrame = new AlignFrame(topPanel);
3158 newTopFrame.setSize(oldTopFrame.getSize());
3159 newTopFrame.setVisible(true);
3160 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3161 .getExplodedGeometry();
3162 if (geometry != null)
3164 newTopFrame.setSize(geometry.getSize());
3167 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3168 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3169 newBottomFrame.setSize(oldBottomFrame.getSize());
3170 newBottomFrame.setVisible(true);
3171 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3172 .getExplodedGeometry();
3173 if (geometry != null)
3175 newBottomFrame.setSize(geometry.getSize());
3178 topPanel.av.setGatherViewsHere(false);
3179 bottomPanel.av.setGatherViewsHere(false);
3180 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3182 if (geometry != null)
3184 splitFrame.setLocation(geometry.getLocation());
3186 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3190 * Clear references to the panels (now relocated in the new SplitFrames)
3191 * before closing the old SplitFrame.
3194 bottomPanels.clear();
3199 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3200 * back into the given SplitFrame as additional views. Note that the gathered
3201 * frames may themselves have multiple views.
3205 public void gatherViews(GSplitFrame source)
3208 * special handling of explodedGeometry for a view within a SplitFrame: - it
3209 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3210 * height) of the AlignFrame component
3212 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3213 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3214 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3215 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3216 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3217 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3219 myTopFrame.viewport.setGatherViewsHere(true);
3220 myBottomFrame.viewport.setGatherViewsHere(true);
3221 String topViewId = myTopFrame.viewport.getSequenceSetId();
3222 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3224 JInternalFrame[] frames = desktop.getAllFrames();
3225 for (JInternalFrame frame : frames)
3227 if (frame instanceof SplitFrame && frame != source)
3229 SplitFrame sf = (SplitFrame) frame;
3230 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3231 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3232 boolean gatherThis = false;
3233 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3235 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3236 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3237 if (topViewId.equals(topPanel.av.getSequenceSetId())
3238 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3241 topPanel.av.setGatherViewsHere(false);
3242 bottomPanel.av.setGatherViewsHere(false);
3243 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3244 topFrame.getSize()));
3245 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3246 .getLocation(), bottomFrame.getSize()));
3247 myTopFrame.addAlignmentPanel(topPanel, false);
3248 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3254 topFrame.getAlignPanels().clear();
3255 bottomFrame.getAlignPanels().clear();
3262 * The dust settles...give focus to the tab we did this from.
3264 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3267 public static groovy.ui.Console getGroovyConsole()
3269 return groovyConsole;
3272 public static void transferFromDropTarget(List<String> files,
3273 List<DataSourceType> protocols, DropTargetDropEvent evt,
3278 DataFlavor uriListFlavor = new DataFlavor(
3279 "text/uri-list;class=java.lang.String");
3280 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3282 // Works on Windows and MacOSX
3283 Cache.log.debug("Drop handled as javaFileListFlavor");
3284 for (Object file : (List) t
3285 .getTransferData(DataFlavor.javaFileListFlavor))
3287 files.add(((File) file).toString());
3288 protocols.add(DataSourceType.FILE);
3293 // Unix like behaviour
3294 boolean added = false;
3296 if (t.isDataFlavorSupported(uriListFlavor))
3298 Cache.log.debug("Drop handled as uriListFlavor");
3299 // This is used by Unix drag system
3300 data = (String) t.getTransferData(uriListFlavor);
3304 // fallback to text: workaround - on OSX where there's a JVM bug
3305 Cache.log.debug("standard URIListFlavor failed. Trying text");
3306 // try text fallback
3307 data = (String) t.getTransferData(new DataFlavor(
3308 "text/plain;class=java.lang.String"));
3309 if (Cache.log.isDebugEnabled())
3311 Cache.log.debug("fallback returned " + data);
3314 while (protocols.size() < files.size())
3316 Cache.log.debug("Adding missing FILE protocol for "
3317 + files.get(protocols.size()));
3318 protocols.add(DataSourceType.FILE);
3320 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3321 data, "\r\n"); st.hasMoreTokens();)
3324 String s = st.nextToken();
3325 if (s.startsWith("#"))
3327 // the line is a comment (as per the RFC 2483)
3330 java.net.URI uri = new java.net.URI(s);
3331 if (uri.getScheme().toLowerCase().startsWith("http"))
3333 protocols.add(DataSourceType.URL);
3334 files.add(uri.toString());
3338 // otherwise preserve old behaviour: catch all for file objects
3339 java.io.File file = new java.io.File(uri);
3340 protocols.add(DataSourceType.FILE);
3341 files.add(file.toString());
3344 if (Cache.log.isDebugEnabled())
3346 if (data == null || !added)
3349 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3350 for (DataFlavor fl : t.getTransferDataFlavors())
3352 Cache.log.debug("Supported transfer dataflavor: "
3354 Object df = t.getTransferData(fl);
3357 Cache.log.debug("Retrieves: " + df);
3361 Cache.log.debug("Retrieved nothing");