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.io.FileLoader;
27 import jalview.io.FormatAdapter;
28 import jalview.io.IdentifyFile;
29 import jalview.io.JalviewFileChooser;
30 import jalview.io.JalviewFileView;
31 import jalview.jbgui.GSplitFrame;
32 import jalview.jbgui.GStructureViewer;
33 import jalview.schemes.ColourSchemeI;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.util.ImageMaker;
36 import jalview.util.MessageManager;
37 import jalview.viewmodel.AlignmentViewport;
38 import jalview.ws.params.ParamManager;
40 import java.awt.BorderLayout;
41 import java.awt.Color;
42 import java.awt.Dimension;
43 import java.awt.FontMetrics;
44 import java.awt.Graphics;
45 import java.awt.GridLayout;
46 import java.awt.Point;
47 import java.awt.Rectangle;
48 import java.awt.Toolkit;
49 import java.awt.datatransfer.Clipboard;
50 import java.awt.datatransfer.ClipboardOwner;
51 import java.awt.datatransfer.DataFlavor;
52 import java.awt.datatransfer.Transferable;
53 import java.awt.dnd.DnDConstants;
54 import java.awt.dnd.DropTargetDragEvent;
55 import java.awt.dnd.DropTargetDropEvent;
56 import java.awt.dnd.DropTargetEvent;
57 import java.awt.dnd.DropTargetListener;
58 import java.awt.event.ActionEvent;
59 import java.awt.event.ActionListener;
60 import java.awt.event.FocusEvent;
61 import java.awt.event.FocusListener;
62 import java.awt.event.MouseAdapter;
63 import java.awt.event.MouseEvent;
64 import java.awt.event.MouseListener;
65 import java.awt.event.WindowAdapter;
66 import java.awt.event.WindowEvent;
67 import java.beans.PropertyChangeEvent;
68 import java.beans.PropertyChangeListener;
69 import java.beans.PropertyVetoException;
70 import java.io.BufferedInputStream;
72 import java.io.FileOutputStream;
73 import java.lang.reflect.Constructor;
75 import java.util.ArrayList;
76 import java.util.Hashtable;
77 import java.util.List;
78 import java.util.StringTokenizer;
79 import java.util.Vector;
80 import java.util.concurrent.ExecutorService;
81 import java.util.concurrent.Executors;
82 import java.util.concurrent.Semaphore;
84 import javax.swing.DefaultDesktopManager;
85 import javax.swing.DesktopManager;
86 import javax.swing.JButton;
87 import javax.swing.JComboBox;
88 import javax.swing.JComponent;
89 import javax.swing.JDesktopPane;
90 import javax.swing.JFrame;
91 import javax.swing.JInternalFrame;
92 import javax.swing.JLabel;
93 import javax.swing.JMenuItem;
94 import javax.swing.JOptionPane;
95 import javax.swing.JPanel;
96 import javax.swing.JPopupMenu;
97 import javax.swing.JProgressBar;
98 import javax.swing.SwingUtilities;
99 import javax.swing.event.HyperlinkEvent;
100 import javax.swing.event.HyperlinkEvent.EventType;
101 import javax.swing.event.MenuEvent;
102 import javax.swing.event.MenuListener;
109 * @version $Revision: 1.155 $
111 public class Desktop extends jalview.jbgui.GDesktop implements
112 DropTargetListener, ClipboardOwner, IProgressIndicator,
113 jalview.api.StructureSelectionManagerProvider
116 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
119 * news reader - null if it was never started.
121 private BlogReader jvnews = null;
123 private File projectFile;
127 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
129 public void addJalviewPropertyChangeListener(
130 PropertyChangeListener listener)
132 changeSupport.addJalviewPropertyChangeListener(listener);
136 * @param propertyName
138 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
139 * java.beans.PropertyChangeListener)
141 public void addJalviewPropertyChangeListener(String propertyName,
142 PropertyChangeListener listener)
144 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
148 * @param propertyName
150 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
151 * java.beans.PropertyChangeListener)
153 public void removeJalviewPropertyChangeListener(String propertyName,
154 PropertyChangeListener listener)
156 changeSupport.removeJalviewPropertyChangeListener(propertyName,
160 /** Singleton Desktop instance */
161 public static Desktop instance;
163 public static MyDesktopPane desktop;
165 static int openFrameCount = 0;
167 static final int xOffset = 30;
169 static final int yOffset = 30;
171 private static final int THREE = 3;
173 private static AlignFrame currentAlignFrame;
175 private static ColourSchemeI currentGlobalColourScheme;
177 private static boolean currentSeqFeaturesVisible;
179 public static jalview.ws.jws1.Discoverer discoverer;
181 public static Object[] jalviewClipboard;
183 public static boolean internalCopy = false;
185 static int fileLoadingCount = 0;
187 class MyDesktopManager implements DesktopManager
190 private DesktopManager delegate;
192 public MyDesktopManager(DesktopManager delegate)
194 this.delegate = delegate;
197 public void activateFrame(JInternalFrame f)
201 delegate.activateFrame(f);
202 } catch (NullPointerException npe)
204 Point p = getMousePosition();
205 instance.showPasteMenu(p.x, p.y);
209 public void beginDraggingFrame(JComponent f)
211 delegate.beginDraggingFrame(f);
214 public void beginResizingFrame(JComponent f, int direction)
216 delegate.beginResizingFrame(f, direction);
219 public void closeFrame(JInternalFrame f)
221 delegate.closeFrame(f);
224 public void deactivateFrame(JInternalFrame f)
226 delegate.deactivateFrame(f);
229 public void deiconifyFrame(JInternalFrame f)
231 delegate.deiconifyFrame(f);
234 public void dragFrame(JComponent f, int newX, int newY)
240 delegate.dragFrame(f, newX, newY);
243 public void endDraggingFrame(JComponent f)
245 delegate.endDraggingFrame(f);
248 public void endResizingFrame(JComponent f)
250 delegate.endResizingFrame(f);
253 public void iconifyFrame(JInternalFrame f)
255 delegate.iconifyFrame(f);
258 public void maximizeFrame(JInternalFrame f)
260 delegate.maximizeFrame(f);
263 public void minimizeFrame(JInternalFrame f)
265 delegate.minimizeFrame(f);
268 public void openFrame(JInternalFrame f)
270 delegate.openFrame(f);
273 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
276 Rectangle b = desktop.getBounds();
281 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
284 public void setBoundsForFrame(JComponent f, int newX, int newY,
285 int newWidth, int newHeight)
287 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
290 // All other methods, simply delegate
295 * Creates a new Desktop object.
300 * A note to implementors. It is ESSENTIAL that any activities that might
301 * block are spawned off as threads rather than waited for during this
305 doVamsasClientCheck();
307 doConfigureStructurePrefs();
308 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
309 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
310 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
312 boolean showjconsole = jalview.bin.Cache.getDefault(
313 "SHOW_JAVA_CONSOLE", false);
314 desktop = new MyDesktopPane(selmemusage);
315 showMemusage.setSelected(selmemusage);
316 desktop.setBackground(Color.white);
317 getContentPane().setLayout(new BorderLayout());
318 // alternate config - have scrollbars - see notes in JAL-153
319 // JScrollPane sp = new JScrollPane();
320 // sp.getViewport().setView(desktop);
321 // getContentPane().add(sp, BorderLayout.CENTER);
322 getContentPane().add(desktop, BorderLayout.CENTER);
323 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
325 // This line prevents Windows Look&Feel resizing all new windows to maximum
326 // if previous window was maximised
327 desktop.setDesktopManager(new MyDesktopManager(
328 new DefaultDesktopManager()));
330 Rectangle dims = getLastKnownDimensions("");
337 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
338 setBounds((screenSize.width - 900) / 2,
339 (screenSize.height - 650) / 2, 900, 650);
341 jconsole = new Console(this, showjconsole);
342 // add essential build information
343 jconsole.setHeader("Jalview Version: "
344 + jalview.bin.Cache.getProperty("VERSION") + "\n"
345 + "Jalview Installation: "
346 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
347 + "\n" + "Build Date: "
348 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
349 + "Java version: " + System.getProperty("java.version") + "\n"
350 + System.getProperty("os.arch") + " "
351 + System.getProperty("os.name") + " "
352 + System.getProperty("os.version"));
354 showConsole(showjconsole);
356 showNews.setVisible(false);
358 this.addWindowListener(new WindowAdapter()
360 public void windowClosing(WindowEvent evt)
367 this.addMouseListener(ma = new MouseAdapter()
369 public void mousePressed(MouseEvent evt)
371 if (SwingUtilities.isRightMouseButton(evt))
373 showPasteMenu(evt.getX(), evt.getY());
377 desktop.addMouseListener(ma);
379 this.addFocusListener(new FocusListener()
383 public void focusLost(FocusEvent e)
385 // TODO Auto-generated method stub
390 public void focusGained(FocusEvent e)
392 Cache.log.debug("Relaying windows after focus gain");
393 // make sure that we sort windows properly after we gain focus
394 instance.relayerWindows();
397 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
398 // Spawn a thread that shows the splashscreen
399 SwingUtilities.invokeLater(new Runnable()
408 // Thread off a new instance of the file chooser - this reduces the time it
409 // takes to open it later on.
410 new Thread(new Runnable()
414 Cache.log.debug("Filechooser init thread started.");
415 JalviewFileChooser chooser = new JalviewFileChooser(
416 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
417 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
418 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
419 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
420 Cache.log.debug("Filechooser init thread finished.");
423 // Add the service change listener
424 changeSupport.addJalviewPropertyChangeListener("services",
425 new PropertyChangeListener()
429 public void propertyChange(PropertyChangeEvent evt)
431 Cache.log.debug("Firing service changed event for "
432 + evt.getNewValue());
433 JalviewServicesChanged(evt);
439 public void doConfigureStructurePrefs()
441 // configure services
442 StructureSelectionManager ssm = StructureSelectionManager
443 .getStructureSelectionManager(this);
444 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
446 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
447 Preferences.ADD_TEMPFACT_ANN, true));
448 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
449 Preferences.STRUCT_FROM_PDB, true));
450 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
451 Preferences.USE_RNAVIEW, true));
455 ssm.setAddTempFacAnnot(false);
456 ssm.setProcessSecondaryStructure(false);
457 ssm.setSecStructServices(false);
461 public void checkForNews()
463 final Desktop me = this;
464 // Thread off the news reader, in case there are connection problems.
465 addDialogThread(new Runnable()
470 Cache.log.debug("Starting news thread.");
472 jvnews = new BlogReader(me);
473 showNews.setVisible(true);
474 Cache.log.debug("Completed news thread.");
479 protected void showNews_actionPerformed(ActionEvent e)
481 showNews(showNews.isSelected());
484 void showNews(boolean visible)
487 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
488 showNews.setSelected(visible);
489 if (visible && !jvnews.isVisible())
491 new Thread(new Runnable()
496 long instance = System.currentTimeMillis();
497 Desktop.instance.setProgressBar(
498 MessageManager.getString("status.refreshing_news"),
500 jvnews.refreshNews();
501 Desktop.instance.setProgressBar(null, instance);
510 * recover the last known dimensions for a jalview window
513 * - empty string is desktop, all other windows have unique prefix
514 * @return null or last known dimensions scaled to current geometry (if last
515 * window geom was known)
517 Rectangle getLastKnownDimensions(String windowName)
519 // TODO: lock aspect ratio for scaling desktop Bug #0058199
520 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
521 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
522 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
523 String width = jalview.bin.Cache.getProperty(windowName
525 String height = jalview.bin.Cache.getProperty(windowName
527 if ((x != null) && (y != null) && (width != null) && (height != null))
529 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
530 .parseInt(width), ih = Integer.parseInt(height);
531 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
533 // attempt #1 - try to cope with change in screen geometry - this
534 // version doesn't preserve original jv aspect ratio.
535 // take ratio of current screen size vs original screen size.
536 double sw = ((1f * screenSize.width) / (1f * Integer
537 .parseInt(jalview.bin.Cache
538 .getProperty("SCREENGEOMETRY_WIDTH"))));
539 double sh = ((1f * screenSize.height) / (1f * Integer
540 .parseInt(jalview.bin.Cache
541 .getProperty("SCREENGEOMETRY_HEIGHT"))));
542 // rescale the bounds depending upon the current screen geometry.
543 ix = (int) (ix * sw);
544 iw = (int) (iw * sw);
545 iy = (int) (iy * sh);
546 ih = (int) (ih * sh);
547 while (ix >= screenSize.width)
549 jalview.bin.Cache.log
550 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
551 ix -= screenSize.width;
553 while (iy >= screenSize.height)
555 jalview.bin.Cache.log
556 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
557 iy -= screenSize.height;
559 jalview.bin.Cache.log.debug("Got last known dimensions for "
560 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
563 // return dimensions for new instance
564 return new Rectangle(ix, iy, iw, ih);
569 private void doVamsasClientCheck()
571 if (jalview.bin.Cache.vamsasJarsPresent())
573 setupVamsasDisconnectedGui();
574 VamsasMenu.setVisible(true);
575 final Desktop us = this;
576 VamsasMenu.addMenuListener(new MenuListener()
578 // this listener remembers when the menu was first selected, and
579 // doesn't rebuild the session list until it has been cleared and
581 boolean refresh = true;
583 public void menuCanceled(MenuEvent e)
588 public void menuDeselected(MenuEvent e)
593 public void menuSelected(MenuEvent e)
597 us.buildVamsasStMenu();
602 vamsasStart.setVisible(true);
606 void showPasteMenu(int x, int y)
608 JPopupMenu popup = new JPopupMenu();
609 JMenuItem item = new JMenuItem(
610 MessageManager.getString("label.paste_new_window"));
611 item.addActionListener(new ActionListener()
613 public void actionPerformed(ActionEvent evt)
620 popup.show(this, x, y);
627 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
628 Transferable contents = c.getContents(this);
630 if (contents != null)
632 String file = (String) contents
633 .getTransferData(DataFlavor.stringFlavor);
635 String format = new IdentifyFile().Identify(file,
636 FormatAdapter.PASTE);
638 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
641 } catch (Exception ex)
644 .println("Unable to paste alignment from system clipboard:\n"
650 * Adds and opens the given frame to the desktop
661 public static synchronized void addInternalFrame(
662 final JInternalFrame frame, String title, int w, int h)
664 addInternalFrame(frame, title, true, w, h, true);
668 * Add an internal frame to the Jalview desktop
675 * When true, display frame immediately, otherwise, caller must call
676 * setVisible themselves.
682 public static synchronized void addInternalFrame(
683 final JInternalFrame frame, String title, boolean makeVisible,
686 addInternalFrame(frame, title, makeVisible, w, h, true);
690 * Add an internal frame to the Jalview desktop and make it visible
703 public static synchronized void addInternalFrame(
704 final JInternalFrame frame, String title, int w, int h,
707 addInternalFrame(frame, title, true, w, h, resizable);
711 * Add an internal frame to the Jalview desktop
718 * When true, display frame immediately, otherwise, caller must call
719 * setVisible themselves.
727 public static synchronized void addInternalFrame(
728 final JInternalFrame frame, String title, boolean makeVisible,
729 int w, int h, boolean resizable)
732 // TODO: allow callers to determine X and Y position of frame (eg. via
734 // TODO: consider fixing method to update entries in the window submenu with
735 // the current window title
737 frame.setTitle(title);
738 if (frame.getWidth() < 1 || frame.getHeight() < 1)
742 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
743 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
744 // IF JALVIEW IS RUNNING HEADLESS
745 // ///////////////////////////////////////////////
747 || (System.getProperty("java.awt.headless") != null && System
748 .getProperty("java.awt.headless").equals("true")))
755 frame.setVisible(makeVisible);
756 frame.setClosable(true);
757 frame.setResizable(resizable);
758 frame.setMaximizable(resizable);
759 frame.setIconifiable(resizable);
760 frame.setFrameIcon(null);
762 if (frame.getX() < 1 && frame.getY() < 1)
764 frame.setLocation(xOffset * openFrameCount, yOffset
765 * ((openFrameCount - 1) % 10) + yOffset);
768 final JMenuItem menuItem = new JMenuItem(title);
769 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
771 public void internalFrameActivated(
772 javax.swing.event.InternalFrameEvent evt)
774 JInternalFrame itf = desktop.getSelectedFrame();
782 public void internalFrameClosed(
783 javax.swing.event.InternalFrameEvent evt)
785 PaintRefresher.RemoveComponent(frame);
787 windowMenu.remove(menuItem);
788 JInternalFrame itf = desktop.getSelectedFrame();
797 menuItem.addActionListener(new ActionListener()
799 public void actionPerformed(ActionEvent e)
803 frame.setSelected(true);
804 frame.setIcon(false);
805 } catch (java.beans.PropertyVetoException ex)
811 menuItem.addMouseListener(new MouseListener()
815 public void mouseReleased(MouseEvent e)
820 public void mousePressed(MouseEvent e)
825 public void mouseExited(MouseEvent e)
829 frame.setSelected(false);
830 } catch (PropertyVetoException e1)
836 public void mouseEntered(MouseEvent e)
840 frame.setSelected(true);
841 } catch (PropertyVetoException e1)
847 public void mouseClicked(MouseEvent e)
853 windowMenu.add(menuItem);
859 frame.setSelected(true);
860 frame.requestFocus();
861 } catch (java.beans.PropertyVetoException ve)
863 } catch (java.lang.ClassCastException cex)
866 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
871 public void lostOwnership(Clipboard clipboard, Transferable contents)
875 Desktop.jalviewClipboard = null;
878 internalCopy = false;
881 public void dragEnter(DropTargetDragEvent evt)
885 public void dragExit(DropTargetEvent evt)
889 public void dragOver(DropTargetDragEvent evt)
893 public void dropActionChanged(DropTargetDragEvent evt)
903 public void drop(DropTargetDropEvent evt)
905 boolean success = true;
906 Transferable t = evt.getTransferable();
907 java.util.List files = null;
908 java.util.List protocols = null;
912 DataFlavor uriListFlavor = new DataFlavor(
913 "text/uri-list;class=java.lang.String");
914 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
916 // Works on Windows and MacOSX
917 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
918 files = (java.util.List) t
919 .getTransferData(DataFlavor.javaFileListFlavor);
921 else if (t.isDataFlavorSupported(uriListFlavor))
923 // This is used by Unix drag system
924 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
925 String data = (String) t.getTransferData(uriListFlavor);
926 files = new java.util.ArrayList(1);
927 protocols = new java.util.ArrayList(1);
928 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
929 data, "\r\n"); st.hasMoreTokens();)
931 String s = st.nextToken();
932 if (s.startsWith("#"))
934 // the line is a comment (as per the RFC 2483)
937 java.net.URI uri = new java.net.URI(s);
938 if (uri.getScheme().toLowerCase().startsWith("http"))
940 protocols.add(FormatAdapter.URL);
941 files.add(uri.toString());
945 // otherwise preserve old behaviour: catch all for file objects
946 java.io.File file = new java.io.File(uri);
947 protocols.add(FormatAdapter.FILE);
948 files.add(file.toString());
952 } catch (Exception e)
961 for (int i = 0; i < files.size(); i++)
963 String file = files.get(i).toString();
964 String protocol = (protocols == null) ? FormatAdapter.FILE
965 : (String) protocols.get(i);
966 String format = null;
968 if (file.endsWith(".jar"))
975 format = new IdentifyFile().Identify(file, protocol);
978 new FileLoader().LoadFile(file, protocol, format);
981 } catch (Exception ex)
986 evt.dropComplete(success); // need this to ensure input focus is properly
987 // transfered to any new windows created
996 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
998 JalviewFileChooser chooser = new JalviewFileChooser(
999 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1000 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1001 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1002 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1004 chooser.setFileView(new JalviewFileView());
1005 chooser.setDialogTitle(MessageManager
1006 .getString("label.open_local_file"));
1007 chooser.setToolTipText(MessageManager.getString("action.open"));
1009 int value = chooser.showOpenDialog(this);
1011 if (value == JalviewFileChooser.APPROVE_OPTION)
1013 String choice = chooser.getSelectedFile().getPath();
1014 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1015 .getSelectedFile().getParent());
1017 String format = null;
1018 if (chooser.getSelectedFormat() != null
1019 && chooser.getSelectedFormat().equals("Jalview"))
1025 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1028 if (viewport != null)
1030 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1032 viewport.setShowSequenceFeatures(isCurrentSeqFeaturesVisible());
1033 AlignFrame af = viewport.getAlignPanel().alignFrame;
1036 af.changeColour(getCurrentGlobalColourScheme());
1037 af.setMenusForViewport();
1042 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1053 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1055 // This construct allows us to have a wider textfield
1057 JLabel label = new JLabel(
1058 MessageManager.getString("label.input_file_url"));
1059 final JComboBox history = new JComboBox();
1061 JPanel panel = new JPanel(new GridLayout(2, 1));
1064 history.setPreferredSize(new Dimension(400, 20));
1065 history.setEditable(true);
1066 history.addItem("http://www.");
1068 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1072 if (historyItems != null)
1074 st = new StringTokenizer(historyItems, "\t");
1076 while (st.hasMoreTokens())
1078 history.addItem(st.nextElement());
1082 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1083 MessageManager.getString("label.input_alignment_from_url"),
1084 JOptionPane.OK_CANCEL_OPTION);
1086 if (reply != JOptionPane.OK_OPTION)
1091 String url = history.getSelectedItem().toString();
1093 if (url.toLowerCase().endsWith(".jar"))
1095 if (viewport != null)
1097 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1102 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1107 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1109 if (format.equals("URL NOT FOUND"))
1111 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1112 MessageManager.formatMessage("label.couldnt_locate",
1114 { url }), MessageManager
1115 .getString("label.url_not_found"),
1116 JOptionPane.WARNING_MESSAGE);
1121 if (viewport != null)
1123 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1127 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1138 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1140 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1141 cap.setForInput(viewport);
1142 Desktop.addInternalFrame(cap,
1143 MessageManager.getString("label.cut_paste_alignmen_file"),
1152 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1154 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1155 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1157 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1158 getBounds().y, getWidth(), getHeight()));
1160 if (jconsole != null)
1162 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1163 jconsole.stopConsole();
1167 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1170 if (dialogExecutor != null)
1172 dialogExecutor.shutdownNow();
1178 private void storeLastKnownDimensions(String string, Rectangle jc)
1180 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1181 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1182 + " height:" + jc.height);
1184 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1185 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1186 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1187 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1196 public void aboutMenuItem_actionPerformed(ActionEvent e)
1198 // StringBuffer message = getAboutMessage(false);
1199 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1201 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1202 new Thread(new Runnable()
1206 new SplashScreen(true);
1211 public StringBuffer getAboutMessage(boolean shortv)
1213 StringBuffer message = new StringBuffer();
1214 message.append("<html>");
1217 message.append("<h1><strong>Version: "
1218 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1219 message.append("<strong>Last Updated: <em>"
1220 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1221 + "</em></strong>");
1227 message.append("<strong>Version "
1228 + jalview.bin.Cache.getProperty("VERSION")
1229 + "; last updated: "
1230 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1233 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1236 message.append("<br>...Checking latest version...</br>");
1238 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1239 .equals(jalview.bin.Cache.getProperty("VERSION")))
1241 boolean red = false;
1242 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1243 .indexOf("automated build") == -1)
1246 // Displayed when code version and jnlp version do not match and code
1247 // version is not a development build
1248 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1251 message.append("<br>!! Version "
1252 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1254 + " is available for download from "
1255 + jalview.bin.Cache.getDefault("www.jalview.org",
1256 "http://www.jalview.org") + " !!");
1259 message.append("</div>");
1262 message.append("<br>Authors: "
1264 .getDefault("AUTHORFNAMES",
1265 "The Jalview Authors (See AUTHORS file for current list)")
1266 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1267 + "<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"
1268 + "<br><br>If you use Jalview, please cite:"
1269 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1270 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1271 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1282 public void documentationMenuItem_actionPerformed(ActionEvent e)
1286 Help.showHelpWindow();
1287 } catch (Exception ex)
1292 public void closeAll_actionPerformed(ActionEvent e)
1294 JInternalFrame[] frames = desktop.getAllFrames();
1295 for (int i = 0; i < frames.length; i++)
1299 frames[i].setClosed(true);
1300 } catch (java.beans.PropertyVetoException ex)
1304 System.out.println("ALL CLOSED");
1305 if (v_client != null)
1307 // TODO clear binding to vamsas document objects on close_all
1312 public void raiseRelated_actionPerformed(ActionEvent e)
1314 reorderAssociatedWindows(false, false);
1317 public void minimizeAssociated_actionPerformed(ActionEvent e)
1319 reorderAssociatedWindows(true, false);
1322 void closeAssociatedWindows()
1324 reorderAssociatedWindows(false, true);
1330 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1333 protected void garbageCollect_actionPerformed(ActionEvent e)
1335 // We simply collect the garbage
1336 jalview.bin.Cache.log.debug("Collecting garbage...");
1338 jalview.bin.Cache.log.debug("Finished garbage collection.");
1345 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1348 protected void showMemusage_actionPerformed(ActionEvent e)
1350 desktop.showMemoryUsage(showMemusage.isSelected());
1357 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1360 protected void showConsole_actionPerformed(ActionEvent e)
1362 showConsole(showConsole.isSelected());
1365 Console jconsole = null;
1368 * control whether the java console is visible or not
1372 void showConsole(boolean selected)
1374 showConsole.setSelected(selected);
1375 // TODO: decide if we should update properties file
1376 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1378 jconsole.setVisible(selected);
1381 void reorderAssociatedWindows(boolean minimize, boolean close)
1383 JInternalFrame[] frames = desktop.getAllFrames();
1384 if (frames == null || frames.length < 1)
1389 AlignmentViewport source = null, target = null;
1390 if (frames[0] instanceof AlignFrame)
1392 source = ((AlignFrame) frames[0]).getCurrentView();
1394 else if (frames[0] instanceof TreePanel)
1396 source = ((TreePanel) frames[0]).getViewPort();
1398 else if (frames[0] instanceof PCAPanel)
1400 source = ((PCAPanel) frames[0]).av;
1402 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1404 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1409 for (int i = 0; i < frames.length; i++)
1412 if (frames[i] == null)
1416 if (frames[i] instanceof AlignFrame)
1418 target = ((AlignFrame) frames[i]).getCurrentView();
1420 else if (frames[i] instanceof TreePanel)
1422 target = ((TreePanel) frames[i]).getViewPort();
1424 else if (frames[i] instanceof PCAPanel)
1426 target = ((PCAPanel) frames[i]).av;
1428 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1430 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1433 if (source == target)
1439 frames[i].setClosed(true);
1443 frames[i].setIcon(minimize);
1446 frames[i].toFront();
1450 } catch (java.beans.PropertyVetoException ex)
1464 protected void preferences_actionPerformed(ActionEvent e)
1475 public void saveState_actionPerformed(ActionEvent e)
1477 JalviewFileChooser chooser = new JalviewFileChooser(
1478 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1479 { "jvp" }, new String[]
1480 { "Jalview Project" }, "Jalview Project");
1482 chooser.setFileView(new JalviewFileView());
1483 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1485 int value = chooser.showSaveDialog(this);
1487 if (value == JalviewFileChooser.APPROVE_OPTION)
1489 final Desktop me = this;
1490 final java.io.File choice = chooser.getSelectedFile();
1491 setProjectFile(choice);
1493 // TODO or move inside the new Thread?
1494 saveChimeraSessions(choice.getAbsolutePath());
1496 new Thread(new Runnable()
1501 setProgressBar(MessageManager.formatMessage(
1502 "label.saving_jalview_project", new Object[]
1503 { choice.getName() }), choice.hashCode());
1504 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1505 choice.getParent());
1506 // TODO catch and handle errors for savestate
1507 // TODO prevent user from messing with the Desktop whilst we're saving
1510 new Jalview2XML().saveState(choice);
1511 } catch (OutOfMemoryError oom)
1513 new OOMWarning("Whilst saving current state to "
1514 + choice.getName(), oom);
1515 } catch (Exception ex)
1518 "Problems whilst trying to save to " + choice.getName(),
1520 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1521 "label.error_whilst_saving_current_state_to",
1523 { choice.getName() }), MessageManager
1524 .getString("label.couldnt_save_project"),
1525 JOptionPane.WARNING_MESSAGE);
1527 setProgressBar(null, choice.hashCode());
1534 * Request any open, linked Chimera sessions to save their state.
1536 * @param jalviewProjectFilename
1537 * the filename of the Jalview project; Chimera session files should
1538 * be given distinct, but obviously related, names.
1540 public void saveChimeraSessions(String jalviewProjectFilename)
1543 for (JInternalFrame frame : getAllFrames())
1545 if (frame instanceof ChimeraViewFrame)
1548 * Construct a filename for the Chimera session by append _chimera<n>.py
1549 * to the Jalview project file name.
1551 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1553 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1559 private void setProjectFile(File choice)
1561 this.projectFile = choice;
1564 public File getProjectFile()
1566 return this.projectFile;
1575 public void loadState_actionPerformed(ActionEvent e)
1577 JalviewFileChooser chooser = new JalviewFileChooser(
1578 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1579 { "jvp", "jar" }, new String[]
1580 { "Jalview Project", "Jalview Project (old)" },
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()
1598 setProgressBar(MessageManager.formatMessage(
1599 "label.loading_jalview_project", new Object[]
1600 { choice }), choice.hashCode());
1603 new Jalview2XML().loadJalviewAlign(choice);
1604 } catch (OutOfMemoryError oom)
1606 new OOMWarning("Whilst loading project from " + choice, oom);
1607 } catch (Exception ex)
1609 Cache.log.error("Problems whilst loading project from "
1611 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1613 "label.error_whilst_loading_project_from",
1615 { choice }), MessageManager
1616 .getString("label.couldnt_load_project"),
1617 JOptionPane.WARNING_MESSAGE);
1619 setProgressBar(null, choice.hashCode());
1625 public void inputSequence_actionPerformed(ActionEvent e)
1627 new SequenceFetcher(this);
1630 JPanel progressPanel;
1632 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1634 public void startLoading(final String fileName)
1636 if (fileLoadingCount == 0)
1638 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1639 "label.loading_file", new Object[]
1645 private JPanel addProgressPanel(String string)
1647 if (progressPanel == null)
1649 progressPanel = new JPanel(new GridLayout(1, 1));
1650 totalProgressCount = 0;
1651 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1653 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1654 JProgressBar progressBar = new JProgressBar();
1655 progressBar.setIndeterminate(true);
1657 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1659 thisprogress.add(progressBar, BorderLayout.CENTER);
1660 progressPanel.add(thisprogress);
1661 ((GridLayout) progressPanel.getLayout())
1662 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1663 ++totalProgressCount;
1664 instance.validate();
1665 return thisprogress;
1668 int totalProgressCount = 0;
1670 private void removeProgressPanel(JPanel progbar)
1672 if (progressPanel != null)
1674 synchronized (progressPanel)
1676 progressPanel.remove(progbar);
1677 GridLayout gl = (GridLayout) progressPanel.getLayout();
1678 gl.setRows(gl.getRows() - 1);
1679 if (--totalProgressCount < 1)
1681 this.getContentPane().remove(progressPanel);
1682 progressPanel = null;
1689 public void stopLoading()
1692 if (fileLoadingCount < 1)
1694 while (fileLoadingPanels.size() > 0)
1696 removeProgressPanel(fileLoadingPanels.remove(0));
1698 fileLoadingPanels.clear();
1699 fileLoadingCount = 0;
1704 public static int getViewCount(String alignmentId)
1706 AlignmentViewport[] aps = getViewports(alignmentId);
1707 return (aps == null) ? 0 : aps.length;
1712 * @param alignmentId
1713 * - if null, all sets are returned
1714 * @return all AlignmentPanels concerning the alignmentId sequence set
1716 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1718 if (Desktop.desktop == null)
1720 // no frames created and in headless mode
1721 // TODO: verify that frames are recoverable when in headless mode
1724 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1725 AlignFrame[] frames = getAlignFrames();
1730 for (AlignFrame af : frames)
1732 for (AlignmentPanel ap : af.alignPanels)
1734 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1740 if (aps.size() == 0)
1744 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1749 * get all the viewports on an alignment.
1751 * @param sequenceSetId
1752 * unique alignment id (may be null - all viewports returned in that
1754 * @return all viewports on the alignment bound to sequenceSetId
1756 public static AlignmentViewport[] getViewports(String sequenceSetId)
1758 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1759 if (desktop != null)
1761 AlignFrame[] frames = Desktop.getAlignFrames();
1763 for (AlignFrame afr : frames)
1765 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1767 if (afr.alignPanels != null)
1769 for (AlignmentPanel ap : afr.alignPanels)
1771 if (sequenceSetId == null
1772 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1780 viewp.add(afr.getViewport());
1784 if (viewp.size() > 0)
1786 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1793 * Explode the views in the given frame into separate AlignFrame
1797 public void explodeViews(AlignFrame af)
1799 int size = af.alignPanels.size();
1805 for (int i = 0; i < size; i++)
1807 AlignmentPanel ap = af.alignPanels.get(i);
1808 AlignFrame newaf = new AlignFrame(ap);
1811 * Restore the view's last exploded frame geometry if known. Multiple
1812 * views from one exploded frame share and restore the same (frame)
1813 * position and size.
1815 Rectangle geometry = ap.av.getExplodedGeometry();
1816 if (geometry != null)
1818 newaf.setBounds(geometry);
1821 ap.av.setGatherViewsHere(false);
1823 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1824 AlignFrame.DEFAULT_HEIGHT);
1827 af.alignPanels.clear();
1828 af.closeMenuItem_actionPerformed(true);
1833 * Gather expanded views (separate AlignFrame's) with the same sequence set
1834 * identifier back in to this frame as additional views, and close the
1835 * expanded views. Note the expanded frames may themselves have multiple
1836 * views. We take the lot.
1840 public void gatherViews(AlignFrame source)
1842 source.viewport.setGatherViewsHere(true);
1843 source.viewport.setExplodedGeometry(source.getBounds());
1844 JInternalFrame[] frames = desktop.getAllFrames();
1845 String viewId = source.viewport.getSequenceSetId();
1847 for (int t = 0; t < frames.length; t++)
1849 if (frames[t] instanceof AlignFrame && frames[t] != source)
1851 AlignFrame af = (AlignFrame) frames[t];
1852 boolean gatherThis = false;
1853 for (int a = 0; a < af.alignPanels.size(); a++)
1855 AlignmentPanel ap = af.alignPanels.get(a);
1856 if (viewId.equals(ap.av.getSequenceSetId()))
1859 ap.av.setGatherViewsHere(false);
1860 ap.av.setExplodedGeometry(af.getBounds());
1861 source.addAlignmentPanel(ap, false);
1867 af.alignPanels.clear();
1868 af.closeMenuItem_actionPerformed(true);
1875 jalview.gui.VamsasApplication v_client = null;
1877 public void vamsasImport_actionPerformed(ActionEvent e)
1879 if (v_client == null)
1881 // Load and try to start a session.
1882 JalviewFileChooser chooser = new JalviewFileChooser(
1883 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1885 chooser.setFileView(new JalviewFileView());
1886 chooser.setDialogTitle(MessageManager
1887 .getString("label.open_saved_vamsas_session"));
1888 chooser.setToolTipText(MessageManager
1889 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1891 int value = chooser.showOpenDialog(this);
1893 if (value == JalviewFileChooser.APPROVE_OPTION)
1895 String fle = chooser.getSelectedFile().toString();
1896 if (!vamsasImport(chooser.getSelectedFile()))
1899 .showInternalMessageDialog(
1901 MessageManager.formatMessage(
1902 "label.couldnt_import_as_vamsas_session",
1906 .getString("label.vamsas_document_import_failed"),
1907 JOptionPane.ERROR_MESSAGE);
1913 jalview.bin.Cache.log
1914 .error("Implementation error - load session from a running session is not supported.");
1919 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1922 * @return true if import was a success and a session was started.
1924 public boolean vamsasImport(URL url)
1926 // TODO: create progress bar
1927 if (v_client != null)
1930 jalview.bin.Cache.log
1931 .error("Implementation error - load session from a running session is not supported.");
1937 // copy the URL content to a temporary local file
1938 // TODO: be a bit cleverer here with nio (?!)
1939 File file = File.createTempFile("vdocfromurl", ".vdj");
1940 FileOutputStream fos = new FileOutputStream(file);
1941 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1942 byte[] buffer = new byte[2048];
1944 while ((ln = bis.read(buffer)) > -1)
1946 fos.write(buffer, 0, ln);
1950 v_client = new jalview.gui.VamsasApplication(this, file,
1951 url.toExternalForm());
1952 } catch (Exception ex)
1954 jalview.bin.Cache.log.error(
1955 "Failed to create new vamsas session from contents of URL "
1959 setupVamsasConnectedGui();
1960 v_client.initial_update(); // TODO: thread ?
1961 return v_client.inSession();
1965 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1968 * @return true if import was a success and a session was started.
1970 public boolean vamsasImport(File file)
1972 if (v_client != null)
1975 jalview.bin.Cache.log
1976 .error("Implementation error - load session from a running session is not supported.");
1980 setProgressBar(MessageManager.formatMessage(
1981 "status.importing_vamsas_session_from", new Object[]
1982 { file.getName() }), file.hashCode());
1985 v_client = new jalview.gui.VamsasApplication(this, file, null);
1986 } catch (Exception ex)
1988 setProgressBar(MessageManager.formatMessage(
1989 "status.importing_vamsas_session_from", new Object[]
1990 { file.getName() }), file.hashCode());
1991 jalview.bin.Cache.log.error(
1992 "New vamsas session from existing session file failed:", ex);
1995 setupVamsasConnectedGui();
1996 v_client.initial_update(); // TODO: thread ?
1997 setProgressBar(MessageManager.formatMessage(
1998 "status.importing_vamsas_session_from", new Object[]
1999 { file.getName() }), file.hashCode());
2000 return v_client.inSession();
2003 public boolean joinVamsasSession(String mysesid)
2005 if (v_client != null)
2009 .getString("error.try_join_vamsas_session_another"));
2011 if (mysesid == null)
2014 MessageManager.getString("error.invalid_vamsas_session_id"));
2016 v_client = new VamsasApplication(this, mysesid);
2017 setupVamsasConnectedGui();
2018 v_client.initial_update();
2019 return (v_client.inSession());
2022 public void vamsasStart_actionPerformed(ActionEvent e)
2024 if (v_client == null)
2027 // we just start a default session for moment.
2029 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2030 * getProperty("LAST_DIRECTORY"));
2032 * chooser.setFileView(new JalviewFileView());
2033 * chooser.setDialogTitle("Load Vamsas file");
2034 * chooser.setToolTipText("Import");
2036 * int value = chooser.showOpenDialog(this);
2038 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2039 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2041 v_client = new VamsasApplication(this);
2042 setupVamsasConnectedGui();
2043 v_client.initial_update(); // TODO: thread ?
2047 // store current data in session.
2048 v_client.push_update(); // TODO: thread
2052 protected void setupVamsasConnectedGui()
2054 vamsasStart.setText(MessageManager.getString("label.session_update"));
2055 vamsasSave.setVisible(true);
2056 vamsasStop.setVisible(true);
2057 vamsasImport.setVisible(false); // Document import to existing session is
2058 // not possible for vamsas-client-1.0.
2061 protected void setupVamsasDisconnectedGui()
2063 vamsasSave.setVisible(false);
2064 vamsasStop.setVisible(false);
2065 vamsasImport.setVisible(true);
2066 vamsasStart.setText(MessageManager
2067 .getString("label.new_vamsas_session"));
2070 public void vamsasStop_actionPerformed(ActionEvent e)
2072 if (v_client != null)
2074 v_client.end_session();
2076 setupVamsasDisconnectedGui();
2080 protected void buildVamsasStMenu()
2082 if (v_client == null)
2084 String[] sess = null;
2087 sess = VamsasApplication.getSessionList();
2088 } catch (Exception e)
2090 jalview.bin.Cache.log.warn(
2091 "Problem getting current sessions list.", e);
2096 jalview.bin.Cache.log.debug("Got current sessions list: "
2097 + sess.length + " entries.");
2098 VamsasStMenu.removeAll();
2099 for (int i = 0; i < sess.length; i++)
2101 JMenuItem sessit = new JMenuItem();
2102 sessit.setText(sess[i]);
2103 sessit.setToolTipText(MessageManager.formatMessage(
2104 "label.connect_to_session", new Object[]
2106 final Desktop dsktp = this;
2107 final String mysesid = sess[i];
2108 sessit.addActionListener(new ActionListener()
2111 public void actionPerformed(ActionEvent e)
2113 if (dsktp.v_client == null)
2115 Thread rthr = new Thread(new Runnable()
2120 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2121 dsktp.setupVamsasConnectedGui();
2122 dsktp.v_client.initial_update();
2130 VamsasStMenu.add(sessit);
2132 // don't show an empty menu.
2133 VamsasStMenu.setVisible(sess.length > 0);
2138 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2139 VamsasStMenu.removeAll();
2140 VamsasStMenu.setVisible(false);
2145 // Not interested in the content. Just hide ourselves.
2146 VamsasStMenu.setVisible(false);
2150 public void vamsasSave_actionPerformed(ActionEvent e)
2152 if (v_client != null)
2154 JalviewFileChooser chooser = new JalviewFileChooser(
2155 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2156 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2158 { "Vamsas Document" }, "Vamsas Document");
2160 chooser.setFileView(new JalviewFileView());
2161 chooser.setDialogTitle(MessageManager
2162 .getString("label.save_vamsas_document_archive"));
2164 int value = chooser.showSaveDialog(this);
2166 if (value == JalviewFileChooser.APPROVE_OPTION)
2168 java.io.File choice = chooser.getSelectedFile();
2169 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2170 "label.saving_vamsas_doc", new Object[]
2171 { choice.getName() }));
2172 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2173 String warnmsg = null;
2174 String warnttl = null;
2177 v_client.vclient.storeDocument(choice);
2180 warnttl = "Serious Problem saving Vamsas Document";
2181 warnmsg = ex.toString();
2182 jalview.bin.Cache.log.error("Error Whilst saving document to "
2185 } catch (Exception ex)
2187 warnttl = "Problem saving Vamsas Document.";
2188 warnmsg = ex.toString();
2189 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2193 removeProgressPanel(progpanel);
2194 if (warnmsg != null)
2196 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2198 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2204 JPanel vamUpdate = null;
2207 * hide vamsas user gui bits when a vamsas document event is being handled.
2210 * true to hide gui, false to reveal gui
2212 public void setVamsasUpdate(boolean b)
2214 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2215 + (b ? "in progress" : "finished"));
2217 if (vamUpdate != null)
2219 this.removeProgressPanel(vamUpdate);
2223 vamUpdate = this.addProgressPanel(MessageManager
2224 .getString("label.updating_vamsas_session"));
2226 vamsasStart.setVisible(!b);
2227 vamsasStop.setVisible(!b);
2228 vamsasSave.setVisible(!b);
2231 public JInternalFrame[] getAllFrames()
2233 return desktop.getAllFrames();
2237 * Checks the given url to see if it gives a response indicating that the user
2238 * should be informed of a new questionnaire.
2242 public void checkForQuestionnaire(String url)
2244 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2245 // javax.swing.SwingUtilities.invokeLater(jvq);
2246 new Thread(jvq).start();
2250 * Proxy class for JDesktopPane which optionally displays the current memory
2251 * usage and highlights the desktop area with a red bar if free memory runs
2256 public class MyDesktopPane extends JDesktopPane implements Runnable
2259 private static final float ONE_MB = 1048576f;
2261 boolean showMemoryUsage = false;
2265 java.text.NumberFormat df;
2267 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2270 public MyDesktopPane(boolean showMemoryUsage)
2272 showMemoryUsage(showMemoryUsage);
2275 public void showMemoryUsage(boolean showMemoryUsage)
2277 this.showMemoryUsage = showMemoryUsage;
2278 if (showMemoryUsage)
2280 Thread worker = new Thread(this);
2285 public boolean isShowMemoryUsage()
2287 return showMemoryUsage;
2292 df = java.text.NumberFormat.getNumberInstance();
2293 df.setMaximumFractionDigits(2);
2294 runtime = Runtime.getRuntime();
2296 while (showMemoryUsage)
2300 maxMemory = runtime.maxMemory() / ONE_MB;
2301 allocatedMemory = runtime.totalMemory() / ONE_MB;
2302 freeMemory = runtime.freeMemory() / ONE_MB;
2303 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2305 percentUsage = (totalFreeMemory / maxMemory) * 100;
2307 // if (percentUsage < 20)
2309 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2311 // instance.set.setBorder(border1);
2314 // sleep after showing usage
2316 } catch (Exception ex)
2318 ex.printStackTrace();
2323 public void paintComponent(Graphics g)
2325 if (showMemoryUsage && g != null && df != null)
2327 if (percentUsage < 20)
2329 g.setColor(Color.red);
2331 FontMetrics fm = g.getFontMetrics();
2334 g.drawString(MessageManager.formatMessage(
2335 "label.memory_stats",
2337 { df.format(totalFreeMemory), df.format(maxMemory),
2338 df.format(percentUsage) }), 10,
2339 getHeight() - fm.getHeight());
2346 * fixes stacking order after a modal dialog to ensure windows that should be
2347 * on top actually are
2349 public void relayerWindows()
2354 protected JMenuItem groovyShell;
2356 public void doGroovyCheck()
2358 if (jalview.bin.Cache.groovyJarsPresent())
2360 groovyShell = new JMenuItem();
2361 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2362 groovyShell.addActionListener(new ActionListener()
2364 public void actionPerformed(ActionEvent e)
2366 groovyShell_actionPerformed(e);
2369 toolsMenu.add(groovyShell);
2370 groovyShell.setVisible(true);
2375 * Accessor method to quickly get all the AlignmentFrames loaded.
2377 * @return an array of AlignFrame, or null if none found
2379 public static AlignFrame[] getAlignFrames()
2381 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2387 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2389 for (int i = frames.length - 1; i > -1; i--)
2391 if (frames[i] instanceof AlignFrame)
2393 avp.add((AlignFrame) frames[i]);
2395 else if (frames[i] instanceof SplitFrame)
2398 * Also check for a split frame containing an AlignFrame
2400 GSplitFrame sf = (GSplitFrame) frames[i];
2401 if (sf.getTopFrame() instanceof AlignFrame)
2403 avp.add((AlignFrame) sf.getTopFrame());
2405 if (sf.getBottomFrame() instanceof AlignFrame)
2407 avp.add((AlignFrame) sf.getBottomFrame());
2411 if (avp.size() == 0)
2415 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2420 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2424 public GStructureViewer[] getJmols()
2426 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2432 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2434 for (int i = frames.length - 1; i > -1; i--)
2436 if (frames[i] instanceof AppJmol)
2438 GStructureViewer af = (GStructureViewer) frames[i];
2442 if (avp.size() == 0)
2446 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2451 * Add Groovy Support to Jalview
2453 public void groovyShell_actionPerformed(ActionEvent e)
2455 // use reflection to avoid creating compilation dependency.
2456 if (!jalview.bin.Cache.groovyJarsPresent())
2460 .getString("error.implementation_error_cannot_create_groovyshell"));
2464 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2465 "groovy.ui.Console");
2466 Constructor<?> gccons = gcClass.getConstructor();
2467 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2469 { String.class, Object.class });
2470 java.lang.reflect.Method run = gcClass.getMethod("run");
2471 Object gc = gccons.newInstance();
2472 setvar.invoke(gc, new Object[]
2473 { "Jalview", this });
2475 } catch (Exception ex)
2477 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2478 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2480 MessageManager.getString("label.couldnt_create_groovy_shell"),
2481 MessageManager.getString("label.groovy_support_failed"),
2482 JOptionPane.ERROR_MESSAGE);
2487 * Progress bars managed by the IProgressIndicator method.
2489 private Hashtable<Long, JPanel> progressBars;
2491 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2496 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2498 public void setProgressBar(String message, long id)
2500 if (progressBars == null)
2502 progressBars = new Hashtable<Long, JPanel>();
2503 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2506 if (progressBars.get(new Long(id)) != null)
2508 JPanel progressPanel = progressBars.remove(new Long(id));
2509 if (progressBarHandlers.contains(new Long(id)))
2511 progressBarHandlers.remove(new Long(id));
2513 removeProgressPanel(progressPanel);
2517 progressBars.put(new Long(id), addProgressPanel(message));
2524 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2525 * jalview.gui.IProgressIndicatorHandler)
2527 public void registerHandler(final long id,
2528 final IProgressIndicatorHandler handler)
2530 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2534 .getString("error.call_setprogressbar_before_registering_handler"));
2536 progressBarHandlers.put(new Long(id), handler);
2537 final JPanel progressPanel = progressBars.get(new Long(id));
2538 if (handler.canCancel())
2540 JButton cancel = new JButton(
2541 MessageManager.getString("action.cancel"));
2542 final IProgressIndicator us = this;
2543 cancel.addActionListener(new ActionListener()
2546 public void actionPerformed(ActionEvent e)
2548 handler.cancelActivity(id);
2549 us.setProgressBar(MessageManager.formatMessage(
2550 "label.cancelled_params", new Object[]
2551 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2555 progressPanel.add(cancel, BorderLayout.EAST);
2561 * @return true if any progress bars are still active
2564 public boolean operationInProgress()
2566 if (progressBars != null && progressBars.size() > 0)
2574 * This will return the first AlignFrame holding the given viewport instance. It
2575 * will break if there are more than one AlignFrames viewing a particular av.
2578 * @return alignFrame for viewport
2580 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2582 if (desktop != null)
2584 AlignmentPanel[] aps = getAlignmentPanels(viewport
2585 .getSequenceSetId());
2586 for (int panel = 0; aps != null && panel < aps.length; panel++)
2588 if (aps[panel] != null && aps[panel].av == viewport)
2590 return aps[panel].alignFrame;
2597 public VamsasApplication getVamsasApplication()
2604 * flag set if jalview GUI is being operated programmatically
2606 private boolean inBatchMode = false;
2609 * check if jalview GUI is being operated programmatically
2611 * @return inBatchMode
2613 public boolean isInBatchMode()
2619 * set flag if jalview GUI is being operated programmatically
2621 * @param inBatchMode
2623 public void setInBatchMode(boolean inBatchMode)
2625 this.inBatchMode = inBatchMode;
2628 public void startServiceDiscovery()
2630 startServiceDiscovery(false);
2633 public void startServiceDiscovery(boolean blocking)
2635 boolean alive = true;
2636 Thread t0 = null, t1 = null, t2 = null;
2637 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2640 // todo: changesupport handlers need to be transferred
2641 if (discoverer == null)
2643 discoverer = new jalview.ws.jws1.Discoverer();
2644 // register PCS handler for desktop.
2645 discoverer.addPropertyChangeListener(changeSupport);
2647 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2648 // until we phase out completely
2649 (t0 = new Thread(discoverer)).start();
2652 // ENFIN services are EOLed as of Jalview 2.8.1 release
2657 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2659 // EnfinEnvision web service menu entries are rebuild every time the
2660 // menu is shown, so no changeSupport events are needed.
2661 jalview.ws.EnfinEnvision2OneWay.getInstance();
2662 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2665 } catch (Exception e)
2668 .info("Exception when trying to launch Envision2 workflow discovery.",
2670 Cache.log.info(e.getStackTrace());
2674 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2676 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2678 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2680 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2686 // TODO: do rest service discovery
2695 } catch (Exception e)
2698 alive = (t1 != null && t1.isAlive())
2699 || (t2 != null && t2.isAlive())
2700 || (t3 != null && t3.isAlive())
2701 || (t0 != null && t0.isAlive());
2707 * called to check if the service discovery process completed successfully.
2711 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2713 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2715 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2716 .getErrorMessages();
2719 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2721 if (serviceChangedDialog == null)
2723 // only run if we aren't already displaying one of these.
2724 addDialogThread(serviceChangedDialog = new Runnable()
2730 * JalviewDialog jd =new JalviewDialog() {
2732 * @Override protected void cancelPressed() { // TODO
2733 * Auto-generated method stub
2735 * }@Override protected void okPressed() { // TODO
2736 * Auto-generated method stub
2738 * }@Override protected void raiseClosed() { // TODO
2739 * Auto-generated method stub
2741 * } }; jd.initDialogFrame(new
2742 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2743 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2744 * + " or mis-configured HTTP proxy settings.<br/>" +
2745 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2747 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2748 * ), true, true, "Web Service Configuration Problem", 450,
2751 * jd.waitForInput();
2757 "<html><table width=\"450\"><tr><td>"
2759 + "</td></tr></table>"
2760 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2761 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2762 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2763 + " Tools->Preferences dialog box to change them.</p></html>"),
2764 "Web Service Configuration Problem",
2765 JOptionPane.DEFAULT_OPTION,
2766 JOptionPane.ERROR_MESSAGE);
2767 serviceChangedDialog = null;
2776 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2783 private Runnable serviceChangedDialog = null;
2786 * start a thread to open a URL in the configured browser. Pops up a warning
2787 * dialog to the user if there is an exception when calling out to the browser
2792 public static void showUrl(final String url)
2794 showUrl(url, Desktop.instance);
2798 * Like showUrl but allows progress handler to be specified
2802 * (null) or object implementing IProgressIndicator
2804 public static void showUrl(final String url,
2805 final IProgressIndicator progress)
2807 new Thread(new Runnable()
2813 if (progress != null)
2815 progress.setProgressBar(MessageManager.formatMessage(
2816 "status.opening_params", new Object[]
2817 { url }), this.hashCode());
2819 jalview.util.BrowserLauncher.openURL(url);
2820 } catch (Exception ex)
2822 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2824 .getString("label.web_browser_not_found_unix"),
2825 MessageManager.getString("label.web_browser_not_found"),
2826 JOptionPane.WARNING_MESSAGE);
2828 ex.printStackTrace();
2830 if (progress != null)
2832 progress.setProgressBar(null, this.hashCode());
2838 public static WsParamSetManager wsparamManager = null;
2840 public static ParamManager getUserParameterStore()
2842 if (wsparamManager == null)
2844 wsparamManager = new WsParamSetManager();
2846 return wsparamManager;
2850 * static hyperlink handler proxy method for use by Jalview's internal windows
2854 public static void hyperlinkUpdate(HyperlinkEvent e)
2856 if (e.getEventType() == EventType.ACTIVATED)
2861 url = e.getURL().toString();
2862 Desktop.showUrl(url);
2863 } catch (Exception x)
2867 if (Cache.log != null)
2869 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2873 System.err.println("Couldn't handle string " + url
2877 // ignore any exceptions due to dud links.
2884 * single thread that handles display of dialogs to user.
2886 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2889 * flag indicating if dialogExecutor should try to acquire a permit
2891 private volatile boolean dialogPause = true;
2896 private java.util.concurrent.Semaphore block = new Semaphore(0);
2899 * add another dialog thread to the queue
2903 public void addDialogThread(final Runnable prompter)
2905 dialogExecutor.submit(new Runnable()
2914 } catch (InterruptedException x)
2919 if (instance == null)
2925 SwingUtilities.invokeAndWait(prompter);
2926 } catch (Exception q)
2928 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2934 public void startDialogQueue()
2936 // set the flag so we don't pause waiting for another permit and semaphore
2937 // the current task to begin
2938 dialogPause = false;
2943 protected void snapShotWindow_actionPerformed(ActionEvent e)
2947 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2948 "View of Desktop", getWidth(), getHeight(), of = new File(
2949 "Jalview_snapshot" + System.currentTimeMillis()
2950 + ".eps"), "View of desktop");
2953 paintAll(im.getGraphics());
2955 } catch (Exception q)
2957 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2961 Cache.log.info("Successfully written snapshot to file "
2962 + of.getAbsolutePath());
2966 * Explode the views in the given frame into separate AlignFrame windows.
2970 public void explodeViews(SplitFrame sf)
2972 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2973 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2974 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2976 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2978 int viewCount = topPanels.size();
2985 * Processing in reverse order works, forwards order leaves the first panels
2986 * not visible. I don't know why!
2988 for (int i = viewCount - 1; i >= 0; i--)
2991 * Make new top and bottom frames. These take over the respective
2992 * AlignmentPanel objects, including their AlignmentViewports, so the
2993 * cdna/protein relationships between the viewports is carried over to the
2996 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2997 AlignFrame newTopFrame = new AlignFrame(topPanel);
2998 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2999 AlignFrame.DEFAULT_HEIGHT));
3000 newTopFrame.setVisible(true);
3001 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3002 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3003 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
3004 AlignFrame.DEFAULT_HEIGHT));
3005 newBottomFrame.setVisible(true);
3006 topPanel.av.setGatherViewsHere(false);
3007 bottomPanel.av.setGatherViewsHere(false);
3008 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3010 // either panel may hold previous exploded frame geometry
3011 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3012 .getExplodedGeometry();
3013 if (geometry != null)
3015 splitFrame.setBounds(geometry);
3017 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3021 * Clear references to the panels (now relocated in the new SplitFrames)
3022 * before closing the old SplitFrame.
3025 bottomPanels.clear();
3030 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3031 * back into the given SplitFrame as additional views. Note that the gathered
3032 * frames may themselves have multiple views.
3036 public void gatherViews(GSplitFrame source)
3038 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3039 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3040 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3041 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3042 myTopFrame.viewport.setGatherViewsHere(true);
3043 myBottomFrame.viewport.setGatherViewsHere(true);
3044 String topViewId = myTopFrame.viewport.getSequenceSetId();
3045 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3047 JInternalFrame[] frames = desktop.getAllFrames();
3048 for (JInternalFrame frame : frames)
3050 if (frame instanceof SplitFrame && frame != source)
3052 SplitFrame sf = (SplitFrame) frame;
3053 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3054 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3055 boolean gatherThis = false;
3056 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3058 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3059 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3060 if (topViewId.equals(topPanel.av.getSequenceSetId())
3061 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3064 topPanel.av.setGatherViewsHere(false);
3065 bottomPanel.av.setGatherViewsHere(false);
3066 // both panels refer to the same split frame geometry
3067 Rectangle position = sf.getBounds();
3068 topPanel.av.setExplodedGeometry(position);
3069 bottomPanel.av.setExplodedGeometry(position);
3070 myTopFrame.addAlignmentPanel(topPanel, false);
3071 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3077 topFrame.getAlignPanels().clear();
3078 bottomFrame.getAlignPanels().clear();
3085 * The dust settles...give focus to the tab we did this from.
3087 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3091 public static AlignFrame getCurrentAlignFrame()
3093 return currentAlignFrame;
3096 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3098 Desktop.currentAlignFrame = currentAlignFrame;
3101 public static ColourSchemeI getCurrentGlobalColourScheme()
3103 return currentGlobalColourScheme;
3106 public static void setCurrentGlobalColourScheme(
3107 ColourSchemeI currentGlobalColourScheme)
3109 Desktop.currentGlobalColourScheme = currentGlobalColourScheme;
3112 public static boolean isCurrentSeqFeaturesVisible()
3114 return currentSeqFeaturesVisible;
3117 public static void setCurrentSeqFeaturesVisible(
3118 boolean currentSeqFeaturesVisible)
3120 Desktop.currentSeqFeaturesVisible = currentSeqFeaturesVisible;