2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
3 * Copyright (C) 2015 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.bin.Cache;
26 import jalview.bin.Jalview;
27 import jalview.io.FileLoader;
28 import jalview.io.FormatAdapter;
29 import jalview.io.IdentifyFile;
30 import jalview.io.JalviewFileChooser;
31 import jalview.io.JalviewFileView;
32 import jalview.jbgui.GSplitFrame;
33 import jalview.jbgui.GStructureViewer;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.util.ImageMaker;
36 import jalview.util.MessageManager;
37 import jalview.util.Platform;
38 import jalview.viewmodel.AlignmentViewport;
39 import jalview.ws.params.ParamManager;
41 import java.awt.BorderLayout;
42 import java.awt.Color;
43 import java.awt.Dimension;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.GridLayout;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.Toolkit;
50 import java.awt.datatransfer.Clipboard;
51 import java.awt.datatransfer.ClipboardOwner;
52 import java.awt.datatransfer.DataFlavor;
53 import java.awt.datatransfer.Transferable;
54 import java.awt.dnd.DnDConstants;
55 import java.awt.dnd.DropTargetDragEvent;
56 import java.awt.dnd.DropTargetDropEvent;
57 import java.awt.dnd.DropTargetEvent;
58 import java.awt.dnd.DropTargetListener;
59 import java.awt.event.ActionEvent;
60 import java.awt.event.ActionListener;
61 import java.awt.event.FocusEvent;
62 import java.awt.event.FocusListener;
63 import java.awt.event.MouseAdapter;
64 import java.awt.event.MouseEvent;
65 import java.awt.event.MouseListener;
66 import java.awt.event.WindowAdapter;
67 import java.awt.event.WindowEvent;
68 import java.beans.PropertyChangeEvent;
69 import java.beans.PropertyChangeListener;
70 import java.beans.PropertyVetoException;
71 import java.io.BufferedInputStream;
73 import java.io.FileOutputStream;
74 import java.lang.reflect.Constructor;
76 import java.util.ArrayList;
77 import java.util.Hashtable;
78 import java.util.List;
79 import java.util.StringTokenizer;
80 import java.util.Vector;
81 import java.util.concurrent.ExecutorService;
82 import java.util.concurrent.Executors;
83 import java.util.concurrent.Semaphore;
85 import javax.swing.DefaultDesktopManager;
86 import javax.swing.DesktopManager;
87 import javax.swing.JButton;
88 import javax.swing.JComboBox;
89 import javax.swing.JComponent;
90 import javax.swing.JDesktopPane;
91 import javax.swing.JFrame;
92 import javax.swing.JInternalFrame;
93 import javax.swing.JLabel;
94 import javax.swing.JMenuItem;
95 import javax.swing.JOptionPane;
96 import javax.swing.JPanel;
97 import javax.swing.JPopupMenu;
98 import javax.swing.JProgressBar;
99 import javax.swing.SwingUtilities;
100 import javax.swing.event.HyperlinkEvent;
101 import javax.swing.event.HyperlinkEvent.EventType;
102 import javax.swing.event.MenuEvent;
103 import javax.swing.event.MenuListener;
110 * @version $Revision: 1.155 $
112 public class Desktop extends jalview.jbgui.GDesktop implements
113 DropTargetListener, ClipboardOwner, IProgressIndicator,
114 jalview.api.StructureSelectionManagerProvider
117 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
120 * news reader - null if it was never started.
122 private BlogReader jvnews = null;
124 private File projectFile;
128 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
130 public void addJalviewPropertyChangeListener(
131 PropertyChangeListener listener)
133 changeSupport.addJalviewPropertyChangeListener(listener);
137 * @param propertyName
139 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
140 * java.beans.PropertyChangeListener)
142 public void addJalviewPropertyChangeListener(String propertyName,
143 PropertyChangeListener listener)
145 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
149 * @param propertyName
151 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
152 * java.beans.PropertyChangeListener)
154 public void removeJalviewPropertyChangeListener(String propertyName,
155 PropertyChangeListener listener)
157 changeSupport.removeJalviewPropertyChangeListener(propertyName,
161 /** Singleton Desktop instance */
162 public static Desktop instance;
164 public static MyDesktopPane desktop;
166 static int openFrameCount = 0;
168 static final int xOffset = 30;
170 static final int yOffset = 30;
172 private static AlignFrame currentAlignFrame;
174 public static jalview.ws.jws1.Discoverer discoverer;
176 public static Object[] jalviewClipboard;
178 public static boolean internalCopy = false;
180 static int fileLoadingCount = 0;
182 class MyDesktopManager implements DesktopManager
185 private DesktopManager delegate;
187 public MyDesktopManager(DesktopManager delegate)
189 this.delegate = delegate;
192 public void activateFrame(JInternalFrame f)
196 delegate.activateFrame(f);
197 } catch (NullPointerException npe)
199 Point p = getMousePosition();
200 instance.showPasteMenu(p.x, p.y);
204 public void beginDraggingFrame(JComponent f)
206 delegate.beginDraggingFrame(f);
209 public void beginResizingFrame(JComponent f, int direction)
211 delegate.beginResizingFrame(f, direction);
214 public void closeFrame(JInternalFrame f)
216 delegate.closeFrame(f);
219 public void deactivateFrame(JInternalFrame f)
221 delegate.deactivateFrame(f);
224 public void deiconifyFrame(JInternalFrame f)
226 delegate.deiconifyFrame(f);
229 public void dragFrame(JComponent f, int newX, int newY)
235 delegate.dragFrame(f, newX, newY);
238 public void endDraggingFrame(JComponent f)
240 delegate.endDraggingFrame(f);
243 public void endResizingFrame(JComponent f)
245 delegate.endResizingFrame(f);
248 public void iconifyFrame(JInternalFrame f)
250 delegate.iconifyFrame(f);
253 public void maximizeFrame(JInternalFrame f)
255 delegate.maximizeFrame(f);
258 public void minimizeFrame(JInternalFrame f)
260 delegate.minimizeFrame(f);
263 public void openFrame(JInternalFrame f)
265 delegate.openFrame(f);
269 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
276 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
279 public void setBoundsForFrame(JComponent f, int newX, int newY,
280 int newWidth, int newHeight)
282 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
285 // All other methods, simply delegate
290 * Creates a new Desktop object.
295 * A note to implementors. It is ESSENTIAL that any activities that might
296 * block are spawned off as threads rather than waited for during this
300 doVamsasClientCheck();
302 doConfigureStructurePrefs();
303 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
304 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
305 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
307 boolean showjconsole = jalview.bin.Cache.getDefault(
308 "SHOW_JAVA_CONSOLE", false);
309 desktop = new MyDesktopPane(selmemusage);
310 if (Platform.isAMac())
312 desktop.setDoubleBuffered(false);
314 showMemusage.setSelected(selmemusage);
315 desktop.setBackground(Color.white);
316 getContentPane().setLayout(new BorderLayout());
317 // alternate config - have scrollbars - see notes in JAL-153
318 // JScrollPane sp = new JScrollPane();
319 // sp.getViewport().setView(desktop);
320 // getContentPane().add(sp, BorderLayout.CENTER);
321 getContentPane().add(desktop, BorderLayout.CENTER);
322 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
324 // This line prevents Windows Look&Feel resizing all new windows to maximum
325 // if previous window was maximised
326 desktop.setDesktopManager(new MyDesktopManager(
327 new DefaultDesktopManager()));
329 Rectangle dims = getLastKnownDimensions("");
336 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
337 setBounds((screenSize.width - 900) / 2,
338 (screenSize.height - 650) / 2, 900, 650);
340 jconsole = new Console(this, showjconsole);
341 // add essential build information
342 jconsole.setHeader("Jalview Version: "
343 + jalview.bin.Cache.getProperty("VERSION") + "\n"
344 + "Jalview Installation: "
345 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
346 + "\n" + "Build Date: "
347 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
348 + "Java version: " + System.getProperty("java.version") + "\n"
349 + System.getProperty("os.arch") + " "
350 + System.getProperty("os.name") + " "
351 + System.getProperty("os.version"));
353 showConsole(showjconsole);
355 showNews.setVisible(false);
357 this.addWindowListener(new WindowAdapter()
359 public void windowClosing(WindowEvent evt)
366 this.addMouseListener(ma = new MouseAdapter()
368 public void mousePressed(MouseEvent evt)
370 if (SwingUtilities.isRightMouseButton(evt))
372 showPasteMenu(evt.getX(), evt.getY());
376 desktop.addMouseListener(ma);
378 this.addFocusListener(new FocusListener()
382 public void focusLost(FocusEvent e)
384 // TODO Auto-generated method stub
389 public void focusGained(FocusEvent e)
391 Cache.log.debug("Relaying windows after focus gain");
392 // make sure that we sort windows properly after we gain focus
393 instance.relayerWindows();
396 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
397 // Spawn a thread that shows the splashscreen
398 SwingUtilities.invokeLater(new Runnable()
407 // Thread off a new instance of the file chooser - this reduces the time it
408 // takes to open it later on.
409 new Thread(new Runnable()
413 Cache.log.debug("Filechooser init thread started.");
414 new JalviewFileChooser(
415 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
416 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
417 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
418 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
419 Cache.log.debug("Filechooser init thread finished.");
422 // Add the service change listener
423 changeSupport.addJalviewPropertyChangeListener("services",
424 new PropertyChangeListener()
428 public void propertyChange(PropertyChangeEvent evt)
430 Cache.log.debug("Firing service changed event for "
431 + evt.getNewValue());
432 JalviewServicesChanged(evt);
438 public void doConfigureStructurePrefs()
440 // configure services
441 StructureSelectionManager ssm = StructureSelectionManager
442 .getStructureSelectionManager(this);
443 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
445 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
446 Preferences.ADD_TEMPFACT_ANN, true));
447 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
448 Preferences.STRUCT_FROM_PDB, true));
449 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
450 Preferences.USE_RNAVIEW, true));
454 ssm.setAddTempFacAnnot(false);
455 ssm.setProcessSecondaryStructure(false);
456 ssm.setSecStructServices(false);
460 public void checkForNews()
462 final Desktop me = this;
463 // Thread off the news reader, in case there are connection problems.
464 addDialogThread(new Runnable()
469 Cache.log.debug("Starting news thread.");
471 jvnews = new BlogReader(me);
472 showNews.setVisible(true);
473 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 now = System.currentTimeMillis();
497 Desktop.instance.setProgressBar(
498 MessageManager.getString("status.refreshing_news"), now);
499 jvnews.refreshNews();
500 Desktop.instance.setProgressBar(null, now);
509 * recover the last known dimensions for a jalview window
512 * - empty string is desktop, all other windows have unique prefix
513 * @return null or last known dimensions scaled to current geometry (if last
514 * window geom was known)
516 Rectangle getLastKnownDimensions(String windowName)
518 // TODO: lock aspect ratio for scaling desktop Bug #0058199
519 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
520 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
521 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
522 String width = jalview.bin.Cache.getProperty(windowName
524 String height = jalview.bin.Cache.getProperty(windowName
526 if ((x != null) && (y != null) && (width != null) && (height != null))
528 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
529 .parseInt(width), ih = Integer.parseInt(height);
530 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
532 // attempt #1 - try to cope with change in screen geometry - this
533 // version doesn't preserve original jv aspect ratio.
534 // take ratio of current screen size vs original screen size.
535 double sw = ((1f * screenSize.width) / (1f * Integer
536 .parseInt(jalview.bin.Cache
537 .getProperty("SCREENGEOMETRY_WIDTH"))));
538 double sh = ((1f * screenSize.height) / (1f * Integer
539 .parseInt(jalview.bin.Cache
540 .getProperty("SCREENGEOMETRY_HEIGHT"))));
541 // rescale the bounds depending upon the current screen geometry.
542 ix = (int) (ix * sw);
543 iw = (int) (iw * sw);
544 iy = (int) (iy * sh);
545 ih = (int) (ih * sh);
546 while (ix >= screenSize.width)
548 jalview.bin.Cache.log
549 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
550 ix -= screenSize.width;
552 while (iy >= screenSize.height)
554 jalview.bin.Cache.log
555 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
556 iy -= screenSize.height;
558 jalview.bin.Cache.log.debug("Got last known dimensions for "
559 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
562 // return dimensions for new instance
563 return new Rectangle(ix, iy, iw, ih);
568 private void doVamsasClientCheck()
570 if (jalview.bin.Cache.vamsasJarsPresent())
572 setupVamsasDisconnectedGui();
573 VamsasMenu.setVisible(true);
574 final Desktop us = this;
575 VamsasMenu.addMenuListener(new MenuListener()
577 // this listener remembers when the menu was first selected, and
578 // doesn't rebuild the session list until it has been cleared and
580 boolean refresh = true;
582 public void menuCanceled(MenuEvent e)
587 public void menuDeselected(MenuEvent e)
592 public void menuSelected(MenuEvent e)
596 us.buildVamsasStMenu();
601 vamsasStart.setVisible(true);
605 void showPasteMenu(int x, int y)
607 JPopupMenu popup = new JPopupMenu();
608 JMenuItem item = new JMenuItem(
609 MessageManager.getString("label.paste_new_window"));
610 item.addActionListener(new ActionListener()
612 public void actionPerformed(ActionEvent evt)
619 popup.show(this, x, y);
626 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
627 Transferable contents = c.getContents(this);
629 if (contents != null)
631 String file = (String) contents
632 .getTransferData(DataFlavor.stringFlavor);
634 String format = new IdentifyFile().Identify(file,
635 FormatAdapter.PASTE);
637 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
640 } catch (Exception ex)
643 .println("Unable to paste alignment from system clipboard:\n"
649 * Adds and opens the given frame to the desktop
660 public static synchronized void addInternalFrame(
661 final JInternalFrame frame, String title, int w, int h)
663 addInternalFrame(frame, title, true, w, h, true);
667 * Add an internal frame to the Jalview desktop
674 * When true, display frame immediately, otherwise, caller must call
675 * setVisible themselves.
681 public static synchronized void addInternalFrame(
682 final JInternalFrame frame, String title, boolean makeVisible,
685 addInternalFrame(frame, title, makeVisible, w, h, true);
689 * Add an internal frame to the Jalview desktop and make it visible
702 public static synchronized void addInternalFrame(
703 final JInternalFrame frame, String title, int w, int h,
706 addInternalFrame(frame, title, true, w, h, resizable);
710 * Add an internal frame to the Jalview desktop
717 * When true, display frame immediately, otherwise, caller must call
718 * setVisible themselves.
726 public static synchronized void addInternalFrame(
727 final JInternalFrame frame, String title, boolean makeVisible,
728 int w, int h, boolean resizable)
731 // TODO: allow callers to determine X and Y position of frame (eg. via
733 // TODO: consider fixing method to update entries in the window submenu with
734 // the current window title
736 frame.setTitle(title);
737 if (frame.getWidth() < 1 || frame.getHeight() < 1)
741 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
742 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
743 // IF JALVIEW IS RUNNING HEADLESS
744 // ///////////////////////////////////////////////
746 || (System.getProperty("java.awt.headless") != null && System
747 .getProperty("java.awt.headless").equals("true")))
754 frame.setVisible(makeVisible);
755 frame.setClosable(true);
756 frame.setResizable(resizable);
757 frame.setMaximizable(resizable);
758 frame.setIconifiable(resizable);
759 if (Platform.isAMac())
761 frame.setIconifiable(false);
762 frame.setFrameIcon(null);
763 // frame.setDesktopIcon(null);
764 frame.setDoubleBuffered(false);
766 if (frame.getX() < 1 && frame.getY() < 1)
768 frame.setLocation(xOffset * openFrameCount, yOffset
769 * ((openFrameCount - 1) % 10) + yOffset);
772 final JMenuItem menuItem = new JMenuItem(title);
773 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
775 public void internalFrameActivated(
776 javax.swing.event.InternalFrameEvent evt)
778 JInternalFrame itf = desktop.getSelectedFrame();
786 public void internalFrameClosed(
787 javax.swing.event.InternalFrameEvent evt)
789 PaintRefresher.RemoveComponent(frame);
791 windowMenu.remove(menuItem);
792 JInternalFrame itf = desktop.getSelectedFrame();
801 menuItem.addActionListener(new ActionListener()
803 public void actionPerformed(ActionEvent e)
807 frame.setSelected(true);
808 frame.setIcon(false);
809 } catch (java.beans.PropertyVetoException ex)
815 menuItem.addMouseListener(new MouseListener()
819 public void mouseReleased(MouseEvent e)
824 public void mousePressed(MouseEvent e)
829 public void mouseExited(MouseEvent e)
833 frame.setSelected(false);
834 } catch (PropertyVetoException e1)
840 public void mouseEntered(MouseEvent e)
844 frame.setSelected(true);
845 } catch (PropertyVetoException e1)
851 public void mouseClicked(MouseEvent e)
857 windowMenu.add(menuItem);
863 frame.setSelected(true);
864 frame.requestFocus();
865 } catch (java.beans.PropertyVetoException ve)
867 } catch (java.lang.ClassCastException cex)
870 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
875 public void lostOwnership(Clipboard clipboard, Transferable contents)
879 Desktop.jalviewClipboard = null;
882 internalCopy = false;
885 public void dragEnter(DropTargetDragEvent evt)
889 public void dragExit(DropTargetEvent evt)
893 public void dragOver(DropTargetDragEvent evt)
898 public void dropActionChanged(DropTargetDragEvent evt)
908 public void drop(DropTargetDropEvent evt)
910 boolean success = true;
911 Transferable t = evt.getTransferable();
912 java.util.List files = null;
913 java.util.List protocols = null;
917 DataFlavor uriListFlavor = new DataFlavor(
918 "text/uri-list;class=java.lang.String");
919 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
921 // Works on Windows and MacOSX
922 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
923 files = (java.util.List) t
924 .getTransferData(DataFlavor.javaFileListFlavor);
926 else if (t.isDataFlavorSupported(uriListFlavor))
928 // This is used by Unix drag system
929 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
930 String data = (String) t.getTransferData(uriListFlavor);
931 files = new java.util.ArrayList(1);
932 protocols = new java.util.ArrayList(1);
933 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
934 data, "\r\n"); st.hasMoreTokens();)
936 String s = st.nextToken();
937 if (s.startsWith("#"))
939 // the line is a comment (as per the RFC 2483)
942 java.net.URI uri = new java.net.URI(s);
943 if (uri.getScheme().toLowerCase().startsWith("http"))
945 protocols.add(FormatAdapter.URL);
946 files.add(uri.toString());
950 // otherwise preserve old behaviour: catch all for file objects
951 java.io.File file = new java.io.File(uri);
952 protocols.add(FormatAdapter.FILE);
953 files.add(file.toString());
957 } catch (Exception e)
966 for (int i = 0; i < files.size(); i++)
968 String file = files.get(i).toString();
969 String protocol = (protocols == null) ? FormatAdapter.FILE
970 : (String) protocols.get(i);
971 String format = null;
973 if (file.endsWith(".jar"))
980 format = new IdentifyFile().Identify(file, protocol);
983 new FileLoader().LoadFile(file, protocol, format);
986 } catch (Exception ex)
991 evt.dropComplete(success); // need this to ensure input focus is properly
992 // transfered to any new windows created
1002 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1004 JalviewFileChooser chooser = new JalviewFileChooser(
1005 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1006 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1007 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1008 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1010 chooser.setFileView(new JalviewFileView());
1011 chooser.setDialogTitle(MessageManager
1012 .getString("label.open_local_file"));
1013 chooser.setToolTipText(MessageManager.getString("action.open"));
1015 int value = chooser.showOpenDialog(this);
1017 if (value == JalviewFileChooser.APPROVE_OPTION)
1019 String choice = chooser.getSelectedFile().getPath();
1020 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1021 .getSelectedFile().getParent());
1023 String format = null;
1024 if (chooser.getSelectedFormat() != null
1025 && chooser.getSelectedFormat().equals("Jalview"))
1031 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1034 if (viewport != null)
1036 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1038 // viewport.setShowSequenceFeatures(JSONFile.isSeqFeaturesEnabled());
1039 // AlignFrame af = viewport.getAlignPanel().alignFrame;
1042 // af.changeColour(JSONFile.getColourScheme());
1043 // af.setMenusForViewport();
1048 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1060 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1062 // This construct allows us to have a wider textfield
1064 JLabel label = new JLabel(
1065 MessageManager.getString("label.input_file_url"));
1066 final JComboBox history = new JComboBox();
1068 JPanel panel = new JPanel(new GridLayout(2, 1));
1071 history.setPreferredSize(new Dimension(400, 20));
1072 history.setEditable(true);
1073 history.addItem("http://www.");
1075 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1079 if (historyItems != null)
1081 st = new StringTokenizer(historyItems, "\t");
1083 while (st.hasMoreTokens())
1085 history.addItem(st.nextElement());
1089 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1090 MessageManager.getString("label.input_alignment_from_url"),
1091 JOptionPane.OK_CANCEL_OPTION);
1093 if (reply != JOptionPane.OK_OPTION)
1098 String url = history.getSelectedItem().toString();
1100 if (url.toLowerCase().endsWith(".jar"))
1102 if (viewport != null)
1104 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1109 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1114 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1116 if (format.equals("URL NOT FOUND"))
1118 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1119 MessageManager.formatMessage("label.couldnt_locate",
1120 new Object[] { url }), MessageManager
1121 .getString("label.url_not_found"),
1122 JOptionPane.WARNING_MESSAGE);
1127 if (viewport != null)
1129 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1133 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1139 * Opens the CutAndPaste window for the user to paste an alignment in to
1142 * - if not null, the pasted alignment is added to the current
1143 * alignment; if null, to a new alignment window
1146 public void inputTextboxMenuItem_actionPerformed(
1147 AlignmentViewPanel viewPanel)
1149 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1150 cap.setForInput(viewPanel);
1151 Desktop.addInternalFrame(cap,
1152 MessageManager.getString("label.cut_paste_alignmen_file"),
1162 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1164 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1165 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1167 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1168 getBounds().y, getWidth(), getHeight()));
1170 if (jconsole != null)
1172 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1173 jconsole.stopConsole();
1177 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1180 if (dialogExecutor != null)
1182 dialogExecutor.shutdownNow();
1184 closeAll_actionPerformed(null);
1188 private void storeLastKnownDimensions(String string, Rectangle jc)
1190 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1191 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1192 + " height:" + jc.height);
1194 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1195 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1196 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1197 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1207 public void aboutMenuItem_actionPerformed(ActionEvent e)
1209 // StringBuffer message = getAboutMessage(false);
1210 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1212 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1213 new Thread(new Runnable()
1217 new SplashScreen(true);
1222 public StringBuffer getAboutMessage(boolean shortv)
1224 StringBuffer message = new StringBuffer();
1225 message.append("<html>");
1228 message.append("<h1><strong>Version: "
1229 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1230 message.append("<strong>Last Updated: <em>"
1231 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1232 + "</em></strong>");
1238 message.append("<strong>Version "
1239 + jalview.bin.Cache.getProperty("VERSION")
1240 + "; last updated: "
1241 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1244 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1247 message.append("<br>...Checking latest version...</br>");
1249 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1250 .equals(jalview.bin.Cache.getProperty("VERSION")))
1252 boolean red = false;
1253 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1254 .indexOf("automated build") == -1)
1257 // Displayed when code version and jnlp version do not match and code
1258 // version is not a development build
1259 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1262 message.append("<br>!! Version "
1263 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1265 + " is available for download from "
1266 + jalview.bin.Cache.getDefault("www.jalview.org",
1267 "http://www.jalview.org") + " !!");
1270 message.append("</div>");
1273 message.append("<br>Authors: "
1275 .getDefault("AUTHORFNAMES",
1276 "The Jalview Authors (See AUTHORS file for current list)")
1277 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1278 + "<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"
1279 + "<br><br>If you use Jalview, please cite:"
1280 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1281 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1282 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1294 public void documentationMenuItem_actionPerformed(ActionEvent e)
1298 Help.showHelpWindow();
1299 } catch (Exception ex)
1305 public void closeAll_actionPerformed(ActionEvent e)
1307 JInternalFrame[] frames = desktop.getAllFrames();
1308 for (int i = 0; i < frames.length; i++)
1312 frames[i].setClosed(true);
1313 } catch (java.beans.PropertyVetoException ex)
1317 System.out.println("ALL CLOSED");
1318 if (v_client != null)
1320 // TODO clear binding to vamsas document objects on close_all
1324 * reset state of singleton objects as appropriate (clear down session state
1325 * when all windows are closed)
1327 StructureSelectionManager ssm = StructureSelectionManager
1328 .getStructureSelectionManager(this);
1336 public void raiseRelated_actionPerformed(ActionEvent e)
1338 reorderAssociatedWindows(false, false);
1342 public void minimizeAssociated_actionPerformed(ActionEvent e)
1344 reorderAssociatedWindows(true, false);
1347 void closeAssociatedWindows()
1349 reorderAssociatedWindows(false, true);
1355 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1359 protected void garbageCollect_actionPerformed(ActionEvent e)
1361 // We simply collect the garbage
1362 jalview.bin.Cache.log.debug("Collecting garbage...");
1364 jalview.bin.Cache.log.debug("Finished garbage collection.");
1371 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1375 protected void showMemusage_actionPerformed(ActionEvent e)
1377 desktop.showMemoryUsage(showMemusage.isSelected());
1384 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1388 protected void showConsole_actionPerformed(ActionEvent e)
1390 showConsole(showConsole.isSelected());
1393 Console jconsole = null;
1396 * control whether the java console is visible or not
1400 void showConsole(boolean selected)
1402 showConsole.setSelected(selected);
1403 // TODO: decide if we should update properties file
1404 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1406 jconsole.setVisible(selected);
1409 void reorderAssociatedWindows(boolean minimize, boolean close)
1411 JInternalFrame[] frames = desktop.getAllFrames();
1412 if (frames == null || frames.length < 1)
1417 AlignmentViewport source = null, target = null;
1418 if (frames[0] instanceof AlignFrame)
1420 source = ((AlignFrame) frames[0]).getCurrentView();
1422 else if (frames[0] instanceof TreePanel)
1424 source = ((TreePanel) frames[0]).getViewPort();
1426 else if (frames[0] instanceof PCAPanel)
1428 source = ((PCAPanel) frames[0]).av;
1430 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1432 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1437 for (int i = 0; i < frames.length; i++)
1440 if (frames[i] == null)
1444 if (frames[i] instanceof AlignFrame)
1446 target = ((AlignFrame) frames[i]).getCurrentView();
1448 else if (frames[i] instanceof TreePanel)
1450 target = ((TreePanel) frames[i]).getViewPort();
1452 else if (frames[i] instanceof PCAPanel)
1454 target = ((PCAPanel) frames[i]).av;
1456 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1458 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1461 if (source == target)
1467 frames[i].setClosed(true);
1471 frames[i].setIcon(minimize);
1474 frames[i].toFront();
1478 } catch (java.beans.PropertyVetoException ex)
1493 protected void preferences_actionPerformed(ActionEvent e)
1505 public void saveState_actionPerformed(ActionEvent e)
1507 JalviewFileChooser chooser = new JalviewFileChooser(
1508 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1509 new String[] { "jvp" }, new String[] { "Jalview Project" },
1512 chooser.setFileView(new JalviewFileView());
1513 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1515 int value = chooser.showSaveDialog(this);
1517 if (value == JalviewFileChooser.APPROVE_OPTION)
1519 final Desktop me = this;
1520 final java.io.File choice = chooser.getSelectedFile();
1521 setProjectFile(choice);
1523 new Thread(new Runnable()
1527 // TODO: refactor to Jalview desktop session controller action.
1528 setProgressBar(MessageManager.formatMessage(
1529 "label.saving_jalview_project",
1530 new Object[] { choice.getName() }), choice.hashCode());
1531 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1532 choice.getParent());
1533 // TODO catch and handle errors for savestate
1534 // TODO prevent user from messing with the Desktop whilst we're saving
1537 new Jalview2XML().saveState(choice);
1538 } catch (OutOfMemoryError oom)
1540 new OOMWarning("Whilst saving current state to "
1541 + choice.getName(), oom);
1542 } catch (Exception ex)
1545 "Problems whilst trying to save to " + choice.getName(),
1547 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1548 "label.error_whilst_saving_current_state_to",
1549 new Object[] { choice.getName() }), MessageManager
1550 .getString("label.couldnt_save_project"),
1551 JOptionPane.WARNING_MESSAGE);
1553 setProgressBar(null, choice.hashCode());
1559 private void setProjectFile(File choice)
1561 this.projectFile = choice;
1564 public File getProjectFile()
1566 return this.projectFile;
1576 public void loadState_actionPerformed(ActionEvent e)
1578 JalviewFileChooser chooser = new JalviewFileChooser(
1579 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1580 "jvp", "jar" }, new String[] { "Jalview Project",
1581 "Jalview Project (old)" }, "Jalview Project");
1582 chooser.setFileView(new JalviewFileView());
1583 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1585 int value = chooser.showOpenDialog(this);
1587 if (value == JalviewFileChooser.APPROVE_OPTION)
1589 final File selectedFile = chooser.getSelectedFile();
1590 setProjectFile(selectedFile);
1591 final String choice = selectedFile.getAbsolutePath();
1592 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1593 selectedFile.getParent());
1594 new Thread(new Runnable()
1599 MessageManager.formatMessage(
1600 "label.loading_jalview_project",
1601 new Object[] { choice }), choice.hashCode());
1604 new Jalview2XML().loadJalviewAlign(choice);
1605 } catch (OutOfMemoryError oom)
1607 new OOMWarning("Whilst loading project from " + choice, oom);
1608 } catch (Exception ex)
1610 Cache.log.error("Problems whilst loading project from "
1612 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1614 "label.error_whilst_loading_project_from",
1615 new Object[] { choice }), MessageManager
1616 .getString("label.couldnt_load_project"),
1617 JOptionPane.WARNING_MESSAGE);
1619 setProgressBar(null, choice.hashCode());
1626 public void inputSequence_actionPerformed(ActionEvent e)
1628 new SequenceFetcher(this);
1631 JPanel progressPanel;
1633 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1635 public void startLoading(final String fileName)
1637 if (fileLoadingCount == 0)
1639 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1640 "label.loading_file", new Object[] { fileName })));
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
1735 || alignmentId.equals(ap.av.getSequenceSetId()))
1741 if (aps.size() == 0)
1745 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1750 * get all the viewports on an alignment.
1752 * @param sequenceSetId
1753 * unique alignment id (may be null - all viewports returned in that
1755 * @return all viewports on the alignment bound to sequenceSetId
1757 public static AlignmentViewport[] getViewports(String sequenceSetId)
1759 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1760 if (desktop != null)
1762 AlignFrame[] frames = Desktop.getAlignFrames();
1764 for (AlignFrame afr : frames)
1766 if (sequenceSetId == null
1767 || afr.getViewport().getSequenceSetId()
1768 .equals(sequenceSetId))
1770 if (afr.alignPanels != null)
1772 for (AlignmentPanel ap : afr.alignPanels)
1774 if (sequenceSetId == null
1775 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1783 viewp.add(afr.getViewport());
1787 if (viewp.size() > 0)
1789 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1796 * Explode the views in the given frame into separate AlignFrame
1800 public void explodeViews(AlignFrame af)
1802 int size = af.alignPanels.size();
1808 for (int i = 0; i < size; i++)
1810 AlignmentPanel ap = af.alignPanels.get(i);
1811 AlignFrame newaf = new AlignFrame(ap);
1814 * Restore the view's last exploded frame geometry if known. Multiple
1815 * views from one exploded frame share and restore the same (frame)
1816 * position and size.
1818 Rectangle geometry = ap.av.getExplodedGeometry();
1819 if (geometry != null)
1821 newaf.setBounds(geometry);
1824 ap.av.setGatherViewsHere(false);
1826 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1827 AlignFrame.DEFAULT_HEIGHT);
1830 af.alignPanels.clear();
1831 af.closeMenuItem_actionPerformed(true);
1836 * Gather expanded views (separate AlignFrame's) with the same sequence set
1837 * identifier back in to this frame as additional views, and close the
1838 * expanded views. Note the expanded frames may themselves have multiple
1839 * views. We take the lot.
1843 public void gatherViews(AlignFrame source)
1845 source.viewport.setGatherViewsHere(true);
1846 source.viewport.setExplodedGeometry(source.getBounds());
1847 JInternalFrame[] frames = desktop.getAllFrames();
1848 String viewId = source.viewport.getSequenceSetId();
1850 for (int t = 0; t < frames.length; t++)
1852 if (frames[t] instanceof AlignFrame && frames[t] != source)
1854 AlignFrame af = (AlignFrame) frames[t];
1855 boolean gatherThis = false;
1856 for (int a = 0; a < af.alignPanels.size(); a++)
1858 AlignmentPanel ap = af.alignPanels.get(a);
1859 if (viewId.equals(ap.av.getSequenceSetId()))
1862 ap.av.setGatherViewsHere(false);
1863 ap.av.setExplodedGeometry(af.getBounds());
1864 source.addAlignmentPanel(ap, false);
1870 af.alignPanels.clear();
1871 af.closeMenuItem_actionPerformed(true);
1878 jalview.gui.VamsasApplication v_client = null;
1881 public void vamsasImport_actionPerformed(ActionEvent e)
1883 if (v_client == null)
1885 // Load and try to start a session.
1886 JalviewFileChooser chooser = new JalviewFileChooser(
1887 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1889 chooser.setFileView(new JalviewFileView());
1890 chooser.setDialogTitle(MessageManager
1891 .getString("label.open_saved_vamsas_session"));
1892 chooser.setToolTipText(MessageManager
1893 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1895 int value = chooser.showOpenDialog(this);
1897 if (value == JalviewFileChooser.APPROVE_OPTION)
1899 String fle = chooser.getSelectedFile().toString();
1900 if (!vamsasImport(chooser.getSelectedFile()))
1903 .showInternalMessageDialog(
1905 MessageManager.formatMessage(
1906 "label.couldnt_import_as_vamsas_session",
1907 new Object[] { fle }),
1909 .getString("label.vamsas_document_import_failed"),
1910 JOptionPane.ERROR_MESSAGE);
1916 jalview.bin.Cache.log
1917 .error("Implementation error - load session from a running session is not supported.");
1922 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1925 * @return true if import was a success and a session was started.
1927 public boolean vamsasImport(URL url)
1929 // TODO: create progress bar
1930 if (v_client != null)
1933 jalview.bin.Cache.log
1934 .error("Implementation error - load session from a running session is not supported.");
1940 // copy the URL content to a temporary local file
1941 // TODO: be a bit cleverer here with nio (?!)
1942 File file = File.createTempFile("vdocfromurl", ".vdj");
1943 FileOutputStream fos = new FileOutputStream(file);
1944 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1945 byte[] buffer = new byte[2048];
1947 while ((ln = bis.read(buffer)) > -1)
1949 fos.write(buffer, 0, ln);
1953 v_client = new jalview.gui.VamsasApplication(this, file,
1954 url.toExternalForm());
1955 } catch (Exception ex)
1957 jalview.bin.Cache.log.error(
1958 "Failed to create new vamsas session from contents of URL "
1962 setupVamsasConnectedGui();
1963 v_client.initial_update(); // TODO: thread ?
1964 return v_client.inSession();
1968 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1971 * @return true if import was a success and a session was started.
1973 public boolean vamsasImport(File file)
1975 if (v_client != null)
1978 jalview.bin.Cache.log
1979 .error("Implementation error - load session from a running session is not supported.");
1983 setProgressBar(MessageManager.formatMessage(
1984 "status.importing_vamsas_session_from",
1985 new Object[] { file.getName() }), file.hashCode());
1988 v_client = new jalview.gui.VamsasApplication(this, file, null);
1989 } catch (Exception ex)
1991 setProgressBar(MessageManager.formatMessage(
1992 "status.importing_vamsas_session_from",
1993 new Object[] { file.getName() }), file.hashCode());
1994 jalview.bin.Cache.log.error(
1995 "New vamsas session from existing session file failed:", ex);
1998 setupVamsasConnectedGui();
1999 v_client.initial_update(); // TODO: thread ?
2000 setProgressBar(MessageManager.formatMessage(
2001 "status.importing_vamsas_session_from",
2002 new Object[] { file.getName() }), file.hashCode());
2003 return v_client.inSession();
2006 public boolean joinVamsasSession(String mysesid)
2008 if (v_client != null)
2012 .getString("error.try_join_vamsas_session_another"));
2014 if (mysesid == null)
2017 MessageManager.getString("error.invalid_vamsas_session_id"));
2019 v_client = new VamsasApplication(this, mysesid);
2020 setupVamsasConnectedGui();
2021 v_client.initial_update();
2022 return (v_client.inSession());
2026 public void vamsasStart_actionPerformed(ActionEvent e)
2028 if (v_client == null)
2031 // we just start a default session for moment.
2033 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2034 * getProperty("LAST_DIRECTORY"));
2036 * chooser.setFileView(new JalviewFileView());
2037 * chooser.setDialogTitle("Load Vamsas file");
2038 * chooser.setToolTipText("Import");
2040 * int value = chooser.showOpenDialog(this);
2042 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2043 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2045 v_client = new VamsasApplication(this);
2046 setupVamsasConnectedGui();
2047 v_client.initial_update(); // TODO: thread ?
2051 // store current data in session.
2052 v_client.push_update(); // TODO: thread
2056 protected void setupVamsasConnectedGui()
2058 vamsasStart.setText(MessageManager.getString("label.session_update"));
2059 vamsasSave.setVisible(true);
2060 vamsasStop.setVisible(true);
2061 vamsasImport.setVisible(false); // Document import to existing session is
2062 // not possible for vamsas-client-1.0.
2065 protected void setupVamsasDisconnectedGui()
2067 vamsasSave.setVisible(false);
2068 vamsasStop.setVisible(false);
2069 vamsasImport.setVisible(true);
2070 vamsasStart.setText(MessageManager
2071 .getString("label.new_vamsas_session"));
2075 public void vamsasStop_actionPerformed(ActionEvent e)
2077 if (v_client != null)
2079 v_client.end_session();
2081 setupVamsasDisconnectedGui();
2085 protected void buildVamsasStMenu()
2087 if (v_client == null)
2089 String[] sess = null;
2092 sess = VamsasApplication.getSessionList();
2093 } catch (Exception e)
2095 jalview.bin.Cache.log.warn(
2096 "Problem getting current sessions list.", e);
2101 jalview.bin.Cache.log.debug("Got current sessions list: "
2102 + sess.length + " entries.");
2103 VamsasStMenu.removeAll();
2104 for (int i = 0; i < sess.length; i++)
2106 JMenuItem sessit = new JMenuItem();
2107 sessit.setText(sess[i]);
2108 sessit.setToolTipText(MessageManager.formatMessage(
2109 "label.connect_to_session", new Object[] { sess[i] }));
2110 final Desktop dsktp = this;
2111 final String mysesid = sess[i];
2112 sessit.addActionListener(new ActionListener()
2115 public void actionPerformed(ActionEvent e)
2117 if (dsktp.v_client == null)
2119 Thread rthr = new Thread(new Runnable()
2124 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2125 dsktp.setupVamsasConnectedGui();
2126 dsktp.v_client.initial_update();
2134 VamsasStMenu.add(sessit);
2136 // don't show an empty menu.
2137 VamsasStMenu.setVisible(sess.length > 0);
2142 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2143 VamsasStMenu.removeAll();
2144 VamsasStMenu.setVisible(false);
2149 // Not interested in the content. Just hide ourselves.
2150 VamsasStMenu.setVisible(false);
2155 public void vamsasSave_actionPerformed(ActionEvent e)
2157 if (v_client != null)
2159 JalviewFileChooser chooser = new JalviewFileChooser(
2160 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2161 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2162 new String[] { "Vamsas Document" }, "Vamsas Document");
2164 chooser.setFileView(new JalviewFileView());
2165 chooser.setDialogTitle(MessageManager
2166 .getString("label.save_vamsas_document_archive"));
2168 int value = chooser.showSaveDialog(this);
2170 if (value == JalviewFileChooser.APPROVE_OPTION)
2172 java.io.File choice = chooser.getSelectedFile();
2173 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2174 "label.saving_vamsas_doc",
2175 new Object[] { choice.getName() }));
2176 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2177 String warnmsg = null;
2178 String warnttl = null;
2181 v_client.vclient.storeDocument(choice);
2184 warnttl = "Serious Problem saving Vamsas Document";
2185 warnmsg = ex.toString();
2186 jalview.bin.Cache.log.error("Error Whilst saving document to "
2189 } catch (Exception ex)
2191 warnttl = "Problem saving Vamsas Document.";
2192 warnmsg = ex.toString();
2193 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2197 removeProgressPanel(progpanel);
2198 if (warnmsg != null)
2200 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2202 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2208 JPanel vamUpdate = null;
2211 * hide vamsas user gui bits when a vamsas document event is being handled.
2214 * true to hide gui, false to reveal gui
2216 public void setVamsasUpdate(boolean b)
2218 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2219 + (b ? "in progress" : "finished"));
2221 if (vamUpdate != null)
2223 this.removeProgressPanel(vamUpdate);
2227 vamUpdate = this.addProgressPanel(MessageManager
2228 .getString("label.updating_vamsas_session"));
2230 vamsasStart.setVisible(!b);
2231 vamsasStop.setVisible(!b);
2232 vamsasSave.setVisible(!b);
2235 public JInternalFrame[] getAllFrames()
2237 return desktop.getAllFrames();
2241 * Checks the given url to see if it gives a response indicating that the user
2242 * should be informed of a new questionnaire.
2246 public void checkForQuestionnaire(String url)
2248 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2249 // javax.swing.SwingUtilities.invokeLater(jvq);
2250 new Thread(jvq).start();
2254 * Proxy class for JDesktopPane which optionally displays the current memory
2255 * usage and highlights the desktop area with a red bar if free memory runs
2260 public class MyDesktopPane extends JDesktopPane implements Runnable
2263 private static final float ONE_MB = 1048576f;
2265 boolean showMemoryUsage = false;
2269 java.text.NumberFormat df;
2271 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2274 public MyDesktopPane(boolean showMemoryUsage)
2276 showMemoryUsage(showMemoryUsage);
2279 public void showMemoryUsage(boolean showMemory)
2281 this.showMemoryUsage = showMemory;
2284 Thread worker = new Thread(this);
2289 public boolean isShowMemoryUsage()
2291 return showMemoryUsage;
2296 df = java.text.NumberFormat.getNumberInstance();
2297 df.setMaximumFractionDigits(2);
2298 runtime = Runtime.getRuntime();
2300 while (showMemoryUsage)
2304 maxMemory = runtime.maxMemory() / ONE_MB;
2305 allocatedMemory = runtime.totalMemory() / ONE_MB;
2306 freeMemory = runtime.freeMemory() / ONE_MB;
2307 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2309 percentUsage = (totalFreeMemory / maxMemory) * 100;
2311 // if (percentUsage < 20)
2313 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2315 // instance.set.setBorder(border1);
2318 // sleep after showing usage
2320 } catch (Exception ex)
2322 ex.printStackTrace();
2328 public void paintComponent(Graphics g)
2330 if (showMemoryUsage && g != null && df != null)
2332 if (percentUsage < 20)
2334 g.setColor(Color.red);
2336 FontMetrics fm = g.getFontMetrics();
2339 g.drawString(MessageManager.formatMessage(
2340 "label.memory_stats",
2341 new Object[] { df.format(totalFreeMemory),
2342 df.format(maxMemory), df.format(percentUsage) }), 10,
2343 getHeight() - fm.getHeight());
2350 * fixes stacking order after a modal dialog to ensure windows that should be
2351 * on top actually are
2353 public void relayerWindows()
2358 protected JMenuItem groovyShell;
2360 public void doGroovyCheck()
2362 if (jalview.bin.Cache.groovyJarsPresent())
2364 groovyShell = new JMenuItem();
2365 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2366 groovyShell.addActionListener(new ActionListener()
2368 public void actionPerformed(ActionEvent e)
2370 groovyShell_actionPerformed();
2373 toolsMenu.add(groovyShell);
2374 groovyShell.setVisible(true);
2379 * Accessor method to quickly get all the AlignmentFrames loaded.
2381 * @return an array of AlignFrame, or null if none found
2383 public static AlignFrame[] getAlignFrames()
2385 if (Jalview.isHeadlessMode())
2387 // Desktop.desktop is null in headless mode
2388 return new AlignFrame[] { currentAlignFrame };
2391 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2397 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2399 for (int i = frames.length - 1; i > -1; i--)
2401 if (frames[i] instanceof AlignFrame)
2403 avp.add((AlignFrame) frames[i]);
2405 else if (frames[i] instanceof SplitFrame)
2408 * Also check for a split frame containing an AlignFrame
2410 GSplitFrame sf = (GSplitFrame) frames[i];
2411 if (sf.getTopFrame() instanceof AlignFrame)
2413 avp.add((AlignFrame) sf.getTopFrame());
2415 if (sf.getBottomFrame() instanceof AlignFrame)
2417 avp.add((AlignFrame) sf.getBottomFrame());
2421 if (avp.size() == 0)
2425 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2430 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2434 public GStructureViewer[] getJmols()
2436 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2442 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2444 for (int i = frames.length - 1; i > -1; i--)
2446 if (frames[i] instanceof AppJmol)
2448 GStructureViewer af = (GStructureViewer) frames[i];
2452 if (avp.size() == 0)
2456 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2461 * Add Groovy Support to Jalview
2463 public void groovyShell_actionPerformed()
2465 // use reflection to avoid creating compilation dependency.
2466 if (!jalview.bin.Cache.groovyJarsPresent())
2470 .getString("error.implementation_error_cannot_create_groovyshell"));
2474 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2475 "groovy.ui.Console");
2476 Constructor<?> gccons = gcClass.getConstructor();
2477 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2478 new Class[] { String.class, Object.class });
2479 java.lang.reflect.Method run = gcClass.getMethod("run");
2480 Object gc = gccons.newInstance();
2481 setvar.invoke(gc, new Object[] { "Jalview", this });
2483 } catch (Exception ex)
2485 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2486 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2488 MessageManager.getString("label.couldnt_create_groovy_shell"),
2489 MessageManager.getString("label.groovy_support_failed"),
2490 JOptionPane.ERROR_MESSAGE);
2495 * Progress bars managed by the IProgressIndicator method.
2497 private Hashtable<Long, JPanel> progressBars;
2499 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2504 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2506 public void setProgressBar(String message, long id)
2508 if (progressBars == null)
2510 progressBars = new Hashtable<Long, JPanel>();
2511 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2514 if (progressBars.get(new Long(id)) != null)
2516 JPanel panel = progressBars.remove(new Long(id));
2517 if (progressBarHandlers.contains(new Long(id)))
2519 progressBarHandlers.remove(new Long(id));
2521 removeProgressPanel(panel);
2525 progressBars.put(new Long(id), addProgressPanel(message));
2532 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2533 * jalview.gui.IProgressIndicatorHandler)
2535 public void registerHandler(final long id,
2536 final IProgressIndicatorHandler handler)
2538 if (progressBarHandlers == null
2539 || !progressBars.containsKey(new Long(id)))
2543 .getString("error.call_setprogressbar_before_registering_handler"));
2545 progressBarHandlers.put(new Long(id), handler);
2546 final JPanel progressPanel = progressBars.get(new Long(id));
2547 if (handler.canCancel())
2549 JButton cancel = new JButton(
2550 MessageManager.getString("action.cancel"));
2551 final IProgressIndicator us = this;
2552 cancel.addActionListener(new ActionListener()
2555 public void actionPerformed(ActionEvent e)
2557 handler.cancelActivity(id);
2558 us.setProgressBar(MessageManager.formatMessage(
2559 "label.cancelled_params",
2560 new Object[] { ((JLabel) progressPanel.getComponent(0))
2564 progressPanel.add(cancel, BorderLayout.EAST);
2570 * @return true if any progress bars are still active
2573 public boolean operationInProgress()
2575 if (progressBars != null && progressBars.size() > 0)
2583 * This will return the first AlignFrame holding the given viewport instance.
2584 * It will break if there are more than one AlignFrames viewing a particular
2588 * @return alignFrame for viewport
2590 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2592 if (desktop != null)
2594 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2595 for (int panel = 0; aps != null && panel < aps.length; panel++)
2597 if (aps[panel] != null && aps[panel].av == viewport)
2599 return aps[panel].alignFrame;
2606 public VamsasApplication getVamsasApplication()
2613 * flag set if jalview GUI is being operated programmatically
2615 private boolean inBatchMode = false;
2618 * check if jalview GUI is being operated programmatically
2620 * @return inBatchMode
2622 public boolean isInBatchMode()
2628 * set flag if jalview GUI is being operated programmatically
2630 * @param inBatchMode
2632 public void setInBatchMode(boolean inBatchMode)
2634 this.inBatchMode = inBatchMode;
2637 public void startServiceDiscovery()
2639 startServiceDiscovery(false);
2642 public void startServiceDiscovery(boolean blocking)
2644 boolean alive = true;
2645 Thread t0 = null, t1 = null, t2 = null;
2646 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2649 // todo: changesupport handlers need to be transferred
2650 if (discoverer == null)
2652 discoverer = new jalview.ws.jws1.Discoverer();
2653 // register PCS handler for desktop.
2654 discoverer.addPropertyChangeListener(changeSupport);
2656 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2657 // until we phase out completely
2658 (t0 = new Thread(discoverer)).start();
2661 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2663 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2665 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2667 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2673 // TODO: do rest service discovery
2682 } catch (Exception e)
2685 alive = (t1 != null && t1.isAlive())
2686 || (t2 != null && t2.isAlive())
2687 || (t3 != null && t3.isAlive())
2688 || (t0 != null && t0.isAlive());
2694 * called to check if the service discovery process completed successfully.
2698 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2700 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2702 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2703 .getErrorMessages();
2706 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2708 if (serviceChangedDialog == null)
2710 // only run if we aren't already displaying one of these.
2711 addDialogThread(serviceChangedDialog = new Runnable()
2717 * JalviewDialog jd =new JalviewDialog() {
2719 * @Override protected void cancelPressed() { // TODO
2720 * Auto-generated method stub
2722 * }@Override protected void okPressed() { // TODO
2723 * Auto-generated method stub
2725 * }@Override protected void raiseClosed() { // TODO
2726 * Auto-generated method stub
2728 * } }; jd.initDialogFrame(new
2729 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2730 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2731 * + " or mis-configured HTTP proxy settings.<br/>" +
2732 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2734 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2735 * ), true, true, "Web Service Configuration Problem", 450,
2738 * jd.waitForInput();
2744 "<html><table width=\"450\"><tr><td>"
2746 + "</td></tr></table>"
2747 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2748 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2749 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2750 + " Tools->Preferences dialog box to change them.</p></html>"),
2751 "Web Service Configuration Problem",
2752 JOptionPane.DEFAULT_OPTION,
2753 JOptionPane.ERROR_MESSAGE);
2754 serviceChangedDialog = null;
2763 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2770 private Runnable serviceChangedDialog = null;
2773 * start a thread to open a URL in the configured browser. Pops up a warning
2774 * dialog to the user if there is an exception when calling out to the browser
2779 public static void showUrl(final String url)
2781 showUrl(url, Desktop.instance);
2785 * Like showUrl but allows progress handler to be specified
2789 * (null) or object implementing IProgressIndicator
2791 public static void showUrl(final String url,
2792 final IProgressIndicator progress)
2794 new Thread(new Runnable()
2800 if (progress != null)
2802 progress.setProgressBar(MessageManager.formatMessage(
2803 "status.opening_params", new Object[] { url }), this
2806 jalview.util.BrowserLauncher.openURL(url);
2807 } catch (Exception ex)
2809 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2811 .getString("label.web_browser_not_found_unix"),
2812 MessageManager.getString("label.web_browser_not_found"),
2813 JOptionPane.WARNING_MESSAGE);
2815 ex.printStackTrace();
2817 if (progress != null)
2819 progress.setProgressBar(null, this.hashCode());
2825 public static WsParamSetManager wsparamManager = null;
2827 public static ParamManager getUserParameterStore()
2829 if (wsparamManager == null)
2831 wsparamManager = new WsParamSetManager();
2833 return wsparamManager;
2837 * static hyperlink handler proxy method for use by Jalview's internal windows
2841 public static void hyperlinkUpdate(HyperlinkEvent e)
2843 if (e.getEventType() == EventType.ACTIVATED)
2848 url = e.getURL().toString();
2849 Desktop.showUrl(url);
2850 } catch (Exception x)
2854 if (Cache.log != null)
2856 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2860 System.err.println("Couldn't handle string " + url
2864 // ignore any exceptions due to dud links.
2871 * single thread that handles display of dialogs to user.
2873 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2876 * flag indicating if dialogExecutor should try to acquire a permit
2878 private volatile boolean dialogPause = true;
2883 private java.util.concurrent.Semaphore block = new Semaphore(0);
2886 * add another dialog thread to the queue
2890 public void addDialogThread(final Runnable prompter)
2892 dialogExecutor.submit(new Runnable()
2901 } catch (InterruptedException x)
2906 if (instance == null)
2912 SwingUtilities.invokeAndWait(prompter);
2913 } catch (Exception q)
2915 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2921 public void startDialogQueue()
2923 // set the flag so we don't pause waiting for another permit and semaphore
2924 // the current task to begin
2925 dialogPause = false;
2930 protected void snapShotWindow_actionPerformed(ActionEvent e)
2934 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2935 "View of Desktop", getWidth(), getHeight(), of = new File(
2936 "Jalview_snapshot" + System.currentTimeMillis()
2937 + ".eps"), "View of desktop");
2940 paintAll(im.getGraphics());
2942 } catch (Exception q)
2944 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2948 Cache.log.info("Successfully written snapshot to file "
2949 + of.getAbsolutePath());
2953 * Explode the views in the given SplitFrame into separate SplitFrame windows.
2954 * This respects (remembers) any previous 'exploded geometry' i.e. the size
2955 * and location last time the view was expanded (if any). However it does not
2956 * remember the split pane divider location - this is set to match the
2957 * 'exploding' frame.
2961 public void explodeViews(SplitFrame sf)
2963 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2964 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2965 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2967 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2969 int viewCount = topPanels.size();
2976 * Processing in reverse order works, forwards order leaves the first panels
2977 * not visible. I don't know why!
2979 for (int i = viewCount - 1; i >= 0; i--)
2982 * Make new top and bottom frames. These take over the respective
2983 * AlignmentPanel objects, including their AlignmentViewports, so the
2984 * cdna/protein relationships between the viewports is carried over to the
2987 * explodedGeometry holds the (x, y) position of the previously exploded
2988 * SplitFrame, and the (width, height) of the AlignFrame component
2990 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2991 AlignFrame newTopFrame = new AlignFrame(topPanel);
2992 newTopFrame.setSize(oldTopFrame.getSize());
2993 newTopFrame.setVisible(true);
2994 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
2995 .getExplodedGeometry();
2996 if (geometry != null)
2998 newTopFrame.setSize(geometry.getSize());
3001 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3002 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3003 newBottomFrame.setSize(oldBottomFrame.getSize());
3004 newBottomFrame.setVisible(true);
3005 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3006 .getExplodedGeometry();
3007 if (geometry != null)
3009 newBottomFrame.setSize(geometry.getSize());
3012 topPanel.av.setGatherViewsHere(false);
3013 bottomPanel.av.setGatherViewsHere(false);
3014 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3016 if (geometry != null)
3018 splitFrame.setLocation(geometry.getLocation());
3020 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3024 * Clear references to the panels (now relocated in the new SplitFrames)
3025 * before closing the old SplitFrame.
3028 bottomPanels.clear();
3033 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3034 * back into the given SplitFrame as additional views. Note that the gathered
3035 * frames may themselves have multiple views.
3039 public void gatherViews(GSplitFrame source)
3042 * special handling of explodedGeometry for a view within a SplitFrame: - it
3043 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3044 * height) of the AlignFrame component
3046 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3047 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3048 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3049 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3050 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3051 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3053 myTopFrame.viewport.setGatherViewsHere(true);
3054 myBottomFrame.viewport.setGatherViewsHere(true);
3055 String topViewId = myTopFrame.viewport.getSequenceSetId();
3056 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3058 JInternalFrame[] frames = desktop.getAllFrames();
3059 for (JInternalFrame frame : frames)
3061 if (frame instanceof SplitFrame && frame != source)
3063 SplitFrame sf = (SplitFrame) frame;
3064 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3065 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3066 boolean gatherThis = false;
3067 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3069 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3070 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3071 if (topViewId.equals(topPanel.av.getSequenceSetId())
3072 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3075 topPanel.av.setGatherViewsHere(false);
3076 bottomPanel.av.setGatherViewsHere(false);
3077 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3078 topFrame.getSize()));
3079 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3080 .getLocation(), bottomFrame.getSize()));
3081 myTopFrame.addAlignmentPanel(topPanel, false);
3082 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3088 topFrame.getAlignPanels().clear();
3089 bottomFrame.getAlignPanels().clear();
3096 * The dust settles...give focus to the tab we did this from.
3098 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3102 public static AlignFrame getCurrentAlignFrame()
3104 return currentAlignFrame;
3107 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3109 Desktop.currentAlignFrame = currentAlignFrame;