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 public static jalview.ws.jws1.Discoverer discoverer;
179 public static Object[] jalviewClipboard;
181 public static boolean internalCopy = false;
183 static int fileLoadingCount = 0;
185 class MyDesktopManager implements DesktopManager
188 private DesktopManager delegate;
190 public MyDesktopManager(DesktopManager delegate)
192 this.delegate = delegate;
195 public void activateFrame(JInternalFrame f)
199 delegate.activateFrame(f);
200 } catch (NullPointerException npe)
202 Point p = getMousePosition();
203 instance.showPasteMenu(p.x, p.y);
207 public void beginDraggingFrame(JComponent f)
209 delegate.beginDraggingFrame(f);
212 public void beginResizingFrame(JComponent f, int direction)
214 delegate.beginResizingFrame(f, direction);
217 public void closeFrame(JInternalFrame f)
219 delegate.closeFrame(f);
222 public void deactivateFrame(JInternalFrame f)
224 delegate.deactivateFrame(f);
227 public void deiconifyFrame(JInternalFrame f)
229 delegate.deiconifyFrame(f);
232 public void dragFrame(JComponent f, int newX, int newY)
238 delegate.dragFrame(f, newX, newY);
241 public void endDraggingFrame(JComponent f)
243 delegate.endDraggingFrame(f);
246 public void endResizingFrame(JComponent f)
248 delegate.endResizingFrame(f);
251 public void iconifyFrame(JInternalFrame f)
253 delegate.iconifyFrame(f);
256 public void maximizeFrame(JInternalFrame f)
258 delegate.maximizeFrame(f);
261 public void minimizeFrame(JInternalFrame f)
263 delegate.minimizeFrame(f);
266 public void openFrame(JInternalFrame f)
268 delegate.openFrame(f);
271 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
274 Rectangle b = desktop.getBounds();
279 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
282 public void setBoundsForFrame(JComponent f, int newX, int newY,
283 int newWidth, int newHeight)
285 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
288 // All other methods, simply delegate
293 * Creates a new Desktop object.
298 * A note to implementors. It is ESSENTIAL that any activities that might
299 * block are spawned off as threads rather than waited for during this
303 doVamsasClientCheck();
305 doConfigureStructurePrefs();
306 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
307 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
308 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
310 boolean showjconsole = jalview.bin.Cache.getDefault(
311 "SHOW_JAVA_CONSOLE", false);
312 desktop = new MyDesktopPane(selmemusage);
313 showMemusage.setSelected(selmemusage);
314 desktop.setBackground(Color.white);
315 getContentPane().setLayout(new BorderLayout());
316 // alternate config - have scrollbars - see notes in JAL-153
317 // JScrollPane sp = new JScrollPane();
318 // sp.getViewport().setView(desktop);
319 // getContentPane().add(sp, BorderLayout.CENTER);
320 getContentPane().add(desktop, BorderLayout.CENTER);
321 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
323 // This line prevents Windows Look&Feel resizing all new windows to maximum
324 // if previous window was maximised
325 desktop.setDesktopManager(new MyDesktopManager(
326 new DefaultDesktopManager()));
328 Rectangle dims = getLastKnownDimensions("");
335 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
336 setBounds((screenSize.width - 900) / 2,
337 (screenSize.height - 650) / 2, 900, 650);
339 jconsole = new Console(this, showjconsole);
340 // add essential build information
341 jconsole.setHeader("Jalview Version: "
342 + jalview.bin.Cache.getProperty("VERSION") + "\n"
343 + "Jalview Installation: "
344 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
345 + "\n" + "Build Date: "
346 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
347 + "Java version: " + System.getProperty("java.version") + "\n"
348 + System.getProperty("os.arch") + " "
349 + System.getProperty("os.name") + " "
350 + System.getProperty("os.version"));
352 showConsole(showjconsole);
354 showNews.setVisible(false);
356 this.addWindowListener(new WindowAdapter()
358 public void windowClosing(WindowEvent evt)
365 this.addMouseListener(ma = new MouseAdapter()
367 public void mousePressed(MouseEvent evt)
369 if (SwingUtilities.isRightMouseButton(evt))
371 showPasteMenu(evt.getX(), evt.getY());
375 desktop.addMouseListener(ma);
377 this.addFocusListener(new FocusListener()
381 public void focusLost(FocusEvent e)
383 // TODO Auto-generated method stub
388 public void focusGained(FocusEvent e)
390 Cache.log.debug("Relaying windows after focus gain");
391 // make sure that we sort windows properly after we gain focus
392 instance.relayerWindows();
395 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
396 // Spawn a thread that shows the splashscreen
397 SwingUtilities.invokeLater(new Runnable()
406 // Thread off a new instance of the file chooser - this reduces the time it
407 // takes to open it later on.
408 new Thread(new Runnable()
412 Cache.log.debug("Filechooser init thread started.");
413 JalviewFileChooser chooser = new JalviewFileChooser(
414 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
415 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
416 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
417 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
418 Cache.log.debug("Filechooser init thread finished.");
421 // Add the service change listener
422 changeSupport.addJalviewPropertyChangeListener("services",
423 new PropertyChangeListener()
427 public void propertyChange(PropertyChangeEvent evt)
429 Cache.log.debug("Firing service changed event for "
430 + evt.getNewValue());
431 JalviewServicesChanged(evt);
437 public void doConfigureStructurePrefs()
439 // configure services
440 StructureSelectionManager ssm = StructureSelectionManager
441 .getStructureSelectionManager(this);
442 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
444 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
445 Preferences.ADD_TEMPFACT_ANN, true));
446 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
447 Preferences.STRUCT_FROM_PDB, true));
448 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
449 Preferences.USE_RNAVIEW, true));
453 ssm.setAddTempFacAnnot(false);
454 ssm.setProcessSecondaryStructure(false);
455 ssm.setSecStructServices(false);
459 public void checkForNews()
461 final Desktop me = this;
462 // Thread off the news reader, in case there are connection problems.
463 addDialogThread(new Runnable()
468 Cache.log.debug("Starting news thread.");
470 jvnews = new BlogReader(me);
471 showNews.setVisible(true);
472 Cache.log.debug("Completed news thread.");
477 protected void showNews_actionPerformed(ActionEvent e)
479 showNews(showNews.isSelected());
482 void showNews(boolean visible)
485 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
486 showNews.setSelected(visible);
487 if (visible && !jvnews.isVisible())
489 new Thread(new Runnable()
494 long instance = System.currentTimeMillis();
495 Desktop.instance.setProgressBar(
496 MessageManager.getString("status.refreshing_news"),
498 jvnews.refreshNews();
499 Desktop.instance.setProgressBar(null, instance);
508 * recover the last known dimensions for a jalview window
511 * - empty string is desktop, all other windows have unique prefix
512 * @return null or last known dimensions scaled to current geometry (if last
513 * window geom was known)
515 Rectangle getLastKnownDimensions(String windowName)
517 // TODO: lock aspect ratio for scaling desktop Bug #0058199
518 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
519 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
520 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
521 String width = jalview.bin.Cache.getProperty(windowName
523 String height = jalview.bin.Cache.getProperty(windowName
525 if ((x != null) && (y != null) && (width != null) && (height != null))
527 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
528 .parseInt(width), ih = Integer.parseInt(height);
529 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
531 // attempt #1 - try to cope with change in screen geometry - this
532 // version doesn't preserve original jv aspect ratio.
533 // take ratio of current screen size vs original screen size.
534 double sw = ((1f * screenSize.width) / (1f * Integer
535 .parseInt(jalview.bin.Cache
536 .getProperty("SCREENGEOMETRY_WIDTH"))));
537 double sh = ((1f * screenSize.height) / (1f * Integer
538 .parseInt(jalview.bin.Cache
539 .getProperty("SCREENGEOMETRY_HEIGHT"))));
540 // rescale the bounds depending upon the current screen geometry.
541 ix = (int) (ix * sw);
542 iw = (int) (iw * sw);
543 iy = (int) (iy * sh);
544 ih = (int) (ih * sh);
545 while (ix >= screenSize.width)
547 jalview.bin.Cache.log
548 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
549 ix -= screenSize.width;
551 while (iy >= screenSize.height)
553 jalview.bin.Cache.log
554 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
555 iy -= screenSize.height;
557 jalview.bin.Cache.log.debug("Got last known dimensions for "
558 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
561 // return dimensions for new instance
562 return new Rectangle(ix, iy, iw, ih);
567 private void doVamsasClientCheck()
569 if (jalview.bin.Cache.vamsasJarsPresent())
571 setupVamsasDisconnectedGui();
572 VamsasMenu.setVisible(true);
573 final Desktop us = this;
574 VamsasMenu.addMenuListener(new MenuListener()
576 // this listener remembers when the menu was first selected, and
577 // doesn't rebuild the session list until it has been cleared and
579 boolean refresh = true;
581 public void menuCanceled(MenuEvent e)
586 public void menuDeselected(MenuEvent e)
591 public void menuSelected(MenuEvent e)
595 us.buildVamsasStMenu();
600 vamsasStart.setVisible(true);
604 void showPasteMenu(int x, int y)
606 JPopupMenu popup = new JPopupMenu();
607 JMenuItem item = new JMenuItem(
608 MessageManager.getString("label.paste_new_window"));
609 item.addActionListener(new ActionListener()
611 public void actionPerformed(ActionEvent evt)
618 popup.show(this, x, y);
625 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
626 Transferable contents = c.getContents(this);
628 if (contents != null)
630 String file = (String) contents
631 .getTransferData(DataFlavor.stringFlavor);
633 String format = new IdentifyFile().Identify(file,
634 FormatAdapter.PASTE);
636 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
639 } catch (Exception ex)
642 .println("Unable to paste alignment from system clipboard:\n"
648 * Adds and opens the given frame to the desktop
659 public static synchronized void addInternalFrame(
660 final JInternalFrame frame, String title, int w, int h)
662 addInternalFrame(frame, title, true, w, h, true);
666 * Add an internal frame to the Jalview desktop
673 * When true, display frame immediately, otherwise, caller must call
674 * setVisible themselves.
680 public static synchronized void addInternalFrame(
681 final JInternalFrame frame, String title, boolean makeVisible,
684 addInternalFrame(frame, title, makeVisible, w, h, true);
688 * Add an internal frame to the Jalview desktop and make it visible
701 public static synchronized void addInternalFrame(
702 final JInternalFrame frame, String title, int w, int h,
705 addInternalFrame(frame, title, true, w, h, resizable);
709 * Add an internal frame to the Jalview desktop
716 * When true, display frame immediately, otherwise, caller must call
717 * setVisible themselves.
725 public static synchronized void addInternalFrame(
726 final JInternalFrame frame, String title, boolean makeVisible,
727 int w, int h, boolean resizable)
730 // TODO: allow callers to determine X and Y position of frame (eg. via
732 // TODO: consider fixing method to update entries in the window submenu with
733 // the current window title
735 frame.setTitle(title);
736 if (frame.getWidth() < 1 || frame.getHeight() < 1)
740 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
741 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
742 // IF JALVIEW IS RUNNING HEADLESS
743 // ///////////////////////////////////////////////
745 || (System.getProperty("java.awt.headless") != null && System
746 .getProperty("java.awt.headless").equals("true")))
753 frame.setVisible(makeVisible);
754 frame.setClosable(true);
755 frame.setResizable(resizable);
756 frame.setMaximizable(resizable);
757 frame.setIconifiable(resizable);
758 frame.setFrameIcon(null);
760 if (frame.getX() < 1 && frame.getY() < 1)
762 frame.setLocation(xOffset * openFrameCount, yOffset
763 * ((openFrameCount - 1) % 10) + yOffset);
766 final JMenuItem menuItem = new JMenuItem(title);
767 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
769 public void internalFrameActivated(
770 javax.swing.event.InternalFrameEvent evt)
772 JInternalFrame itf = desktop.getSelectedFrame();
780 public void internalFrameClosed(
781 javax.swing.event.InternalFrameEvent evt)
783 PaintRefresher.RemoveComponent(frame);
785 windowMenu.remove(menuItem);
786 JInternalFrame itf = desktop.getSelectedFrame();
795 menuItem.addActionListener(new ActionListener()
797 public void actionPerformed(ActionEvent e)
801 frame.setSelected(true);
802 frame.setIcon(false);
803 } catch (java.beans.PropertyVetoException ex)
809 menuItem.addMouseListener(new MouseListener()
813 public void mouseReleased(MouseEvent e)
818 public void mousePressed(MouseEvent e)
823 public void mouseExited(MouseEvent e)
827 frame.setSelected(false);
828 } catch (PropertyVetoException e1)
834 public void mouseEntered(MouseEvent e)
838 frame.setSelected(true);
839 } catch (PropertyVetoException e1)
845 public void mouseClicked(MouseEvent e)
851 windowMenu.add(menuItem);
857 frame.setSelected(true);
858 frame.requestFocus();
859 } catch (java.beans.PropertyVetoException ve)
861 } catch (java.lang.ClassCastException cex)
864 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
869 public void lostOwnership(Clipboard clipboard, Transferable contents)
873 Desktop.jalviewClipboard = null;
876 internalCopy = false;
879 public void dragEnter(DropTargetDragEvent evt)
883 public void dragExit(DropTargetEvent evt)
887 public void dragOver(DropTargetDragEvent evt)
891 public void dropActionChanged(DropTargetDragEvent evt)
901 public void drop(DropTargetDropEvent evt)
903 boolean success = true;
904 Transferable t = evt.getTransferable();
905 java.util.List files = null;
906 java.util.List protocols = null;
910 DataFlavor uriListFlavor = new DataFlavor(
911 "text/uri-list;class=java.lang.String");
912 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
914 // Works on Windows and MacOSX
915 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
916 files = (java.util.List) t
917 .getTransferData(DataFlavor.javaFileListFlavor);
919 else if (t.isDataFlavorSupported(uriListFlavor))
921 // This is used by Unix drag system
922 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
923 String data = (String) t.getTransferData(uriListFlavor);
924 files = new java.util.ArrayList(1);
925 protocols = new java.util.ArrayList(1);
926 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
927 data, "\r\n"); st.hasMoreTokens();)
929 String s = st.nextToken();
930 if (s.startsWith("#"))
932 // the line is a comment (as per the RFC 2483)
935 java.net.URI uri = new java.net.URI(s);
936 if (uri.getScheme().toLowerCase().startsWith("http"))
938 protocols.add(FormatAdapter.URL);
939 files.add(uri.toString());
943 // otherwise preserve old behaviour: catch all for file objects
944 java.io.File file = new java.io.File(uri);
945 protocols.add(FormatAdapter.FILE);
946 files.add(file.toString());
950 } catch (Exception e)
959 for (int i = 0; i < files.size(); i++)
961 String file = files.get(i).toString();
962 String protocol = (protocols == null) ? FormatAdapter.FILE
963 : (String) protocols.get(i);
964 String format = null;
966 if (file.endsWith(".jar"))
973 format = new IdentifyFile().Identify(file, protocol);
976 new FileLoader().LoadFile(file, protocol, format);
979 } catch (Exception ex)
984 evt.dropComplete(success); // need this to ensure input focus is properly
985 // transfered to any new windows created
994 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
996 JalviewFileChooser chooser = new JalviewFileChooser(
997 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
998 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
999 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1000 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1002 chooser.setFileView(new JalviewFileView());
1003 chooser.setDialogTitle(MessageManager
1004 .getString("label.open_local_file"));
1005 chooser.setToolTipText(MessageManager.getString("action.open"));
1007 int value = chooser.showOpenDialog(this);
1009 if (value == JalviewFileChooser.APPROVE_OPTION)
1011 String choice = chooser.getSelectedFile().getPath();
1012 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1013 .getSelectedFile().getParent());
1015 String format = null;
1016 if (chooser.getSelectedFormat() != null
1017 && chooser.getSelectedFormat().equals("Jalview"))
1023 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1026 if (viewport != null)
1028 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1031 viewport.setShowSequenceFeatures(true);
1032 viewport.getAlignPanel().alignFrame.changeColour(Desktop
1033 .getCurrentGlobalColourScheme());
1034 viewport.getAlignPanel().alignFrame.setMenusForViewport();
1038 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1049 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1051 // This construct allows us to have a wider textfield
1053 JLabel label = new JLabel(
1054 MessageManager.getString("label.input_file_url"));
1055 final JComboBox history = new JComboBox();
1057 JPanel panel = new JPanel(new GridLayout(2, 1));
1060 history.setPreferredSize(new Dimension(400, 20));
1061 history.setEditable(true);
1062 history.addItem("http://www.");
1064 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1068 if (historyItems != null)
1070 st = new StringTokenizer(historyItems, "\t");
1072 while (st.hasMoreTokens())
1074 history.addItem(st.nextElement());
1078 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1079 MessageManager.getString("label.input_alignment_from_url"),
1080 JOptionPane.OK_CANCEL_OPTION);
1082 if (reply != JOptionPane.OK_OPTION)
1087 String url = history.getSelectedItem().toString();
1089 if (url.toLowerCase().endsWith(".jar"))
1091 if (viewport != null)
1093 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1098 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1103 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1105 if (format.equals("URL NOT FOUND"))
1107 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1108 MessageManager.formatMessage("label.couldnt_locate",
1110 { url }), MessageManager
1111 .getString("label.url_not_found"),
1112 JOptionPane.WARNING_MESSAGE);
1117 if (viewport != null)
1119 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1123 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1134 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1136 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1137 cap.setForInput(viewport);
1138 Desktop.addInternalFrame(cap,
1139 MessageManager.getString("label.cut_paste_alignmen_file"),
1148 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1150 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1151 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1153 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1154 getBounds().y, getWidth(), getHeight()));
1156 if (jconsole != null)
1158 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1159 jconsole.stopConsole();
1163 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1166 if (dialogExecutor != null)
1168 dialogExecutor.shutdownNow();
1174 private void storeLastKnownDimensions(String string, Rectangle jc)
1176 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1177 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1178 + " height:" + jc.height);
1180 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1181 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1182 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1183 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1192 public void aboutMenuItem_actionPerformed(ActionEvent e)
1194 // StringBuffer message = getAboutMessage(false);
1195 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1197 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1198 new Thread(new Runnable()
1202 new SplashScreen(true);
1207 public StringBuffer getAboutMessage(boolean shortv)
1209 StringBuffer message = new StringBuffer();
1210 message.append("<html>");
1213 message.append("<h1><strong>Version: "
1214 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1215 message.append("<strong>Last Updated: <em>"
1216 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1217 + "</em></strong>");
1223 message.append("<strong>Version "
1224 + jalview.bin.Cache.getProperty("VERSION")
1225 + "; last updated: "
1226 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1229 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1232 message.append("<br>...Checking latest version...</br>");
1234 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1235 .equals(jalview.bin.Cache.getProperty("VERSION")))
1237 boolean red = false;
1238 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1239 .indexOf("automated build") == -1)
1242 // Displayed when code version and jnlp version do not match and code
1243 // version is not a development build
1244 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1247 message.append("<br>!! Version "
1248 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1250 + " is available for download from "
1251 + jalview.bin.Cache.getDefault("www.jalview.org",
1252 "http://www.jalview.org") + " !!");
1255 message.append("</div>");
1258 message.append("<br>Authors: "
1260 .getDefault("AUTHORFNAMES",
1261 "The Jalview Authors (See AUTHORS file for current list)")
1262 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1263 + "<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"
1264 + "<br><br>If you use Jalview, please cite:"
1265 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1266 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1267 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1278 public void documentationMenuItem_actionPerformed(ActionEvent e)
1282 Help.showHelpWindow();
1283 } catch (Exception ex)
1288 public void closeAll_actionPerformed(ActionEvent e)
1290 JInternalFrame[] frames = desktop.getAllFrames();
1291 for (int i = 0; i < frames.length; i++)
1295 frames[i].setClosed(true);
1296 } catch (java.beans.PropertyVetoException ex)
1300 System.out.println("ALL CLOSED");
1301 if (v_client != null)
1303 // TODO clear binding to vamsas document objects on close_all
1308 public void raiseRelated_actionPerformed(ActionEvent e)
1310 reorderAssociatedWindows(false, false);
1313 public void minimizeAssociated_actionPerformed(ActionEvent e)
1315 reorderAssociatedWindows(true, false);
1318 void closeAssociatedWindows()
1320 reorderAssociatedWindows(false, true);
1326 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1329 protected void garbageCollect_actionPerformed(ActionEvent e)
1331 // We simply collect the garbage
1332 jalview.bin.Cache.log.debug("Collecting garbage...");
1334 jalview.bin.Cache.log.debug("Finished garbage collection.");
1341 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1344 protected void showMemusage_actionPerformed(ActionEvent e)
1346 desktop.showMemoryUsage(showMemusage.isSelected());
1353 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1356 protected void showConsole_actionPerformed(ActionEvent e)
1358 showConsole(showConsole.isSelected());
1361 Console jconsole = null;
1364 * control whether the java console is visible or not
1368 void showConsole(boolean selected)
1370 showConsole.setSelected(selected);
1371 // TODO: decide if we should update properties file
1372 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1374 jconsole.setVisible(selected);
1377 void reorderAssociatedWindows(boolean minimize, boolean close)
1379 JInternalFrame[] frames = desktop.getAllFrames();
1380 if (frames == null || frames.length < 1)
1385 AlignmentViewport source = null, target = null;
1386 if (frames[0] instanceof AlignFrame)
1388 source = ((AlignFrame) frames[0]).getCurrentView();
1390 else if (frames[0] instanceof TreePanel)
1392 source = ((TreePanel) frames[0]).getViewPort();
1394 else if (frames[0] instanceof PCAPanel)
1396 source = ((PCAPanel) frames[0]).av;
1398 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1400 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1405 for (int i = 0; i < frames.length; i++)
1408 if (frames[i] == null)
1412 if (frames[i] instanceof AlignFrame)
1414 target = ((AlignFrame) frames[i]).getCurrentView();
1416 else if (frames[i] instanceof TreePanel)
1418 target = ((TreePanel) frames[i]).getViewPort();
1420 else if (frames[i] instanceof PCAPanel)
1422 target = ((PCAPanel) frames[i]).av;
1424 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1426 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1429 if (source == target)
1435 frames[i].setClosed(true);
1439 frames[i].setIcon(minimize);
1442 frames[i].toFront();
1446 } catch (java.beans.PropertyVetoException ex)
1460 protected void preferences_actionPerformed(ActionEvent e)
1471 public void saveState_actionPerformed(ActionEvent e)
1473 JalviewFileChooser chooser = new JalviewFileChooser(
1474 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1475 { "jvp" }, new String[]
1476 { "Jalview Project" }, "Jalview Project");
1478 chooser.setFileView(new JalviewFileView());
1479 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1481 int value = chooser.showSaveDialog(this);
1483 if (value == JalviewFileChooser.APPROVE_OPTION)
1485 final Desktop me = this;
1486 final java.io.File choice = chooser.getSelectedFile();
1487 setProjectFile(choice);
1489 // TODO or move inside the new Thread?
1490 saveChimeraSessions(choice.getAbsolutePath());
1492 new Thread(new Runnable()
1497 setProgressBar(MessageManager.formatMessage(
1498 "label.saving_jalview_project", new Object[]
1499 { choice.getName() }), choice.hashCode());
1500 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1501 choice.getParent());
1502 // TODO catch and handle errors for savestate
1503 // TODO prevent user from messing with the Desktop whilst we're saving
1506 new Jalview2XML().saveState(choice);
1507 } catch (OutOfMemoryError oom)
1509 new OOMWarning("Whilst saving current state to "
1510 + choice.getName(), oom);
1511 } catch (Exception ex)
1514 "Problems whilst trying to save to " + choice.getName(),
1516 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1517 "label.error_whilst_saving_current_state_to",
1519 { choice.getName() }), MessageManager
1520 .getString("label.couldnt_save_project"),
1521 JOptionPane.WARNING_MESSAGE);
1523 setProgressBar(null, choice.hashCode());
1530 * Request any open, linked Chimera sessions to save their state.
1532 * @param jalviewProjectFilename
1533 * the filename of the Jalview project; Chimera session files should
1534 * be given distinct, but obviously related, names.
1536 public void saveChimeraSessions(String jalviewProjectFilename)
1539 for (JInternalFrame frame : getAllFrames())
1541 if (frame instanceof ChimeraViewFrame)
1544 * Construct a filename for the Chimera session by append _chimera<n>.py
1545 * to the Jalview project file name.
1547 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1549 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1555 private void setProjectFile(File choice)
1557 this.projectFile = choice;
1560 public File getProjectFile()
1562 return this.projectFile;
1571 public void loadState_actionPerformed(ActionEvent e)
1573 JalviewFileChooser chooser = new JalviewFileChooser(
1574 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1575 { "jvp", "jar" }, new String[]
1576 { "Jalview Project", "Jalview Project (old)" },
1578 chooser.setFileView(new JalviewFileView());
1579 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1581 int value = chooser.showOpenDialog(this);
1583 if (value == JalviewFileChooser.APPROVE_OPTION)
1585 final File selectedFile = chooser.getSelectedFile();
1586 setProjectFile(selectedFile);
1587 final String choice = selectedFile.getAbsolutePath();
1588 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1589 selectedFile.getParent());
1590 new Thread(new Runnable()
1594 setProgressBar(MessageManager.formatMessage(
1595 "label.loading_jalview_project", new Object[]
1596 { choice }), choice.hashCode());
1599 new Jalview2XML().loadJalviewAlign(choice);
1600 } catch (OutOfMemoryError oom)
1602 new OOMWarning("Whilst loading project from " + choice, oom);
1603 } catch (Exception ex)
1605 Cache.log.error("Problems whilst loading project from "
1607 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1609 "label.error_whilst_loading_project_from",
1611 { choice }), MessageManager
1612 .getString("label.couldnt_load_project"),
1613 JOptionPane.WARNING_MESSAGE);
1615 setProgressBar(null, choice.hashCode());
1621 public void inputSequence_actionPerformed(ActionEvent e)
1623 new SequenceFetcher(this);
1626 JPanel progressPanel;
1628 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1630 public void startLoading(final String fileName)
1632 if (fileLoadingCount == 0)
1634 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1635 "label.loading_file", new Object[]
1641 private JPanel addProgressPanel(String string)
1643 if (progressPanel == null)
1645 progressPanel = new JPanel(new GridLayout(1, 1));
1646 totalProgressCount = 0;
1647 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1649 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1650 JProgressBar progressBar = new JProgressBar();
1651 progressBar.setIndeterminate(true);
1653 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1655 thisprogress.add(progressBar, BorderLayout.CENTER);
1656 progressPanel.add(thisprogress);
1657 ((GridLayout) progressPanel.getLayout())
1658 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1659 ++totalProgressCount;
1660 instance.validate();
1661 return thisprogress;
1664 int totalProgressCount = 0;
1666 private void removeProgressPanel(JPanel progbar)
1668 if (progressPanel != null)
1670 synchronized (progressPanel)
1672 progressPanel.remove(progbar);
1673 GridLayout gl = (GridLayout) progressPanel.getLayout();
1674 gl.setRows(gl.getRows() - 1);
1675 if (--totalProgressCount < 1)
1677 this.getContentPane().remove(progressPanel);
1678 progressPanel = null;
1685 public void stopLoading()
1688 if (fileLoadingCount < 1)
1690 while (fileLoadingPanels.size() > 0)
1692 removeProgressPanel(fileLoadingPanels.remove(0));
1694 fileLoadingPanels.clear();
1695 fileLoadingCount = 0;
1700 public static int getViewCount(String alignmentId)
1702 AlignmentViewport[] aps = getViewports(alignmentId);
1703 return (aps == null) ? 0 : aps.length;
1708 * @param alignmentId
1709 * - if null, all sets are returned
1710 * @return all AlignmentPanels concerning the alignmentId sequence set
1712 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1714 if (Desktop.desktop == null)
1716 // no frames created and in headless mode
1717 // TODO: verify that frames are recoverable when in headless mode
1720 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1721 AlignFrame[] frames = getAlignFrames();
1726 for (AlignFrame af : frames)
1728 for (AlignmentPanel ap : af.alignPanels)
1730 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1736 if (aps.size() == 0)
1740 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1745 * get all the viewports on an alignment.
1747 * @param sequenceSetId
1748 * unique alignment id (may be null - all viewports returned in that
1750 * @return all viewports on the alignment bound to sequenceSetId
1752 public static AlignmentViewport[] getViewports(String sequenceSetId)
1754 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1755 if (desktop != null)
1757 AlignFrame[] frames = Desktop.getAlignFrames();
1759 for (AlignFrame afr : frames)
1761 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1763 if (afr.alignPanels != null)
1765 for (AlignmentPanel ap : afr.alignPanels)
1767 if (sequenceSetId == null
1768 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1776 viewp.add(afr.getViewport());
1780 if (viewp.size() > 0)
1782 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1789 * Explode the views in the given frame into separate AlignFrame
1793 public void explodeViews(AlignFrame af)
1795 int size = af.alignPanels.size();
1801 for (int i = 0; i < size; i++)
1803 AlignmentPanel ap = af.alignPanels.get(i);
1804 AlignFrame newaf = new AlignFrame(ap);
1807 * Restore the view's last exploded frame geometry if known. Multiple
1808 * views from one exploded frame share and restore the same (frame)
1809 * position and size.
1811 Rectangle geometry = ap.av.getExplodedGeometry();
1812 if (geometry != null)
1814 newaf.setBounds(geometry);
1817 ap.av.setGatherViewsHere(false);
1819 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1820 AlignFrame.DEFAULT_HEIGHT);
1823 af.alignPanels.clear();
1824 af.closeMenuItem_actionPerformed(true);
1829 * Gather expanded views (separate AlignFrame's) with the same sequence set
1830 * identifier back in to this frame as additional views, and close the
1831 * expanded views. Note the expanded frames may themselves have multiple
1832 * views. We take the lot.
1836 public void gatherViews(AlignFrame source)
1838 source.viewport.setGatherViewsHere(true);
1839 source.viewport.setExplodedGeometry(source.getBounds());
1840 JInternalFrame[] frames = desktop.getAllFrames();
1841 String viewId = source.viewport.getSequenceSetId();
1843 for (int t = 0; t < frames.length; t++)
1845 if (frames[t] instanceof AlignFrame && frames[t] != source)
1847 AlignFrame af = (AlignFrame) frames[t];
1848 boolean gatherThis = false;
1849 for (int a = 0; a < af.alignPanels.size(); a++)
1851 AlignmentPanel ap = af.alignPanels.get(a);
1852 if (viewId.equals(ap.av.getSequenceSetId()))
1855 ap.av.setGatherViewsHere(false);
1856 ap.av.setExplodedGeometry(af.getBounds());
1857 source.addAlignmentPanel(ap, false);
1863 af.alignPanels.clear();
1864 af.closeMenuItem_actionPerformed(true);
1871 jalview.gui.VamsasApplication v_client = null;
1873 public void vamsasImport_actionPerformed(ActionEvent e)
1875 if (v_client == null)
1877 // Load and try to start a session.
1878 JalviewFileChooser chooser = new JalviewFileChooser(
1879 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1881 chooser.setFileView(new JalviewFileView());
1882 chooser.setDialogTitle(MessageManager
1883 .getString("label.open_saved_vamsas_session"));
1884 chooser.setToolTipText(MessageManager
1885 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1887 int value = chooser.showOpenDialog(this);
1889 if (value == JalviewFileChooser.APPROVE_OPTION)
1891 String fle = chooser.getSelectedFile().toString();
1892 if (!vamsasImport(chooser.getSelectedFile()))
1895 .showInternalMessageDialog(
1897 MessageManager.formatMessage(
1898 "label.couldnt_import_as_vamsas_session",
1902 .getString("label.vamsas_document_import_failed"),
1903 JOptionPane.ERROR_MESSAGE);
1909 jalview.bin.Cache.log
1910 .error("Implementation error - load session from a running session is not supported.");
1915 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1918 * @return true if import was a success and a session was started.
1920 public boolean vamsasImport(URL url)
1922 // TODO: create progress bar
1923 if (v_client != null)
1926 jalview.bin.Cache.log
1927 .error("Implementation error - load session from a running session is not supported.");
1933 // copy the URL content to a temporary local file
1934 // TODO: be a bit cleverer here with nio (?!)
1935 File file = File.createTempFile("vdocfromurl", ".vdj");
1936 FileOutputStream fos = new FileOutputStream(file);
1937 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1938 byte[] buffer = new byte[2048];
1940 while ((ln = bis.read(buffer)) > -1)
1942 fos.write(buffer, 0, ln);
1946 v_client = new jalview.gui.VamsasApplication(this, file,
1947 url.toExternalForm());
1948 } catch (Exception ex)
1950 jalview.bin.Cache.log.error(
1951 "Failed to create new vamsas session from contents of URL "
1955 setupVamsasConnectedGui();
1956 v_client.initial_update(); // TODO: thread ?
1957 return v_client.inSession();
1961 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1964 * @return true if import was a success and a session was started.
1966 public boolean vamsasImport(File file)
1968 if (v_client != null)
1971 jalview.bin.Cache.log
1972 .error("Implementation error - load session from a running session is not supported.");
1976 setProgressBar(MessageManager.formatMessage(
1977 "status.importing_vamsas_session_from", new Object[]
1978 { file.getName() }), file.hashCode());
1981 v_client = new jalview.gui.VamsasApplication(this, file, null);
1982 } catch (Exception ex)
1984 setProgressBar(MessageManager.formatMessage(
1985 "status.importing_vamsas_session_from", new Object[]
1986 { file.getName() }), file.hashCode());
1987 jalview.bin.Cache.log.error(
1988 "New vamsas session from existing session file failed:", ex);
1991 setupVamsasConnectedGui();
1992 v_client.initial_update(); // TODO: thread ?
1993 setProgressBar(MessageManager.formatMessage(
1994 "status.importing_vamsas_session_from", new Object[]
1995 { file.getName() }), file.hashCode());
1996 return v_client.inSession();
1999 public boolean joinVamsasSession(String mysesid)
2001 if (v_client != null)
2005 .getString("error.try_join_vamsas_session_another"));
2007 if (mysesid == null)
2010 MessageManager.getString("error.invalid_vamsas_session_id"));
2012 v_client = new VamsasApplication(this, mysesid);
2013 setupVamsasConnectedGui();
2014 v_client.initial_update();
2015 return (v_client.inSession());
2018 public void vamsasStart_actionPerformed(ActionEvent e)
2020 if (v_client == null)
2023 // we just start a default session for moment.
2025 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2026 * getProperty("LAST_DIRECTORY"));
2028 * chooser.setFileView(new JalviewFileView());
2029 * chooser.setDialogTitle("Load Vamsas file");
2030 * chooser.setToolTipText("Import");
2032 * int value = chooser.showOpenDialog(this);
2034 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2035 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2037 v_client = new VamsasApplication(this);
2038 setupVamsasConnectedGui();
2039 v_client.initial_update(); // TODO: thread ?
2043 // store current data in session.
2044 v_client.push_update(); // TODO: thread
2048 protected void setupVamsasConnectedGui()
2050 vamsasStart.setText(MessageManager.getString("label.session_update"));
2051 vamsasSave.setVisible(true);
2052 vamsasStop.setVisible(true);
2053 vamsasImport.setVisible(false); // Document import to existing session is
2054 // not possible for vamsas-client-1.0.
2057 protected void setupVamsasDisconnectedGui()
2059 vamsasSave.setVisible(false);
2060 vamsasStop.setVisible(false);
2061 vamsasImport.setVisible(true);
2062 vamsasStart.setText(MessageManager
2063 .getString("label.new_vamsas_session"));
2066 public void vamsasStop_actionPerformed(ActionEvent e)
2068 if (v_client != null)
2070 v_client.end_session();
2072 setupVamsasDisconnectedGui();
2076 protected void buildVamsasStMenu()
2078 if (v_client == null)
2080 String[] sess = null;
2083 sess = VamsasApplication.getSessionList();
2084 } catch (Exception e)
2086 jalview.bin.Cache.log.warn(
2087 "Problem getting current sessions list.", e);
2092 jalview.bin.Cache.log.debug("Got current sessions list: "
2093 + sess.length + " entries.");
2094 VamsasStMenu.removeAll();
2095 for (int i = 0; i < sess.length; i++)
2097 JMenuItem sessit = new JMenuItem();
2098 sessit.setText(sess[i]);
2099 sessit.setToolTipText(MessageManager.formatMessage(
2100 "label.connect_to_session", new Object[]
2102 final Desktop dsktp = this;
2103 final String mysesid = sess[i];
2104 sessit.addActionListener(new ActionListener()
2107 public void actionPerformed(ActionEvent e)
2109 if (dsktp.v_client == null)
2111 Thread rthr = new Thread(new Runnable()
2116 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2117 dsktp.setupVamsasConnectedGui();
2118 dsktp.v_client.initial_update();
2126 VamsasStMenu.add(sessit);
2128 // don't show an empty menu.
2129 VamsasStMenu.setVisible(sess.length > 0);
2134 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2135 VamsasStMenu.removeAll();
2136 VamsasStMenu.setVisible(false);
2141 // Not interested in the content. Just hide ourselves.
2142 VamsasStMenu.setVisible(false);
2146 public void vamsasSave_actionPerformed(ActionEvent e)
2148 if (v_client != null)
2150 JalviewFileChooser chooser = new JalviewFileChooser(
2151 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2152 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2154 { "Vamsas Document" }, "Vamsas Document");
2156 chooser.setFileView(new JalviewFileView());
2157 chooser.setDialogTitle(MessageManager
2158 .getString("label.save_vamsas_document_archive"));
2160 int value = chooser.showSaveDialog(this);
2162 if (value == JalviewFileChooser.APPROVE_OPTION)
2164 java.io.File choice = chooser.getSelectedFile();
2165 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2166 "label.saving_vamsas_doc", new Object[]
2167 { choice.getName() }));
2168 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2169 String warnmsg = null;
2170 String warnttl = null;
2173 v_client.vclient.storeDocument(choice);
2176 warnttl = "Serious Problem saving Vamsas Document";
2177 warnmsg = ex.toString();
2178 jalview.bin.Cache.log.error("Error Whilst saving document to "
2181 } catch (Exception ex)
2183 warnttl = "Problem saving Vamsas Document.";
2184 warnmsg = ex.toString();
2185 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2189 removeProgressPanel(progpanel);
2190 if (warnmsg != null)
2192 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2194 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2200 JPanel vamUpdate = null;
2203 * hide vamsas user gui bits when a vamsas document event is being handled.
2206 * true to hide gui, false to reveal gui
2208 public void setVamsasUpdate(boolean b)
2210 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2211 + (b ? "in progress" : "finished"));
2213 if (vamUpdate != null)
2215 this.removeProgressPanel(vamUpdate);
2219 vamUpdate = this.addProgressPanel(MessageManager
2220 .getString("label.updating_vamsas_session"));
2222 vamsasStart.setVisible(!b);
2223 vamsasStop.setVisible(!b);
2224 vamsasSave.setVisible(!b);
2227 public JInternalFrame[] getAllFrames()
2229 return desktop.getAllFrames();
2233 * Checks the given url to see if it gives a response indicating that the user
2234 * should be informed of a new questionnaire.
2238 public void checkForQuestionnaire(String url)
2240 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2241 // javax.swing.SwingUtilities.invokeLater(jvq);
2242 new Thread(jvq).start();
2246 * Proxy class for JDesktopPane which optionally displays the current memory
2247 * usage and highlights the desktop area with a red bar if free memory runs
2252 public class MyDesktopPane extends JDesktopPane implements Runnable
2255 private static final float ONE_MB = 1048576f;
2257 boolean showMemoryUsage = false;
2261 java.text.NumberFormat df;
2263 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2266 public MyDesktopPane(boolean showMemoryUsage)
2268 showMemoryUsage(showMemoryUsage);
2271 public void showMemoryUsage(boolean showMemoryUsage)
2273 this.showMemoryUsage = showMemoryUsage;
2274 if (showMemoryUsage)
2276 Thread worker = new Thread(this);
2281 public boolean isShowMemoryUsage()
2283 return showMemoryUsage;
2288 df = java.text.NumberFormat.getNumberInstance();
2289 df.setMaximumFractionDigits(2);
2290 runtime = Runtime.getRuntime();
2292 while (showMemoryUsage)
2296 maxMemory = runtime.maxMemory() / ONE_MB;
2297 allocatedMemory = runtime.totalMemory() / ONE_MB;
2298 freeMemory = runtime.freeMemory() / ONE_MB;
2299 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2301 percentUsage = (totalFreeMemory / maxMemory) * 100;
2303 // if (percentUsage < 20)
2305 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2307 // instance.set.setBorder(border1);
2310 // sleep after showing usage
2312 } catch (Exception ex)
2314 ex.printStackTrace();
2319 public void paintComponent(Graphics g)
2321 if (showMemoryUsage && g != null && df != null)
2323 if (percentUsage < 20)
2325 g.setColor(Color.red);
2327 FontMetrics fm = g.getFontMetrics();
2330 g.drawString(MessageManager.formatMessage(
2331 "label.memory_stats",
2333 { df.format(totalFreeMemory), df.format(maxMemory),
2334 df.format(percentUsage) }), 10,
2335 getHeight() - fm.getHeight());
2342 * fixes stacking order after a modal dialog to ensure windows that should be
2343 * on top actually are
2345 public void relayerWindows()
2350 protected JMenuItem groovyShell;
2352 public void doGroovyCheck()
2354 if (jalview.bin.Cache.groovyJarsPresent())
2356 groovyShell = new JMenuItem();
2357 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2358 groovyShell.addActionListener(new ActionListener()
2360 public void actionPerformed(ActionEvent e)
2362 groovyShell_actionPerformed(e);
2365 toolsMenu.add(groovyShell);
2366 groovyShell.setVisible(true);
2371 * Accessor method to quickly get all the AlignmentFrames loaded.
2373 * @return an array of AlignFrame, or null if none found
2375 public static AlignFrame[] getAlignFrames()
2377 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2383 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2385 for (int i = frames.length - 1; i > -1; i--)
2387 if (frames[i] instanceof AlignFrame)
2389 avp.add((AlignFrame) frames[i]);
2391 else if (frames[i] instanceof SplitFrame)
2394 * Also check for a split frame containing an AlignFrame
2396 GSplitFrame sf = (GSplitFrame) frames[i];
2397 if (sf.getTopFrame() instanceof AlignFrame)
2399 avp.add((AlignFrame) sf.getTopFrame());
2401 if (sf.getBottomFrame() instanceof AlignFrame)
2403 avp.add((AlignFrame) sf.getBottomFrame());
2407 if (avp.size() == 0)
2411 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2416 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2420 public GStructureViewer[] getJmols()
2422 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2428 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2430 for (int i = frames.length - 1; i > -1; i--)
2432 if (frames[i] instanceof AppJmol)
2434 GStructureViewer af = (GStructureViewer) frames[i];
2438 if (avp.size() == 0)
2442 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2447 * Add Groovy Support to Jalview
2449 public void groovyShell_actionPerformed(ActionEvent e)
2451 // use reflection to avoid creating compilation dependency.
2452 if (!jalview.bin.Cache.groovyJarsPresent())
2456 .getString("error.implementation_error_cannot_create_groovyshell"));
2460 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2461 "groovy.ui.Console");
2462 Constructor<?> gccons = gcClass.getConstructor();
2463 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2465 { String.class, Object.class });
2466 java.lang.reflect.Method run = gcClass.getMethod("run");
2467 Object gc = gccons.newInstance();
2468 setvar.invoke(gc, new Object[]
2469 { "Jalview", this });
2471 } catch (Exception ex)
2473 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2474 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2476 MessageManager.getString("label.couldnt_create_groovy_shell"),
2477 MessageManager.getString("label.groovy_support_failed"),
2478 JOptionPane.ERROR_MESSAGE);
2483 * Progress bars managed by the IProgressIndicator method.
2485 private Hashtable<Long, JPanel> progressBars;
2487 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2492 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2494 public void setProgressBar(String message, long id)
2496 if (progressBars == null)
2498 progressBars = new Hashtable<Long, JPanel>();
2499 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2502 if (progressBars.get(new Long(id)) != null)
2504 JPanel progressPanel = progressBars.remove(new Long(id));
2505 if (progressBarHandlers.contains(new Long(id)))
2507 progressBarHandlers.remove(new Long(id));
2509 removeProgressPanel(progressPanel);
2513 progressBars.put(new Long(id), addProgressPanel(message));
2520 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2521 * jalview.gui.IProgressIndicatorHandler)
2523 public void registerHandler(final long id,
2524 final IProgressIndicatorHandler handler)
2526 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2530 .getString("error.call_setprogressbar_before_registering_handler"));
2532 progressBarHandlers.put(new Long(id), handler);
2533 final JPanel progressPanel = progressBars.get(new Long(id));
2534 if (handler.canCancel())
2536 JButton cancel = new JButton(
2537 MessageManager.getString("action.cancel"));
2538 final IProgressIndicator us = this;
2539 cancel.addActionListener(new ActionListener()
2542 public void actionPerformed(ActionEvent e)
2544 handler.cancelActivity(id);
2545 us.setProgressBar(MessageManager.formatMessage(
2546 "label.cancelled_params", new Object[]
2547 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2551 progressPanel.add(cancel, BorderLayout.EAST);
2557 * @return true if any progress bars are still active
2560 public boolean operationInProgress()
2562 if (progressBars != null && progressBars.size() > 0)
2570 * This will return the first AlignFrame holding the given viewport instance. It
2571 * will break if there are more than one AlignFrames viewing a particular av.
2574 * @return alignFrame for viewport
2576 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2578 if (desktop != null)
2580 AlignmentPanel[] aps = getAlignmentPanels(viewport
2581 .getSequenceSetId());
2582 for (int panel = 0; aps != null && panel < aps.length; panel++)
2584 if (aps[panel] != null && aps[panel].av == viewport)
2586 return aps[panel].alignFrame;
2593 public VamsasApplication getVamsasApplication()
2600 * flag set if jalview GUI is being operated programmatically
2602 private boolean inBatchMode = false;
2605 * check if jalview GUI is being operated programmatically
2607 * @return inBatchMode
2609 public boolean isInBatchMode()
2615 * set flag if jalview GUI is being operated programmatically
2617 * @param inBatchMode
2619 public void setInBatchMode(boolean inBatchMode)
2621 this.inBatchMode = inBatchMode;
2624 public void startServiceDiscovery()
2626 startServiceDiscovery(false);
2629 public void startServiceDiscovery(boolean blocking)
2631 boolean alive = true;
2632 Thread t0 = null, t1 = null, t2 = null;
2633 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2636 // todo: changesupport handlers need to be transferred
2637 if (discoverer == null)
2639 discoverer = new jalview.ws.jws1.Discoverer();
2640 // register PCS handler for desktop.
2641 discoverer.addPropertyChangeListener(changeSupport);
2643 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2644 // until we phase out completely
2645 (t0 = new Thread(discoverer)).start();
2648 // ENFIN services are EOLed as of Jalview 2.8.1 release
2653 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2655 // EnfinEnvision web service menu entries are rebuild every time the
2656 // menu is shown, so no changeSupport events are needed.
2657 jalview.ws.EnfinEnvision2OneWay.getInstance();
2658 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2661 } catch (Exception e)
2664 .info("Exception when trying to launch Envision2 workflow discovery.",
2666 Cache.log.info(e.getStackTrace());
2670 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2672 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2674 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2676 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2682 // TODO: do rest service discovery
2691 } catch (Exception e)
2694 alive = (t1 != null && t1.isAlive())
2695 || (t2 != null && t2.isAlive())
2696 || (t3 != null && t3.isAlive())
2697 || (t0 != null && t0.isAlive());
2703 * called to check if the service discovery process completed successfully.
2707 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2709 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2711 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2712 .getErrorMessages();
2715 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2717 if (serviceChangedDialog == null)
2719 // only run if we aren't already displaying one of these.
2720 addDialogThread(serviceChangedDialog = new Runnable()
2726 * JalviewDialog jd =new JalviewDialog() {
2728 * @Override protected void cancelPressed() { // TODO
2729 * Auto-generated method stub
2731 * }@Override protected void okPressed() { // TODO
2732 * Auto-generated method stub
2734 * }@Override protected void raiseClosed() { // TODO
2735 * Auto-generated method stub
2737 * } }; jd.initDialogFrame(new
2738 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2739 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2740 * + " or mis-configured HTTP proxy settings.<br/>" +
2741 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2743 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2744 * ), true, true, "Web Service Configuration Problem", 450,
2747 * jd.waitForInput();
2753 "<html><table width=\"450\"><tr><td>"
2755 + "</td></tr></table>"
2756 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2757 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2758 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2759 + " Tools->Preferences dialog box to change them.</p></html>"),
2760 "Web Service Configuration Problem",
2761 JOptionPane.DEFAULT_OPTION,
2762 JOptionPane.ERROR_MESSAGE);
2763 serviceChangedDialog = null;
2772 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2779 private Runnable serviceChangedDialog = null;
2782 * start a thread to open a URL in the configured browser. Pops up a warning
2783 * dialog to the user if there is an exception when calling out to the browser
2788 public static void showUrl(final String url)
2790 showUrl(url, Desktop.instance);
2794 * Like showUrl but allows progress handler to be specified
2798 * (null) or object implementing IProgressIndicator
2800 public static void showUrl(final String url,
2801 final IProgressIndicator progress)
2803 new Thread(new Runnable()
2809 if (progress != null)
2811 progress.setProgressBar(MessageManager.formatMessage(
2812 "status.opening_params", new Object[]
2813 { url }), this.hashCode());
2815 jalview.util.BrowserLauncher.openURL(url);
2816 } catch (Exception ex)
2818 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2820 .getString("label.web_browser_not_found_unix"),
2821 MessageManager.getString("label.web_browser_not_found"),
2822 JOptionPane.WARNING_MESSAGE);
2824 ex.printStackTrace();
2826 if (progress != null)
2828 progress.setProgressBar(null, this.hashCode());
2834 public static WsParamSetManager wsparamManager = null;
2836 public static ParamManager getUserParameterStore()
2838 if (wsparamManager == null)
2840 wsparamManager = new WsParamSetManager();
2842 return wsparamManager;
2846 * static hyperlink handler proxy method for use by Jalview's internal windows
2850 public static void hyperlinkUpdate(HyperlinkEvent e)
2852 if (e.getEventType() == EventType.ACTIVATED)
2857 url = e.getURL().toString();
2858 Desktop.showUrl(url);
2859 } catch (Exception x)
2863 if (Cache.log != null)
2865 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2869 System.err.println("Couldn't handle string " + url
2873 // ignore any exceptions due to dud links.
2880 * single thread that handles display of dialogs to user.
2882 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2885 * flag indicating if dialogExecutor should try to acquire a permit
2887 private volatile boolean dialogPause = true;
2892 private java.util.concurrent.Semaphore block = new Semaphore(0);
2895 * add another dialog thread to the queue
2899 public void addDialogThread(final Runnable prompter)
2901 dialogExecutor.submit(new Runnable()
2910 } catch (InterruptedException x)
2915 if (instance == null)
2921 SwingUtilities.invokeAndWait(prompter);
2922 } catch (Exception q)
2924 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2930 public void startDialogQueue()
2932 // set the flag so we don't pause waiting for another permit and semaphore
2933 // the current task to begin
2934 dialogPause = false;
2939 protected void snapShotWindow_actionPerformed(ActionEvent e)
2943 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2944 "View of Desktop", getWidth(), getHeight(), of = new File(
2945 "Jalview_snapshot" + System.currentTimeMillis()
2946 + ".eps"), "View of desktop");
2949 paintAll(im.getGraphics());
2951 } catch (Exception q)
2953 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2957 Cache.log.info("Successfully written snapshot to file "
2958 + of.getAbsolutePath());
2962 * Explode the views in the given frame into separate AlignFrame windows.
2966 public void explodeViews(SplitFrame sf)
2968 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2969 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2970 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2972 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2974 int viewCount = topPanels.size();
2981 * Processing in reverse order works, forwards order leaves the first panels
2982 * not visible. I don't know why!
2984 for (int i = viewCount - 1; i >= 0; i--)
2987 * Make new top and bottom frames. These take over the respective
2988 * AlignmentPanel objects, including their AlignmentViewports, so the
2989 * cdna/protein relationships between the viewports is carried over to the
2992 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2993 AlignFrame newTopFrame = new AlignFrame(topPanel);
2994 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2995 AlignFrame.DEFAULT_HEIGHT));
2996 newTopFrame.setVisible(true);
2997 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2998 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2999 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
3000 AlignFrame.DEFAULT_HEIGHT));
3001 newBottomFrame.setVisible(true);
3002 topPanel.av.setGatherViewsHere(false);
3003 bottomPanel.av.setGatherViewsHere(false);
3004 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3006 // either panel may hold previous exploded frame geometry
3007 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3008 .getExplodedGeometry();
3009 if (geometry != null)
3011 splitFrame.setBounds(geometry);
3013 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3017 * Clear references to the panels (now relocated in the new SplitFrames)
3018 * before closing the old SplitFrame.
3021 bottomPanels.clear();
3026 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3027 * back into the given SplitFrame as additional views. Note that the gathered
3028 * frames may themselves have multiple views.
3032 public void gatherViews(GSplitFrame source)
3034 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3035 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3036 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3037 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3038 myTopFrame.viewport.setGatherViewsHere(true);
3039 myBottomFrame.viewport.setGatherViewsHere(true);
3040 String topViewId = myTopFrame.viewport.getSequenceSetId();
3041 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3043 JInternalFrame[] frames = desktop.getAllFrames();
3044 for (JInternalFrame frame : frames)
3046 if (frame instanceof SplitFrame && frame != source)
3048 SplitFrame sf = (SplitFrame) frame;
3049 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3050 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3051 boolean gatherThis = false;
3052 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3054 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3055 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3056 if (topViewId.equals(topPanel.av.getSequenceSetId())
3057 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3060 topPanel.av.setGatherViewsHere(false);
3061 bottomPanel.av.setGatherViewsHere(false);
3062 // both panels refer to the same split frame geometry
3063 Rectangle position = sf.getBounds();
3064 topPanel.av.setExplodedGeometry(position);
3065 bottomPanel.av.setExplodedGeometry(position);
3066 myTopFrame.addAlignmentPanel(topPanel, false);
3067 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3073 topFrame.getAlignPanels().clear();
3074 bottomFrame.getAlignPanels().clear();
3081 * The dust settles...give focus to the tab we did this from.
3083 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3087 public static AlignFrame getCurrentAlignFrame()
3089 return currentAlignFrame;
3092 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3094 Desktop.currentAlignFrame = currentAlignFrame;
3097 public static ColourSchemeI getCurrentGlobalColourScheme()
3099 return currentGlobalColourScheme;
3102 public static void setCurrentGlobalColourScheme(
3103 ColourSchemeI currentGlobalColourScheme)
3105 Desktop.currentGlobalColourScheme = currentGlobalColourScheme;