2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.bin.Cache;
26 import jalview.bin.Jalview;
27 import jalview.io.FileLoader;
28 import jalview.io.FormatAdapter;
29 import jalview.io.IdentifyFile;
30 import jalview.io.JalviewFileChooser;
31 import jalview.io.JalviewFileView;
32 import jalview.jbgui.GSplitFrame;
33 import jalview.jbgui.GStructureViewer;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.util.ImageMaker;
36 import jalview.util.MessageManager;
37 import jalview.util.Platform;
38 import jalview.viewmodel.AlignmentViewport;
39 import jalview.ws.params.ParamManager;
41 import java.awt.BorderLayout;
42 import java.awt.Color;
43 import java.awt.Dimension;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.GridLayout;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.Toolkit;
50 import java.awt.Window;
51 import java.awt.datatransfer.Clipboard;
52 import java.awt.datatransfer.ClipboardOwner;
53 import java.awt.datatransfer.DataFlavor;
54 import java.awt.datatransfer.Transferable;
55 import java.awt.dnd.DnDConstants;
56 import java.awt.dnd.DropTargetDragEvent;
57 import java.awt.dnd.DropTargetDropEvent;
58 import java.awt.dnd.DropTargetEvent;
59 import java.awt.dnd.DropTargetListener;
60 import java.awt.event.ActionEvent;
61 import java.awt.event.ActionListener;
62 import java.awt.event.FocusEvent;
63 import java.awt.event.FocusListener;
64 import java.awt.event.MouseAdapter;
65 import java.awt.event.MouseEvent;
66 import java.awt.event.MouseListener;
67 import java.awt.event.WindowAdapter;
68 import java.awt.event.WindowEvent;
69 import java.beans.PropertyChangeEvent;
70 import java.beans.PropertyChangeListener;
71 import java.beans.PropertyVetoException;
72 import java.io.BufferedInputStream;
74 import java.io.FileOutputStream;
76 import java.util.ArrayList;
77 import java.util.Hashtable;
78 import java.util.List;
79 import java.util.StringTokenizer;
80 import java.util.Vector;
81 import java.util.concurrent.ExecutorService;
82 import java.util.concurrent.Executors;
83 import java.util.concurrent.Semaphore;
85 import javax.swing.DefaultDesktopManager;
86 import javax.swing.DesktopManager;
87 import javax.swing.JButton;
88 import javax.swing.JComboBox;
89 import javax.swing.JComponent;
90 import javax.swing.JDesktopPane;
91 import javax.swing.JFrame;
92 import javax.swing.JInternalFrame;
93 import javax.swing.JLabel;
94 import javax.swing.JMenuItem;
95 import javax.swing.JOptionPane;
96 import javax.swing.JPanel;
97 import javax.swing.JPopupMenu;
98 import javax.swing.JProgressBar;
99 import javax.swing.SwingUtilities;
100 import javax.swing.event.HyperlinkEvent;
101 import javax.swing.event.HyperlinkEvent.EventType;
102 import javax.swing.event.MenuEvent;
103 import javax.swing.event.MenuListener;
110 * @version $Revision: 1.155 $
112 public class Desktop extends jalview.jbgui.GDesktop implements
113 DropTargetListener, ClipboardOwner, IProgressIndicator,
114 jalview.api.StructureSelectionManagerProvider
117 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
120 * news reader - null if it was never started.
122 private BlogReader jvnews = null;
124 private File projectFile;
128 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
130 public void addJalviewPropertyChangeListener(
131 PropertyChangeListener listener)
133 changeSupport.addJalviewPropertyChangeListener(listener);
137 * @param propertyName
139 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
140 * java.beans.PropertyChangeListener)
142 public void addJalviewPropertyChangeListener(String propertyName,
143 PropertyChangeListener listener)
145 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
149 * @param propertyName
151 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
152 * java.beans.PropertyChangeListener)
154 public void removeJalviewPropertyChangeListener(String propertyName,
155 PropertyChangeListener listener)
157 changeSupport.removeJalviewPropertyChangeListener(propertyName,
161 /** Singleton Desktop instance */
162 public static Desktop instance;
164 public static MyDesktopPane desktop;
166 static int openFrameCount = 0;
168 static final int xOffset = 30;
170 static final int yOffset = 30;
172 private static AlignFrame currentAlignFrame;
174 public static jalview.ws.jws1.Discoverer discoverer;
176 public static Object[] jalviewClipboard;
178 public static boolean internalCopy = false;
180 static int fileLoadingCount = 0;
182 class MyDesktopManager implements DesktopManager
185 private DesktopManager delegate;
187 public MyDesktopManager(DesktopManager delegate)
189 this.delegate = delegate;
193 public void activateFrame(JInternalFrame f)
197 delegate.activateFrame(f);
198 } catch (NullPointerException npe)
200 Point p = getMousePosition();
201 instance.showPasteMenu(p.x, p.y);
206 public void beginDraggingFrame(JComponent f)
208 delegate.beginDraggingFrame(f);
212 public void beginResizingFrame(JComponent f, int direction)
214 delegate.beginResizingFrame(f, direction);
218 public void closeFrame(JInternalFrame f)
220 delegate.closeFrame(f);
224 public void deactivateFrame(JInternalFrame f)
226 delegate.deactivateFrame(f);
230 public void deiconifyFrame(JInternalFrame f)
232 delegate.deiconifyFrame(f);
236 public void dragFrame(JComponent f, int newX, int newY)
242 delegate.dragFrame(f, newX, newY);
246 public void endDraggingFrame(JComponent f)
248 delegate.endDraggingFrame(f);
252 public void endResizingFrame(JComponent f)
254 delegate.endResizingFrame(f);
258 public void iconifyFrame(JInternalFrame f)
260 delegate.iconifyFrame(f);
264 public void maximizeFrame(JInternalFrame f)
266 delegate.maximizeFrame(f);
270 public void minimizeFrame(JInternalFrame f)
272 delegate.minimizeFrame(f);
276 public void openFrame(JInternalFrame f)
278 delegate.openFrame(f);
282 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
289 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
293 public void setBoundsForFrame(JComponent f, int newX, int newY,
294 int newWidth, int newHeight)
296 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
299 // All other methods, simply delegate
304 * Creates a new Desktop object.
309 * A note to implementors. It is ESSENTIAL that any activities that might
310 * block are spawned off as threads rather than waited for during this
314 doVamsasClientCheck();
316 groovyShell = new JMenuItem();
317 groovyShell.setText(MessageManager.getString("label.groovy_console"));
318 groovyShell.addActionListener(new ActionListener()
321 public void actionPerformed(ActionEvent e)
323 groovyShell_actionPerformed();
326 toolsMenu.add(groovyShell);
327 groovyShell.setVisible(true);
329 doConfigureStructurePrefs();
330 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
331 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
332 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
334 boolean showjconsole = jalview.bin.Cache.getDefault(
335 "SHOW_JAVA_CONSOLE", false);
336 desktop = new MyDesktopPane(selmemusage);
337 if (Platform.isAMac())
339 desktop.setDoubleBuffered(false);
341 showMemusage.setSelected(selmemusage);
342 desktop.setBackground(Color.white);
343 getContentPane().setLayout(new BorderLayout());
344 // alternate config - have scrollbars - see notes in JAL-153
345 // JScrollPane sp = new JScrollPane();
346 // sp.getViewport().setView(desktop);
347 // getContentPane().add(sp, BorderLayout.CENTER);
348 getContentPane().add(desktop, BorderLayout.CENTER);
349 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
351 // This line prevents Windows Look&Feel resizing all new windows to maximum
352 // if previous window was maximised
353 desktop.setDesktopManager(new MyDesktopManager(
354 new DefaultDesktopManager()));
356 Rectangle dims = getLastKnownDimensions("");
363 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
364 setBounds((screenSize.width - 900) / 2,
365 (screenSize.height - 650) / 2, 900, 650);
367 jconsole = new Console(this, showjconsole);
368 // add essential build information
369 jconsole.setHeader("Jalview Version: "
370 + jalview.bin.Cache.getProperty("VERSION") + "\n"
371 + "Jalview Installation: "
372 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
373 + "\n" + "Build Date: "
374 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
375 + "Java version: " + System.getProperty("java.version") + "\n"
376 + System.getProperty("os.arch") + " "
377 + System.getProperty("os.name") + " "
378 + System.getProperty("os.version"));
380 showConsole(showjconsole);
382 showNews.setVisible(false);
384 this.addWindowListener(new WindowAdapter()
387 public void windowClosing(WindowEvent evt)
394 this.addMouseListener(ma = new MouseAdapter()
397 public void mousePressed(MouseEvent evt)
399 if (evt.isPopupTrigger())
401 showPasteMenu(evt.getX(), evt.getY());
405 desktop.addMouseListener(ma);
407 this.addFocusListener(new FocusListener()
411 public void focusLost(FocusEvent e)
413 // TODO Auto-generated method stub
418 public void focusGained(FocusEvent e)
420 Cache.log.debug("Relaying windows after focus gain");
421 // make sure that we sort windows properly after we gain focus
422 instance.relayerWindows();
425 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
426 // Spawn a thread that shows the splashscreen
427 SwingUtilities.invokeLater(new Runnable()
437 // Thread off a new instance of the file chooser - this reduces the time it
438 // takes to open it later on.
439 new Thread(new Runnable()
444 Cache.log.debug("Filechooser init thread started.");
445 new JalviewFileChooser(
446 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
447 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
448 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
449 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
450 Cache.log.debug("Filechooser init thread finished.");
453 // Add the service change listener
454 changeSupport.addJalviewPropertyChangeListener("services",
455 new PropertyChangeListener()
459 public void propertyChange(PropertyChangeEvent evt)
461 Cache.log.debug("Firing service changed event for "
462 + evt.getNewValue());
463 JalviewServicesChanged(evt);
469 public void doConfigureStructurePrefs()
471 // configure services
472 StructureSelectionManager ssm = StructureSelectionManager
473 .getStructureSelectionManager(this);
474 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
476 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
477 Preferences.ADD_TEMPFACT_ANN, true));
478 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
479 Preferences.STRUCT_FROM_PDB, true));
480 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
481 Preferences.USE_RNAVIEW, true));
485 ssm.setAddTempFacAnnot(false);
486 ssm.setProcessSecondaryStructure(false);
487 ssm.setSecStructServices(false);
491 public void checkForNews()
493 final Desktop me = this;
494 // Thread off the news reader, in case there are connection problems.
495 addDialogThread(new Runnable()
500 Cache.log.debug("Starting news thread.");
502 jvnews = new BlogReader(me);
503 showNews.setVisible(true);
504 Cache.log.debug("Completed news thread.");
510 protected void showNews_actionPerformed(ActionEvent e)
512 showNews(showNews.isSelected());
515 void showNews(boolean visible)
518 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
519 showNews.setSelected(visible);
520 if (visible && !jvnews.isVisible())
522 new Thread(new Runnable()
527 long now = System.currentTimeMillis();
528 Desktop.instance.setProgressBar(
529 MessageManager.getString("status.refreshing_news"), now);
530 jvnews.refreshNews();
531 Desktop.instance.setProgressBar(null, now);
540 * recover the last known dimensions for a jalview window
543 * - empty string is desktop, all other windows have unique prefix
544 * @return null or last known dimensions scaled to current geometry (if last
545 * window geom was known)
547 Rectangle getLastKnownDimensions(String windowName)
549 // TODO: lock aspect ratio for scaling desktop Bug #0058199
550 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
551 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
552 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
553 String width = jalview.bin.Cache.getProperty(windowName
555 String height = jalview.bin.Cache.getProperty(windowName
557 if ((x != null) && (y != null) && (width != null) && (height != null))
559 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
560 .parseInt(width), ih = Integer.parseInt(height);
561 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
563 // attempt #1 - try to cope with change in screen geometry - this
564 // version doesn't preserve original jv aspect ratio.
565 // take ratio of current screen size vs original screen size.
566 double sw = ((1f * screenSize.width) / (1f * Integer
567 .parseInt(jalview.bin.Cache
568 .getProperty("SCREENGEOMETRY_WIDTH"))));
569 double sh = ((1f * screenSize.height) / (1f * Integer
570 .parseInt(jalview.bin.Cache
571 .getProperty("SCREENGEOMETRY_HEIGHT"))));
572 // rescale the bounds depending upon the current screen geometry.
573 ix = (int) (ix * sw);
574 iw = (int) (iw * sw);
575 iy = (int) (iy * sh);
576 ih = (int) (ih * sh);
577 while (ix >= screenSize.width)
579 jalview.bin.Cache.log
580 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
581 ix -= screenSize.width;
583 while (iy >= screenSize.height)
585 jalview.bin.Cache.log
586 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
587 iy -= screenSize.height;
589 jalview.bin.Cache.log.debug("Got last known dimensions for "
590 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
593 // return dimensions for new instance
594 return new Rectangle(ix, iy, iw, ih);
599 private void doVamsasClientCheck()
601 if (jalview.bin.Cache.vamsasJarsPresent())
603 setupVamsasDisconnectedGui();
604 VamsasMenu.setVisible(true);
605 final Desktop us = this;
606 VamsasMenu.addMenuListener(new MenuListener()
608 // this listener remembers when the menu was first selected, and
609 // doesn't rebuild the session list until it has been cleared and
611 boolean refresh = true;
614 public void menuCanceled(MenuEvent e)
620 public void menuDeselected(MenuEvent e)
626 public void menuSelected(MenuEvent e)
630 us.buildVamsasStMenu();
635 vamsasStart.setVisible(true);
639 void showPasteMenu(int x, int y)
641 JPopupMenu popup = new JPopupMenu();
642 JMenuItem item = new JMenuItem(
643 MessageManager.getString("label.paste_new_window"));
644 item.addActionListener(new ActionListener()
647 public void actionPerformed(ActionEvent evt)
654 popup.show(this, x, y);
661 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
662 Transferable contents = c.getContents(this);
664 if (contents != null)
666 String file = (String) contents
667 .getTransferData(DataFlavor.stringFlavor);
669 String format = new IdentifyFile().identify(file,
670 FormatAdapter.PASTE);
672 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
675 } catch (Exception ex)
678 .println("Unable to paste alignment from system clipboard:\n"
684 * Adds and opens the given frame to the desktop
695 public static synchronized void addInternalFrame(
696 final JInternalFrame frame, String title, int w, int h)
698 addInternalFrame(frame, title, true, w, h, true);
702 * Add an internal frame to the Jalview desktop
709 * When true, display frame immediately, otherwise, caller must call
710 * setVisible themselves.
716 public static synchronized void addInternalFrame(
717 final JInternalFrame frame, String title, boolean makeVisible,
720 addInternalFrame(frame, title, makeVisible, w, h, true);
724 * Add an internal frame to the Jalview desktop and make it visible
737 public static synchronized void addInternalFrame(
738 final JInternalFrame frame, String title, int w, int h,
741 addInternalFrame(frame, title, true, w, h, resizable);
745 * Add an internal frame to the Jalview desktop
752 * When true, display frame immediately, otherwise, caller must call
753 * setVisible themselves.
761 public static synchronized void addInternalFrame(
762 final JInternalFrame frame, String title, boolean makeVisible,
763 int w, int h, boolean resizable)
766 // TODO: allow callers to determine X and Y position of frame (eg. via
768 // TODO: consider fixing method to update entries in the window submenu with
769 // the current window title
771 frame.setTitle(title);
772 if (frame.getWidth() < 1 || frame.getHeight() < 1)
776 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
777 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
778 // IF JALVIEW IS RUNNING HEADLESS
779 // ///////////////////////////////////////////////
781 || (System.getProperty("java.awt.headless") != null && System
782 .getProperty("java.awt.headless").equals("true")))
789 frame.setVisible(makeVisible);
790 frame.setClosable(true);
791 frame.setResizable(resizable);
792 frame.setMaximizable(resizable);
793 frame.setIconifiable(resizable);
794 if (Platform.isAMac())
796 frame.setIconifiable(false);
797 frame.setFrameIcon(null);
798 // frame.setDesktopIcon(null);
799 frame.setDoubleBuffered(false);
801 if (frame.getX() < 1 && frame.getY() < 1)
803 frame.setLocation(xOffset * openFrameCount, yOffset
804 * ((openFrameCount - 1) % 10) + yOffset);
807 final JMenuItem menuItem = new JMenuItem(title);
808 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
811 public void internalFrameActivated(
812 javax.swing.event.InternalFrameEvent evt)
814 JInternalFrame itf = desktop.getSelectedFrame();
823 public void internalFrameClosed(
824 javax.swing.event.InternalFrameEvent evt)
826 PaintRefresher.RemoveComponent(frame);
828 windowMenu.remove(menuItem);
829 JInternalFrame itf = desktop.getSelectedFrame();
838 menuItem.addActionListener(new ActionListener()
841 public void actionPerformed(ActionEvent e)
845 frame.setSelected(true);
846 frame.setIcon(false);
847 } catch (java.beans.PropertyVetoException ex)
853 menuItem.addMouseListener(new MouseListener()
857 public void mouseReleased(MouseEvent e)
862 public void mousePressed(MouseEvent e)
867 public void mouseExited(MouseEvent e)
871 frame.setSelected(false);
872 } catch (PropertyVetoException e1)
878 public void mouseEntered(MouseEvent e)
882 frame.setSelected(true);
883 } catch (PropertyVetoException e1)
889 public void mouseClicked(MouseEvent e)
895 windowMenu.add(menuItem);
901 frame.setSelected(true);
902 frame.requestFocus();
903 } catch (java.beans.PropertyVetoException ve)
905 } catch (java.lang.ClassCastException cex)
908 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
914 public void lostOwnership(Clipboard clipboard, Transferable contents)
918 Desktop.jalviewClipboard = null;
921 internalCopy = false;
925 public void dragEnter(DropTargetDragEvent evt)
930 public void dragExit(DropTargetEvent evt)
935 public void dragOver(DropTargetDragEvent evt)
940 public void dropActionChanged(DropTargetDragEvent evt)
951 public void drop(DropTargetDropEvent evt)
953 boolean success = true;
954 Transferable t = evt.getTransferable();
955 java.util.List<String> files = new ArrayList<String>();
956 java.util.List<String> protocols = new ArrayList<String>();
960 Desktop.transferFromDropTarget(files, protocols, evt, t);
961 } catch (Exception e)
971 for (int i = 0; i < files.size(); i++)
973 String file = files.get(i).toString();
974 String protocol = (protocols == null) ? FormatAdapter.FILE
975 : (String) protocols.get(i);
976 String format = null;
978 if (file.endsWith(".jar"))
985 format = new IdentifyFile().identify(file, protocol);
988 new FileLoader().LoadFile(file, protocol, format);
991 } catch (Exception ex)
996 evt.dropComplete(success); // need this to ensure input focus is properly
997 // transfered to any new windows created
1007 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1009 JalviewFileChooser chooser = new JalviewFileChooser(
1010 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1011 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1012 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1013 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1015 chooser.setFileView(new JalviewFileView());
1016 chooser.setDialogTitle(MessageManager
1017 .getString("label.open_local_file"));
1018 chooser.setToolTipText(MessageManager.getString("action.open"));
1020 int value = chooser.showOpenDialog(this);
1022 if (value == JalviewFileChooser.APPROVE_OPTION)
1024 String choice = chooser.getSelectedFile().getPath();
1025 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1026 .getSelectedFile().getParent());
1028 String format = null;
1029 if (chooser.getSelectedFormat() != null
1030 && chooser.getSelectedFormat().equals("Jalview"))
1036 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1039 if (viewport != null)
1041 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1046 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1058 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1060 // This construct allows us to have a wider textfield
1062 JLabel label = new JLabel(
1063 MessageManager.getString("label.input_file_url"));
1064 final JComboBox history = new JComboBox();
1066 JPanel panel = new JPanel(new GridLayout(2, 1));
1069 history.setPreferredSize(new Dimension(400, 20));
1070 history.setEditable(true);
1071 history.addItem("http://www.");
1073 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1077 if (historyItems != null)
1079 st = new StringTokenizer(historyItems, "\t");
1081 while (st.hasMoreTokens())
1083 history.addItem(st.nextElement());
1087 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1088 MessageManager.getString("label.input_alignment_from_url"),
1089 JOptionPane.OK_CANCEL_OPTION);
1091 if (reply != JOptionPane.OK_OPTION)
1096 String url = history.getSelectedItem().toString();
1098 if (url.toLowerCase().endsWith(".jar"))
1100 if (viewport != null)
1102 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1107 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1112 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1114 if (format.equals("URL NOT FOUND"))
1116 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1117 MessageManager.formatMessage("label.couldnt_locate",
1118 new Object[] { url }), MessageManager
1119 .getString("label.url_not_found"),
1120 JOptionPane.WARNING_MESSAGE);
1125 if (viewport != null)
1127 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1131 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1137 * Opens the CutAndPaste window for the user to paste an alignment in to
1140 * - if not null, the pasted alignment is added to the current
1141 * alignment; if null, to a new alignment window
1144 public void inputTextboxMenuItem_actionPerformed(
1145 AlignmentViewPanel viewPanel)
1147 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1148 cap.setForInput(viewPanel);
1149 Desktop.addInternalFrame(cap,
1150 MessageManager.getString("label.cut_paste_alignmen_file"),
1160 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1162 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1163 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1165 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1166 getBounds().y, getWidth(), getHeight()));
1168 if (jconsole != null)
1170 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1171 jconsole.stopConsole();
1175 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1178 if (dialogExecutor != null)
1180 dialogExecutor.shutdownNow();
1182 closeAll_actionPerformed(null);
1186 private void storeLastKnownDimensions(String string, Rectangle jc)
1188 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1189 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1190 + " height:" + jc.height);
1192 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1193 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1194 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1195 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1205 public void aboutMenuItem_actionPerformed(ActionEvent e)
1207 // StringBuffer message = getAboutMessage(false);
1208 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1210 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1211 new Thread(new Runnable()
1216 new SplashScreen(true);
1221 public StringBuffer getAboutMessage(boolean shortv)
1223 StringBuffer message = new StringBuffer();
1224 message.append("<html>");
1227 message.append("<h1><strong>Version: "
1228 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1229 message.append("<strong>Last Updated: <em>"
1230 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1231 + "</em></strong>");
1237 message.append("<strong>Version "
1238 + jalview.bin.Cache.getProperty("VERSION")
1239 + "; last updated: "
1240 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1243 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1246 message.append("<br>...Checking latest version...</br>");
1248 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1249 .equals(jalview.bin.Cache.getProperty("VERSION")))
1251 boolean red = false;
1252 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1253 .indexOf("automated build") == -1)
1256 // Displayed when code version and jnlp version do not match and code
1257 // version is not a development build
1258 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1261 message.append("<br>!! Version "
1262 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1264 + " is available for download from "
1265 + jalview.bin.Cache.getDefault("www.jalview.org",
1266 "http://www.jalview.org") + " !!");
1269 message.append("</div>");
1272 message.append("<br>Authors: "
1274 .getDefault("AUTHORFNAMES",
1275 "The Jalview Authors (See AUTHORS file for current list)")
1276 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1277 + "<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"
1278 + "<br><br>If you use Jalview, please cite:"
1279 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1280 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1281 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1293 public void documentationMenuItem_actionPerformed(ActionEvent e)
1297 Help.showHelpWindow();
1298 } catch (Exception ex)
1304 public void closeAll_actionPerformed(ActionEvent e)
1306 JInternalFrame[] frames = desktop.getAllFrames();
1307 for (int i = 0; i < frames.length; i++)
1311 frames[i].setClosed(true);
1312 } catch (java.beans.PropertyVetoException ex)
1316 System.out.println("ALL CLOSED");
1317 if (v_client != null)
1319 // TODO clear binding to vamsas document objects on close_all
1323 * reset state of singleton objects as appropriate (clear down session state
1324 * when all windows are closed)
1326 StructureSelectionManager ssm = StructureSelectionManager
1327 .getStructureSelectionManager(this);
1335 public void raiseRelated_actionPerformed(ActionEvent e)
1337 reorderAssociatedWindows(false, false);
1341 public void minimizeAssociated_actionPerformed(ActionEvent e)
1343 reorderAssociatedWindows(true, false);
1346 void closeAssociatedWindows()
1348 reorderAssociatedWindows(false, true);
1354 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1358 protected void garbageCollect_actionPerformed(ActionEvent e)
1360 // We simply collect the garbage
1361 jalview.bin.Cache.log.debug("Collecting garbage...");
1363 jalview.bin.Cache.log.debug("Finished garbage collection.");
1370 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1374 protected void showMemusage_actionPerformed(ActionEvent e)
1376 desktop.showMemoryUsage(showMemusage.isSelected());
1383 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1387 protected void showConsole_actionPerformed(ActionEvent e)
1389 showConsole(showConsole.isSelected());
1392 Console jconsole = null;
1395 * control whether the java console is visible or not
1399 void showConsole(boolean selected)
1401 showConsole.setSelected(selected);
1402 // TODO: decide if we should update properties file
1403 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1405 jconsole.setVisible(selected);
1408 void reorderAssociatedWindows(boolean minimize, boolean close)
1410 JInternalFrame[] frames = desktop.getAllFrames();
1411 if (frames == null || frames.length < 1)
1416 AlignmentViewport source = null, target = null;
1417 if (frames[0] instanceof AlignFrame)
1419 source = ((AlignFrame) frames[0]).getCurrentView();
1421 else if (frames[0] instanceof TreePanel)
1423 source = ((TreePanel) frames[0]).getViewPort();
1425 else if (frames[0] instanceof PCAPanel)
1427 source = ((PCAPanel) frames[0]).av;
1429 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1431 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1436 for (int i = 0; i < frames.length; i++)
1439 if (frames[i] == null)
1443 if (frames[i] instanceof AlignFrame)
1445 target = ((AlignFrame) frames[i]).getCurrentView();
1447 else if (frames[i] instanceof TreePanel)
1449 target = ((TreePanel) frames[i]).getViewPort();
1451 else if (frames[i] instanceof PCAPanel)
1453 target = ((PCAPanel) frames[i]).av;
1455 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1457 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1460 if (source == target)
1466 frames[i].setClosed(true);
1470 frames[i].setIcon(minimize);
1473 frames[i].toFront();
1477 } catch (java.beans.PropertyVetoException ex)
1492 protected void preferences_actionPerformed(ActionEvent e)
1504 public void saveState_actionPerformed(ActionEvent e)
1506 JalviewFileChooser chooser = new JalviewFileChooser(
1507 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1508 new String[] { "jvp" }, new String[] { "Jalview Project" },
1511 chooser.setFileView(new JalviewFileView());
1512 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1514 int value = chooser.showSaveDialog(this);
1516 if (value == JalviewFileChooser.APPROVE_OPTION)
1518 final Desktop me = this;
1519 final java.io.File choice = chooser.getSelectedFile();
1520 setProjectFile(choice);
1522 new Thread(new Runnable()
1527 // TODO: refactor to Jalview desktop session controller action.
1528 setProgressBar(MessageManager.formatMessage(
1529 "label.saving_jalview_project",
1530 new Object[] { choice.getName() }), choice.hashCode());
1531 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1532 choice.getParent());
1533 // TODO catch and handle errors for savestate
1534 // TODO prevent user from messing with the Desktop whilst we're saving
1537 new Jalview2XML().saveState(choice);
1538 } catch (OutOfMemoryError oom)
1540 new OOMWarning("Whilst saving current state to "
1541 + choice.getName(), oom);
1542 } catch (Exception ex)
1545 "Problems whilst trying to save to " + choice.getName(),
1547 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1548 "label.error_whilst_saving_current_state_to",
1549 new Object[] { choice.getName() }), MessageManager
1550 .getString("label.couldnt_save_project"),
1551 JOptionPane.WARNING_MESSAGE);
1553 setProgressBar(null, choice.hashCode());
1559 private void setProjectFile(File choice)
1561 this.projectFile = choice;
1564 public File getProjectFile()
1566 return this.projectFile;
1576 public void loadState_actionPerformed(ActionEvent e)
1578 JalviewFileChooser chooser = new JalviewFileChooser(
1579 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1580 "jvp", "jar" }, new String[] { "Jalview Project",
1581 "Jalview Project (old)" }, "Jalview Project");
1582 chooser.setFileView(new JalviewFileView());
1583 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1585 int value = chooser.showOpenDialog(this);
1587 if (value == JalviewFileChooser.APPROVE_OPTION)
1589 final File selectedFile = chooser.getSelectedFile();
1590 setProjectFile(selectedFile);
1591 final String choice = selectedFile.getAbsolutePath();
1592 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1593 selectedFile.getParent());
1594 new Thread(new Runnable()
1600 MessageManager.formatMessage(
1601 "label.loading_jalview_project",
1602 new Object[] { choice }), choice.hashCode());
1605 new Jalview2XML().loadJalviewAlign(choice);
1606 } catch (OutOfMemoryError oom)
1608 new OOMWarning("Whilst loading project from " + choice, oom);
1609 } catch (Exception ex)
1611 Cache.log.error("Problems whilst loading project from "
1613 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1615 "label.error_whilst_loading_project_from",
1616 new Object[] { choice }), MessageManager
1617 .getString("label.couldnt_load_project"),
1618 JOptionPane.WARNING_MESSAGE);
1620 setProgressBar(null, choice.hashCode());
1627 public void inputSequence_actionPerformed(ActionEvent e)
1629 new SequenceFetcher(this);
1632 JPanel progressPanel;
1634 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1636 public void startLoading(final String fileName)
1638 if (fileLoadingCount == 0)
1640 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1641 "label.loading_file", new Object[] { fileName })));
1646 private JPanel addProgressPanel(String string)
1648 if (progressPanel == null)
1650 progressPanel = new JPanel(new GridLayout(1, 1));
1651 totalProgressCount = 0;
1652 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1654 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1655 JProgressBar progressBar = new JProgressBar();
1656 progressBar.setIndeterminate(true);
1658 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1660 thisprogress.add(progressBar, BorderLayout.CENTER);
1661 progressPanel.add(thisprogress);
1662 ((GridLayout) progressPanel.getLayout())
1663 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1664 ++totalProgressCount;
1665 instance.validate();
1666 return thisprogress;
1669 int totalProgressCount = 0;
1671 private void removeProgressPanel(JPanel progbar)
1673 if (progressPanel != null)
1675 synchronized (progressPanel)
1677 progressPanel.remove(progbar);
1678 GridLayout gl = (GridLayout) progressPanel.getLayout();
1679 gl.setRows(gl.getRows() - 1);
1680 if (--totalProgressCount < 1)
1682 this.getContentPane().remove(progressPanel);
1683 progressPanel = null;
1690 public void stopLoading()
1693 if (fileLoadingCount < 1)
1695 while (fileLoadingPanels.size() > 0)
1697 removeProgressPanel(fileLoadingPanels.remove(0));
1699 fileLoadingPanels.clear();
1700 fileLoadingCount = 0;
1705 public static int getViewCount(String alignmentId)
1707 AlignmentViewport[] aps = getViewports(alignmentId);
1708 return (aps == null) ? 0 : aps.length;
1713 * @param alignmentId
1714 * - if null, all sets are returned
1715 * @return all AlignmentPanels concerning the alignmentId sequence set
1717 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1719 if (Desktop.desktop == null)
1721 // no frames created and in headless mode
1722 // TODO: verify that frames are recoverable when in headless mode
1725 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1726 AlignFrame[] frames = getAlignFrames();
1731 for (AlignFrame af : frames)
1733 for (AlignmentPanel ap : af.alignPanels)
1735 if (alignmentId == null
1736 || alignmentId.equals(ap.av.getSequenceSetId()))
1742 if (aps.size() == 0)
1746 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1751 * get all the viewports on an alignment.
1753 * @param sequenceSetId
1754 * unique alignment id (may be null - all viewports returned in that
1756 * @return all viewports on the alignment bound to sequenceSetId
1758 public static AlignmentViewport[] getViewports(String sequenceSetId)
1760 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1761 if (desktop != null)
1763 AlignFrame[] frames = Desktop.getAlignFrames();
1765 for (AlignFrame afr : frames)
1767 if (sequenceSetId == null
1768 || afr.getViewport().getSequenceSetId()
1769 .equals(sequenceSetId))
1771 if (afr.alignPanels != null)
1773 for (AlignmentPanel ap : afr.alignPanels)
1775 if (sequenceSetId == null
1776 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1784 viewp.add(afr.getViewport());
1788 if (viewp.size() > 0)
1790 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1797 * Explode the views in the given frame into separate AlignFrame
1801 public void explodeViews(AlignFrame af)
1803 int size = af.alignPanels.size();
1809 for (int i = 0; i < size; i++)
1811 AlignmentPanel ap = af.alignPanels.get(i);
1812 AlignFrame newaf = new AlignFrame(ap);
1815 * Restore the view's last exploded frame geometry if known. Multiple
1816 * views from one exploded frame share and restore the same (frame)
1817 * position and size.
1819 Rectangle geometry = ap.av.getExplodedGeometry();
1820 if (geometry != null)
1822 newaf.setBounds(geometry);
1825 ap.av.setGatherViewsHere(false);
1827 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1828 AlignFrame.DEFAULT_HEIGHT);
1831 af.alignPanels.clear();
1832 af.closeMenuItem_actionPerformed(true);
1837 * Gather expanded views (separate AlignFrame's) with the same sequence set
1838 * identifier back in to this frame as additional views, and close the
1839 * expanded views. Note the expanded frames may themselves have multiple
1840 * views. We take the lot.
1844 public void gatherViews(AlignFrame source)
1846 source.viewport.setGatherViewsHere(true);
1847 source.viewport.setExplodedGeometry(source.getBounds());
1848 JInternalFrame[] frames = desktop.getAllFrames();
1849 String viewId = source.viewport.getSequenceSetId();
1851 for (int t = 0; t < frames.length; t++)
1853 if (frames[t] instanceof AlignFrame && frames[t] != source)
1855 AlignFrame af = (AlignFrame) frames[t];
1856 boolean gatherThis = false;
1857 for (int a = 0; a < af.alignPanels.size(); a++)
1859 AlignmentPanel ap = af.alignPanels.get(a);
1860 if (viewId.equals(ap.av.getSequenceSetId()))
1863 ap.av.setGatherViewsHere(false);
1864 ap.av.setExplodedGeometry(af.getBounds());
1865 source.addAlignmentPanel(ap, false);
1871 af.alignPanels.clear();
1872 af.closeMenuItem_actionPerformed(true);
1879 jalview.gui.VamsasApplication v_client = null;
1882 public void vamsasImport_actionPerformed(ActionEvent e)
1884 if (v_client == null)
1886 // Load and try to start a session.
1887 JalviewFileChooser chooser = new JalviewFileChooser(
1888 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1890 chooser.setFileView(new JalviewFileView());
1891 chooser.setDialogTitle(MessageManager
1892 .getString("label.open_saved_vamsas_session"));
1893 chooser.setToolTipText(MessageManager
1894 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1896 int value = chooser.showOpenDialog(this);
1898 if (value == JalviewFileChooser.APPROVE_OPTION)
1900 String fle = chooser.getSelectedFile().toString();
1901 if (!vamsasImport(chooser.getSelectedFile()))
1904 .showInternalMessageDialog(
1906 MessageManager.formatMessage(
1907 "label.couldnt_import_as_vamsas_session",
1908 new Object[] { fle }),
1910 .getString("label.vamsas_document_import_failed"),
1911 JOptionPane.ERROR_MESSAGE);
1917 jalview.bin.Cache.log
1918 .error("Implementation error - load session from a running session is not supported.");
1923 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1926 * @return true if import was a success and a session was started.
1928 public boolean vamsasImport(URL url)
1930 // TODO: create progress bar
1931 if (v_client != null)
1934 jalview.bin.Cache.log
1935 .error("Implementation error - load session from a running session is not supported.");
1941 // copy the URL content to a temporary local file
1942 // TODO: be a bit cleverer here with nio (?!)
1943 File file = File.createTempFile("vdocfromurl", ".vdj");
1944 FileOutputStream fos = new FileOutputStream(file);
1945 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1946 byte[] buffer = new byte[2048];
1948 while ((ln = bis.read(buffer)) > -1)
1950 fos.write(buffer, 0, ln);
1954 v_client = new jalview.gui.VamsasApplication(this, file,
1955 url.toExternalForm());
1956 } catch (Exception ex)
1958 jalview.bin.Cache.log.error(
1959 "Failed to create new vamsas session from contents of URL "
1963 setupVamsasConnectedGui();
1964 v_client.initial_update(); // TODO: thread ?
1965 return v_client.inSession();
1969 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1972 * @return true if import was a success and a session was started.
1974 public boolean vamsasImport(File file)
1976 if (v_client != null)
1979 jalview.bin.Cache.log
1980 .error("Implementation error - load session from a running session is not supported.");
1984 setProgressBar(MessageManager.formatMessage(
1985 "status.importing_vamsas_session_from",
1986 new Object[] { file.getName() }), file.hashCode());
1989 v_client = new jalview.gui.VamsasApplication(this, file, null);
1990 } catch (Exception ex)
1992 setProgressBar(MessageManager.formatMessage(
1993 "status.importing_vamsas_session_from",
1994 new Object[] { file.getName() }), file.hashCode());
1995 jalview.bin.Cache.log.error(
1996 "New vamsas session from existing session file failed:", ex);
1999 setupVamsasConnectedGui();
2000 v_client.initial_update(); // TODO: thread ?
2001 setProgressBar(MessageManager.formatMessage(
2002 "status.importing_vamsas_session_from",
2003 new Object[] { file.getName() }), file.hashCode());
2004 return v_client.inSession();
2007 public boolean joinVamsasSession(String mysesid)
2009 if (v_client != null)
2013 .getString("error.try_join_vamsas_session_another"));
2015 if (mysesid == null)
2018 MessageManager.getString("error.invalid_vamsas_session_id"));
2020 v_client = new VamsasApplication(this, mysesid);
2021 setupVamsasConnectedGui();
2022 v_client.initial_update();
2023 return (v_client.inSession());
2027 public void vamsasStart_actionPerformed(ActionEvent e)
2029 if (v_client == null)
2032 // we just start a default session for moment.
2034 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2035 * getProperty("LAST_DIRECTORY"));
2037 * chooser.setFileView(new JalviewFileView());
2038 * chooser.setDialogTitle("Load Vamsas file");
2039 * chooser.setToolTipText("Import");
2041 * int value = chooser.showOpenDialog(this);
2043 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2044 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2046 v_client = new VamsasApplication(this);
2047 setupVamsasConnectedGui();
2048 v_client.initial_update(); // TODO: thread ?
2052 // store current data in session.
2053 v_client.push_update(); // TODO: thread
2057 protected void setupVamsasConnectedGui()
2059 vamsasStart.setText(MessageManager.getString("label.session_update"));
2060 vamsasSave.setVisible(true);
2061 vamsasStop.setVisible(true);
2062 vamsasImport.setVisible(false); // Document import to existing session is
2063 // not possible for vamsas-client-1.0.
2066 protected void setupVamsasDisconnectedGui()
2068 vamsasSave.setVisible(false);
2069 vamsasStop.setVisible(false);
2070 vamsasImport.setVisible(true);
2071 vamsasStart.setText(MessageManager
2072 .getString("label.new_vamsas_session"));
2076 public void vamsasStop_actionPerformed(ActionEvent e)
2078 if (v_client != null)
2080 v_client.end_session();
2082 setupVamsasDisconnectedGui();
2086 protected void buildVamsasStMenu()
2088 if (v_client == null)
2090 String[] sess = null;
2093 sess = VamsasApplication.getSessionList();
2094 } catch (Exception e)
2096 jalview.bin.Cache.log.warn(
2097 "Problem getting current sessions list.", e);
2102 jalview.bin.Cache.log.debug("Got current sessions list: "
2103 + sess.length + " entries.");
2104 VamsasStMenu.removeAll();
2105 for (int i = 0; i < sess.length; i++)
2107 JMenuItem sessit = new JMenuItem();
2108 sessit.setText(sess[i]);
2109 sessit.setToolTipText(MessageManager.formatMessage(
2110 "label.connect_to_session", new Object[] { sess[i] }));
2111 final Desktop dsktp = this;
2112 final String mysesid = sess[i];
2113 sessit.addActionListener(new ActionListener()
2117 public void actionPerformed(ActionEvent e)
2119 if (dsktp.v_client == null)
2121 Thread rthr = new Thread(new Runnable()
2127 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2128 dsktp.setupVamsasConnectedGui();
2129 dsktp.v_client.initial_update();
2137 VamsasStMenu.add(sessit);
2139 // don't show an empty menu.
2140 VamsasStMenu.setVisible(sess.length > 0);
2145 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2146 VamsasStMenu.removeAll();
2147 VamsasStMenu.setVisible(false);
2152 // Not interested in the content. Just hide ourselves.
2153 VamsasStMenu.setVisible(false);
2158 public void vamsasSave_actionPerformed(ActionEvent e)
2160 if (v_client != null)
2162 JalviewFileChooser chooser = new JalviewFileChooser(
2163 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2164 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2165 new String[] { "Vamsas Document" }, "Vamsas Document");
2167 chooser.setFileView(new JalviewFileView());
2168 chooser.setDialogTitle(MessageManager
2169 .getString("label.save_vamsas_document_archive"));
2171 int value = chooser.showSaveDialog(this);
2173 if (value == JalviewFileChooser.APPROVE_OPTION)
2175 java.io.File choice = chooser.getSelectedFile();
2176 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2177 "label.saving_vamsas_doc",
2178 new Object[] { choice.getName() }));
2179 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2180 String warnmsg = null;
2181 String warnttl = null;
2184 v_client.vclient.storeDocument(choice);
2187 warnttl = "Serious Problem saving Vamsas Document";
2188 warnmsg = ex.toString();
2189 jalview.bin.Cache.log.error("Error Whilst saving document to "
2192 } catch (Exception ex)
2194 warnttl = "Problem saving Vamsas Document.";
2195 warnmsg = ex.toString();
2196 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2200 removeProgressPanel(progpanel);
2201 if (warnmsg != null)
2203 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2205 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2211 JPanel vamUpdate = null;
2214 * hide vamsas user gui bits when a vamsas document event is being handled.
2217 * true to hide gui, false to reveal gui
2219 public void setVamsasUpdate(boolean b)
2221 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2222 + (b ? "in progress" : "finished"));
2224 if (vamUpdate != null)
2226 this.removeProgressPanel(vamUpdate);
2230 vamUpdate = this.addProgressPanel(MessageManager
2231 .getString("label.updating_vamsas_session"));
2233 vamsasStart.setVisible(!b);
2234 vamsasStop.setVisible(!b);
2235 vamsasSave.setVisible(!b);
2238 public JInternalFrame[] getAllFrames()
2240 return desktop.getAllFrames();
2244 * Checks the given url to see if it gives a response indicating that the user
2245 * should be informed of a new questionnaire.
2249 public void checkForQuestionnaire(String url)
2251 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2252 // javax.swing.SwingUtilities.invokeLater(jvq);
2253 new Thread(jvq).start();
2257 * Proxy class for JDesktopPane which optionally displays the current memory
2258 * usage and highlights the desktop area with a red bar if free memory runs
2263 public class MyDesktopPane extends JDesktopPane implements Runnable
2266 private static final float ONE_MB = 1048576f;
2268 boolean showMemoryUsage = false;
2272 java.text.NumberFormat df;
2274 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2277 public MyDesktopPane(boolean showMemoryUsage)
2279 showMemoryUsage(showMemoryUsage);
2282 public void showMemoryUsage(boolean showMemory)
2284 this.showMemoryUsage = showMemory;
2287 Thread worker = new Thread(this);
2292 public boolean isShowMemoryUsage()
2294 return showMemoryUsage;
2300 df = java.text.NumberFormat.getNumberInstance();
2301 df.setMaximumFractionDigits(2);
2302 runtime = Runtime.getRuntime();
2304 while (showMemoryUsage)
2308 maxMemory = runtime.maxMemory() / ONE_MB;
2309 allocatedMemory = runtime.totalMemory() / ONE_MB;
2310 freeMemory = runtime.freeMemory() / ONE_MB;
2311 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2313 percentUsage = (totalFreeMemory / maxMemory) * 100;
2315 // if (percentUsage < 20)
2317 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2319 // instance.set.setBorder(border1);
2322 // sleep after showing usage
2324 } catch (Exception ex)
2326 ex.printStackTrace();
2332 public void paintComponent(Graphics g)
2334 if (showMemoryUsage && g != null && df != null)
2336 if (percentUsage < 20)
2338 g.setColor(Color.red);
2340 FontMetrics fm = g.getFontMetrics();
2343 g.drawString(MessageManager.formatMessage(
2344 "label.memory_stats",
2345 new Object[] { df.format(totalFreeMemory),
2346 df.format(maxMemory), df.format(percentUsage) }), 10,
2347 getHeight() - fm.getHeight());
2354 * fixes stacking order after a modal dialog to ensure windows that should be
2355 * on top actually are
2357 public void relayerWindows()
2362 protected JMenuItem groovyShell;
2365 * Accessor method to quickly get all the AlignmentFrames loaded.
2367 * @return an array of AlignFrame, or null if none found
2369 public static AlignFrame[] getAlignFrames()
2371 if (Jalview.isHeadlessMode())
2373 // Desktop.desktop is null in headless mode
2374 return new AlignFrame[] { currentAlignFrame };
2377 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2383 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2385 for (int i = frames.length - 1; i > -1; i--)
2387 if (frames[i] instanceof AlignFrame)
2389 avp.add((AlignFrame) frames[i]);
2391 else if (frames[i] instanceof SplitFrame)
2394 * Also check for a split frame containing an AlignFrame
2396 GSplitFrame sf = (GSplitFrame) frames[i];
2397 if (sf.getTopFrame() instanceof AlignFrame)
2399 avp.add((AlignFrame) sf.getTopFrame());
2401 if (sf.getBottomFrame() instanceof AlignFrame)
2403 avp.add((AlignFrame) sf.getBottomFrame());
2407 if (avp.size() == 0)
2411 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2416 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2420 public GStructureViewer[] getJmols()
2422 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2428 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2430 for (int i = frames.length - 1; i > -1; i--)
2432 if (frames[i] instanceof AppJmol)
2434 GStructureViewer af = (GStructureViewer) frames[i];
2438 if (avp.size() == 0)
2442 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2447 * Add Groovy Support to Jalview
2449 public void groovyShell_actionPerformed()
2453 openGroovyConsole();
2454 } catch (Exception ex)
2456 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2457 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2459 MessageManager.getString("label.couldnt_create_groovy_shell"),
2460 MessageManager.getString("label.groovy_support_failed"),
2461 JOptionPane.ERROR_MESSAGE);
2466 * Open the Groovy console
2468 void openGroovyConsole()
2470 groovyConsole = new groovy.ui.Console();
2473 * bind groovy variable 'Jalview' to the Desktop object
2475 groovyConsole.setVariable("Jalview", this);
2480 groovyConsole.run();
2483 * Allow only one console at a time, so that the AlignFrame menu option
2484 * 'Calculate | Run Groovy script' is unambiguous.
2485 * Disable 'new console', and enable 'Run script', when the console is
2486 * opened, and the reverse when it is closed
2488 Window window = (Window) groovyConsole.getFrame();
2489 window.addWindowListener(new WindowAdapter()
2492 public void windowClosed(WindowEvent e)
2494 groovyShell.setEnabled(true);
2495 enableExecuteGroovy(false);
2500 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2501 * and disable opening a second console
2503 groovyShell.setEnabled(false);
2504 enableExecuteGroovy(true);
2508 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2512 public void enableExecuteGroovy(boolean enabled)
2514 AlignFrame[] alignFrames = getAlignFrames();
2515 if (alignFrames != null)
2517 for (AlignFrame af : alignFrames)
2519 af.setGroovyEnabled(enabled);
2525 * Progress bars managed by the IProgressIndicator method.
2527 private Hashtable<Long, JPanel> progressBars;
2529 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2534 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2537 public void setProgressBar(String message, long id)
2539 if (progressBars == null)
2541 progressBars = new Hashtable<Long, JPanel>();
2542 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2545 if (progressBars.get(new Long(id)) != null)
2547 JPanel panel = progressBars.remove(new Long(id));
2548 if (progressBarHandlers.contains(new Long(id)))
2550 progressBarHandlers.remove(new Long(id));
2552 removeProgressPanel(panel);
2556 progressBars.put(new Long(id), addProgressPanel(message));
2563 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2564 * jalview.gui.IProgressIndicatorHandler)
2567 public void registerHandler(final long id,
2568 final IProgressIndicatorHandler handler)
2570 if (progressBarHandlers == null
2571 || !progressBars.containsKey(new Long(id)))
2575 .getString("error.call_setprogressbar_before_registering_handler"));
2577 progressBarHandlers.put(new Long(id), handler);
2578 final JPanel progressPanel = progressBars.get(new Long(id));
2579 if (handler.canCancel())
2581 JButton cancel = new JButton(
2582 MessageManager.getString("action.cancel"));
2583 final IProgressIndicator us = this;
2584 cancel.addActionListener(new ActionListener()
2588 public void actionPerformed(ActionEvent e)
2590 handler.cancelActivity(id);
2591 us.setProgressBar(MessageManager.formatMessage(
2592 "label.cancelled_params",
2593 new Object[] { ((JLabel) progressPanel.getComponent(0))
2597 progressPanel.add(cancel, BorderLayout.EAST);
2603 * @return true if any progress bars are still active
2606 public boolean operationInProgress()
2608 if (progressBars != null && progressBars.size() > 0)
2616 * This will return the first AlignFrame holding the given viewport instance.
2617 * It will break if there are more than one AlignFrames viewing a particular
2621 * @return alignFrame for viewport
2623 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2625 if (desktop != null)
2627 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2628 for (int panel = 0; aps != null && panel < aps.length; panel++)
2630 if (aps[panel] != null && aps[panel].av == viewport)
2632 return aps[panel].alignFrame;
2639 public VamsasApplication getVamsasApplication()
2646 * flag set if jalview GUI is being operated programmatically
2648 private boolean inBatchMode = false;
2651 * check if jalview GUI is being operated programmatically
2653 * @return inBatchMode
2655 public boolean isInBatchMode()
2661 * set flag if jalview GUI is being operated programmatically
2663 * @param inBatchMode
2665 public void setInBatchMode(boolean inBatchMode)
2667 this.inBatchMode = inBatchMode;
2670 public void startServiceDiscovery()
2672 startServiceDiscovery(false);
2675 public void startServiceDiscovery(boolean blocking)
2677 boolean alive = true;
2678 Thread t0 = null, t1 = null, t2 = null;
2679 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2682 // todo: changesupport handlers need to be transferred
2683 if (discoverer == null)
2685 discoverer = new jalview.ws.jws1.Discoverer();
2686 // register PCS handler for desktop.
2687 discoverer.addPropertyChangeListener(changeSupport);
2689 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2690 // until we phase out completely
2691 (t0 = new Thread(discoverer)).start();
2694 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2696 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2698 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2700 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2706 // TODO: do rest service discovery
2715 } catch (Exception e)
2718 alive = (t1 != null && t1.isAlive())
2719 || (t2 != null && t2.isAlive())
2720 || (t3 != null && t3.isAlive())
2721 || (t0 != null && t0.isAlive());
2727 * called to check if the service discovery process completed successfully.
2731 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2733 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2735 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2736 .getErrorMessages();
2739 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2741 if (serviceChangedDialog == null)
2743 // only run if we aren't already displaying one of these.
2744 addDialogThread(serviceChangedDialog = new Runnable()
2751 * JalviewDialog jd =new JalviewDialog() {
2753 * @Override protected void cancelPressed() { // TODO
2754 * Auto-generated method stub
2756 * }@Override protected void okPressed() { // TODO
2757 * Auto-generated method stub
2759 * }@Override protected void raiseClosed() { // TODO
2760 * Auto-generated method stub
2762 * } }; jd.initDialogFrame(new
2763 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2764 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2765 * + " or mis-configured HTTP proxy settings.<br/>" +
2766 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2768 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2769 * ), true, true, "Web Service Configuration Problem", 450,
2772 * jd.waitForInput();
2778 "<html><table width=\"450\"><tr><td>"
2780 + "</td></tr></table>"
2781 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2782 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2783 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2784 + " Tools->Preferences dialog box to change them.</p></html>"),
2785 "Web Service Configuration Problem",
2786 JOptionPane.DEFAULT_OPTION,
2787 JOptionPane.ERROR_MESSAGE);
2788 serviceChangedDialog = null;
2797 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2804 private Runnable serviceChangedDialog = null;
2807 * start a thread to open a URL in the configured browser. Pops up a warning
2808 * dialog to the user if there is an exception when calling out to the browser
2813 public static void showUrl(final String url)
2815 showUrl(url, Desktop.instance);
2819 * Like showUrl but allows progress handler to be specified
2823 * (null) or object implementing IProgressIndicator
2825 public static void showUrl(final String url,
2826 final IProgressIndicator progress)
2828 new Thread(new Runnable()
2835 if (progress != null)
2837 progress.setProgressBar(MessageManager.formatMessage(
2838 "status.opening_params", new Object[] { url }), this
2841 jalview.util.BrowserLauncher.openURL(url);
2842 } catch (Exception ex)
2844 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2846 .getString("label.web_browser_not_found_unix"),
2847 MessageManager.getString("label.web_browser_not_found"),
2848 JOptionPane.WARNING_MESSAGE);
2850 ex.printStackTrace();
2852 if (progress != null)
2854 progress.setProgressBar(null, this.hashCode());
2860 public static WsParamSetManager wsparamManager = null;
2862 public static ParamManager getUserParameterStore()
2864 if (wsparamManager == null)
2866 wsparamManager = new WsParamSetManager();
2868 return wsparamManager;
2872 * static hyperlink handler proxy method for use by Jalview's internal windows
2876 public static void hyperlinkUpdate(HyperlinkEvent e)
2878 if (e.getEventType() == EventType.ACTIVATED)
2883 url = e.getURL().toString();
2884 Desktop.showUrl(url);
2885 } catch (Exception x)
2889 if (Cache.log != null)
2891 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2895 System.err.println("Couldn't handle string " + url
2899 // ignore any exceptions due to dud links.
2906 * single thread that handles display of dialogs to user.
2908 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2911 * flag indicating if dialogExecutor should try to acquire a permit
2913 private volatile boolean dialogPause = true;
2918 private java.util.concurrent.Semaphore block = new Semaphore(0);
2920 private static groovy.ui.Console groovyConsole;
2923 * add another dialog thread to the queue
2927 public void addDialogThread(final Runnable prompter)
2929 dialogExecutor.submit(new Runnable()
2939 } catch (InterruptedException x)
2944 if (instance == null)
2950 SwingUtilities.invokeAndWait(prompter);
2951 } catch (Exception q)
2953 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2959 public void startDialogQueue()
2961 // set the flag so we don't pause waiting for another permit and semaphore
2962 // the current task to begin
2963 dialogPause = false;
2968 protected void snapShotWindow_actionPerformed(ActionEvent e)
2972 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2973 "View of Desktop", getWidth(), getHeight(), of = new File(
2974 "Jalview_snapshot" + System.currentTimeMillis()
2975 + ".eps"), "View of desktop", null, 0, false);
2978 paintAll(im.getGraphics());
2980 } catch (Exception q)
2982 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2986 Cache.log.info("Successfully written snapshot to file "
2987 + of.getAbsolutePath());
2991 * Explode the views in the given SplitFrame into separate SplitFrame windows.
2992 * This respects (remembers) any previous 'exploded geometry' i.e. the size
2993 * and location last time the view was expanded (if any). However it does not
2994 * remember the split pane divider location - this is set to match the
2995 * 'exploding' frame.
2999 public void explodeViews(SplitFrame sf)
3001 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3002 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3003 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3005 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3007 int viewCount = topPanels.size();
3014 * Processing in reverse order works, forwards order leaves the first panels
3015 * not visible. I don't know why!
3017 for (int i = viewCount - 1; i >= 0; i--)
3020 * Make new top and bottom frames. These take over the respective
3021 * AlignmentPanel objects, including their AlignmentViewports, so the
3022 * cdna/protein relationships between the viewports is carried over to the
3025 * explodedGeometry holds the (x, y) position of the previously exploded
3026 * SplitFrame, and the (width, height) of the AlignFrame component
3028 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3029 AlignFrame newTopFrame = new AlignFrame(topPanel);
3030 newTopFrame.setSize(oldTopFrame.getSize());
3031 newTopFrame.setVisible(true);
3032 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3033 .getExplodedGeometry();
3034 if (geometry != null)
3036 newTopFrame.setSize(geometry.getSize());
3039 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3040 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3041 newBottomFrame.setSize(oldBottomFrame.getSize());
3042 newBottomFrame.setVisible(true);
3043 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3044 .getExplodedGeometry();
3045 if (geometry != null)
3047 newBottomFrame.setSize(geometry.getSize());
3050 topPanel.av.setGatherViewsHere(false);
3051 bottomPanel.av.setGatherViewsHere(false);
3052 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3054 if (geometry != null)
3056 splitFrame.setLocation(geometry.getLocation());
3058 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3062 * Clear references to the panels (now relocated in the new SplitFrames)
3063 * before closing the old SplitFrame.
3066 bottomPanels.clear();
3071 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3072 * back into the given SplitFrame as additional views. Note that the gathered
3073 * frames may themselves have multiple views.
3077 public void gatherViews(GSplitFrame source)
3080 * special handling of explodedGeometry for a view within a SplitFrame: - it
3081 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3082 * height) of the AlignFrame component
3084 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3085 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3086 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3087 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3088 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3089 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3091 myTopFrame.viewport.setGatherViewsHere(true);
3092 myBottomFrame.viewport.setGatherViewsHere(true);
3093 String topViewId = myTopFrame.viewport.getSequenceSetId();
3094 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3096 JInternalFrame[] frames = desktop.getAllFrames();
3097 for (JInternalFrame frame : frames)
3099 if (frame instanceof SplitFrame && frame != source)
3101 SplitFrame sf = (SplitFrame) frame;
3102 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3103 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3104 boolean gatherThis = false;
3105 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3107 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3108 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3109 if (topViewId.equals(topPanel.av.getSequenceSetId())
3110 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3113 topPanel.av.setGatherViewsHere(false);
3114 bottomPanel.av.setGatherViewsHere(false);
3115 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3116 topFrame.getSize()));
3117 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3118 .getLocation(), bottomFrame.getSize()));
3119 myTopFrame.addAlignmentPanel(topPanel, false);
3120 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3126 topFrame.getAlignPanels().clear();
3127 bottomFrame.getAlignPanels().clear();
3134 * The dust settles...give focus to the tab we did this from.
3136 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3140 public static AlignFrame getCurrentAlignFrame()
3142 return currentAlignFrame;
3145 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3147 Desktop.currentAlignFrame = currentAlignFrame;
3150 public static groovy.ui.Console getGroovyConsole()
3152 return groovyConsole;
3155 public static void transferFromDropTarget(List<String> files,
3156 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3160 DataFlavor uriListFlavor = new DataFlavor(
3161 "text/uri-list;class=java.lang.String");
3162 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3164 // Works on Windows and MacOSX
3165 Cache.log.debug("Drop handled as javaFileListFlavor");
3166 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3167 for (Object file : (List) t
3168 .getTransferData(DataFlavor.javaFileListFlavor))
3170 files.add(((File)file).toString());
3171 protocols.add(FormatAdapter.FILE);
3176 // Unix like behaviour
3177 boolean added = false;
3179 if (t.isDataFlavorSupported(uriListFlavor))
3181 Cache.log.debug("Drop handled as uriListFlavor");
3182 // This is used by Unix drag system
3183 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3184 data = (String) t.getTransferData(uriListFlavor);
3188 // fallback to text: workaround - on OSX where there's a JVM bug
3189 Cache.log.debug("standard URIListFlavor failed. Trying text");
3190 // try text fallback
3191 data = (String) t.getTransferData(new DataFlavor(
3192 "text/plain;class=java.lang.String"));
3193 if (Cache.log.isDebugEnabled())
3195 Cache.log.debug("fallback returned " + data);
3198 while (protocols.size() < files.size())
3200 Cache.log.debug("Adding missing FILE protocol for "
3201 + files.get(protocols.size()));
3202 protocols.add(FormatAdapter.FILE);
3204 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3205 data, "\r\n"); st.hasMoreTokens();)
3208 String s = st.nextToken();
3209 if (s.startsWith("#"))
3211 // the line is a comment (as per the RFC 2483)
3214 java.net.URI uri = new java.net.URI(s);
3215 if (uri.getScheme().toLowerCase().startsWith("http"))
3217 protocols.add(FormatAdapter.URL);
3218 files.add(uri.toString());
3222 // otherwise preserve old behaviour: catch all for file objects
3223 java.io.File file = new java.io.File(uri);
3224 protocols.add(FormatAdapter.FILE);
3225 files.add(file.toString());
3228 if (Cache.log.isDebugEnabled())
3230 if (data == null || !added)
3233 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3234 for (DataFlavor fl : t.getTransferDataFlavors())
3236 Cache.log.debug("Supported transfer dataflavor: "
3238 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3239 Object df = t.getTransferData(fl);
3242 Cache.log.debug("Retrieves: " + df);
3246 Cache.log.debug("Retrieved nothing");