2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import static jalview.util.UrlConstants.EMBLEBI_STRING;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.bin.Cache;
28 import jalview.bin.Jalview;
29 import jalview.io.FileLoader;
30 import jalview.io.FormatAdapter;
31 import jalview.io.IdentifyFile;
32 import jalview.io.JalviewFileChooser;
33 import jalview.io.JalviewFileView;
34 import jalview.jbgui.GSplitFrame;
35 import jalview.jbgui.GStructureViewer;
36 import jalview.structure.StructureSelectionManager;
37 import jalview.util.ImageMaker;
38 import jalview.util.MessageManager;
39 import jalview.util.Platform;
40 import jalview.viewmodel.AlignmentViewport;
41 import jalview.ws.params.ParamManager;
43 import java.awt.BorderLayout;
44 import java.awt.Color;
45 import java.awt.Dimension;
46 import java.awt.FontMetrics;
47 import java.awt.Graphics;
48 import java.awt.GridLayout;
49 import java.awt.Point;
50 import java.awt.Rectangle;
51 import java.awt.Toolkit;
52 import java.awt.Window;
53 import java.awt.datatransfer.Clipboard;
54 import java.awt.datatransfer.ClipboardOwner;
55 import java.awt.datatransfer.DataFlavor;
56 import java.awt.datatransfer.Transferable;
57 import java.awt.dnd.DnDConstants;
58 import java.awt.dnd.DropTargetDragEvent;
59 import java.awt.dnd.DropTargetDropEvent;
60 import java.awt.dnd.DropTargetEvent;
61 import java.awt.dnd.DropTargetListener;
62 import java.awt.event.ActionEvent;
63 import java.awt.event.ActionListener;
64 import java.awt.event.FocusEvent;
65 import java.awt.event.FocusListener;
66 import java.awt.event.KeyEvent;
67 import java.awt.event.MouseAdapter;
68 import java.awt.event.MouseEvent;
69 import java.awt.event.WindowAdapter;
70 import java.awt.event.WindowEvent;
71 import java.beans.PropertyChangeEvent;
72 import java.beans.PropertyChangeListener;
73 import java.io.BufferedInputStream;
75 import java.io.FileOutputStream;
77 import java.util.ArrayList;
78 import java.util.Hashtable;
79 import java.util.List;
80 import java.util.StringTokenizer;
81 import java.util.Vector;
82 import java.util.concurrent.ExecutorService;
83 import java.util.concurrent.Executors;
84 import java.util.concurrent.Semaphore;
86 import javax.swing.AbstractAction;
87 import javax.swing.Box;
88 import javax.swing.BoxLayout;
89 import javax.swing.DefaultDesktopManager;
90 import javax.swing.DesktopManager;
91 import javax.swing.JButton;
92 import javax.swing.JCheckBox;
93 import javax.swing.JComboBox;
94 import javax.swing.JComponent;
95 import javax.swing.JDesktopPane;
96 import javax.swing.JFrame;
97 import javax.swing.JInternalFrame;
98 import javax.swing.JLabel;
99 import javax.swing.JMenuItem;
100 import javax.swing.JOptionPane;
101 import javax.swing.JPanel;
102 import javax.swing.JPopupMenu;
103 import javax.swing.JProgressBar;
104 import javax.swing.KeyStroke;
105 import javax.swing.SwingUtilities;
106 import javax.swing.event.HyperlinkEvent;
107 import javax.swing.event.HyperlinkEvent.EventType;
108 import javax.swing.event.InternalFrameAdapter;
109 import javax.swing.event.InternalFrameEvent;
110 import javax.swing.event.MenuEvent;
111 import javax.swing.event.MenuListener;
118 * @version $Revision: 1.155 $
120 public class Desktop extends jalview.jbgui.GDesktop implements
121 DropTargetListener, ClipboardOwner, IProgressIndicator,
122 jalview.api.StructureSelectionManagerProvider
125 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
128 * news reader - null if it was never started.
130 private BlogReader jvnews = null;
132 private File projectFile;
136 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
138 public void addJalviewPropertyChangeListener(
139 PropertyChangeListener listener)
141 changeSupport.addJalviewPropertyChangeListener(listener);
145 * @param propertyName
147 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
148 * java.beans.PropertyChangeListener)
150 public void addJalviewPropertyChangeListener(String propertyName,
151 PropertyChangeListener listener)
153 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
157 * @param propertyName
159 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
160 * java.beans.PropertyChangeListener)
162 public void removeJalviewPropertyChangeListener(String propertyName,
163 PropertyChangeListener listener)
165 changeSupport.removeJalviewPropertyChangeListener(propertyName,
169 /** Singleton Desktop instance */
170 public static Desktop instance;
172 public static MyDesktopPane desktop;
174 static int openFrameCount = 0;
176 static final int xOffset = 30;
178 static final int yOffset = 30;
180 public static jalview.ws.jws1.Discoverer discoverer;
182 public static Object[] jalviewClipboard;
184 public static boolean internalCopy = false;
186 static int fileLoadingCount = 0;
188 class MyDesktopManager implements DesktopManager
191 private DesktopManager delegate;
193 public MyDesktopManager(DesktopManager delegate)
195 this.delegate = delegate;
199 public void activateFrame(JInternalFrame f)
203 delegate.activateFrame(f);
204 } catch (NullPointerException npe)
206 Point p = getMousePosition();
207 instance.showPasteMenu(p.x, p.y);
212 public void beginDraggingFrame(JComponent f)
214 delegate.beginDraggingFrame(f);
218 public void beginResizingFrame(JComponent f, int direction)
220 delegate.beginResizingFrame(f, direction);
224 public void closeFrame(JInternalFrame f)
226 delegate.closeFrame(f);
230 public void deactivateFrame(JInternalFrame f)
232 delegate.deactivateFrame(f);
236 public void deiconifyFrame(JInternalFrame f)
238 delegate.deiconifyFrame(f);
242 public void dragFrame(JComponent f, int newX, int newY)
248 delegate.dragFrame(f, newX, newY);
252 public void endDraggingFrame(JComponent f)
254 delegate.endDraggingFrame(f);
258 public void endResizingFrame(JComponent f)
260 delegate.endResizingFrame(f);
264 public void iconifyFrame(JInternalFrame f)
266 delegate.iconifyFrame(f);
270 public void maximizeFrame(JInternalFrame f)
272 delegate.maximizeFrame(f);
276 public void minimizeFrame(JInternalFrame f)
278 delegate.minimizeFrame(f);
282 public void openFrame(JInternalFrame f)
284 delegate.openFrame(f);
288 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
295 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
299 public void setBoundsForFrame(JComponent f, int newX, int newY,
300 int newWidth, int newHeight)
302 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
305 // All other methods, simply delegate
310 * Creates a new Desktop object.
315 * A note to implementors. It is ESSENTIAL that any activities that might
316 * block are spawned off as threads rather than waited for during this
320 doVamsasClientCheck();
322 groovyShell = new JMenuItem();
323 groovyShell.setText(MessageManager.getString("label.groovy_console"));
324 groovyShell.addActionListener(new ActionListener()
327 public void actionPerformed(ActionEvent e)
329 groovyShell_actionPerformed();
332 toolsMenu.add(groovyShell);
333 groovyShell.setVisible(true);
335 doConfigureStructurePrefs();
336 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
337 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
338 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
340 boolean showjconsole = jalview.bin.Cache.getDefault(
341 "SHOW_JAVA_CONSOLE", false);
342 desktop = new MyDesktopPane(selmemusage);
343 if (Platform.isAMac())
345 desktop.setDoubleBuffered(false);
347 showMemusage.setSelected(selmemusage);
348 desktop.setBackground(Color.white);
349 getContentPane().setLayout(new BorderLayout());
350 // alternate config - have scrollbars - see notes in JAL-153
351 // JScrollPane sp = new JScrollPane();
352 // sp.getViewport().setView(desktop);
353 // getContentPane().add(sp, BorderLayout.CENTER);
354 getContentPane().add(desktop, BorderLayout.CENTER);
355 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
357 // This line prevents Windows Look&Feel resizing all new windows to maximum
358 // if previous window was maximised
359 desktop.setDesktopManager(new MyDesktopManager(
360 new DefaultDesktopManager()));
362 Rectangle dims = getLastKnownDimensions("");
369 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
370 setBounds((screenSize.width - 900) / 2,
371 (screenSize.height - 650) / 2, 900, 650);
373 jconsole = new Console(this, showjconsole);
374 // add essential build information
375 jconsole.setHeader("Jalview Version: "
376 + jalview.bin.Cache.getProperty("VERSION") + "\n"
377 + "Jalview Installation: "
378 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
379 + "\n" + "Build Date: "
380 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
381 + "Java version: " + System.getProperty("java.version") + "\n"
382 + System.getProperty("os.arch") + " "
383 + System.getProperty("os.name") + " "
384 + System.getProperty("os.version"));
386 showConsole(showjconsole);
388 showNews.setVisible(false);
392 this.addWindowListener(new WindowAdapter()
395 public void windowClosing(WindowEvent evt)
402 this.addMouseListener(ma = new MouseAdapter()
405 public void mousePressed(MouseEvent evt)
407 if (evt.isPopupTrigger()) // Mac
409 showPasteMenu(evt.getX(), evt.getY());
414 public void mouseReleased(MouseEvent evt)
416 if (evt.isPopupTrigger()) // Windows
418 showPasteMenu(evt.getX(), evt.getY());
422 desktop.addMouseListener(ma);
424 this.addFocusListener(new FocusListener()
428 public void focusLost(FocusEvent e)
430 // TODO Auto-generated method stub
435 public void focusGained(FocusEvent e)
437 Cache.log.debug("Relaying windows after focus gain");
438 // make sure that we sort windows properly after we gain focus
439 instance.relayerWindows();
442 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
443 // Spawn a thread that shows the splashscreen
444 SwingUtilities.invokeLater(new Runnable()
454 // Thread off a new instance of the file chooser - this reduces the time it
455 // takes to open it later on.
456 new Thread(new Runnable()
461 Cache.log.debug("Filechooser init thread started.");
462 new JalviewFileChooser(
463 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
464 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
465 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
466 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
467 Cache.log.debug("Filechooser init thread finished.");
470 // Add the service change listener
471 changeSupport.addJalviewPropertyChangeListener("services",
472 new PropertyChangeListener()
476 public void propertyChange(PropertyChangeEvent evt)
478 Cache.log.debug("Firing service changed event for "
479 + evt.getNewValue());
480 JalviewServicesChanged(evt);
486 public void doConfigureStructurePrefs()
488 // configure services
489 StructureSelectionManager ssm = StructureSelectionManager
490 .getStructureSelectionManager(this);
491 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
493 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
494 Preferences.ADD_TEMPFACT_ANN, true));
495 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
496 Preferences.STRUCT_FROM_PDB, true));
497 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
498 Preferences.USE_RNAVIEW, true));
502 ssm.setAddTempFacAnnot(false);
503 ssm.setProcessSecondaryStructure(false);
504 ssm.setSecStructServices(false);
508 public void checkForNews()
510 final Desktop me = this;
511 // Thread off the news reader, in case there are connection problems.
512 addDialogThread(new Runnable()
517 Cache.log.debug("Starting news thread.");
519 jvnews = new BlogReader(me);
520 showNews.setVisible(true);
521 Cache.log.debug("Completed news thread.");
527 protected void showNews_actionPerformed(ActionEvent e)
529 showNews(showNews.isSelected());
532 void showNews(boolean visible)
535 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
536 showNews.setSelected(visible);
537 if (visible && !jvnews.isVisible())
539 new Thread(new Runnable()
544 long now = System.currentTimeMillis();
545 Desktop.instance.setProgressBar(
546 MessageManager.getString("status.refreshing_news"), now);
547 jvnews.refreshNews();
548 Desktop.instance.setProgressBar(null, now);
557 * recover the last known dimensions for a jalview window
560 * - empty string is desktop, all other windows have unique prefix
561 * @return null or last known dimensions scaled to current geometry (if last
562 * window geom was known)
564 Rectangle getLastKnownDimensions(String windowName)
566 // TODO: lock aspect ratio for scaling desktop Bug #0058199
567 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
568 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
569 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
570 String width = jalview.bin.Cache.getProperty(windowName
572 String height = jalview.bin.Cache.getProperty(windowName
574 if ((x != null) && (y != null) && (width != null) && (height != null))
576 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
577 .parseInt(width), ih = Integer.parseInt(height);
578 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
580 // attempt #1 - try to cope with change in screen geometry - this
581 // version doesn't preserve original jv aspect ratio.
582 // take ratio of current screen size vs original screen size.
583 double sw = ((1f * screenSize.width) / (1f * Integer
584 .parseInt(jalview.bin.Cache
585 .getProperty("SCREENGEOMETRY_WIDTH"))));
586 double sh = ((1f * screenSize.height) / (1f * Integer
587 .parseInt(jalview.bin.Cache
588 .getProperty("SCREENGEOMETRY_HEIGHT"))));
589 // rescale the bounds depending upon the current screen geometry.
590 ix = (int) (ix * sw);
591 iw = (int) (iw * sw);
592 iy = (int) (iy * sh);
593 ih = (int) (ih * sh);
594 while (ix >= screenSize.width)
596 jalview.bin.Cache.log
597 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
598 ix -= screenSize.width;
600 while (iy >= screenSize.height)
602 jalview.bin.Cache.log
603 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
604 iy -= screenSize.height;
606 jalview.bin.Cache.log.debug("Got last known dimensions for "
607 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
610 // return dimensions for new instance
611 return new Rectangle(ix, iy, iw, ih);
616 private void doVamsasClientCheck()
618 if (jalview.bin.Cache.vamsasJarsPresent())
620 setupVamsasDisconnectedGui();
621 VamsasMenu.setVisible(true);
622 final Desktop us = this;
623 VamsasMenu.addMenuListener(new MenuListener()
625 // this listener remembers when the menu was first selected, and
626 // doesn't rebuild the session list until it has been cleared and
628 boolean refresh = true;
631 public void menuCanceled(MenuEvent e)
637 public void menuDeselected(MenuEvent e)
643 public void menuSelected(MenuEvent e)
647 us.buildVamsasStMenu();
652 vamsasStart.setVisible(true);
656 void showPasteMenu(int x, int y)
658 JPopupMenu popup = new JPopupMenu();
659 JMenuItem item = new JMenuItem(
660 MessageManager.getString("label.paste_new_window"));
661 item.addActionListener(new ActionListener()
664 public void actionPerformed(ActionEvent evt)
671 popup.show(this, x, y);
678 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
679 Transferable contents = c.getContents(this);
681 if (contents != null)
683 String file = (String) contents
684 .getTransferData(DataFlavor.stringFlavor);
686 String format = new IdentifyFile().identify(file,
687 FormatAdapter.PASTE);
689 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
692 } catch (Exception ex)
695 .println("Unable to paste alignment from system clipboard:\n"
701 * Adds and opens the given frame to the desktop
712 public static synchronized void addInternalFrame(
713 final JInternalFrame frame, String title, int w, int h)
715 addInternalFrame(frame, title, true, w, h, true);
719 * Add an internal frame to the Jalview desktop
726 * When true, display frame immediately, otherwise, caller must call
727 * setVisible themselves.
733 public static synchronized void addInternalFrame(
734 final JInternalFrame frame, String title, boolean makeVisible,
737 addInternalFrame(frame, title, makeVisible, w, h, true);
741 * Add an internal frame to the Jalview desktop and make it visible
754 public static synchronized void addInternalFrame(
755 final JInternalFrame frame, String title, int w, int h,
758 addInternalFrame(frame, title, true, w, h, resizable);
762 * Add an internal frame to the Jalview desktop
769 * When true, display frame immediately, otherwise, caller must call
770 * setVisible themselves.
778 public static synchronized void addInternalFrame(
779 final JInternalFrame frame, String title, boolean makeVisible,
780 int w, int h, boolean resizable)
783 // TODO: allow callers to determine X and Y position of frame (eg. via
785 // TODO: consider fixing method to update entries in the window submenu with
786 // the current window title
788 frame.setTitle(title);
789 if (frame.getWidth() < 1 || frame.getHeight() < 1)
793 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
794 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
795 // IF JALVIEW IS RUNNING HEADLESS
796 // ///////////////////////////////////////////////
798 || (System.getProperty("java.awt.headless") != null && System
799 .getProperty("java.awt.headless").equals("true")))
806 frame.setVisible(makeVisible);
807 frame.setClosable(true);
808 frame.setResizable(resizable);
809 frame.setMaximizable(resizable);
810 frame.setIconifiable(resizable);
811 if (Platform.isAMac())
813 frame.setIconifiable(false);
814 frame.setFrameIcon(null);
815 // frame.setDesktopIcon(null);
816 frame.setDoubleBuffered(false);
818 if (frame.getX() < 1 && frame.getY() < 1)
820 frame.setLocation(xOffset * openFrameCount, yOffset
821 * ((openFrameCount - 1) % 10) + yOffset);
825 * add an entry for the new frame in the Window menu
826 * (and remove it when the frame is closed)
828 final JMenuItem menuItem = new JMenuItem(title);
829 frame.addInternalFrameListener(new InternalFrameAdapter()
832 public void internalFrameActivated(InternalFrameEvent evt)
834 JInternalFrame itf = desktop.getSelectedFrame();
842 public void internalFrameClosed(InternalFrameEvent evt)
844 PaintRefresher.RemoveComponent(frame);
847 * defensive check to prevent frames being
848 * added half off the window
850 if (openFrameCount > 0)
856 * ensure no reference to alignFrame retained by menu item listener
858 if (menuItem.getActionListeners().length > 0)
860 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
862 windowMenu.remove(menuItem);
863 JInternalFrame itf = desktop.getSelectedFrame();
867 if (itf instanceof AlignFrame)
869 Jalview.setCurrentAlignFrame((AlignFrame) itf);
876 menuItem.addActionListener(new ActionListener()
879 public void actionPerformed(ActionEvent e)
883 frame.setSelected(true);
884 frame.setIcon(false);
885 } catch (java.beans.PropertyVetoException ex)
892 windowMenu.add(menuItem);
898 frame.setSelected(true);
899 frame.requestFocus();
900 } catch (java.beans.PropertyVetoException ve)
902 } catch (java.lang.ClassCastException cex)
905 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
911 public void lostOwnership(Clipboard clipboard, Transferable contents)
915 Desktop.jalviewClipboard = null;
918 internalCopy = false;
922 public void dragEnter(DropTargetDragEvent evt)
927 public void dragExit(DropTargetEvent evt)
932 public void dragOver(DropTargetDragEvent evt)
937 public void dropActionChanged(DropTargetDragEvent evt)
948 public void drop(DropTargetDropEvent evt)
950 boolean success = true;
951 // JAL-1552 - acceptDrop required before getTransferable call for
952 // Java's Transferable for native dnd
953 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
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);
1184 if (groovyConsole != null)
1186 // suppress a possible repeat prompt to save script
1187 groovyConsole.setDirty(false);
1188 groovyConsole.exit();
1193 private void storeLastKnownDimensions(String string, Rectangle jc)
1195 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1196 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1197 + " height:" + jc.height);
1199 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1200 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1201 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1202 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1212 public void aboutMenuItem_actionPerformed(ActionEvent e)
1214 // StringBuffer message = getAboutMessage(false);
1215 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1217 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1218 new Thread(new Runnable()
1223 new SplashScreen(true);
1228 public StringBuffer getAboutMessage(boolean shortv)
1230 StringBuffer message = new StringBuffer();
1231 message.append("<html>");
1234 message.append("<h1><strong>Version: "
1235 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1236 message.append("<strong>Last Updated: <em>"
1237 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1238 + "</em></strong>");
1244 message.append("<strong>Version "
1245 + jalview.bin.Cache.getProperty("VERSION")
1246 + "; last updated: "
1247 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1250 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1253 message.append("<br>...Checking latest version...</br>");
1255 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1256 .equals(jalview.bin.Cache.getProperty("VERSION")))
1258 boolean red = false;
1259 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1260 .indexOf("automated build") == -1)
1263 // Displayed when code version and jnlp version do not match and code
1264 // version is not a development build
1265 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1268 message.append("<br>!! Version "
1269 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1271 + " is available for download from "
1272 + jalview.bin.Cache.getDefault("www.jalview.org",
1273 "http://www.jalview.org") + " !!");
1276 message.append("</div>");
1279 message.append("<br>Authors: "
1281 .getDefault("AUTHORFNAMES",
1282 "The Jalview Authors (See AUTHORS file for current list)")
1283 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1284 + "<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"
1285 + "<br><br>If you use Jalview, please cite:"
1286 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1287 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1288 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1300 public void documentationMenuItem_actionPerformed(ActionEvent e)
1304 Help.showHelpWindow();
1305 } catch (Exception ex)
1311 public void closeAll_actionPerformed(ActionEvent e)
1313 // TODO show a progress bar while closing?
1314 JInternalFrame[] frames = desktop.getAllFrames();
1315 for (int i = 0; i < frames.length; i++)
1319 frames[i].setClosed(true);
1320 } catch (java.beans.PropertyVetoException ex)
1324 Jalview.setCurrentAlignFrame(null);
1325 System.out.println("ALL CLOSED");
1326 if (v_client != null)
1328 // TODO clear binding to vamsas document objects on close_all
1332 * reset state of singleton objects as appropriate (clear down session state
1333 * when all windows are closed)
1335 StructureSelectionManager ssm = StructureSelectionManager
1336 .getStructureSelectionManager(this);
1345 public void raiseRelated_actionPerformed(ActionEvent e)
1347 reorderAssociatedWindows(false, false);
1351 public void minimizeAssociated_actionPerformed(ActionEvent e)
1353 reorderAssociatedWindows(true, false);
1356 void closeAssociatedWindows()
1358 reorderAssociatedWindows(false, true);
1364 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1368 protected void garbageCollect_actionPerformed(ActionEvent e)
1370 // We simply collect the garbage
1371 jalview.bin.Cache.log.debug("Collecting garbage...");
1373 jalview.bin.Cache.log.debug("Finished garbage collection.");
1380 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1384 protected void showMemusage_actionPerformed(ActionEvent e)
1386 desktop.showMemoryUsage(showMemusage.isSelected());
1393 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1397 protected void showConsole_actionPerformed(ActionEvent e)
1399 showConsole(showConsole.isSelected());
1402 Console jconsole = null;
1405 * control whether the java console is visible or not
1409 void showConsole(boolean selected)
1411 showConsole.setSelected(selected);
1412 // TODO: decide if we should update properties file
1413 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1415 jconsole.setVisible(selected);
1418 void reorderAssociatedWindows(boolean minimize, boolean close)
1420 JInternalFrame[] frames = desktop.getAllFrames();
1421 if (frames == null || frames.length < 1)
1426 AlignmentViewport source = null, target = null;
1427 if (frames[0] instanceof AlignFrame)
1429 source = ((AlignFrame) frames[0]).getCurrentView();
1431 else if (frames[0] instanceof TreePanel)
1433 source = ((TreePanel) frames[0]).getViewPort();
1435 else if (frames[0] instanceof PCAPanel)
1437 source = ((PCAPanel) frames[0]).av;
1439 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1441 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1446 for (int i = 0; i < frames.length; i++)
1449 if (frames[i] == null)
1453 if (frames[i] instanceof AlignFrame)
1455 target = ((AlignFrame) frames[i]).getCurrentView();
1457 else if (frames[i] instanceof TreePanel)
1459 target = ((TreePanel) frames[i]).getViewPort();
1461 else if (frames[i] instanceof PCAPanel)
1463 target = ((PCAPanel) frames[i]).av;
1465 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1467 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1470 if (source == target)
1476 frames[i].setClosed(true);
1480 frames[i].setIcon(minimize);
1483 frames[i].toFront();
1487 } catch (java.beans.PropertyVetoException ex)
1502 protected void preferences_actionPerformed(ActionEvent e)
1514 public void saveState_actionPerformed(ActionEvent e)
1516 JalviewFileChooser chooser = new JalviewFileChooser(
1517 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1518 new String[] { "jvp" }, new String[] { "Jalview Project" },
1521 chooser.setFileView(new JalviewFileView());
1522 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1524 int value = chooser.showSaveDialog(this);
1526 if (value == JalviewFileChooser.APPROVE_OPTION)
1528 final Desktop me = this;
1529 final java.io.File choice = chooser.getSelectedFile();
1530 setProjectFile(choice);
1532 new Thread(new Runnable()
1537 // TODO: refactor to Jalview desktop session controller action.
1538 setProgressBar(MessageManager.formatMessage(
1539 "label.saving_jalview_project",
1540 new Object[] { choice.getName() }), choice.hashCode());
1541 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1542 choice.getParent());
1543 // TODO catch and handle errors for savestate
1544 // TODO prevent user from messing with the Desktop whilst we're saving
1547 new Jalview2XML().saveState(choice);
1548 } catch (OutOfMemoryError oom)
1550 new OOMWarning("Whilst saving current state to "
1551 + choice.getName(), oom);
1552 } catch (Exception ex)
1555 "Problems whilst trying to save to " + choice.getName(),
1557 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1558 "label.error_whilst_saving_current_state_to",
1559 new Object[] { choice.getName() }), MessageManager
1560 .getString("label.couldnt_save_project"),
1561 JOptionPane.WARNING_MESSAGE);
1563 setProgressBar(null, choice.hashCode());
1569 private void setProjectFile(File choice)
1571 this.projectFile = choice;
1574 public File getProjectFile()
1576 return this.projectFile;
1586 public void loadState_actionPerformed(ActionEvent e)
1588 JalviewFileChooser chooser = new JalviewFileChooser(
1589 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1590 "jvp", "jar" }, new String[] { "Jalview Project",
1591 "Jalview Project (old)" }, "Jalview Project");
1592 chooser.setFileView(new JalviewFileView());
1593 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1595 int value = chooser.showOpenDialog(this);
1597 if (value == JalviewFileChooser.APPROVE_OPTION)
1599 final File selectedFile = chooser.getSelectedFile();
1600 setProjectFile(selectedFile);
1601 final String choice = selectedFile.getAbsolutePath();
1602 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1603 selectedFile.getParent());
1604 new Thread(new Runnable()
1610 MessageManager.formatMessage(
1611 "label.loading_jalview_project",
1612 new Object[] { choice }), choice.hashCode());
1615 new Jalview2XML().loadJalviewAlign(choice);
1616 } catch (OutOfMemoryError oom)
1618 new OOMWarning("Whilst loading project from " + choice, oom);
1619 } catch (Exception ex)
1621 Cache.log.error("Problems whilst loading project from "
1623 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1625 "label.error_whilst_loading_project_from",
1626 new Object[] { choice }), MessageManager
1627 .getString("label.couldnt_load_project"),
1628 JOptionPane.WARNING_MESSAGE);
1630 setProgressBar(null, choice.hashCode());
1637 public void inputSequence_actionPerformed(ActionEvent e)
1639 new SequenceFetcher(this);
1642 JPanel progressPanel;
1644 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1646 public void startLoading(final String fileName)
1648 if (fileLoadingCount == 0)
1650 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1651 "label.loading_file", new Object[] { fileName })));
1656 private JPanel addProgressPanel(String string)
1658 if (progressPanel == null)
1660 progressPanel = new JPanel(new GridLayout(1, 1));
1661 totalProgressCount = 0;
1662 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1664 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1665 JProgressBar progressBar = new JProgressBar();
1666 progressBar.setIndeterminate(true);
1668 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1670 thisprogress.add(progressBar, BorderLayout.CENTER);
1671 progressPanel.add(thisprogress);
1672 ((GridLayout) progressPanel.getLayout())
1673 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1674 ++totalProgressCount;
1675 instance.validate();
1676 return thisprogress;
1679 int totalProgressCount = 0;
1681 private void removeProgressPanel(JPanel progbar)
1683 if (progressPanel != null)
1685 synchronized (progressPanel)
1687 progressPanel.remove(progbar);
1688 GridLayout gl = (GridLayout) progressPanel.getLayout();
1689 gl.setRows(gl.getRows() - 1);
1690 if (--totalProgressCount < 1)
1692 this.getContentPane().remove(progressPanel);
1693 progressPanel = null;
1700 public void stopLoading()
1703 if (fileLoadingCount < 1)
1705 while (fileLoadingPanels.size() > 0)
1707 removeProgressPanel(fileLoadingPanels.remove(0));
1709 fileLoadingPanels.clear();
1710 fileLoadingCount = 0;
1715 public static int getViewCount(String alignmentId)
1717 AlignmentViewport[] aps = getViewports(alignmentId);
1718 return (aps == null) ? 0 : aps.length;
1723 * @param alignmentId
1724 * - if null, all sets are returned
1725 * @return all AlignmentPanels concerning the alignmentId sequence set
1727 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1729 if (Desktop.desktop == null)
1731 // no frames created and in headless mode
1732 // TODO: verify that frames are recoverable when in headless mode
1735 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1736 AlignFrame[] frames = getAlignFrames();
1741 for (AlignFrame af : frames)
1743 for (AlignmentPanel ap : af.alignPanels)
1745 if (alignmentId == null
1746 || alignmentId.equals(ap.av.getSequenceSetId()))
1752 if (aps.size() == 0)
1756 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1761 * get all the viewports on an alignment.
1763 * @param sequenceSetId
1764 * unique alignment id (may be null - all viewports returned in that
1766 * @return all viewports on the alignment bound to sequenceSetId
1768 public static AlignmentViewport[] getViewports(String sequenceSetId)
1770 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1771 if (desktop != null)
1773 AlignFrame[] frames = Desktop.getAlignFrames();
1775 for (AlignFrame afr : frames)
1777 if (sequenceSetId == null
1778 || afr.getViewport().getSequenceSetId()
1779 .equals(sequenceSetId))
1781 if (afr.alignPanels != null)
1783 for (AlignmentPanel ap : afr.alignPanels)
1785 if (sequenceSetId == null
1786 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1794 viewp.add(afr.getViewport());
1798 if (viewp.size() > 0)
1800 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1807 * Explode the views in the given frame into separate AlignFrame
1811 public static void explodeViews(AlignFrame af)
1813 int size = af.alignPanels.size();
1819 for (int i = 0; i < size; i++)
1821 AlignmentPanel ap = af.alignPanels.get(i);
1822 AlignFrame newaf = new AlignFrame(ap);
1825 * Restore the view's last exploded frame geometry if known. Multiple
1826 * views from one exploded frame share and restore the same (frame)
1827 * position and size.
1829 Rectangle geometry = ap.av.getExplodedGeometry();
1830 if (geometry != null)
1832 newaf.setBounds(geometry);
1835 ap.av.setGatherViewsHere(false);
1837 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1838 AlignFrame.DEFAULT_HEIGHT);
1841 af.alignPanels.clear();
1842 af.closeMenuItem_actionPerformed(true);
1847 * Gather expanded views (separate AlignFrame's) with the same sequence set
1848 * identifier back in to this frame as additional views, and close the
1849 * expanded views. Note the expanded frames may themselves have multiple
1850 * views. We take the lot.
1854 public void gatherViews(AlignFrame source)
1856 source.viewport.setGatherViewsHere(true);
1857 source.viewport.setExplodedGeometry(source.getBounds());
1858 JInternalFrame[] frames = desktop.getAllFrames();
1859 String viewId = source.viewport.getSequenceSetId();
1861 for (int t = 0; t < frames.length; t++)
1863 if (frames[t] instanceof AlignFrame && frames[t] != source)
1865 AlignFrame af = (AlignFrame) frames[t];
1866 boolean gatherThis = false;
1867 for (int a = 0; a < af.alignPanels.size(); a++)
1869 AlignmentPanel ap = af.alignPanels.get(a);
1870 if (viewId.equals(ap.av.getSequenceSetId()))
1873 ap.av.setGatherViewsHere(false);
1874 ap.av.setExplodedGeometry(af.getBounds());
1875 source.addAlignmentPanel(ap, false);
1881 af.alignPanels.clear();
1882 af.closeMenuItem_actionPerformed(true);
1889 jalview.gui.VamsasApplication v_client = null;
1892 public void vamsasImport_actionPerformed(ActionEvent e)
1894 if (v_client == null)
1896 // Load and try to start a session.
1897 JalviewFileChooser chooser = new JalviewFileChooser(
1898 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1900 chooser.setFileView(new JalviewFileView());
1901 chooser.setDialogTitle(MessageManager
1902 .getString("label.open_saved_vamsas_session"));
1903 chooser.setToolTipText(MessageManager
1904 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1906 int value = chooser.showOpenDialog(this);
1908 if (value == JalviewFileChooser.APPROVE_OPTION)
1910 String fle = chooser.getSelectedFile().toString();
1911 if (!vamsasImport(chooser.getSelectedFile()))
1914 .showInternalMessageDialog(
1916 MessageManager.formatMessage(
1917 "label.couldnt_import_as_vamsas_session",
1918 new Object[] { fle }),
1920 .getString("label.vamsas_document_import_failed"),
1921 JOptionPane.ERROR_MESSAGE);
1927 jalview.bin.Cache.log
1928 .error("Implementation error - load session from a running session is not supported.");
1933 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1936 * @return true if import was a success and a session was started.
1938 public boolean vamsasImport(URL url)
1940 // TODO: create progress bar
1941 if (v_client != null)
1944 jalview.bin.Cache.log
1945 .error("Implementation error - load session from a running session is not supported.");
1951 // copy the URL content to a temporary local file
1952 // TODO: be a bit cleverer here with nio (?!)
1953 File file = File.createTempFile("vdocfromurl", ".vdj");
1954 FileOutputStream fos = new FileOutputStream(file);
1955 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1956 byte[] buffer = new byte[2048];
1958 while ((ln = bis.read(buffer)) > -1)
1960 fos.write(buffer, 0, ln);
1964 v_client = new jalview.gui.VamsasApplication(this, file,
1965 url.toExternalForm());
1966 } catch (Exception ex)
1968 jalview.bin.Cache.log.error(
1969 "Failed to create new vamsas session from contents of URL "
1973 setupVamsasConnectedGui();
1974 v_client.initial_update(); // TODO: thread ?
1975 return v_client.inSession();
1979 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1982 * @return true if import was a success and a session was started.
1984 public boolean vamsasImport(File file)
1986 if (v_client != null)
1989 jalview.bin.Cache.log
1990 .error("Implementation error - load session from a running session is not supported.");
1994 setProgressBar(MessageManager.formatMessage(
1995 "status.importing_vamsas_session_from",
1996 new Object[] { file.getName() }), file.hashCode());
1999 v_client = new jalview.gui.VamsasApplication(this, file, null);
2000 } catch (Exception ex)
2002 setProgressBar(MessageManager.formatMessage(
2003 "status.importing_vamsas_session_from",
2004 new Object[] { file.getName() }), file.hashCode());
2005 jalview.bin.Cache.log.error(
2006 "New vamsas session from existing session file failed:", ex);
2009 setupVamsasConnectedGui();
2010 v_client.initial_update(); // TODO: thread ?
2011 setProgressBar(MessageManager.formatMessage(
2012 "status.importing_vamsas_session_from",
2013 new Object[] { file.getName() }), file.hashCode());
2014 return v_client.inSession();
2017 public boolean joinVamsasSession(String mysesid)
2019 if (v_client != null)
2023 .getString("error.try_join_vamsas_session_another"));
2025 if (mysesid == null)
2028 MessageManager.getString("error.invalid_vamsas_session_id"));
2030 v_client = new VamsasApplication(this, mysesid);
2031 setupVamsasConnectedGui();
2032 v_client.initial_update();
2033 return (v_client.inSession());
2037 public void vamsasStart_actionPerformed(ActionEvent e)
2039 if (v_client == null)
2042 // we just start a default session for moment.
2044 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2045 * getProperty("LAST_DIRECTORY"));
2047 * chooser.setFileView(new JalviewFileView());
2048 * chooser.setDialogTitle("Load Vamsas file");
2049 * chooser.setToolTipText("Import");
2051 * int value = chooser.showOpenDialog(this);
2053 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2054 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2056 v_client = new VamsasApplication(this);
2057 setupVamsasConnectedGui();
2058 v_client.initial_update(); // TODO: thread ?
2062 // store current data in session.
2063 v_client.push_update(); // TODO: thread
2067 protected void setupVamsasConnectedGui()
2069 vamsasStart.setText(MessageManager.getString("label.session_update"));
2070 vamsasSave.setVisible(true);
2071 vamsasStop.setVisible(true);
2072 vamsasImport.setVisible(false); // Document import to existing session is
2073 // not possible for vamsas-client-1.0.
2076 protected void setupVamsasDisconnectedGui()
2078 vamsasSave.setVisible(false);
2079 vamsasStop.setVisible(false);
2080 vamsasImport.setVisible(true);
2081 vamsasStart.setText(MessageManager
2082 .getString("label.new_vamsas_session"));
2086 public void vamsasStop_actionPerformed(ActionEvent e)
2088 if (v_client != null)
2090 v_client.end_session();
2092 setupVamsasDisconnectedGui();
2096 protected void buildVamsasStMenu()
2098 if (v_client == null)
2100 String[] sess = null;
2103 sess = VamsasApplication.getSessionList();
2104 } catch (Exception e)
2106 jalview.bin.Cache.log.warn(
2107 "Problem getting current sessions list.", e);
2112 jalview.bin.Cache.log.debug("Got current sessions list: "
2113 + sess.length + " entries.");
2114 VamsasStMenu.removeAll();
2115 for (int i = 0; i < sess.length; i++)
2117 JMenuItem sessit = new JMenuItem();
2118 sessit.setText(sess[i]);
2119 sessit.setToolTipText(MessageManager.formatMessage(
2120 "label.connect_to_session", new Object[] { sess[i] }));
2121 final Desktop dsktp = this;
2122 final String mysesid = sess[i];
2123 sessit.addActionListener(new ActionListener()
2127 public void actionPerformed(ActionEvent e)
2129 if (dsktp.v_client == null)
2131 Thread rthr = new Thread(new Runnable()
2137 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2138 dsktp.setupVamsasConnectedGui();
2139 dsktp.v_client.initial_update();
2147 VamsasStMenu.add(sessit);
2149 // don't show an empty menu.
2150 VamsasStMenu.setVisible(sess.length > 0);
2155 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2156 VamsasStMenu.removeAll();
2157 VamsasStMenu.setVisible(false);
2162 // Not interested in the content. Just hide ourselves.
2163 VamsasStMenu.setVisible(false);
2168 public void vamsasSave_actionPerformed(ActionEvent e)
2170 if (v_client != null)
2172 JalviewFileChooser chooser = new JalviewFileChooser(
2173 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2174 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2175 new String[] { "Vamsas Document" }, "Vamsas Document");
2177 chooser.setFileView(new JalviewFileView());
2178 chooser.setDialogTitle(MessageManager
2179 .getString("label.save_vamsas_document_archive"));
2181 int value = chooser.showSaveDialog(this);
2183 if (value == JalviewFileChooser.APPROVE_OPTION)
2185 java.io.File choice = chooser.getSelectedFile();
2186 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2187 "label.saving_vamsas_doc",
2188 new Object[] { choice.getName() }));
2189 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2190 String warnmsg = null;
2191 String warnttl = null;
2194 v_client.vclient.storeDocument(choice);
2197 warnttl = "Serious Problem saving Vamsas Document";
2198 warnmsg = ex.toString();
2199 jalview.bin.Cache.log.error("Error Whilst saving document to "
2202 } catch (Exception ex)
2204 warnttl = "Problem saving Vamsas Document.";
2205 warnmsg = ex.toString();
2206 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2210 removeProgressPanel(progpanel);
2211 if (warnmsg != null)
2213 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2215 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2221 JPanel vamUpdate = null;
2224 * hide vamsas user gui bits when a vamsas document event is being handled.
2227 * true to hide gui, false to reveal gui
2229 public void setVamsasUpdate(boolean b)
2231 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2232 + (b ? "in progress" : "finished"));
2234 if (vamUpdate != null)
2236 this.removeProgressPanel(vamUpdate);
2240 vamUpdate = this.addProgressPanel(MessageManager
2241 .getString("label.updating_vamsas_session"));
2243 vamsasStart.setVisible(!b);
2244 vamsasStop.setVisible(!b);
2245 vamsasSave.setVisible(!b);
2248 public JInternalFrame[] getAllFrames()
2250 return desktop.getAllFrames();
2254 * Checks the given url to see if it gives a response indicating that the user
2255 * should be informed of a new questionnaire.
2259 public void checkForQuestionnaire(String url)
2261 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2262 // javax.swing.SwingUtilities.invokeLater(jvq);
2263 new Thread(jvq).start();
2266 public void checkURLLinks()
2268 // Thread off the URL link checker
2269 addDialogThread(new Runnable()
2274 if (Cache.getDefault("CHECKURLLINKS", true))
2276 // check what the actual links are - if it's just the default don't
2277 // bother with the warning
2278 Vector<String> links = Preferences.sequenceURLLinks;
2279 if (links == null || links.size() < 1)
2281 // there are no links
2284 else if ((links.size() == 1)
2285 && links.get(0).equals(EMBLEBI_STRING))
2287 // the only link is the default EMBL-EBI link
2291 // check in case URL links use old style tokens ($SEQUENCE_ID$ for
2292 // sequence id _or_ accession id)
2293 JPanel msgPanel = new JPanel();
2294 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2295 msgPanel.add(Box.createVerticalGlue());
2296 JLabel msg = new JLabel(
2298 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2299 JLabel msg2 = new JLabel(
2301 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2305 final JCheckBox jcb = new JCheckBox(
2306 MessageManager.getString("label.do_not_display_again"));
2307 jcb.addActionListener(new ActionListener()
2311 public void actionPerformed(ActionEvent e)
2313 // update Cache settings if checkbox is selected
2314 if (jcb.isSelected())
2316 Cache.setProperty("CHECKURLLINKS", "false");
2320 Cache.setProperty("CHECKURLLINKS", "true");
2326 JOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2328 .getString("label.SEQUENCE_ID_no_longer_used"),
2329 JOptionPane.WARNING_MESSAGE);
2337 * Proxy class for JDesktopPane which optionally displays the current memory
2338 * usage and highlights the desktop area with a red bar if free memory runs
2343 public class MyDesktopPane extends JDesktopPane implements Runnable
2346 private static final float ONE_MB = 1048576f;
2348 boolean showMemoryUsage = false;
2352 java.text.NumberFormat df;
2354 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2357 public MyDesktopPane(boolean showMemoryUsage)
2359 showMemoryUsage(showMemoryUsage);
2362 public void showMemoryUsage(boolean showMemory)
2364 this.showMemoryUsage = showMemory;
2367 Thread worker = new Thread(this);
2372 public boolean isShowMemoryUsage()
2374 return showMemoryUsage;
2380 df = java.text.NumberFormat.getNumberInstance();
2381 df.setMaximumFractionDigits(2);
2382 runtime = Runtime.getRuntime();
2384 while (showMemoryUsage)
2388 maxMemory = runtime.maxMemory() / ONE_MB;
2389 allocatedMemory = runtime.totalMemory() / ONE_MB;
2390 freeMemory = runtime.freeMemory() / ONE_MB;
2391 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2393 percentUsage = (totalFreeMemory / maxMemory) * 100;
2395 // if (percentUsage < 20)
2397 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2399 // instance.set.setBorder(border1);
2402 // sleep after showing usage
2404 } catch (Exception ex)
2406 ex.printStackTrace();
2412 public void paintComponent(Graphics g)
2414 if (showMemoryUsage && g != null && df != null)
2416 if (percentUsage < 20)
2418 g.setColor(Color.red);
2420 FontMetrics fm = g.getFontMetrics();
2423 g.drawString(MessageManager.formatMessage(
2424 "label.memory_stats",
2425 new Object[] { df.format(totalFreeMemory),
2426 df.format(maxMemory), df.format(percentUsage) }), 10,
2427 getHeight() - fm.getHeight());
2434 * fixes stacking order after a modal dialog to ensure windows that should be
2435 * on top actually are
2437 public void relayerWindows()
2442 protected JMenuItem groovyShell;
2445 * Accessor method to quickly get all the AlignmentFrames loaded.
2447 * @return an array of AlignFrame, or null if none found
2449 public static AlignFrame[] getAlignFrames()
2451 if (Jalview.isHeadlessMode())
2453 // Desktop.desktop is null in headless mode
2454 return new AlignFrame[] { Jalview.currentAlignFrame };
2457 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2463 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2465 for (int i = frames.length - 1; i > -1; i--)
2467 if (frames[i] instanceof AlignFrame)
2469 avp.add((AlignFrame) frames[i]);
2471 else if (frames[i] instanceof SplitFrame)
2474 * Also check for a split frame containing an AlignFrame
2476 GSplitFrame sf = (GSplitFrame) frames[i];
2477 if (sf.getTopFrame() instanceof AlignFrame)
2479 avp.add((AlignFrame) sf.getTopFrame());
2481 if (sf.getBottomFrame() instanceof AlignFrame)
2483 avp.add((AlignFrame) sf.getBottomFrame());
2487 if (avp.size() == 0)
2491 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2496 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2500 public GStructureViewer[] getJmols()
2502 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2508 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2510 for (int i = frames.length - 1; i > -1; i--)
2512 if (frames[i] instanceof AppJmol)
2514 GStructureViewer af = (GStructureViewer) frames[i];
2518 if (avp.size() == 0)
2522 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2527 * Add Groovy Support to Jalview
2529 public void groovyShell_actionPerformed()
2533 openGroovyConsole();
2534 } catch (Exception ex)
2536 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2537 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2539 MessageManager.getString("label.couldnt_create_groovy_shell"),
2540 MessageManager.getString("label.groovy_support_failed"),
2541 JOptionPane.ERROR_MESSAGE);
2546 * Open the Groovy console
2548 void openGroovyConsole()
2550 if (groovyConsole == null)
2552 groovyConsole = new groovy.ui.Console();
2553 groovyConsole.setVariable("Jalview", this);
2554 groovyConsole.run();
2557 * We allow only one console at a time, so that AlignFrame menu option
2558 * 'Calculate | Run Groovy script' is unambiguous.
2559 * Disable 'Groovy Console', and enable 'Run script', when the console is
2560 * opened, and the reverse when it is closed
2562 Window window = (Window) groovyConsole.getFrame();
2563 window.addWindowListener(new WindowAdapter()
2566 public void windowClosed(WindowEvent e)
2569 * rebind CMD-Q from Groovy Console to Jalview Quit
2572 enableExecuteGroovy(false);
2578 * show Groovy console window (after close and reopen)
2580 ((Window) groovyConsole.getFrame()).setVisible(true);
2583 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2584 * and disable opening a second console
2586 enableExecuteGroovy(true);
2590 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2591 * binding when opened
2593 protected void addQuitHandler()
2595 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2596 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2597 .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
2598 getRootPane().getActionMap().put("Quit", new AbstractAction()
2601 public void actionPerformed(ActionEvent e)
2609 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2612 * true if Groovy console is open
2614 public void enableExecuteGroovy(boolean enabled)
2617 * disable opening a second Groovy console
2618 * (or re-enable when the console is closed)
2620 groovyShell.setEnabled(!enabled);
2622 AlignFrame[] alignFrames = getAlignFrames();
2623 if (alignFrames != null)
2625 for (AlignFrame af : alignFrames)
2627 af.setGroovyEnabled(enabled);
2633 * Progress bars managed by the IProgressIndicator method.
2635 private Hashtable<Long, JPanel> progressBars;
2637 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2642 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2645 public void setProgressBar(String message, long id)
2647 if (progressBars == null)
2649 progressBars = new Hashtable<Long, JPanel>();
2650 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2653 if (progressBars.get(new Long(id)) != null)
2655 JPanel panel = progressBars.remove(new Long(id));
2656 if (progressBarHandlers.contains(new Long(id)))
2658 progressBarHandlers.remove(new Long(id));
2660 removeProgressPanel(panel);
2664 progressBars.put(new Long(id), addProgressPanel(message));
2671 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2672 * jalview.gui.IProgressIndicatorHandler)
2675 public void registerHandler(final long id,
2676 final IProgressIndicatorHandler handler)
2678 if (progressBarHandlers == null
2679 || !progressBars.containsKey(new Long(id)))
2683 .getString("error.call_setprogressbar_before_registering_handler"));
2685 progressBarHandlers.put(new Long(id), handler);
2686 final JPanel progressPanel = progressBars.get(new Long(id));
2687 if (handler.canCancel())
2689 JButton cancel = new JButton(
2690 MessageManager.getString("action.cancel"));
2691 final IProgressIndicator us = this;
2692 cancel.addActionListener(new ActionListener()
2696 public void actionPerformed(ActionEvent e)
2698 handler.cancelActivity(id);
2699 us.setProgressBar(MessageManager.formatMessage(
2700 "label.cancelled_params",
2701 new Object[] { ((JLabel) progressPanel.getComponent(0))
2705 progressPanel.add(cancel, BorderLayout.EAST);
2711 * @return true if any progress bars are still active
2714 public boolean operationInProgress()
2716 if (progressBars != null && progressBars.size() > 0)
2724 * This will return the first AlignFrame holding the given viewport instance.
2725 * It will break if there are more than one AlignFrames viewing a particular
2729 * @return alignFrame for viewport
2731 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2733 if (desktop != null)
2735 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2736 for (int panel = 0; aps != null && panel < aps.length; panel++)
2738 if (aps[panel] != null && aps[panel].av == viewport)
2740 return aps[panel].alignFrame;
2747 public VamsasApplication getVamsasApplication()
2754 * flag set if jalview GUI is being operated programmatically
2756 private boolean inBatchMode = false;
2759 * check if jalview GUI is being operated programmatically
2761 * @return inBatchMode
2763 public boolean isInBatchMode()
2769 * set flag if jalview GUI is being operated programmatically
2771 * @param inBatchMode
2773 public void setInBatchMode(boolean inBatchMode)
2775 this.inBatchMode = inBatchMode;
2778 public void startServiceDiscovery()
2780 startServiceDiscovery(false);
2783 public void startServiceDiscovery(boolean blocking)
2785 boolean alive = true;
2786 Thread t0 = null, t1 = null, t2 = null;
2787 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2790 // todo: changesupport handlers need to be transferred
2791 if (discoverer == null)
2793 discoverer = new jalview.ws.jws1.Discoverer();
2794 // register PCS handler for desktop.
2795 discoverer.addPropertyChangeListener(changeSupport);
2797 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2798 // until we phase out completely
2799 (t0 = new Thread(discoverer)).start();
2802 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2804 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2806 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2808 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2814 // TODO: do rest service discovery
2823 } catch (Exception e)
2826 alive = (t1 != null && t1.isAlive())
2827 || (t2 != null && t2.isAlive())
2828 || (t3 != null && t3.isAlive())
2829 || (t0 != null && t0.isAlive());
2835 * called to check if the service discovery process completed successfully.
2839 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2841 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2843 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2844 .getErrorMessages();
2847 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2849 if (serviceChangedDialog == null)
2851 // only run if we aren't already displaying one of these.
2852 addDialogThread(serviceChangedDialog = new Runnable()
2859 * JalviewDialog jd =new JalviewDialog() {
2861 * @Override protected void cancelPressed() { // TODO
2862 * Auto-generated method stub
2864 * }@Override protected void okPressed() { // TODO
2865 * Auto-generated method stub
2867 * }@Override protected void raiseClosed() { // TODO
2868 * Auto-generated method stub
2870 * } }; jd.initDialogFrame(new
2871 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2872 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2873 * + " or mis-configured HTTP proxy settings.<br/>" +
2874 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2876 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2877 * ), true, true, "Web Service Configuration Problem", 450,
2880 * jd.waitForInput();
2886 "<html><table width=\"450\"><tr><td>"
2888 + "</td></tr></table>"
2889 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2890 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2891 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2892 + " Tools->Preferences dialog box to change them.</p></html>"),
2893 "Web Service Configuration Problem",
2894 JOptionPane.DEFAULT_OPTION,
2895 JOptionPane.ERROR_MESSAGE);
2896 serviceChangedDialog = null;
2905 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2912 private Runnable serviceChangedDialog = null;
2915 * start a thread to open a URL in the configured browser. Pops up a warning
2916 * dialog to the user if there is an exception when calling out to the browser
2921 public static void showUrl(final String url)
2923 showUrl(url, Desktop.instance);
2927 * Like showUrl but allows progress handler to be specified
2931 * (null) or object implementing IProgressIndicator
2933 public static void showUrl(final String url,
2934 final IProgressIndicator progress)
2936 new Thread(new Runnable()
2943 if (progress != null)
2945 progress.setProgressBar(MessageManager.formatMessage(
2946 "status.opening_params", new Object[] { url }), this
2949 jalview.util.BrowserLauncher.openURL(url);
2950 } catch (Exception ex)
2952 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2954 .getString("label.web_browser_not_found_unix"),
2955 MessageManager.getString("label.web_browser_not_found"),
2956 JOptionPane.WARNING_MESSAGE);
2958 ex.printStackTrace();
2960 if (progress != null)
2962 progress.setProgressBar(null, this.hashCode());
2968 public static WsParamSetManager wsparamManager = null;
2970 public static ParamManager getUserParameterStore()
2972 if (wsparamManager == null)
2974 wsparamManager = new WsParamSetManager();
2976 return wsparamManager;
2980 * static hyperlink handler proxy method for use by Jalview's internal windows
2984 public static void hyperlinkUpdate(HyperlinkEvent e)
2986 if (e.getEventType() == EventType.ACTIVATED)
2991 url = e.getURL().toString();
2992 Desktop.showUrl(url);
2993 } catch (Exception x)
2997 if (Cache.log != null)
2999 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3003 System.err.println("Couldn't handle string " + url
3007 // ignore any exceptions due to dud links.
3014 * single thread that handles display of dialogs to user.
3016 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3019 * flag indicating if dialogExecutor should try to acquire a permit
3021 private volatile boolean dialogPause = true;
3026 private java.util.concurrent.Semaphore block = new Semaphore(0);
3028 private static groovy.ui.Console groovyConsole;
3031 * add another dialog thread to the queue
3035 public void addDialogThread(final Runnable prompter)
3037 dialogExecutor.submit(new Runnable()
3047 } catch (InterruptedException x)
3052 if (instance == null)
3058 SwingUtilities.invokeAndWait(prompter);
3059 } catch (Exception q)
3061 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3067 public void startDialogQueue()
3069 // set the flag so we don't pause waiting for another permit and semaphore
3070 // the current task to begin
3071 dialogPause = false;
3076 protected void snapShotWindow_actionPerformed(ActionEvent e)
3080 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3081 "View of Desktop", getWidth(), getHeight(), of = new File(
3082 "Jalview_snapshot" + System.currentTimeMillis()
3083 + ".eps"), "View of desktop", null, 0, false);
3086 paintAll(im.getGraphics());
3088 } catch (Exception q)
3090 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3094 Cache.log.info("Successfully written snapshot to file "
3095 + of.getAbsolutePath());
3099 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3100 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3101 * and location last time the view was expanded (if any). However it does not
3102 * remember the split pane divider location - this is set to match the
3103 * 'exploding' frame.
3107 public void explodeViews(SplitFrame sf)
3109 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3110 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3111 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3113 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3115 int viewCount = topPanels.size();
3122 * Processing in reverse order works, forwards order leaves the first panels
3123 * not visible. I don't know why!
3125 for (int i = viewCount - 1; i >= 0; i--)
3128 * Make new top and bottom frames. These take over the respective
3129 * AlignmentPanel objects, including their AlignmentViewports, so the
3130 * cdna/protein relationships between the viewports is carried over to the
3133 * explodedGeometry holds the (x, y) position of the previously exploded
3134 * SplitFrame, and the (width, height) of the AlignFrame component
3136 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3137 AlignFrame newTopFrame = new AlignFrame(topPanel);
3138 newTopFrame.setSize(oldTopFrame.getSize());
3139 newTopFrame.setVisible(true);
3140 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3141 .getExplodedGeometry();
3142 if (geometry != null)
3144 newTopFrame.setSize(geometry.getSize());
3147 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3148 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3149 newBottomFrame.setSize(oldBottomFrame.getSize());
3150 newBottomFrame.setVisible(true);
3151 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3152 .getExplodedGeometry();
3153 if (geometry != null)
3155 newBottomFrame.setSize(geometry.getSize());
3158 topPanel.av.setGatherViewsHere(false);
3159 bottomPanel.av.setGatherViewsHere(false);
3160 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3162 if (geometry != null)
3164 splitFrame.setLocation(geometry.getLocation());
3166 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3170 * Clear references to the panels (now relocated in the new SplitFrames)
3171 * before closing the old SplitFrame.
3174 bottomPanels.clear();
3179 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3180 * back into the given SplitFrame as additional views. Note that the gathered
3181 * frames may themselves have multiple views.
3185 public void gatherViews(GSplitFrame source)
3188 * special handling of explodedGeometry for a view within a SplitFrame: - it
3189 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3190 * height) of the AlignFrame component
3192 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3193 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3194 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3195 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3196 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3197 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3199 myTopFrame.viewport.setGatherViewsHere(true);
3200 myBottomFrame.viewport.setGatherViewsHere(true);
3201 String topViewId = myTopFrame.viewport.getSequenceSetId();
3202 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3204 JInternalFrame[] frames = desktop.getAllFrames();
3205 for (JInternalFrame frame : frames)
3207 if (frame instanceof SplitFrame && frame != source)
3209 SplitFrame sf = (SplitFrame) frame;
3210 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3211 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3212 boolean gatherThis = false;
3213 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3215 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3216 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3217 if (topViewId.equals(topPanel.av.getSequenceSetId())
3218 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3221 topPanel.av.setGatherViewsHere(false);
3222 bottomPanel.av.setGatherViewsHere(false);
3223 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3224 topFrame.getSize()));
3225 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3226 .getLocation(), bottomFrame.getSize()));
3227 myTopFrame.addAlignmentPanel(topPanel, false);
3228 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3234 topFrame.getAlignPanels().clear();
3235 bottomFrame.getAlignPanels().clear();
3242 * The dust settles...give focus to the tab we did this from.
3244 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3247 public static groovy.ui.Console getGroovyConsole()
3249 return groovyConsole;
3252 public static void transferFromDropTarget(List<String> files,
3253 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3257 DataFlavor uriListFlavor = new DataFlavor(
3258 "text/uri-list;class=java.lang.String");
3259 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3261 // Works on Windows and MacOSX
3262 Cache.log.debug("Drop handled as javaFileListFlavor");
3263 for (Object file : (List) t
3264 .getTransferData(DataFlavor.javaFileListFlavor))
3266 files.add(((File) file).toString());
3267 protocols.add(FormatAdapter.FILE);
3272 // Unix like behaviour
3273 boolean added = false;
3275 if (t.isDataFlavorSupported(uriListFlavor))
3277 Cache.log.debug("Drop handled as uriListFlavor");
3278 // This is used by Unix drag system
3279 data = (String) t.getTransferData(uriListFlavor);
3283 // fallback to text: workaround - on OSX where there's a JVM bug
3284 Cache.log.debug("standard URIListFlavor failed. Trying text");
3285 // try text fallback
3286 data = (String) t.getTransferData(new DataFlavor(
3287 "text/plain;class=java.lang.String"));
3288 if (Cache.log.isDebugEnabled())
3290 Cache.log.debug("fallback returned " + data);
3293 while (protocols.size() < files.size())
3295 Cache.log.debug("Adding missing FILE protocol for "
3296 + files.get(protocols.size()));
3297 protocols.add(FormatAdapter.FILE);
3299 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3300 data, "\r\n"); st.hasMoreTokens();)
3303 String s = st.nextToken();
3304 if (s.startsWith("#"))
3306 // the line is a comment (as per the RFC 2483)
3309 java.net.URI uri = new java.net.URI(s);
3310 if (uri.getScheme().toLowerCase().startsWith("http"))
3312 protocols.add(FormatAdapter.URL);
3313 files.add(uri.toString());
3317 // otherwise preserve old behaviour: catch all for file objects
3318 java.io.File file = new java.io.File(uri);
3319 protocols.add(FormatAdapter.FILE);
3320 files.add(file.toString());
3323 if (Cache.log.isDebugEnabled())
3325 if (data == null || !added)
3328 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3329 for (DataFlavor fl : t.getTransferDataFlavors())
3331 Cache.log.debug("Supported transfer dataflavor: "
3333 Object df = t.getTransferData(fl);
3336 Cache.log.debug("Retrieves: " + df);
3340 Cache.log.debug("Retrieved nothing");