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.SEQUENCE_ID;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.bin.Cache;
28 import jalview.bin.Jalview;
29 import jalview.io.DataSourceType;
30 import jalview.io.FileFormat;
31 import jalview.io.FileFormatException;
32 import jalview.io.FileFormatI;
33 import jalview.io.FileFormats;
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.urls.IdOrgSettings;
42 import jalview.util.ImageMaker;
43 import jalview.util.MessageManager;
44 import jalview.util.Platform;
45 import jalview.util.UrlConstants;
46 import jalview.viewmodel.AlignmentViewport;
47 import jalview.ws.params.ParamManager;
48 import jalview.ws.utils.UrlDownloadClient;
50 import java.awt.BorderLayout;
51 import java.awt.Color;
52 import java.awt.Dimension;
53 import java.awt.FontMetrics;
54 import java.awt.Graphics;
55 import java.awt.GridLayout;
56 import java.awt.Point;
57 import java.awt.Rectangle;
58 import java.awt.Toolkit;
59 import java.awt.Window;
60 import java.awt.datatransfer.Clipboard;
61 import java.awt.datatransfer.ClipboardOwner;
62 import java.awt.datatransfer.DataFlavor;
63 import java.awt.datatransfer.Transferable;
64 import java.awt.dnd.DnDConstants;
65 import java.awt.dnd.DropTargetDragEvent;
66 import java.awt.dnd.DropTargetDropEvent;
67 import java.awt.dnd.DropTargetEvent;
68 import java.awt.dnd.DropTargetListener;
69 import java.awt.event.ActionEvent;
70 import java.awt.event.ActionListener;
71 import java.awt.event.FocusEvent;
72 import java.awt.event.FocusListener;
73 import java.awt.event.KeyEvent;
74 import java.awt.event.MouseAdapter;
75 import java.awt.event.MouseEvent;
76 import java.awt.event.WindowAdapter;
77 import java.awt.event.WindowEvent;
78 import java.beans.PropertyChangeEvent;
79 import java.beans.PropertyChangeListener;
80 import java.io.BufferedInputStream;
82 import java.io.FileOutputStream;
83 import java.io.IOException;
85 import java.util.ArrayList;
86 import java.util.Hashtable;
87 import java.util.List;
88 import java.util.ListIterator;
89 import java.util.StringTokenizer;
90 import java.util.Vector;
91 import java.util.concurrent.ExecutorService;
92 import java.util.concurrent.Executors;
93 import java.util.concurrent.Semaphore;
95 import javax.swing.AbstractAction;
96 import javax.swing.Box;
97 import javax.swing.BoxLayout;
98 import javax.swing.DefaultDesktopManager;
99 import javax.swing.DesktopManager;
100 import javax.swing.JButton;
101 import javax.swing.JCheckBox;
102 import javax.swing.JComboBox;
103 import javax.swing.JComponent;
104 import javax.swing.JDesktopPane;
105 import javax.swing.JFrame;
106 import javax.swing.JInternalFrame;
107 import javax.swing.JLabel;
108 import javax.swing.JMenuItem;
109 import javax.swing.JPanel;
110 import javax.swing.JPopupMenu;
111 import javax.swing.JProgressBar;
112 import javax.swing.KeyStroke;
113 import javax.swing.SwingUtilities;
114 import javax.swing.event.HyperlinkEvent;
115 import javax.swing.event.HyperlinkEvent.EventType;
116 import javax.swing.event.InternalFrameAdapter;
117 import javax.swing.event.InternalFrameEvent;
118 import javax.swing.event.MenuEvent;
119 import javax.swing.event.MenuListener;
126 * @version $Revision: 1.155 $
128 public class Desktop extends jalview.jbgui.GDesktop implements
129 DropTargetListener, ClipboardOwner, IProgressIndicator,
130 jalview.api.StructureSelectionManagerProvider
132 private static int DEFAULT_MIN_WIDTH = 300;
134 private static int DEFAULT_MIN_HEIGHT = 250;
136 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
139 * news reader - null if it was never started.
141 private BlogReader jvnews = null;
143 private File projectFile;
147 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
149 public void addJalviewPropertyChangeListener(
150 PropertyChangeListener listener)
152 changeSupport.addJalviewPropertyChangeListener(listener);
156 * @param propertyName
158 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
159 * java.beans.PropertyChangeListener)
161 public void addJalviewPropertyChangeListener(String propertyName,
162 PropertyChangeListener listener)
164 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
168 * @param propertyName
170 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
171 * java.beans.PropertyChangeListener)
173 public void removeJalviewPropertyChangeListener(String propertyName,
174 PropertyChangeListener listener)
176 changeSupport.removeJalviewPropertyChangeListener(propertyName,
180 /** Singleton Desktop instance */
181 public static Desktop instance;
183 public static MyDesktopPane desktop;
185 static int openFrameCount = 0;
187 static final int xOffset = 30;
189 static final int yOffset = 30;
191 public static jalview.ws.jws1.Discoverer discoverer;
193 public static Object[] jalviewClipboard;
195 public static boolean internalCopy = false;
197 static int fileLoadingCount = 0;
199 class MyDesktopManager implements DesktopManager
202 private DesktopManager delegate;
204 public MyDesktopManager(DesktopManager delegate)
206 this.delegate = delegate;
210 public void activateFrame(JInternalFrame f)
214 delegate.activateFrame(f);
215 } catch (NullPointerException npe)
217 Point p = getMousePosition();
218 instance.showPasteMenu(p.x, p.y);
223 public void beginDraggingFrame(JComponent f)
225 delegate.beginDraggingFrame(f);
229 public void beginResizingFrame(JComponent f, int direction)
231 delegate.beginResizingFrame(f, direction);
235 public void closeFrame(JInternalFrame f)
237 delegate.closeFrame(f);
241 public void deactivateFrame(JInternalFrame f)
243 delegate.deactivateFrame(f);
247 public void deiconifyFrame(JInternalFrame f)
249 delegate.deiconifyFrame(f);
253 public void dragFrame(JComponent f, int newX, int newY)
259 delegate.dragFrame(f, newX, newY);
263 public void endDraggingFrame(JComponent f)
265 delegate.endDraggingFrame(f);
269 public void endResizingFrame(JComponent f)
271 delegate.endResizingFrame(f);
275 public void iconifyFrame(JInternalFrame f)
277 delegate.iconifyFrame(f);
281 public void maximizeFrame(JInternalFrame f)
283 delegate.maximizeFrame(f);
287 public void minimizeFrame(JInternalFrame f)
289 delegate.minimizeFrame(f);
293 public void openFrame(JInternalFrame f)
295 delegate.openFrame(f);
299 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
306 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
310 public void setBoundsForFrame(JComponent f, int newX, int newY,
311 int newWidth, int newHeight)
313 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
316 // All other methods, simply delegate
321 * Creates a new Desktop object.
326 * A note to implementors. It is ESSENTIAL that any activities that might
327 * block are spawned off as threads rather than waited for during this
331 doVamsasClientCheck();
333 groovyShell = new JMenuItem();
334 groovyShell.setText(MessageManager.getString("label.groovy_console"));
335 groovyShell.addActionListener(new ActionListener()
338 public void actionPerformed(ActionEvent e)
340 groovyShell_actionPerformed();
343 toolsMenu.add(groovyShell);
344 groovyShell.setVisible(true);
346 doConfigureStructurePrefs();
347 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
348 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
349 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
351 boolean showjconsole = jalview.bin.Cache.getDefault(
352 "SHOW_JAVA_CONSOLE", false);
353 desktop = new MyDesktopPane(selmemusage);
354 if (Platform.isAMac())
356 desktop.setDoubleBuffered(false);
358 showMemusage.setSelected(selmemusage);
359 desktop.setBackground(Color.white);
360 getContentPane().setLayout(new BorderLayout());
361 // alternate config - have scrollbars - see notes in JAL-153
362 // JScrollPane sp = new JScrollPane();
363 // sp.getViewport().setView(desktop);
364 // getContentPane().add(sp, BorderLayout.CENTER);
365 getContentPane().add(desktop, BorderLayout.CENTER);
366 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
368 // This line prevents Windows Look&Feel resizing all new windows to maximum
369 // if previous window was maximised
370 desktop.setDesktopManager(new MyDesktopManager(
371 new DefaultDesktopManager()));
373 Rectangle dims = getLastKnownDimensions("");
380 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
381 setBounds((screenSize.width - 900) / 2,
382 (screenSize.height - 650) / 2, 900, 650);
384 jconsole = new Console(this, showjconsole);
385 // add essential build information
386 jconsole.setHeader("Jalview Version: "
387 + jalview.bin.Cache.getProperty("VERSION") + "\n"
388 + "Jalview Installation: "
389 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
390 + "\n" + "Build Date: "
391 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
392 + "Java version: " + System.getProperty("java.version") + "\n"
393 + System.getProperty("os.arch") + " "
394 + System.getProperty("os.name") + " "
395 + System.getProperty("os.version"));
397 showConsole(showjconsole);
399 showNews.setVisible(false);
401 getIdentifiersOrgData();
405 this.addWindowListener(new WindowAdapter()
408 public void windowClosing(WindowEvent evt)
415 this.addMouseListener(ma = new MouseAdapter()
418 public void mousePressed(MouseEvent evt)
420 if (evt.isPopupTrigger()) // Mac
422 showPasteMenu(evt.getX(), evt.getY());
427 public void mouseReleased(MouseEvent evt)
429 if (evt.isPopupTrigger()) // Windows
431 showPasteMenu(evt.getX(), evt.getY());
435 desktop.addMouseListener(ma);
437 this.addFocusListener(new FocusListener()
441 public void focusLost(FocusEvent e)
443 // TODO Auto-generated method stub
448 public void focusGained(FocusEvent e)
450 Cache.log.debug("Relaying windows after focus gain");
451 // make sure that we sort windows properly after we gain focus
452 instance.relayerWindows();
455 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
456 // Spawn a thread that shows the splashscreen
457 SwingUtilities.invokeLater(new Runnable()
466 // Thread off a new instance of the file chooser - this reduces the time it
467 // takes to open it later on.
468 new Thread(new Runnable()
473 Cache.log.debug("Filechooser init thread started.");
474 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
475 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
477 Cache.log.debug("Filechooser init thread finished.");
480 // Add the service change listener
481 changeSupport.addJalviewPropertyChangeListener("services",
482 new PropertyChangeListener()
486 public void propertyChange(PropertyChangeEvent evt)
488 Cache.log.debug("Firing service changed event for "
489 + evt.getNewValue());
490 JalviewServicesChanged(evt);
496 public void doConfigureStructurePrefs()
498 // configure services
499 StructureSelectionManager ssm = StructureSelectionManager
500 .getStructureSelectionManager(this);
501 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
503 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
504 Preferences.ADD_TEMPFACT_ANN, true));
505 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
506 Preferences.STRUCT_FROM_PDB, true));
507 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
508 Preferences.USE_RNAVIEW, true));
512 ssm.setAddTempFacAnnot(false);
513 ssm.setProcessSecondaryStructure(false);
514 ssm.setSecStructServices(false);
518 public void checkForNews()
520 final Desktop me = this;
521 // Thread off the news reader, in case there are connection problems.
522 addDialogThread(new Runnable()
527 Cache.log.debug("Starting news thread.");
529 jvnews = new BlogReader(me);
530 showNews.setVisible(true);
531 Cache.log.debug("Completed news thread.");
536 public void getIdentifiersOrgData()
538 // Thread off the identifiers fetcher
539 addDialogThread(new Runnable()
544 Cache.log.debug("Downloading data from identifiers.org");
545 UrlDownloadClient client = new UrlDownloadClient();
548 client.download(IdOrgSettings.getUrl(),
549 IdOrgSettings.getDownloadLocation());
550 } catch (IOException e)
552 Cache.log.debug("Exception downloading identifiers.org data"
560 protected void showNews_actionPerformed(ActionEvent e)
562 showNews(showNews.isSelected());
565 void showNews(boolean visible)
568 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
569 showNews.setSelected(visible);
570 if (visible && !jvnews.isVisible())
572 new Thread(new Runnable()
577 long now = System.currentTimeMillis();
578 Desktop.instance.setProgressBar(
579 MessageManager.getString("status.refreshing_news"), now);
580 jvnews.refreshNews();
581 Desktop.instance.setProgressBar(null, now);
590 * recover the last known dimensions for a jalview window
593 * - empty string is desktop, all other windows have unique prefix
594 * @return null or last known dimensions scaled to current geometry (if last
595 * window geom was known)
597 Rectangle getLastKnownDimensions(String windowName)
599 // TODO: lock aspect ratio for scaling desktop Bug #0058199
600 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
601 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
602 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
603 String width = jalview.bin.Cache.getProperty(windowName
605 String height = jalview.bin.Cache.getProperty(windowName
607 if ((x != null) && (y != null) && (width != null) && (height != null))
609 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
610 .parseInt(width), ih = Integer.parseInt(height);
611 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
613 // attempt #1 - try to cope with change in screen geometry - this
614 // version doesn't preserve original jv aspect ratio.
615 // take ratio of current screen size vs original screen size.
616 double sw = ((1f * screenSize.width) / (1f * Integer
617 .parseInt(jalview.bin.Cache
618 .getProperty("SCREENGEOMETRY_WIDTH"))));
619 double sh = ((1f * screenSize.height) / (1f * Integer
620 .parseInt(jalview.bin.Cache
621 .getProperty("SCREENGEOMETRY_HEIGHT"))));
622 // rescale the bounds depending upon the current screen geometry.
623 ix = (int) (ix * sw);
624 iw = (int) (iw * sw);
625 iy = (int) (iy * sh);
626 ih = (int) (ih * sh);
627 while (ix >= screenSize.width)
629 jalview.bin.Cache.log
630 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
631 ix -= screenSize.width;
633 while (iy >= screenSize.height)
635 jalview.bin.Cache.log
636 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
637 iy -= screenSize.height;
639 jalview.bin.Cache.log.debug("Got last known dimensions for "
640 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
643 // return dimensions for new instance
644 return new Rectangle(ix, iy, iw, ih);
649 private void doVamsasClientCheck()
651 if (jalview.bin.Cache.vamsasJarsPresent())
653 setupVamsasDisconnectedGui();
654 VamsasMenu.setVisible(true);
655 final Desktop us = this;
656 VamsasMenu.addMenuListener(new MenuListener()
658 // this listener remembers when the menu was first selected, and
659 // doesn't rebuild the session list until it has been cleared and
661 boolean refresh = true;
664 public void menuCanceled(MenuEvent e)
670 public void menuDeselected(MenuEvent e)
676 public void menuSelected(MenuEvent e)
680 us.buildVamsasStMenu();
685 vamsasStart.setVisible(true);
689 void showPasteMenu(int x, int y)
691 JPopupMenu popup = new JPopupMenu();
692 JMenuItem item = new JMenuItem(
693 MessageManager.getString("label.paste_new_window"));
694 item.addActionListener(new ActionListener()
697 public void actionPerformed(ActionEvent evt)
704 popup.show(this, x, y);
711 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
712 Transferable contents = c.getContents(this);
714 if (contents != null)
716 String file = (String) contents
717 .getTransferData(DataFlavor.stringFlavor);
719 FileFormatI format = new IdentifyFile().identify(file,
720 DataSourceType.PASTE);
722 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
725 } catch (Exception ex)
728 .println("Unable to paste alignment from system clipboard:\n"
734 * Adds and opens the given frame to the desktop
745 public static synchronized void addInternalFrame(
746 final JInternalFrame frame, String title, int w, int h)
748 addInternalFrame(frame, title, true, w, h, true, false);
752 * Add an internal frame to the Jalview desktop
759 * When true, display frame immediately, otherwise, caller must call
760 * setVisible themselves.
766 public static synchronized void addInternalFrame(
767 final JInternalFrame frame, String title, boolean makeVisible,
770 addInternalFrame(frame, title, makeVisible, w, h, true, false);
774 * Add an internal frame to the Jalview desktop and make it visible
787 public static synchronized void addInternalFrame(
788 final JInternalFrame frame, String title, int w, int h,
791 addInternalFrame(frame, title, true, w, h, resizable, false);
795 * Add an internal frame to the Jalview desktop
802 * When true, display frame immediately, otherwise, caller must call
803 * setVisible themselves.
810 * @param ignoreMinSize
811 * No minimum size is set for the dialog
813 public static synchronized void addInternalFrame(
814 final JInternalFrame frame, String title, boolean makeVisible,
815 int w, int h, boolean resizable, boolean ignoreMinSize)
818 // TODO: allow callers to determine X and Y position of frame (eg. via
820 // TODO: consider fixing method to update entries in the window submenu with
821 // the current window title
823 frame.setTitle(title);
824 if (frame.getWidth() < 1 || frame.getHeight() < 1)
828 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
829 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
830 // IF JALVIEW IS RUNNING HEADLESS
831 // ///////////////////////////////////////////////
833 || (System.getProperty("java.awt.headless") != null && System
834 .getProperty("java.awt.headless").equals("true")))
843 frame.setMinimumSize(new Dimension(DEFAULT_MIN_WIDTH,
844 DEFAULT_MIN_HEIGHT));
846 frame.setVisible(makeVisible);
847 frame.setClosable(true);
848 frame.setResizable(resizable);
849 frame.setMaximizable(resizable);
850 frame.setIconifiable(resizable);
851 if (Platform.isAMac())
853 frame.setIconifiable(false);
854 frame.setFrameIcon(null);
855 // frame.setDesktopIcon(null);
856 frame.setDoubleBuffered(false);
858 if (frame.getX() < 1 && frame.getY() < 1)
860 frame.setLocation(xOffset * openFrameCount, yOffset
861 * ((openFrameCount - 1) % 10) + yOffset);
865 * add an entry for the new frame in the Window menu
866 * (and remove it when the frame is closed)
868 final JMenuItem menuItem = new JMenuItem(title);
869 frame.addInternalFrameListener(new InternalFrameAdapter()
872 public void internalFrameActivated(InternalFrameEvent evt)
874 JInternalFrame itf = desktop.getSelectedFrame();
882 public void internalFrameClosed(InternalFrameEvent evt)
884 PaintRefresher.RemoveComponent(frame);
887 * defensive check to prevent frames being
888 * added half off the window
890 if (openFrameCount > 0)
896 * ensure no reference to alignFrame retained by menu item listener
898 if (menuItem.getActionListeners().length > 0)
900 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
902 windowMenu.remove(menuItem);
903 JInternalFrame itf = desktop.getSelectedFrame();
907 if (itf instanceof AlignFrame)
909 Jalview.setCurrentAlignFrame((AlignFrame) itf);
916 menuItem.addActionListener(new ActionListener()
919 public void actionPerformed(ActionEvent e)
923 frame.setSelected(true);
924 frame.setIcon(false);
925 } catch (java.beans.PropertyVetoException ex)
934 windowMenu.add(menuItem);
939 frame.setSelected(true);
940 frame.requestFocus();
941 } catch (java.beans.PropertyVetoException ve)
943 } catch (java.lang.ClassCastException cex)
946 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
952 public void lostOwnership(Clipboard clipboard, Transferable contents)
956 Desktop.jalviewClipboard = null;
959 internalCopy = false;
963 public void dragEnter(DropTargetDragEvent evt)
968 public void dragExit(DropTargetEvent evt)
973 public void dragOver(DropTargetDragEvent evt)
978 public void dropActionChanged(DropTargetDragEvent evt)
989 public void drop(DropTargetDropEvent evt)
991 boolean success = true;
992 // JAL-1552 - acceptDrop required before getTransferable call for
993 // Java's Transferable for native dnd
994 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
995 Transferable t = evt.getTransferable();
996 List<String> files = new ArrayList<String>();
997 List<DataSourceType> protocols = new ArrayList<DataSourceType>();
1001 Desktop.transferFromDropTarget(files, protocols, evt, t);
1002 } catch (Exception e)
1004 e.printStackTrace();
1012 for (int i = 0; i < files.size(); i++)
1014 String file = files.get(i).toString();
1015 DataSourceType protocol = (protocols == null) ? DataSourceType.FILE
1017 FileFormatI format = null;
1019 if (file.endsWith(".jar"))
1021 format = FileFormat.Jalview;
1026 format = new IdentifyFile().identify(file, protocol);
1029 new FileLoader().LoadFile(file, protocol, format);
1032 } catch (Exception ex)
1037 evt.dropComplete(success); // need this to ensure input focus is properly
1038 // transfered to any new windows created
1048 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1050 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1051 JalviewFileChooser chooser = JalviewFileChooser.forRead(
1052 Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1054 chooser.setFileView(new JalviewFileView());
1055 chooser.setDialogTitle(MessageManager
1056 .getString("label.open_local_file"));
1057 chooser.setToolTipText(MessageManager.getString("action.open"));
1059 int value = chooser.showOpenDialog(this);
1061 if (value == JalviewFileChooser.APPROVE_OPTION)
1063 String choice = chooser.getSelectedFile().getPath();
1064 Cache.setProperty("LAST_DIRECTORY", chooser
1065 .getSelectedFile().getParent());
1067 FileFormatI format = chooser.getSelectedFormat();
1070 * Call IdentifyFile to verify the file contains what its extension implies.
1071 * Skip this step for dynamically added file formats, because
1072 * IdentifyFile does not know how to recognise them.
1074 if (FileFormats.getInstance().isIdentifiable(format))
1078 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1079 } catch (FileFormatException e)
1081 // format = null; //??
1085 if (viewport != null)
1087 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1092 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1104 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1106 // This construct allows us to have a wider textfield
1108 JLabel label = new JLabel(
1109 MessageManager.getString("label.input_file_url"));
1110 final JComboBox history = new JComboBox();
1112 JPanel panel = new JPanel(new GridLayout(2, 1));
1115 history.setPreferredSize(new Dimension(400, 20));
1116 history.setEditable(true);
1117 history.addItem("http://www.");
1119 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1123 if (historyItems != null)
1125 st = new StringTokenizer(historyItems, "\t");
1127 while (st.hasMoreTokens())
1129 history.addItem(st.nextElement());
1133 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1134 MessageManager.getString("label.input_alignment_from_url"),
1135 JvOptionPane.OK_CANCEL_OPTION);
1137 if (reply != JvOptionPane.OK_OPTION)
1142 String url = history.getSelectedItem().toString();
1144 if (url.toLowerCase().endsWith(".jar"))
1146 if (viewport != null)
1148 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1149 FileFormat.Jalview);
1153 new FileLoader().LoadFile(url, DataSourceType.URL,
1154 FileFormat.Jalview);
1159 FileFormatI format = null;
1162 format = new IdentifyFile().identify(url, DataSourceType.URL);
1163 } catch (FileFormatException e)
1165 // TODO revise error handling, distinguish between
1166 // URL not found and response not valid
1171 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1172 MessageManager.formatMessage("label.couldnt_locate",
1173 new Object[] { url }), MessageManager
1174 .getString("label.url_not_found"),
1175 JvOptionPane.WARNING_MESSAGE);
1180 if (viewport != null)
1183 .LoadFile(viewport, url, DataSourceType.URL, format);
1187 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1193 * Opens the CutAndPaste window for the user to paste an alignment in to
1196 * - if not null, the pasted alignment is added to the current
1197 * alignment; if null, to a new alignment window
1200 public void inputTextboxMenuItem_actionPerformed(
1201 AlignmentViewPanel viewPanel)
1203 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1204 cap.setForInput(viewPanel);
1205 Desktop.addInternalFrame(cap,
1206 MessageManager.getString("label.cut_paste_alignmen_file"),
1216 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1218 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1219 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1221 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1222 getBounds().y, getWidth(), getHeight()));
1224 if (jconsole != null)
1226 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1227 jconsole.stopConsole();
1231 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1234 if (dialogExecutor != null)
1236 dialogExecutor.shutdownNow();
1238 closeAll_actionPerformed(null);
1240 if (groovyConsole != null)
1242 // suppress a possible repeat prompt to save script
1243 groovyConsole.setDirty(false);
1244 groovyConsole.exit();
1249 private void storeLastKnownDimensions(String string, Rectangle jc)
1251 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1252 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1253 + " height:" + jc.height);
1255 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1256 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1257 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1258 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1268 public void aboutMenuItem_actionPerformed(ActionEvent e)
1270 // StringBuffer message = getAboutMessage(false);
1271 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1273 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1274 new Thread(new Runnable()
1279 new SplashScreen(true);
1284 public StringBuffer getAboutMessage(boolean shortv)
1286 StringBuffer message = new StringBuffer();
1287 message.append("<html>");
1290 message.append("<h1><strong>Version: "
1291 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1292 message.append("<strong>Last Updated: <em>"
1293 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1294 + "</em></strong>");
1300 message.append("<strong>Version "
1301 + jalview.bin.Cache.getProperty("VERSION")
1302 + "; last updated: "
1303 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1306 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1309 message.append("<br>...Checking latest version...</br>");
1311 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1312 .equals(jalview.bin.Cache.getProperty("VERSION")))
1314 boolean red = false;
1315 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1316 .indexOf("automated build") == -1)
1319 // Displayed when code version and jnlp version do not match and code
1320 // version is not a development build
1321 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1324 message.append("<br>!! Version "
1325 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1327 + " is available for download from "
1328 + jalview.bin.Cache.getDefault("www.jalview.org",
1329 "http://www.jalview.org") + " !!");
1332 message.append("</div>");
1335 message.append("<br>Authors: "
1337 .getDefault("AUTHORFNAMES",
1338 "The Jalview Authors (See AUTHORS file for current list)")
1339 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1340 + "<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"
1341 + "<br><br>If you use Jalview, please cite:"
1342 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1343 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1344 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1356 public void documentationMenuItem_actionPerformed(ActionEvent e)
1360 Help.showHelpWindow();
1361 } catch (Exception ex)
1367 public void closeAll_actionPerformed(ActionEvent e)
1369 // TODO show a progress bar while closing?
1370 JInternalFrame[] frames = desktop.getAllFrames();
1371 for (int i = 0; i < frames.length; i++)
1375 frames[i].setClosed(true);
1376 } catch (java.beans.PropertyVetoException ex)
1380 Jalview.setCurrentAlignFrame(null);
1381 System.out.println("ALL CLOSED");
1382 if (v_client != null)
1384 // TODO clear binding to vamsas document objects on close_all
1388 * reset state of singleton objects as appropriate (clear down session state
1389 * when all windows are closed)
1391 StructureSelectionManager ssm = StructureSelectionManager
1392 .getStructureSelectionManager(this);
1401 public void raiseRelated_actionPerformed(ActionEvent e)
1403 reorderAssociatedWindows(false, false);
1407 public void minimizeAssociated_actionPerformed(ActionEvent e)
1409 reorderAssociatedWindows(true, false);
1412 void closeAssociatedWindows()
1414 reorderAssociatedWindows(false, true);
1420 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1424 protected void garbageCollect_actionPerformed(ActionEvent e)
1426 // We simply collect the garbage
1427 jalview.bin.Cache.log.debug("Collecting garbage...");
1429 jalview.bin.Cache.log.debug("Finished garbage collection.");
1436 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1440 protected void showMemusage_actionPerformed(ActionEvent e)
1442 desktop.showMemoryUsage(showMemusage.isSelected());
1449 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1453 protected void showConsole_actionPerformed(ActionEvent e)
1455 showConsole(showConsole.isSelected());
1458 Console jconsole = null;
1461 * control whether the java console is visible or not
1465 void showConsole(boolean selected)
1467 showConsole.setSelected(selected);
1468 // TODO: decide if we should update properties file
1469 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1471 jconsole.setVisible(selected);
1474 void reorderAssociatedWindows(boolean minimize, boolean close)
1476 JInternalFrame[] frames = desktop.getAllFrames();
1477 if (frames == null || frames.length < 1)
1482 AlignmentViewport source = null, target = null;
1483 if (frames[0] instanceof AlignFrame)
1485 source = ((AlignFrame) frames[0]).getCurrentView();
1487 else if (frames[0] instanceof TreePanel)
1489 source = ((TreePanel) frames[0]).getViewPort();
1491 else if (frames[0] instanceof PCAPanel)
1493 source = ((PCAPanel) frames[0]).av;
1495 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1497 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1502 for (int i = 0; i < frames.length; i++)
1505 if (frames[i] == null)
1509 if (frames[i] instanceof AlignFrame)
1511 target = ((AlignFrame) frames[i]).getCurrentView();
1513 else if (frames[i] instanceof TreePanel)
1515 target = ((TreePanel) frames[i]).getViewPort();
1517 else if (frames[i] instanceof PCAPanel)
1519 target = ((PCAPanel) frames[i]).av;
1521 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1523 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1526 if (source == target)
1532 frames[i].setClosed(true);
1536 frames[i].setIcon(minimize);
1539 frames[i].toFront();
1543 } catch (java.beans.PropertyVetoException ex)
1558 protected void preferences_actionPerformed(ActionEvent e)
1570 public void saveState_actionPerformed(ActionEvent e)
1572 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1575 chooser.setFileView(new JalviewFileView());
1576 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1578 int value = chooser.showSaveDialog(this);
1580 if (value == JalviewFileChooser.APPROVE_OPTION)
1582 final Desktop me = this;
1583 final java.io.File choice = chooser.getSelectedFile();
1584 setProjectFile(choice);
1586 new Thread(new Runnable()
1591 // TODO: refactor to Jalview desktop session controller action.
1592 setProgressBar(MessageManager.formatMessage(
1593 "label.saving_jalview_project",
1594 new Object[] { choice.getName() }), choice.hashCode());
1595 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1596 choice.getParent());
1597 // TODO catch and handle errors for savestate
1598 // TODO prevent user from messing with the Desktop whilst we're saving
1601 new Jalview2XML().saveState(choice);
1602 } catch (OutOfMemoryError oom)
1604 new OOMWarning("Whilst saving current state to "
1605 + choice.getName(), oom);
1606 } catch (Exception ex)
1609 "Problems whilst trying to save to " + choice.getName(),
1611 JvOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1612 "label.error_whilst_saving_current_state_to",
1613 new Object[] { choice.getName() }), MessageManager
1614 .getString("label.couldnt_save_project"),
1615 JvOptionPane.WARNING_MESSAGE);
1617 setProgressBar(null, choice.hashCode());
1623 private void setProjectFile(File choice)
1625 this.projectFile = choice;
1628 public File getProjectFile()
1630 return this.projectFile;
1640 public void loadState_actionPerformed(ActionEvent e)
1642 JalviewFileChooser chooser = new JalviewFileChooser(
1643 Cache.getProperty("LAST_DIRECTORY"), new String[] {
1644 "jvp", "jar" }, new String[] { "Jalview Project",
1645 "Jalview Project (old)" }, "Jalview Project");
1646 chooser.setFileView(new JalviewFileView());
1647 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1649 int value = chooser.showOpenDialog(this);
1651 if (value == JalviewFileChooser.APPROVE_OPTION)
1653 final File selectedFile = chooser.getSelectedFile();
1654 setProjectFile(selectedFile);
1655 final String choice = selectedFile.getAbsolutePath();
1656 Cache.setProperty("LAST_DIRECTORY",
1657 selectedFile.getParent());
1658 new Thread(new Runnable()
1664 MessageManager.formatMessage(
1665 "label.loading_jalview_project",
1666 new Object[] { choice }), choice.hashCode());
1669 new Jalview2XML().loadJalviewAlign(choice);
1670 } catch (OutOfMemoryError oom)
1672 new OOMWarning("Whilst loading project from " + choice, oom);
1673 } catch (Exception ex)
1675 Cache.log.error("Problems whilst loading project from "
1677 JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1679 "label.error_whilst_loading_project_from",
1680 new Object[] { choice }), MessageManager
1681 .getString("label.couldnt_load_project"),
1682 JvOptionPane.WARNING_MESSAGE);
1684 setProgressBar(null, choice.hashCode());
1691 public void inputSequence_actionPerformed(ActionEvent e)
1693 new SequenceFetcher(this);
1696 JPanel progressPanel;
1698 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1700 public void startLoading(final String fileName)
1702 if (fileLoadingCount == 0)
1704 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1705 "label.loading_file", new Object[] { fileName })));
1710 private JPanel addProgressPanel(String string)
1712 if (progressPanel == null)
1714 progressPanel = new JPanel(new GridLayout(1, 1));
1715 totalProgressCount = 0;
1716 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1718 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1719 JProgressBar progressBar = new JProgressBar();
1720 progressBar.setIndeterminate(true);
1722 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1724 thisprogress.add(progressBar, BorderLayout.CENTER);
1725 progressPanel.add(thisprogress);
1726 ((GridLayout) progressPanel.getLayout())
1727 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1728 ++totalProgressCount;
1729 instance.validate();
1730 return thisprogress;
1733 int totalProgressCount = 0;
1735 private void removeProgressPanel(JPanel progbar)
1737 if (progressPanel != null)
1739 synchronized (progressPanel)
1741 progressPanel.remove(progbar);
1742 GridLayout gl = (GridLayout) progressPanel.getLayout();
1743 gl.setRows(gl.getRows() - 1);
1744 if (--totalProgressCount < 1)
1746 this.getContentPane().remove(progressPanel);
1747 progressPanel = null;
1754 public void stopLoading()
1757 if (fileLoadingCount < 1)
1759 while (fileLoadingPanels.size() > 0)
1761 removeProgressPanel(fileLoadingPanels.remove(0));
1763 fileLoadingPanels.clear();
1764 fileLoadingCount = 0;
1769 public static int getViewCount(String alignmentId)
1771 AlignmentViewport[] aps = getViewports(alignmentId);
1772 return (aps == null) ? 0 : aps.length;
1777 * @param alignmentId
1778 * - if null, all sets are returned
1779 * @return all AlignmentPanels concerning the alignmentId sequence set
1781 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1783 if (Desktop.desktop == null)
1785 // no frames created and in headless mode
1786 // TODO: verify that frames are recoverable when in headless mode
1789 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1790 AlignFrame[] frames = getAlignFrames();
1795 for (AlignFrame af : frames)
1797 for (AlignmentPanel ap : af.alignPanels)
1799 if (alignmentId == null
1800 || alignmentId.equals(ap.av.getSequenceSetId()))
1806 if (aps.size() == 0)
1810 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1815 * get all the viewports on an alignment.
1817 * @param sequenceSetId
1818 * unique alignment id (may be null - all viewports returned in that
1820 * @return all viewports on the alignment bound to sequenceSetId
1822 public static AlignmentViewport[] getViewports(String sequenceSetId)
1824 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1825 if (desktop != null)
1827 AlignFrame[] frames = Desktop.getAlignFrames();
1829 for (AlignFrame afr : frames)
1831 if (sequenceSetId == null
1832 || afr.getViewport().getSequenceSetId()
1833 .equals(sequenceSetId))
1835 if (afr.alignPanels != null)
1837 for (AlignmentPanel ap : afr.alignPanels)
1839 if (sequenceSetId == null
1840 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1848 viewp.add(afr.getViewport());
1852 if (viewp.size() > 0)
1854 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1861 * Explode the views in the given frame into separate AlignFrame
1865 public static void explodeViews(AlignFrame af)
1867 int size = af.alignPanels.size();
1873 for (int i = 0; i < size; i++)
1875 AlignmentPanel ap = af.alignPanels.get(i);
1876 AlignFrame newaf = new AlignFrame(ap);
1879 * Restore the view's last exploded frame geometry if known. Multiple
1880 * views from one exploded frame share and restore the same (frame)
1881 * position and size.
1883 Rectangle geometry = ap.av.getExplodedGeometry();
1884 if (geometry != null)
1886 newaf.setBounds(geometry);
1889 ap.av.setGatherViewsHere(false);
1891 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1892 AlignFrame.DEFAULT_HEIGHT);
1895 af.alignPanels.clear();
1896 af.closeMenuItem_actionPerformed(true);
1901 * Gather expanded views (separate AlignFrame's) with the same sequence set
1902 * identifier back in to this frame as additional views, and close the
1903 * expanded views. Note the expanded frames may themselves have multiple
1904 * views. We take the lot.
1908 public void gatherViews(AlignFrame source)
1910 source.viewport.setGatherViewsHere(true);
1911 source.viewport.setExplodedGeometry(source.getBounds());
1912 JInternalFrame[] frames = desktop.getAllFrames();
1913 String viewId = source.viewport.getSequenceSetId();
1915 for (int t = 0; t < frames.length; t++)
1917 if (frames[t] instanceof AlignFrame && frames[t] != source)
1919 AlignFrame af = (AlignFrame) frames[t];
1920 boolean gatherThis = false;
1921 for (int a = 0; a < af.alignPanels.size(); a++)
1923 AlignmentPanel ap = af.alignPanels.get(a);
1924 if (viewId.equals(ap.av.getSequenceSetId()))
1927 ap.av.setGatherViewsHere(false);
1928 ap.av.setExplodedGeometry(af.getBounds());
1929 source.addAlignmentPanel(ap, false);
1935 af.alignPanels.clear();
1936 af.closeMenuItem_actionPerformed(true);
1943 jalview.gui.VamsasApplication v_client = null;
1946 public void vamsasImport_actionPerformed(ActionEvent e)
1948 if (v_client == null)
1950 // Load and try to start a session.
1951 JalviewFileChooser chooser = new JalviewFileChooser(
1952 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1954 chooser.setFileView(new JalviewFileView());
1955 chooser.setDialogTitle(MessageManager
1956 .getString("label.open_saved_vamsas_session"));
1957 chooser.setToolTipText(MessageManager
1958 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1960 int value = chooser.showOpenDialog(this);
1962 if (value == JalviewFileChooser.APPROVE_OPTION)
1964 String fle = chooser.getSelectedFile().toString();
1965 if (!vamsasImport(chooser.getSelectedFile()))
1968 .showInternalMessageDialog(
1970 MessageManager.formatMessage(
1971 "label.couldnt_import_as_vamsas_session",
1972 new Object[] { fle }),
1974 .getString("label.vamsas_document_import_failed"),
1975 JvOptionPane.ERROR_MESSAGE);
1981 jalview.bin.Cache.log
1982 .error("Implementation error - load session from a running session is not supported.");
1987 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1990 * @return true if import was a success and a session was started.
1992 public boolean vamsasImport(URL url)
1994 // TODO: create progress bar
1995 if (v_client != null)
1998 jalview.bin.Cache.log
1999 .error("Implementation error - load session from a running session is not supported.");
2005 // copy the URL content to a temporary local file
2006 // TODO: be a bit cleverer here with nio (?!)
2007 File file = File.createTempFile("vdocfromurl", ".vdj");
2008 FileOutputStream fos = new FileOutputStream(file);
2009 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2010 byte[] buffer = new byte[2048];
2012 while ((ln = bis.read(buffer)) > -1)
2014 fos.write(buffer, 0, ln);
2018 v_client = new jalview.gui.VamsasApplication(this, file,
2019 url.toExternalForm());
2020 } catch (Exception ex)
2022 jalview.bin.Cache.log.error(
2023 "Failed to create new vamsas session from contents of URL "
2027 setupVamsasConnectedGui();
2028 v_client.initial_update(); // TODO: thread ?
2029 return v_client.inSession();
2033 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2036 * @return true if import was a success and a session was started.
2038 public boolean vamsasImport(File file)
2040 if (v_client != null)
2043 jalview.bin.Cache.log
2044 .error("Implementation error - load session from a running session is not supported.");
2048 setProgressBar(MessageManager.formatMessage(
2049 "status.importing_vamsas_session_from",
2050 new Object[] { file.getName() }), file.hashCode());
2053 v_client = new jalview.gui.VamsasApplication(this, file, null);
2054 } catch (Exception ex)
2056 setProgressBar(MessageManager.formatMessage(
2057 "status.importing_vamsas_session_from",
2058 new Object[] { file.getName() }), file.hashCode());
2059 jalview.bin.Cache.log.error(
2060 "New vamsas session from existing session file failed:", ex);
2063 setupVamsasConnectedGui();
2064 v_client.initial_update(); // TODO: thread ?
2065 setProgressBar(MessageManager.formatMessage(
2066 "status.importing_vamsas_session_from",
2067 new Object[] { file.getName() }), file.hashCode());
2068 return v_client.inSession();
2071 public boolean joinVamsasSession(String mysesid)
2073 if (v_client != null)
2077 .getString("error.try_join_vamsas_session_another"));
2079 if (mysesid == null)
2082 MessageManager.getString("error.invalid_vamsas_session_id"));
2084 v_client = new VamsasApplication(this, mysesid);
2085 setupVamsasConnectedGui();
2086 v_client.initial_update();
2087 return (v_client.inSession());
2091 public void vamsasStart_actionPerformed(ActionEvent e)
2093 if (v_client == null)
2096 // we just start a default session for moment.
2098 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2099 * getProperty("LAST_DIRECTORY"));
2101 * chooser.setFileView(new JalviewFileView());
2102 * chooser.setDialogTitle("Load Vamsas file");
2103 * chooser.setToolTipText("Import");
2105 * int value = chooser.showOpenDialog(this);
2107 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2108 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2110 v_client = new VamsasApplication(this);
2111 setupVamsasConnectedGui();
2112 v_client.initial_update(); // TODO: thread ?
2116 // store current data in session.
2117 v_client.push_update(); // TODO: thread
2121 protected void setupVamsasConnectedGui()
2123 vamsasStart.setText(MessageManager.getString("label.session_update"));
2124 vamsasSave.setVisible(true);
2125 vamsasStop.setVisible(true);
2126 vamsasImport.setVisible(false); // Document import to existing session is
2127 // not possible for vamsas-client-1.0.
2130 protected void setupVamsasDisconnectedGui()
2132 vamsasSave.setVisible(false);
2133 vamsasStop.setVisible(false);
2134 vamsasImport.setVisible(true);
2135 vamsasStart.setText(MessageManager
2136 .getString("label.new_vamsas_session"));
2140 public void vamsasStop_actionPerformed(ActionEvent e)
2142 if (v_client != null)
2144 v_client.end_session();
2146 setupVamsasDisconnectedGui();
2150 protected void buildVamsasStMenu()
2152 if (v_client == null)
2154 String[] sess = null;
2157 sess = VamsasApplication.getSessionList();
2158 } catch (Exception e)
2160 jalview.bin.Cache.log.warn(
2161 "Problem getting current sessions list.", e);
2166 jalview.bin.Cache.log.debug("Got current sessions list: "
2167 + sess.length + " entries.");
2168 VamsasStMenu.removeAll();
2169 for (int i = 0; i < sess.length; i++)
2171 JMenuItem sessit = new JMenuItem();
2172 sessit.setText(sess[i]);
2173 sessit.setToolTipText(MessageManager.formatMessage(
2174 "label.connect_to_session", new Object[] { sess[i] }));
2175 final Desktop dsktp = this;
2176 final String mysesid = sess[i];
2177 sessit.addActionListener(new ActionListener()
2181 public void actionPerformed(ActionEvent e)
2183 if (dsktp.v_client == null)
2185 Thread rthr = new Thread(new Runnable()
2191 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2192 dsktp.setupVamsasConnectedGui();
2193 dsktp.v_client.initial_update();
2201 VamsasStMenu.add(sessit);
2203 // don't show an empty menu.
2204 VamsasStMenu.setVisible(sess.length > 0);
2209 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2210 VamsasStMenu.removeAll();
2211 VamsasStMenu.setVisible(false);
2216 // Not interested in the content. Just hide ourselves.
2217 VamsasStMenu.setVisible(false);
2222 public void vamsasSave_actionPerformed(ActionEvent e)
2224 if (v_client != null)
2226 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2227 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2230 chooser.setFileView(new JalviewFileView());
2231 chooser.setDialogTitle(MessageManager
2232 .getString("label.save_vamsas_document_archive"));
2234 int value = chooser.showSaveDialog(this);
2236 if (value == JalviewFileChooser.APPROVE_OPTION)
2238 java.io.File choice = chooser.getSelectedFile();
2239 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2240 "label.saving_vamsas_doc",
2241 new Object[] { choice.getName() }));
2242 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2243 String warnmsg = null;
2244 String warnttl = null;
2247 v_client.vclient.storeDocument(choice);
2250 warnttl = "Serious Problem saving Vamsas Document";
2251 warnmsg = ex.toString();
2252 jalview.bin.Cache.log.error("Error Whilst saving document to "
2255 } catch (Exception ex)
2257 warnttl = "Problem saving Vamsas Document.";
2258 warnmsg = ex.toString();
2259 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2263 removeProgressPanel(progpanel);
2264 if (warnmsg != null)
2266 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2268 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2274 JPanel vamUpdate = null;
2277 * hide vamsas user gui bits when a vamsas document event is being handled.
2280 * true to hide gui, false to reveal gui
2282 public void setVamsasUpdate(boolean b)
2284 Cache.log.debug("Setting gui for Vamsas update "
2285 + (b ? "in progress" : "finished"));
2287 if (vamUpdate != null)
2289 this.removeProgressPanel(vamUpdate);
2293 vamUpdate = this.addProgressPanel(MessageManager
2294 .getString("label.updating_vamsas_session"));
2296 vamsasStart.setVisible(!b);
2297 vamsasStop.setVisible(!b);
2298 vamsasSave.setVisible(!b);
2301 public JInternalFrame[] getAllFrames()
2303 return desktop.getAllFrames();
2307 * Checks the given url to see if it gives a response indicating that the user
2308 * should be informed of a new questionnaire.
2312 public void checkForQuestionnaire(String url)
2314 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2315 // javax.swing.SwingUtilities.invokeLater(jvq);
2316 new Thread(jvq).start();
2319 public void checkURLLinks()
2321 // Thread off the URL link checker
2322 addDialogThread(new Runnable()
2327 if (Cache.getDefault("CHECKURLLINKS", true))
2329 // check what the actual links are - if it's just the default don't
2330 // bother with the warning
2331 List<String> links = Preferences.sequenceUrlLinks
2334 // only need to check links if there is one with a
2335 // SEQUENCE_ID which is not the default EMBL_EBI link
2336 ListIterator<String> li = links.listIterator();
2337 boolean check = false;
2338 List<JLabel> urls = new ArrayList<JLabel>();
2339 while (li.hasNext())
2341 String link = li.next();
2342 if (link.contains(SEQUENCE_ID)
2343 && !link.equals(UrlConstants.DEFAULT_STRING))
2346 int barPos = link.indexOf("|");
2347 String urlMsg = barPos == -1 ? link : link.substring(0,
2348 barPos) + ": " + link.substring(barPos + 1);
2349 urls.add(new JLabel(urlMsg));
2357 // ask user to check in case URL links use old style tokens
2358 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2359 JPanel msgPanel = new JPanel();
2360 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2361 msgPanel.add(Box.createVerticalGlue());
2362 JLabel msg = new JLabel(
2364 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2365 JLabel msg2 = new JLabel(
2367 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2369 for (JLabel url : urls)
2375 final JCheckBox jcb = new JCheckBox(
2376 MessageManager.getString("label.do_not_display_again"));
2377 jcb.addActionListener(new ActionListener()
2380 public void actionPerformed(ActionEvent e)
2382 // update Cache settings for "don't show this again"
2383 boolean showWarningAgain = !jcb.isSelected();
2384 Cache.setProperty("CHECKURLLINKS",
2385 Boolean.valueOf(showWarningAgain).toString());
2390 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2392 .getString("label.SEQUENCE_ID_no_longer_used"),
2393 JvOptionPane.WARNING_MESSAGE);
2400 * Proxy class for JDesktopPane which optionally displays the current memory
2401 * usage and highlights the desktop area with a red bar if free memory runs
2406 public class MyDesktopPane extends JDesktopPane implements Runnable
2409 private static final float ONE_MB = 1048576f;
2411 boolean showMemoryUsage = false;
2415 java.text.NumberFormat df;
2417 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2420 public MyDesktopPane(boolean showMemoryUsage)
2422 showMemoryUsage(showMemoryUsage);
2425 public void showMemoryUsage(boolean showMemory)
2427 this.showMemoryUsage = showMemory;
2430 Thread worker = new Thread(this);
2435 public boolean isShowMemoryUsage()
2437 return showMemoryUsage;
2443 df = java.text.NumberFormat.getNumberInstance();
2444 df.setMaximumFractionDigits(2);
2445 runtime = Runtime.getRuntime();
2447 while (showMemoryUsage)
2451 maxMemory = runtime.maxMemory() / ONE_MB;
2452 allocatedMemory = runtime.totalMemory() / ONE_MB;
2453 freeMemory = runtime.freeMemory() / ONE_MB;
2454 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2456 percentUsage = (totalFreeMemory / maxMemory) * 100;
2458 // if (percentUsage < 20)
2460 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2462 // instance.set.setBorder(border1);
2465 // sleep after showing usage
2467 } catch (Exception ex)
2469 ex.printStackTrace();
2475 public void paintComponent(Graphics g)
2477 if (showMemoryUsage && g != null && df != null)
2479 if (percentUsage < 20)
2481 g.setColor(Color.red);
2483 FontMetrics fm = g.getFontMetrics();
2486 g.drawString(MessageManager.formatMessage(
2487 "label.memory_stats",
2488 new Object[] { df.format(totalFreeMemory),
2489 df.format(maxMemory), df.format(percentUsage) }), 10,
2490 getHeight() - fm.getHeight());
2497 * fixes stacking order after a modal dialog to ensure windows that should be
2498 * on top actually are
2500 public void relayerWindows()
2505 protected JMenuItem groovyShell;
2508 * Accessor method to quickly get all the AlignmentFrames loaded.
2510 * @return an array of AlignFrame, or null if none found
2512 public static AlignFrame[] getAlignFrames()
2514 if (Jalview.isHeadlessMode())
2516 // Desktop.desktop is null in headless mode
2517 return new AlignFrame[] { Jalview.currentAlignFrame };
2520 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2526 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2528 for (int i = frames.length - 1; i > -1; i--)
2530 if (frames[i] instanceof AlignFrame)
2532 avp.add((AlignFrame) frames[i]);
2534 else if (frames[i] instanceof SplitFrame)
2537 * Also check for a split frame containing an AlignFrame
2539 GSplitFrame sf = (GSplitFrame) frames[i];
2540 if (sf.getTopFrame() instanceof AlignFrame)
2542 avp.add((AlignFrame) sf.getTopFrame());
2544 if (sf.getBottomFrame() instanceof AlignFrame)
2546 avp.add((AlignFrame) sf.getBottomFrame());
2550 if (avp.size() == 0)
2554 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2559 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2563 public GStructureViewer[] getJmols()
2565 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2571 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2573 for (int i = frames.length - 1; i > -1; i--)
2575 if (frames[i] instanceof AppJmol)
2577 GStructureViewer af = (GStructureViewer) frames[i];
2581 if (avp.size() == 0)
2585 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2590 * Add Groovy Support to Jalview
2592 public void groovyShell_actionPerformed()
2596 openGroovyConsole();
2597 } catch (Exception ex)
2599 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2600 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2602 MessageManager.getString("label.couldnt_create_groovy_shell"),
2603 MessageManager.getString("label.groovy_support_failed"),
2604 JvOptionPane.ERROR_MESSAGE);
2609 * Open the Groovy console
2611 void openGroovyConsole()
2613 if (groovyConsole == null)
2615 groovyConsole = new groovy.ui.Console();
2616 groovyConsole.setVariable("Jalview", this);
2617 groovyConsole.run();
2620 * We allow only one console at a time, so that AlignFrame menu option
2621 * 'Calculate | Run Groovy script' is unambiguous.
2622 * Disable 'Groovy Console', and enable 'Run script', when the console is
2623 * opened, and the reverse when it is closed
2625 Window window = (Window) groovyConsole.getFrame();
2626 window.addWindowListener(new WindowAdapter()
2629 public void windowClosed(WindowEvent e)
2632 * rebind CMD-Q from Groovy Console to Jalview Quit
2635 enableExecuteGroovy(false);
2641 * show Groovy console window (after close and reopen)
2643 ((Window) groovyConsole.getFrame()).setVisible(true);
2646 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2647 * and disable opening a second console
2649 enableExecuteGroovy(true);
2653 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2654 * binding when opened
2656 protected void addQuitHandler()
2658 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2659 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2660 .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
2661 getRootPane().getActionMap().put("Quit", new AbstractAction()
2664 public void actionPerformed(ActionEvent e)
2672 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2675 * true if Groovy console is open
2677 public void enableExecuteGroovy(boolean enabled)
2680 * disable opening a second Groovy console
2681 * (or re-enable when the console is closed)
2683 groovyShell.setEnabled(!enabled);
2685 AlignFrame[] alignFrames = getAlignFrames();
2686 if (alignFrames != null)
2688 for (AlignFrame af : alignFrames)
2690 af.setGroovyEnabled(enabled);
2696 * Progress bars managed by the IProgressIndicator method.
2698 private Hashtable<Long, JPanel> progressBars;
2700 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2705 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2708 public void setProgressBar(String message, long id)
2710 if (progressBars == null)
2712 progressBars = new Hashtable<Long, JPanel>();
2713 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2716 if (progressBars.get(new Long(id)) != null)
2718 JPanel panel = progressBars.remove(new Long(id));
2719 if (progressBarHandlers.contains(new Long(id)))
2721 progressBarHandlers.remove(new Long(id));
2723 removeProgressPanel(panel);
2727 progressBars.put(new Long(id), addProgressPanel(message));
2734 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2735 * jalview.gui.IProgressIndicatorHandler)
2738 public void registerHandler(final long id,
2739 final IProgressIndicatorHandler handler)
2741 if (progressBarHandlers == null
2742 || !progressBars.containsKey(new Long(id)))
2746 .getString("error.call_setprogressbar_before_registering_handler"));
2748 progressBarHandlers.put(new Long(id), handler);
2749 final JPanel progressPanel = progressBars.get(new Long(id));
2750 if (handler.canCancel())
2752 JButton cancel = new JButton(
2753 MessageManager.getString("action.cancel"));
2754 final IProgressIndicator us = this;
2755 cancel.addActionListener(new ActionListener()
2759 public void actionPerformed(ActionEvent e)
2761 handler.cancelActivity(id);
2762 us.setProgressBar(MessageManager.formatMessage(
2763 "label.cancelled_params",
2764 new Object[] { ((JLabel) progressPanel.getComponent(0))
2768 progressPanel.add(cancel, BorderLayout.EAST);
2774 * @return true if any progress bars are still active
2777 public boolean operationInProgress()
2779 if (progressBars != null && progressBars.size() > 0)
2787 * This will return the first AlignFrame holding the given viewport instance.
2788 * It will break if there are more than one AlignFrames viewing a particular
2792 * @return alignFrame for viewport
2794 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2796 if (desktop != null)
2798 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2799 for (int panel = 0; aps != null && panel < aps.length; panel++)
2801 if (aps[panel] != null && aps[panel].av == viewport)
2803 return aps[panel].alignFrame;
2810 public VamsasApplication getVamsasApplication()
2817 * flag set if jalview GUI is being operated programmatically
2819 private boolean inBatchMode = false;
2822 * check if jalview GUI is being operated programmatically
2824 * @return inBatchMode
2826 public boolean isInBatchMode()
2832 * set flag if jalview GUI is being operated programmatically
2834 * @param inBatchMode
2836 public void setInBatchMode(boolean inBatchMode)
2838 this.inBatchMode = inBatchMode;
2841 public void startServiceDiscovery()
2843 startServiceDiscovery(false);
2846 public void startServiceDiscovery(boolean blocking)
2848 boolean alive = true;
2849 Thread t0 = null, t1 = null, t2 = null;
2850 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2853 // todo: changesupport handlers need to be transferred
2854 if (discoverer == null)
2856 discoverer = new jalview.ws.jws1.Discoverer();
2857 // register PCS handler for desktop.
2858 discoverer.addPropertyChangeListener(changeSupport);
2860 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2861 // until we phase out completely
2862 (t0 = new Thread(discoverer)).start();
2865 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2867 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2872 // TODO: do rest service discovery
2881 } catch (Exception e)
2884 alive = (t1 != null && t1.isAlive())
2885 || (t2 != null && t2.isAlive())
2886 || (t3 != null && t3.isAlive())
2887 || (t0 != null && t0.isAlive());
2893 * called to check if the service discovery process completed successfully.
2897 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2899 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2901 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2902 .getErrorMessages();
2905 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2907 if (serviceChangedDialog == null)
2909 // only run if we aren't already displaying one of these.
2910 addDialogThread(serviceChangedDialog = new Runnable()
2917 * JalviewDialog jd =new JalviewDialog() {
2919 * @Override protected void cancelPressed() { // TODO
2920 * Auto-generated method stub
2922 * }@Override protected void okPressed() { // TODO
2923 * Auto-generated method stub
2925 * }@Override protected void raiseClosed() { // TODO
2926 * Auto-generated method stub
2928 * } }; jd.initDialogFrame(new
2929 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2930 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2931 * + " or mis-configured HTTP proxy settings.<br/>" +
2932 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2934 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2935 * ), true, true, "Web Service Configuration Problem", 450,
2938 * jd.waitForInput();
2944 "<html><table width=\"450\"><tr><td>"
2946 + "</td></tr></table>"
2947 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2948 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2949 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2950 + " Tools->Preferences dialog box to change them.</p></html>"),
2951 "Web Service Configuration Problem",
2952 JvOptionPane.DEFAULT_OPTION,
2953 JvOptionPane.ERROR_MESSAGE);
2954 serviceChangedDialog = null;
2963 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2970 private Runnable serviceChangedDialog = null;
2973 * start a thread to open a URL in the configured browser. Pops up a warning
2974 * dialog to the user if there is an exception when calling out to the browser
2979 public static void showUrl(final String url)
2981 showUrl(url, Desktop.instance);
2985 * Like showUrl but allows progress handler to be specified
2989 * (null) or object implementing IProgressIndicator
2991 public static void showUrl(final String url,
2992 final IProgressIndicator progress)
2994 new Thread(new Runnable()
3001 if (progress != null)
3003 progress.setProgressBar(MessageManager.formatMessage(
3004 "status.opening_params", new Object[] { url }), this
3007 jalview.util.BrowserLauncher.openURL(url);
3008 } catch (Exception ex)
3010 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3012 .getString("label.web_browser_not_found_unix"),
3013 MessageManager.getString("label.web_browser_not_found"),
3014 JvOptionPane.WARNING_MESSAGE);
3016 ex.printStackTrace();
3018 if (progress != null)
3020 progress.setProgressBar(null, this.hashCode());
3026 public static WsParamSetManager wsparamManager = null;
3028 public static ParamManager getUserParameterStore()
3030 if (wsparamManager == null)
3032 wsparamManager = new WsParamSetManager();
3034 return wsparamManager;
3038 * static hyperlink handler proxy method for use by Jalview's internal windows
3042 public static void hyperlinkUpdate(HyperlinkEvent e)
3044 if (e.getEventType() == EventType.ACTIVATED)
3049 url = e.getURL().toString();
3050 Desktop.showUrl(url);
3051 } catch (Exception x)
3055 if (Cache.log != null)
3057 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3061 System.err.println("Couldn't handle string " + url
3065 // ignore any exceptions due to dud links.
3072 * single thread that handles display of dialogs to user.
3074 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3077 * flag indicating if dialogExecutor should try to acquire a permit
3079 private volatile boolean dialogPause = true;
3084 private java.util.concurrent.Semaphore block = new Semaphore(0);
3086 private static groovy.ui.Console groovyConsole;
3089 * add another dialog thread to the queue
3093 public void addDialogThread(final Runnable prompter)
3095 dialogExecutor.submit(new Runnable()
3105 } catch (InterruptedException x)
3110 if (instance == null)
3116 SwingUtilities.invokeAndWait(prompter);
3117 } catch (Exception q)
3119 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3125 public void startDialogQueue()
3127 // set the flag so we don't pause waiting for another permit and semaphore
3128 // the current task to begin
3129 dialogPause = false;
3134 protected void snapShotWindow_actionPerformed(ActionEvent e)
3138 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3139 "View of Desktop", getWidth(), getHeight(), of = new File(
3140 "Jalview_snapshot" + System.currentTimeMillis()
3141 + ".eps"), "View of desktop", null, 0, false);
3144 paintAll(im.getGraphics());
3146 } catch (Exception q)
3148 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3152 Cache.log.info("Successfully written snapshot to file "
3153 + of.getAbsolutePath());
3157 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3158 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3159 * and location last time the view was expanded (if any). However it does not
3160 * remember the split pane divider location - this is set to match the
3161 * 'exploding' frame.
3165 public void explodeViews(SplitFrame sf)
3167 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3168 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3169 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3171 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3173 int viewCount = topPanels.size();
3180 * Processing in reverse order works, forwards order leaves the first panels
3181 * not visible. I don't know why!
3183 for (int i = viewCount - 1; i >= 0; i--)
3186 * Make new top and bottom frames. These take over the respective
3187 * AlignmentPanel objects, including their AlignmentViewports, so the
3188 * cdna/protein relationships between the viewports is carried over to the
3191 * explodedGeometry holds the (x, y) position of the previously exploded
3192 * SplitFrame, and the (width, height) of the AlignFrame component
3194 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3195 AlignFrame newTopFrame = new AlignFrame(topPanel);
3196 newTopFrame.setSize(oldTopFrame.getSize());
3197 newTopFrame.setVisible(true);
3198 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3199 .getExplodedGeometry();
3200 if (geometry != null)
3202 newTopFrame.setSize(geometry.getSize());
3205 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3206 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3207 newBottomFrame.setSize(oldBottomFrame.getSize());
3208 newBottomFrame.setVisible(true);
3209 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3210 .getExplodedGeometry();
3211 if (geometry != null)
3213 newBottomFrame.setSize(geometry.getSize());
3216 topPanel.av.setGatherViewsHere(false);
3217 bottomPanel.av.setGatherViewsHere(false);
3218 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3220 if (geometry != null)
3222 splitFrame.setLocation(geometry.getLocation());
3224 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3228 * Clear references to the panels (now relocated in the new SplitFrames)
3229 * before closing the old SplitFrame.
3232 bottomPanels.clear();
3237 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3238 * back into the given SplitFrame as additional views. Note that the gathered
3239 * frames may themselves have multiple views.
3243 public void gatherViews(GSplitFrame source)
3246 * special handling of explodedGeometry for a view within a SplitFrame: - it
3247 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3248 * height) of the AlignFrame component
3250 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3251 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3252 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3253 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3254 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3255 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3257 myTopFrame.viewport.setGatherViewsHere(true);
3258 myBottomFrame.viewport.setGatherViewsHere(true);
3259 String topViewId = myTopFrame.viewport.getSequenceSetId();
3260 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3262 JInternalFrame[] frames = desktop.getAllFrames();
3263 for (JInternalFrame frame : frames)
3265 if (frame instanceof SplitFrame && frame != source)
3267 SplitFrame sf = (SplitFrame) frame;
3268 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3269 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3270 boolean gatherThis = false;
3271 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3273 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3274 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3275 if (topViewId.equals(topPanel.av.getSequenceSetId())
3276 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3279 topPanel.av.setGatherViewsHere(false);
3280 bottomPanel.av.setGatherViewsHere(false);
3281 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3282 topFrame.getSize()));
3283 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3284 .getLocation(), bottomFrame.getSize()));
3285 myTopFrame.addAlignmentPanel(topPanel, false);
3286 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3292 topFrame.getAlignPanels().clear();
3293 bottomFrame.getAlignPanels().clear();
3300 * The dust settles...give focus to the tab we did this from.
3302 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3305 public static groovy.ui.Console getGroovyConsole()
3307 return groovyConsole;
3310 public static void transferFromDropTarget(List<String> files,
3311 List<DataSourceType> protocols, DropTargetDropEvent evt,
3316 DataFlavor uriListFlavor = new DataFlavor(
3317 "text/uri-list;class=java.lang.String");
3318 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3320 // Works on Windows and MacOSX
3321 Cache.log.debug("Drop handled as javaFileListFlavor");
3322 for (Object file : (List) t
3323 .getTransferData(DataFlavor.javaFileListFlavor))
3325 files.add(((File) file).toString());
3326 protocols.add(DataSourceType.FILE);
3331 // Unix like behaviour
3332 boolean added = false;
3334 if (t.isDataFlavorSupported(uriListFlavor))
3336 Cache.log.debug("Drop handled as uriListFlavor");
3337 // This is used by Unix drag system
3338 data = (String) t.getTransferData(uriListFlavor);
3342 // fallback to text: workaround - on OSX where there's a JVM bug
3343 Cache.log.debug("standard URIListFlavor failed. Trying text");
3344 // try text fallback
3345 data = (String) t.getTransferData(new DataFlavor(
3346 "text/plain;class=java.lang.String"));
3347 if (Cache.log.isDebugEnabled())
3349 Cache.log.debug("fallback returned " + data);
3352 while (protocols.size() < files.size())
3354 Cache.log.debug("Adding missing FILE protocol for "
3355 + files.get(protocols.size()));
3356 protocols.add(DataSourceType.FILE);
3358 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3359 data, "\r\n"); st.hasMoreTokens();)
3362 String s = st.nextToken();
3363 if (s.startsWith("#"))
3365 // the line is a comment (as per the RFC 2483)
3368 java.net.URI uri = new java.net.URI(s);
3369 if (uri.getScheme().toLowerCase().startsWith("http"))
3371 protocols.add(DataSourceType.URL);
3372 files.add(uri.toString());
3376 // otherwise preserve old behaviour: catch all for file objects
3377 java.io.File file = new java.io.File(uri);
3378 protocols.add(DataSourceType.FILE);
3379 files.add(file.toString());
3382 if (Cache.log.isDebugEnabled())
3384 if (data == null || !added)
3387 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3388 for (DataFlavor fl : t.getTransferDataFlavors())
3390 Cache.log.debug("Supported transfer dataflavor: "
3392 Object df = t.getTransferData(fl);
3395 Cache.log.debug("Retrieves: " + df);
3399 Cache.log.debug("Retrieved nothing");