2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.bin.Cache;
26 import jalview.bin.Jalview;
27 import jalview.io.FileLoader;
28 import jalview.io.FormatAdapter;
29 import jalview.io.IdentifyFile;
30 import jalview.io.JalviewFileChooser;
31 import jalview.io.JalviewFileView;
32 import jalview.jbgui.GSplitFrame;
33 import jalview.jbgui.GStructureViewer;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.util.ImageMaker;
36 import jalview.util.MessageManager;
37 import jalview.util.Platform;
38 import jalview.viewmodel.AlignmentViewport;
39 import jalview.ws.params.ParamManager;
41 import java.awt.BorderLayout;
42 import java.awt.Color;
43 import java.awt.Dimension;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.GridLayout;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.Toolkit;
50 import java.awt.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;
193 public void activateFrame(JInternalFrame f)
197 delegate.activateFrame(f);
198 } catch (NullPointerException npe)
200 Point p = getMousePosition();
201 instance.showPasteMenu(p.x, p.y);
206 public void beginDraggingFrame(JComponent f)
208 delegate.beginDraggingFrame(f);
212 public void beginResizingFrame(JComponent f, int direction)
214 delegate.beginResizingFrame(f, direction);
218 public void closeFrame(JInternalFrame f)
220 delegate.closeFrame(f);
224 public void deactivateFrame(JInternalFrame f)
226 delegate.deactivateFrame(f);
230 public void deiconifyFrame(JInternalFrame f)
232 delegate.deiconifyFrame(f);
236 public void dragFrame(JComponent f, int newX, int newY)
242 delegate.dragFrame(f, newX, newY);
246 public void endDraggingFrame(JComponent f)
248 delegate.endDraggingFrame(f);
252 public void endResizingFrame(JComponent f)
254 delegate.endResizingFrame(f);
258 public void iconifyFrame(JInternalFrame f)
260 delegate.iconifyFrame(f);
264 public void maximizeFrame(JInternalFrame f)
266 delegate.maximizeFrame(f);
270 public void minimizeFrame(JInternalFrame f)
272 delegate.minimizeFrame(f);
276 public void openFrame(JInternalFrame f)
278 delegate.openFrame(f);
282 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
289 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
293 public void setBoundsForFrame(JComponent f, int newX, int newY,
294 int newWidth, int newHeight)
296 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
299 // All other methods, simply delegate
304 * Creates a new Desktop object.
309 * A note to implementors. It is ESSENTIAL that any activities that might
310 * block are spawned off as threads rather than waited for during this
314 doVamsasClientCheck();
316 doConfigureStructurePrefs();
317 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
318 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
319 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
321 boolean showjconsole = jalview.bin.Cache.getDefault(
322 "SHOW_JAVA_CONSOLE", false);
323 desktop = new MyDesktopPane(selmemusage);
324 if (Platform.isAMac())
326 desktop.setDoubleBuffered(false);
328 showMemusage.setSelected(selmemusage);
329 desktop.setBackground(Color.white);
330 getContentPane().setLayout(new BorderLayout());
331 // alternate config - have scrollbars - see notes in JAL-153
332 // JScrollPane sp = new JScrollPane();
333 // sp.getViewport().setView(desktop);
334 // getContentPane().add(sp, BorderLayout.CENTER);
335 getContentPane().add(desktop, BorderLayout.CENTER);
336 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
338 // This line prevents Windows Look&Feel resizing all new windows to maximum
339 // if previous window was maximised
340 desktop.setDesktopManager(new MyDesktopManager(
341 new DefaultDesktopManager()));
343 Rectangle dims = getLastKnownDimensions("");
350 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
351 setBounds((screenSize.width - 900) / 2,
352 (screenSize.height - 650) / 2, 900, 650);
354 jconsole = new Console(this, showjconsole);
355 // add essential build information
356 jconsole.setHeader("Jalview Version: "
357 + jalview.bin.Cache.getProperty("VERSION") + "\n"
358 + "Jalview Installation: "
359 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
360 + "\n" + "Build Date: "
361 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
362 + "Java version: " + System.getProperty("java.version") + "\n"
363 + System.getProperty("os.arch") + " "
364 + System.getProperty("os.name") + " "
365 + System.getProperty("os.version"));
367 showConsole(showjconsole);
369 showNews.setVisible(false);
371 this.addWindowListener(new WindowAdapter()
374 public void windowClosing(WindowEvent evt)
381 this.addMouseListener(ma = new MouseAdapter()
384 public void mousePressed(MouseEvent evt)
386 if (SwingUtilities.isRightMouseButton(evt))
388 showPasteMenu(evt.getX(), evt.getY());
392 desktop.addMouseListener(ma);
394 this.addFocusListener(new FocusListener()
398 public void focusLost(FocusEvent e)
400 // TODO Auto-generated method stub
405 public void focusGained(FocusEvent e)
407 Cache.log.debug("Relaying windows after focus gain");
408 // make sure that we sort windows properly after we gain focus
409 instance.relayerWindows();
412 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
413 // Spawn a thread that shows the splashscreen
414 SwingUtilities.invokeLater(new Runnable()
424 // Thread off a new instance of the file chooser - this reduces the time it
425 // takes to open it later on.
426 new Thread(new Runnable()
431 Cache.log.debug("Filechooser init thread started.");
432 new JalviewFileChooser(
433 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
434 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
435 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
436 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
437 Cache.log.debug("Filechooser init thread finished.");
440 // Add the service change listener
441 changeSupport.addJalviewPropertyChangeListener("services",
442 new PropertyChangeListener()
446 public void propertyChange(PropertyChangeEvent evt)
448 Cache.log.debug("Firing service changed event for "
449 + evt.getNewValue());
450 JalviewServicesChanged(evt);
456 public void doConfigureStructurePrefs()
458 // configure services
459 StructureSelectionManager ssm = StructureSelectionManager
460 .getStructureSelectionManager(this);
461 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
463 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
464 Preferences.ADD_TEMPFACT_ANN, true));
465 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
466 Preferences.STRUCT_FROM_PDB, true));
467 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
468 Preferences.USE_RNAVIEW, true));
472 ssm.setAddTempFacAnnot(false);
473 ssm.setProcessSecondaryStructure(false);
474 ssm.setSecStructServices(false);
478 public void checkForNews()
480 final Desktop me = this;
481 // Thread off the news reader, in case there are connection problems.
482 addDialogThread(new Runnable()
487 Cache.log.debug("Starting news thread.");
489 jvnews = new BlogReader(me);
490 showNews.setVisible(true);
491 Cache.log.debug("Completed news thread.");
497 protected void showNews_actionPerformed(ActionEvent e)
499 showNews(showNews.isSelected());
502 void showNews(boolean visible)
505 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
506 showNews.setSelected(visible);
507 if (visible && !jvnews.isVisible())
509 new Thread(new Runnable()
514 long now = System.currentTimeMillis();
515 Desktop.instance.setProgressBar(
516 MessageManager.getString("status.refreshing_news"), now);
517 jvnews.refreshNews();
518 Desktop.instance.setProgressBar(null, now);
527 * recover the last known dimensions for a jalview window
530 * - empty string is desktop, all other windows have unique prefix
531 * @return null or last known dimensions scaled to current geometry (if last
532 * window geom was known)
534 Rectangle getLastKnownDimensions(String windowName)
536 // TODO: lock aspect ratio for scaling desktop Bug #0058199
537 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
538 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
539 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
540 String width = jalview.bin.Cache.getProperty(windowName
542 String height = jalview.bin.Cache.getProperty(windowName
544 if ((x != null) && (y != null) && (width != null) && (height != null))
546 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
547 .parseInt(width), ih = Integer.parseInt(height);
548 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
550 // attempt #1 - try to cope with change in screen geometry - this
551 // version doesn't preserve original jv aspect ratio.
552 // take ratio of current screen size vs original screen size.
553 double sw = ((1f * screenSize.width) / (1f * Integer
554 .parseInt(jalview.bin.Cache
555 .getProperty("SCREENGEOMETRY_WIDTH"))));
556 double sh = ((1f * screenSize.height) / (1f * Integer
557 .parseInt(jalview.bin.Cache
558 .getProperty("SCREENGEOMETRY_HEIGHT"))));
559 // rescale the bounds depending upon the current screen geometry.
560 ix = (int) (ix * sw);
561 iw = (int) (iw * sw);
562 iy = (int) (iy * sh);
563 ih = (int) (ih * sh);
564 while (ix >= screenSize.width)
566 jalview.bin.Cache.log
567 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
568 ix -= screenSize.width;
570 while (iy >= screenSize.height)
572 jalview.bin.Cache.log
573 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
574 iy -= screenSize.height;
576 jalview.bin.Cache.log.debug("Got last known dimensions for "
577 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
580 // return dimensions for new instance
581 return new Rectangle(ix, iy, iw, ih);
586 private void doVamsasClientCheck()
588 if (jalview.bin.Cache.vamsasJarsPresent())
590 setupVamsasDisconnectedGui();
591 VamsasMenu.setVisible(true);
592 final Desktop us = this;
593 VamsasMenu.addMenuListener(new MenuListener()
595 // this listener remembers when the menu was first selected, and
596 // doesn't rebuild the session list until it has been cleared and
598 boolean refresh = true;
601 public void menuCanceled(MenuEvent e)
607 public void menuDeselected(MenuEvent e)
613 public void menuSelected(MenuEvent e)
617 us.buildVamsasStMenu();
622 vamsasStart.setVisible(true);
626 void showPasteMenu(int x, int y)
628 JPopupMenu popup = new JPopupMenu();
629 JMenuItem item = new JMenuItem(
630 MessageManager.getString("label.paste_new_window"));
631 item.addActionListener(new ActionListener()
634 public void actionPerformed(ActionEvent evt)
641 popup.show(this, x, y);
648 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
649 Transferable contents = c.getContents(this);
651 if (contents != null)
653 String file = (String) contents
654 .getTransferData(DataFlavor.stringFlavor);
656 String format = new IdentifyFile().identify(file,
657 FormatAdapter.PASTE);
659 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
662 } catch (Exception ex)
665 .println("Unable to paste alignment from system clipboard:\n"
671 * Adds and opens the given frame to the desktop
682 public static synchronized void addInternalFrame(
683 final JInternalFrame frame, String title, int w, int h)
685 addInternalFrame(frame, title, true, w, h, true);
689 * Add an internal frame to the Jalview desktop
696 * When true, display frame immediately, otherwise, caller must call
697 * setVisible themselves.
703 public static synchronized void addInternalFrame(
704 final JInternalFrame frame, String title, boolean makeVisible,
707 addInternalFrame(frame, title, makeVisible, w, h, true);
711 * Add an internal frame to the Jalview desktop and make it visible
724 public static synchronized void addInternalFrame(
725 final JInternalFrame frame, String title, int w, int h,
728 addInternalFrame(frame, title, true, w, h, resizable);
732 * Add an internal frame to the Jalview desktop
739 * When true, display frame immediately, otherwise, caller must call
740 * setVisible themselves.
748 public static synchronized void addInternalFrame(
749 final JInternalFrame frame, String title, boolean makeVisible,
750 int w, int h, boolean resizable)
753 // TODO: allow callers to determine X and Y position of frame (eg. via
755 // TODO: consider fixing method to update entries in the window submenu with
756 // the current window title
758 frame.setTitle(title);
759 if (frame.getWidth() < 1 || frame.getHeight() < 1)
763 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
764 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
765 // IF JALVIEW IS RUNNING HEADLESS
766 // ///////////////////////////////////////////////
768 || (System.getProperty("java.awt.headless") != null && System
769 .getProperty("java.awt.headless").equals("true")))
776 frame.setVisible(makeVisible);
777 frame.setClosable(true);
778 frame.setResizable(resizable);
779 frame.setMaximizable(resizable);
780 frame.setIconifiable(resizable);
781 if (Platform.isAMac())
783 frame.setIconifiable(false);
784 frame.setFrameIcon(null);
785 // frame.setDesktopIcon(null);
786 frame.setDoubleBuffered(false);
788 if (frame.getX() < 1 && frame.getY() < 1)
790 frame.setLocation(xOffset * openFrameCount, yOffset
791 * ((openFrameCount - 1) % 10) + yOffset);
794 final JMenuItem menuItem = new JMenuItem(title);
795 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
798 public void internalFrameActivated(
799 javax.swing.event.InternalFrameEvent evt)
801 JInternalFrame itf = desktop.getSelectedFrame();
810 public void internalFrameClosed(
811 javax.swing.event.InternalFrameEvent evt)
813 PaintRefresher.RemoveComponent(frame);
815 windowMenu.remove(menuItem);
816 JInternalFrame itf = desktop.getSelectedFrame();
825 menuItem.addActionListener(new ActionListener()
828 public void actionPerformed(ActionEvent e)
832 frame.setSelected(true);
833 frame.setIcon(false);
834 } catch (java.beans.PropertyVetoException ex)
840 menuItem.addMouseListener(new MouseListener()
844 public void mouseReleased(MouseEvent e)
849 public void mousePressed(MouseEvent e)
854 public void mouseExited(MouseEvent e)
858 frame.setSelected(false);
859 } catch (PropertyVetoException e1)
865 public void mouseEntered(MouseEvent e)
869 frame.setSelected(true);
870 } catch (PropertyVetoException e1)
876 public void mouseClicked(MouseEvent e)
882 windowMenu.add(menuItem);
888 frame.setSelected(true);
889 frame.requestFocus();
890 } catch (java.beans.PropertyVetoException ve)
892 } catch (java.lang.ClassCastException cex)
895 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
901 public void lostOwnership(Clipboard clipboard, Transferable contents)
905 Desktop.jalviewClipboard = null;
908 internalCopy = false;
912 public void dragEnter(DropTargetDragEvent evt)
917 public void dragExit(DropTargetEvent evt)
922 public void dragOver(DropTargetDragEvent evt)
927 public void dropActionChanged(DropTargetDragEvent evt)
938 public void drop(DropTargetDropEvent evt)
940 boolean success = true;
941 Transferable t = evt.getTransferable();
942 java.util.List files = null;
943 java.util.List protocols = null;
947 DataFlavor uriListFlavor = new DataFlavor(
948 "text/uri-list;class=java.lang.String");
949 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
951 // Works on Windows and MacOSX
952 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
953 files = (java.util.List) t
954 .getTransferData(DataFlavor.javaFileListFlavor);
956 else if (t.isDataFlavorSupported(uriListFlavor))
958 // This is used by Unix drag system
959 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
960 String data = (String) t.getTransferData(uriListFlavor);
961 files = new java.util.ArrayList(1);
962 protocols = new java.util.ArrayList(1);
963 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
964 data, "\r\n"); st.hasMoreTokens();)
966 String s = st.nextToken();
967 if (s.startsWith("#"))
969 // the line is a comment (as per the RFC 2483)
972 java.net.URI uri = new java.net.URI(s);
973 if (uri.getScheme().toLowerCase().startsWith("http"))
975 protocols.add(FormatAdapter.URL);
976 files.add(uri.toString());
980 // otherwise preserve old behaviour: catch all for file objects
981 java.io.File file = new java.io.File(uri);
982 protocols.add(FormatAdapter.FILE);
983 files.add(file.toString());
987 } catch (Exception e)
996 for (int i = 0; i < files.size(); i++)
998 String file = files.get(i).toString();
999 String protocol = (protocols == null) ? FormatAdapter.FILE
1000 : (String) protocols.get(i);
1001 String format = null;
1003 if (file.endsWith(".jar"))
1010 format = new IdentifyFile().identify(file, protocol);
1013 new FileLoader().LoadFile(file, protocol, format);
1016 } catch (Exception ex)
1021 evt.dropComplete(success); // need this to ensure input focus is properly
1022 // transfered to any new windows created
1032 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1034 JalviewFileChooser chooser = new JalviewFileChooser(
1035 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1036 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1037 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1038 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1040 chooser.setFileView(new JalviewFileView());
1041 chooser.setDialogTitle(MessageManager
1042 .getString("label.open_local_file"));
1043 chooser.setToolTipText(MessageManager.getString("action.open"));
1045 int value = chooser.showOpenDialog(this);
1047 if (value == JalviewFileChooser.APPROVE_OPTION)
1049 String choice = chooser.getSelectedFile().getPath();
1050 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1051 .getSelectedFile().getParent());
1053 String format = null;
1054 if (chooser.getSelectedFormat() != null
1055 && chooser.getSelectedFormat().equals("Jalview"))
1061 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1064 if (viewport != null)
1066 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1068 // viewport.setShowSequenceFeatures(JSONFile.isSeqFeaturesEnabled());
1069 // AlignFrame af = viewport.getAlignPanel().alignFrame;
1072 // af.changeColour(JSONFile.getColourScheme());
1073 // af.setMenusForViewport();
1078 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1090 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1092 // This construct allows us to have a wider textfield
1094 JLabel label = new JLabel(
1095 MessageManager.getString("label.input_file_url"));
1096 final JComboBox history = new JComboBox();
1098 JPanel panel = new JPanel(new GridLayout(2, 1));
1101 history.setPreferredSize(new Dimension(400, 20));
1102 history.setEditable(true);
1103 history.addItem("http://www.");
1105 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1109 if (historyItems != null)
1111 st = new StringTokenizer(historyItems, "\t");
1113 while (st.hasMoreTokens())
1115 history.addItem(st.nextElement());
1119 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1120 MessageManager.getString("label.input_alignment_from_url"),
1121 JOptionPane.OK_CANCEL_OPTION);
1123 if (reply != JOptionPane.OK_OPTION)
1128 String url = history.getSelectedItem().toString();
1130 if (url.toLowerCase().endsWith(".jar"))
1132 if (viewport != null)
1134 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1139 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1144 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1146 if (format.equals("URL NOT FOUND"))
1148 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1149 MessageManager.formatMessage("label.couldnt_locate",
1150 new Object[] { url }), MessageManager
1151 .getString("label.url_not_found"),
1152 JOptionPane.WARNING_MESSAGE);
1157 if (viewport != null)
1159 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1163 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1169 * Opens the CutAndPaste window for the user to paste an alignment in to
1172 * - if not null, the pasted alignment is added to the current
1173 * alignment; if null, to a new alignment window
1176 public void inputTextboxMenuItem_actionPerformed(
1177 AlignmentViewPanel viewPanel)
1179 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1180 cap.setForInput(viewPanel);
1181 Desktop.addInternalFrame(cap,
1182 MessageManager.getString("label.cut_paste_alignmen_file"),
1192 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1194 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1195 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1197 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1198 getBounds().y, getWidth(), getHeight()));
1200 if (jconsole != null)
1202 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1203 jconsole.stopConsole();
1207 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1210 if (dialogExecutor != null)
1212 dialogExecutor.shutdownNow();
1214 closeAll_actionPerformed(null);
1218 private void storeLastKnownDimensions(String string, Rectangle jc)
1220 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1221 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1222 + " height:" + jc.height);
1224 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1225 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1226 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1227 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1237 public void aboutMenuItem_actionPerformed(ActionEvent e)
1239 // StringBuffer message = getAboutMessage(false);
1240 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1242 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1243 new Thread(new Runnable()
1248 new SplashScreen(true);
1253 public StringBuffer getAboutMessage(boolean shortv)
1255 StringBuffer message = new StringBuffer();
1256 message.append("<html>");
1259 message.append("<h1><strong>Version: "
1260 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1261 message.append("<strong>Last Updated: <em>"
1262 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1263 + "</em></strong>");
1269 message.append("<strong>Version "
1270 + jalview.bin.Cache.getProperty("VERSION")
1271 + "; last updated: "
1272 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1275 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1278 message.append("<br>...Checking latest version...</br>");
1280 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1281 .equals(jalview.bin.Cache.getProperty("VERSION")))
1283 boolean red = false;
1284 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1285 .indexOf("automated build") == -1)
1288 // Displayed when code version and jnlp version do not match and code
1289 // version is not a development build
1290 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1293 message.append("<br>!! Version "
1294 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1296 + " is available for download from "
1297 + jalview.bin.Cache.getDefault("www.jalview.org",
1298 "http://www.jalview.org") + " !!");
1301 message.append("</div>");
1304 message.append("<br>Authors: "
1306 .getDefault("AUTHORFNAMES",
1307 "The Jalview Authors (See AUTHORS file for current list)")
1308 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1309 + "<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"
1310 + "<br><br>If you use Jalview, please cite:"
1311 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1312 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1313 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1325 public void documentationMenuItem_actionPerformed(ActionEvent e)
1329 Help.showHelpWindow();
1330 } catch (Exception ex)
1336 public void closeAll_actionPerformed(ActionEvent e)
1338 JInternalFrame[] frames = desktop.getAllFrames();
1339 for (int i = 0; i < frames.length; i++)
1343 frames[i].setClosed(true);
1344 } catch (java.beans.PropertyVetoException ex)
1348 System.out.println("ALL CLOSED");
1349 if (v_client != null)
1351 // TODO clear binding to vamsas document objects on close_all
1355 * reset state of singleton objects as appropriate (clear down session state
1356 * when all windows are closed)
1358 StructureSelectionManager ssm = StructureSelectionManager
1359 .getStructureSelectionManager(this);
1367 public void raiseRelated_actionPerformed(ActionEvent e)
1369 reorderAssociatedWindows(false, false);
1373 public void minimizeAssociated_actionPerformed(ActionEvent e)
1375 reorderAssociatedWindows(true, false);
1378 void closeAssociatedWindows()
1380 reorderAssociatedWindows(false, true);
1386 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1390 protected void garbageCollect_actionPerformed(ActionEvent e)
1392 // We simply collect the garbage
1393 jalview.bin.Cache.log.debug("Collecting garbage...");
1395 jalview.bin.Cache.log.debug("Finished garbage collection.");
1402 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1406 protected void showMemusage_actionPerformed(ActionEvent e)
1408 desktop.showMemoryUsage(showMemusage.isSelected());
1415 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1419 protected void showConsole_actionPerformed(ActionEvent e)
1421 showConsole(showConsole.isSelected());
1424 Console jconsole = null;
1427 * control whether the java console is visible or not
1431 void showConsole(boolean selected)
1433 showConsole.setSelected(selected);
1434 // TODO: decide if we should update properties file
1435 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1437 jconsole.setVisible(selected);
1440 void reorderAssociatedWindows(boolean minimize, boolean close)
1442 JInternalFrame[] frames = desktop.getAllFrames();
1443 if (frames == null || frames.length < 1)
1448 AlignmentViewport source = null, target = null;
1449 if (frames[0] instanceof AlignFrame)
1451 source = ((AlignFrame) frames[0]).getCurrentView();
1453 else if (frames[0] instanceof TreePanel)
1455 source = ((TreePanel) frames[0]).getViewPort();
1457 else if (frames[0] instanceof PCAPanel)
1459 source = ((PCAPanel) frames[0]).av;
1461 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1463 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1468 for (int i = 0; i < frames.length; i++)
1471 if (frames[i] == null)
1475 if (frames[i] instanceof AlignFrame)
1477 target = ((AlignFrame) frames[i]).getCurrentView();
1479 else if (frames[i] instanceof TreePanel)
1481 target = ((TreePanel) frames[i]).getViewPort();
1483 else if (frames[i] instanceof PCAPanel)
1485 target = ((PCAPanel) frames[i]).av;
1487 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1489 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1492 if (source == target)
1498 frames[i].setClosed(true);
1502 frames[i].setIcon(minimize);
1505 frames[i].toFront();
1509 } catch (java.beans.PropertyVetoException ex)
1524 protected void preferences_actionPerformed(ActionEvent e)
1536 public void saveState_actionPerformed(ActionEvent e)
1538 JalviewFileChooser chooser = new JalviewFileChooser(
1539 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1540 new String[] { "jvp" }, new String[] { "Jalview Project" },
1543 chooser.setFileView(new JalviewFileView());
1544 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1546 int value = chooser.showSaveDialog(this);
1548 if (value == JalviewFileChooser.APPROVE_OPTION)
1550 final Desktop me = this;
1551 final java.io.File choice = chooser.getSelectedFile();
1552 setProjectFile(choice);
1554 new Thread(new Runnable()
1559 // TODO: refactor to Jalview desktop session controller action.
1560 setProgressBar(MessageManager.formatMessage(
1561 "label.saving_jalview_project",
1562 new Object[] { choice.getName() }), choice.hashCode());
1563 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1564 choice.getParent());
1565 // TODO catch and handle errors for savestate
1566 // TODO prevent user from messing with the Desktop whilst we're saving
1569 new Jalview2XML().saveState(choice);
1570 } catch (OutOfMemoryError oom)
1572 new OOMWarning("Whilst saving current state to "
1573 + choice.getName(), oom);
1574 } catch (Exception ex)
1577 "Problems whilst trying to save to " + choice.getName(),
1579 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1580 "label.error_whilst_saving_current_state_to",
1581 new Object[] { choice.getName() }), MessageManager
1582 .getString("label.couldnt_save_project"),
1583 JOptionPane.WARNING_MESSAGE);
1585 setProgressBar(null, choice.hashCode());
1591 private void setProjectFile(File choice)
1593 this.projectFile = choice;
1596 public File getProjectFile()
1598 return this.projectFile;
1608 public void loadState_actionPerformed(ActionEvent e)
1610 JalviewFileChooser chooser = new JalviewFileChooser(
1611 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1612 "jvp", "jar" }, new String[] { "Jalview Project",
1613 "Jalview Project (old)" }, "Jalview Project");
1614 chooser.setFileView(new JalviewFileView());
1615 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1617 int value = chooser.showOpenDialog(this);
1619 if (value == JalviewFileChooser.APPROVE_OPTION)
1621 final File selectedFile = chooser.getSelectedFile();
1622 setProjectFile(selectedFile);
1623 final String choice = selectedFile.getAbsolutePath();
1624 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1625 selectedFile.getParent());
1626 new Thread(new Runnable()
1632 MessageManager.formatMessage(
1633 "label.loading_jalview_project",
1634 new Object[] { choice }), choice.hashCode());
1637 new Jalview2XML().loadJalviewAlign(choice);
1638 } catch (OutOfMemoryError oom)
1640 new OOMWarning("Whilst loading project from " + choice, oom);
1641 } catch (Exception ex)
1643 Cache.log.error("Problems whilst loading project from "
1645 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1647 "label.error_whilst_loading_project_from",
1648 new Object[] { choice }), MessageManager
1649 .getString("label.couldnt_load_project"),
1650 JOptionPane.WARNING_MESSAGE);
1652 setProgressBar(null, choice.hashCode());
1659 public void inputSequence_actionPerformed(ActionEvent e)
1661 new SequenceFetcher(this);
1664 JPanel progressPanel;
1666 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1668 public void startLoading(final String fileName)
1670 if (fileLoadingCount == 0)
1672 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1673 "label.loading_file", new Object[] { fileName })));
1678 private JPanel addProgressPanel(String string)
1680 if (progressPanel == null)
1682 progressPanel = new JPanel(new GridLayout(1, 1));
1683 totalProgressCount = 0;
1684 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1686 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1687 JProgressBar progressBar = new JProgressBar();
1688 progressBar.setIndeterminate(true);
1690 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1692 thisprogress.add(progressBar, BorderLayout.CENTER);
1693 progressPanel.add(thisprogress);
1694 ((GridLayout) progressPanel.getLayout())
1695 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1696 ++totalProgressCount;
1697 instance.validate();
1698 return thisprogress;
1701 int totalProgressCount = 0;
1703 private void removeProgressPanel(JPanel progbar)
1705 if (progressPanel != null)
1707 synchronized (progressPanel)
1709 progressPanel.remove(progbar);
1710 GridLayout gl = (GridLayout) progressPanel.getLayout();
1711 gl.setRows(gl.getRows() - 1);
1712 if (--totalProgressCount < 1)
1714 this.getContentPane().remove(progressPanel);
1715 progressPanel = null;
1722 public void stopLoading()
1725 if (fileLoadingCount < 1)
1727 while (fileLoadingPanels.size() > 0)
1729 removeProgressPanel(fileLoadingPanels.remove(0));
1731 fileLoadingPanels.clear();
1732 fileLoadingCount = 0;
1737 public static int getViewCount(String alignmentId)
1739 AlignmentViewport[] aps = getViewports(alignmentId);
1740 return (aps == null) ? 0 : aps.length;
1745 * @param alignmentId
1746 * - if null, all sets are returned
1747 * @return all AlignmentPanels concerning the alignmentId sequence set
1749 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1751 if (Desktop.desktop == null)
1753 // no frames created and in headless mode
1754 // TODO: verify that frames are recoverable when in headless mode
1757 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1758 AlignFrame[] frames = getAlignFrames();
1763 for (AlignFrame af : frames)
1765 for (AlignmentPanel ap : af.alignPanels)
1767 if (alignmentId == null
1768 || alignmentId.equals(ap.av.getSequenceSetId()))
1774 if (aps.size() == 0)
1778 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1783 * get all the viewports on an alignment.
1785 * @param sequenceSetId
1786 * unique alignment id (may be null - all viewports returned in that
1788 * @return all viewports on the alignment bound to sequenceSetId
1790 public static AlignmentViewport[] getViewports(String sequenceSetId)
1792 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1793 if (desktop != null)
1795 AlignFrame[] frames = Desktop.getAlignFrames();
1797 for (AlignFrame afr : frames)
1799 if (sequenceSetId == null
1800 || afr.getViewport().getSequenceSetId()
1801 .equals(sequenceSetId))
1803 if (afr.alignPanels != null)
1805 for (AlignmentPanel ap : afr.alignPanels)
1807 if (sequenceSetId == null
1808 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1816 viewp.add(afr.getViewport());
1820 if (viewp.size() > 0)
1822 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1829 * Explode the views in the given frame into separate AlignFrame
1833 public void explodeViews(AlignFrame af)
1835 int size = af.alignPanels.size();
1841 for (int i = 0; i < size; i++)
1843 AlignmentPanel ap = af.alignPanels.get(i);
1844 AlignFrame newaf = new AlignFrame(ap);
1847 * Restore the view's last exploded frame geometry if known. Multiple
1848 * views from one exploded frame share and restore the same (frame)
1849 * position and size.
1851 Rectangle geometry = ap.av.getExplodedGeometry();
1852 if (geometry != null)
1854 newaf.setBounds(geometry);
1857 ap.av.setGatherViewsHere(false);
1859 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1860 AlignFrame.DEFAULT_HEIGHT);
1863 af.alignPanels.clear();
1864 af.closeMenuItem_actionPerformed(true);
1869 * Gather expanded views (separate AlignFrame's) with the same sequence set
1870 * identifier back in to this frame as additional views, and close the
1871 * expanded views. Note the expanded frames may themselves have multiple
1872 * views. We take the lot.
1876 public void gatherViews(AlignFrame source)
1878 source.viewport.setGatherViewsHere(true);
1879 source.viewport.setExplodedGeometry(source.getBounds());
1880 JInternalFrame[] frames = desktop.getAllFrames();
1881 String viewId = source.viewport.getSequenceSetId();
1883 for (int t = 0; t < frames.length; t++)
1885 if (frames[t] instanceof AlignFrame && frames[t] != source)
1887 AlignFrame af = (AlignFrame) frames[t];
1888 boolean gatherThis = false;
1889 for (int a = 0; a < af.alignPanels.size(); a++)
1891 AlignmentPanel ap = af.alignPanels.get(a);
1892 if (viewId.equals(ap.av.getSequenceSetId()))
1895 ap.av.setGatherViewsHere(false);
1896 ap.av.setExplodedGeometry(af.getBounds());
1897 source.addAlignmentPanel(ap, false);
1903 af.alignPanels.clear();
1904 af.closeMenuItem_actionPerformed(true);
1911 jalview.gui.VamsasApplication v_client = null;
1914 public void vamsasImport_actionPerformed(ActionEvent e)
1916 if (v_client == null)
1918 // Load and try to start a session.
1919 JalviewFileChooser chooser = new JalviewFileChooser(
1920 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1922 chooser.setFileView(new JalviewFileView());
1923 chooser.setDialogTitle(MessageManager
1924 .getString("label.open_saved_vamsas_session"));
1925 chooser.setToolTipText(MessageManager
1926 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1928 int value = chooser.showOpenDialog(this);
1930 if (value == JalviewFileChooser.APPROVE_OPTION)
1932 String fle = chooser.getSelectedFile().toString();
1933 if (!vamsasImport(chooser.getSelectedFile()))
1936 .showInternalMessageDialog(
1938 MessageManager.formatMessage(
1939 "label.couldnt_import_as_vamsas_session",
1940 new Object[] { fle }),
1942 .getString("label.vamsas_document_import_failed"),
1943 JOptionPane.ERROR_MESSAGE);
1949 jalview.bin.Cache.log
1950 .error("Implementation error - load session from a running session is not supported.");
1955 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1958 * @return true if import was a success and a session was started.
1960 public boolean vamsasImport(URL url)
1962 // TODO: create progress bar
1963 if (v_client != null)
1966 jalview.bin.Cache.log
1967 .error("Implementation error - load session from a running session is not supported.");
1973 // copy the URL content to a temporary local file
1974 // TODO: be a bit cleverer here with nio (?!)
1975 File file = File.createTempFile("vdocfromurl", ".vdj");
1976 FileOutputStream fos = new FileOutputStream(file);
1977 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1978 byte[] buffer = new byte[2048];
1980 while ((ln = bis.read(buffer)) > -1)
1982 fos.write(buffer, 0, ln);
1986 v_client = new jalview.gui.VamsasApplication(this, file,
1987 url.toExternalForm());
1988 } catch (Exception ex)
1990 jalview.bin.Cache.log.error(
1991 "Failed to create new vamsas session from contents of URL "
1995 setupVamsasConnectedGui();
1996 v_client.initial_update(); // TODO: thread ?
1997 return v_client.inSession();
2001 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2004 * @return true if import was a success and a session was started.
2006 public boolean vamsasImport(File file)
2008 if (v_client != null)
2011 jalview.bin.Cache.log
2012 .error("Implementation error - load session from a running session is not supported.");
2016 setProgressBar(MessageManager.formatMessage(
2017 "status.importing_vamsas_session_from",
2018 new Object[] { file.getName() }), file.hashCode());
2021 v_client = new jalview.gui.VamsasApplication(this, file, null);
2022 } catch (Exception ex)
2024 setProgressBar(MessageManager.formatMessage(
2025 "status.importing_vamsas_session_from",
2026 new Object[] { file.getName() }), file.hashCode());
2027 jalview.bin.Cache.log.error(
2028 "New vamsas session from existing session file failed:", ex);
2031 setupVamsasConnectedGui();
2032 v_client.initial_update(); // TODO: thread ?
2033 setProgressBar(MessageManager.formatMessage(
2034 "status.importing_vamsas_session_from",
2035 new Object[] { file.getName() }), file.hashCode());
2036 return v_client.inSession();
2039 public boolean joinVamsasSession(String mysesid)
2041 if (v_client != null)
2045 .getString("error.try_join_vamsas_session_another"));
2047 if (mysesid == null)
2050 MessageManager.getString("error.invalid_vamsas_session_id"));
2052 v_client = new VamsasApplication(this, mysesid);
2053 setupVamsasConnectedGui();
2054 v_client.initial_update();
2055 return (v_client.inSession());
2059 public void vamsasStart_actionPerformed(ActionEvent e)
2061 if (v_client == null)
2064 // we just start a default session for moment.
2066 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2067 * getProperty("LAST_DIRECTORY"));
2069 * chooser.setFileView(new JalviewFileView());
2070 * chooser.setDialogTitle("Load Vamsas file");
2071 * chooser.setToolTipText("Import");
2073 * int value = chooser.showOpenDialog(this);
2075 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2076 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2078 v_client = new VamsasApplication(this);
2079 setupVamsasConnectedGui();
2080 v_client.initial_update(); // TODO: thread ?
2084 // store current data in session.
2085 v_client.push_update(); // TODO: thread
2089 protected void setupVamsasConnectedGui()
2091 vamsasStart.setText(MessageManager.getString("label.session_update"));
2092 vamsasSave.setVisible(true);
2093 vamsasStop.setVisible(true);
2094 vamsasImport.setVisible(false); // Document import to existing session is
2095 // not possible for vamsas-client-1.0.
2098 protected void setupVamsasDisconnectedGui()
2100 vamsasSave.setVisible(false);
2101 vamsasStop.setVisible(false);
2102 vamsasImport.setVisible(true);
2103 vamsasStart.setText(MessageManager
2104 .getString("label.new_vamsas_session"));
2108 public void vamsasStop_actionPerformed(ActionEvent e)
2110 if (v_client != null)
2112 v_client.end_session();
2114 setupVamsasDisconnectedGui();
2118 protected void buildVamsasStMenu()
2120 if (v_client == null)
2122 String[] sess = null;
2125 sess = VamsasApplication.getSessionList();
2126 } catch (Exception e)
2128 jalview.bin.Cache.log.warn(
2129 "Problem getting current sessions list.", e);
2134 jalview.bin.Cache.log.debug("Got current sessions list: "
2135 + sess.length + " entries.");
2136 VamsasStMenu.removeAll();
2137 for (int i = 0; i < sess.length; i++)
2139 JMenuItem sessit = new JMenuItem();
2140 sessit.setText(sess[i]);
2141 sessit.setToolTipText(MessageManager.formatMessage(
2142 "label.connect_to_session", new Object[] { sess[i] }));
2143 final Desktop dsktp = this;
2144 final String mysesid = sess[i];
2145 sessit.addActionListener(new ActionListener()
2149 public void actionPerformed(ActionEvent e)
2151 if (dsktp.v_client == null)
2153 Thread rthr = new Thread(new Runnable()
2159 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2160 dsktp.setupVamsasConnectedGui();
2161 dsktp.v_client.initial_update();
2169 VamsasStMenu.add(sessit);
2171 // don't show an empty menu.
2172 VamsasStMenu.setVisible(sess.length > 0);
2177 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2178 VamsasStMenu.removeAll();
2179 VamsasStMenu.setVisible(false);
2184 // Not interested in the content. Just hide ourselves.
2185 VamsasStMenu.setVisible(false);
2190 public void vamsasSave_actionPerformed(ActionEvent e)
2192 if (v_client != null)
2194 JalviewFileChooser chooser = new JalviewFileChooser(
2195 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2196 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2197 new String[] { "Vamsas Document" }, "Vamsas Document");
2199 chooser.setFileView(new JalviewFileView());
2200 chooser.setDialogTitle(MessageManager
2201 .getString("label.save_vamsas_document_archive"));
2203 int value = chooser.showSaveDialog(this);
2205 if (value == JalviewFileChooser.APPROVE_OPTION)
2207 java.io.File choice = chooser.getSelectedFile();
2208 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2209 "label.saving_vamsas_doc",
2210 new Object[] { choice.getName() }));
2211 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2212 String warnmsg = null;
2213 String warnttl = null;
2216 v_client.vclient.storeDocument(choice);
2219 warnttl = "Serious Problem saving Vamsas Document";
2220 warnmsg = ex.toString();
2221 jalview.bin.Cache.log.error("Error Whilst saving document to "
2224 } catch (Exception ex)
2226 warnttl = "Problem saving Vamsas Document.";
2227 warnmsg = ex.toString();
2228 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2232 removeProgressPanel(progpanel);
2233 if (warnmsg != null)
2235 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2237 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2243 JPanel vamUpdate = null;
2246 * hide vamsas user gui bits when a vamsas document event is being handled.
2249 * true to hide gui, false to reveal gui
2251 public void setVamsasUpdate(boolean b)
2253 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2254 + (b ? "in progress" : "finished"));
2256 if (vamUpdate != null)
2258 this.removeProgressPanel(vamUpdate);
2262 vamUpdate = this.addProgressPanel(MessageManager
2263 .getString("label.updating_vamsas_session"));
2265 vamsasStart.setVisible(!b);
2266 vamsasStop.setVisible(!b);
2267 vamsasSave.setVisible(!b);
2270 public JInternalFrame[] getAllFrames()
2272 return desktop.getAllFrames();
2276 * Checks the given url to see if it gives a response indicating that the user
2277 * should be informed of a new questionnaire.
2281 public void checkForQuestionnaire(String url)
2283 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2284 // javax.swing.SwingUtilities.invokeLater(jvq);
2285 new Thread(jvq).start();
2289 * Proxy class for JDesktopPane which optionally displays the current memory
2290 * usage and highlights the desktop area with a red bar if free memory runs
2295 public class MyDesktopPane extends JDesktopPane implements Runnable
2298 private static final float ONE_MB = 1048576f;
2300 boolean showMemoryUsage = false;
2304 java.text.NumberFormat df;
2306 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2309 public MyDesktopPane(boolean showMemoryUsage)
2311 showMemoryUsage(showMemoryUsage);
2314 public void showMemoryUsage(boolean showMemory)
2316 this.showMemoryUsage = showMemory;
2319 Thread worker = new Thread(this);
2324 public boolean isShowMemoryUsage()
2326 return showMemoryUsage;
2332 df = java.text.NumberFormat.getNumberInstance();
2333 df.setMaximumFractionDigits(2);
2334 runtime = Runtime.getRuntime();
2336 while (showMemoryUsage)
2340 maxMemory = runtime.maxMemory() / ONE_MB;
2341 allocatedMemory = runtime.totalMemory() / ONE_MB;
2342 freeMemory = runtime.freeMemory() / ONE_MB;
2343 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2345 percentUsage = (totalFreeMemory / maxMemory) * 100;
2347 // if (percentUsage < 20)
2349 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2351 // instance.set.setBorder(border1);
2354 // sleep after showing usage
2356 } catch (Exception ex)
2358 ex.printStackTrace();
2364 public void paintComponent(Graphics g)
2366 if (showMemoryUsage && g != null && df != null)
2368 if (percentUsage < 20)
2370 g.setColor(Color.red);
2372 FontMetrics fm = g.getFontMetrics();
2375 g.drawString(MessageManager.formatMessage(
2376 "label.memory_stats",
2377 new Object[] { df.format(totalFreeMemory),
2378 df.format(maxMemory), df.format(percentUsage) }), 10,
2379 getHeight() - fm.getHeight());
2386 * fixes stacking order after a modal dialog to ensure windows that should be
2387 * on top actually are
2389 public void relayerWindows()
2394 protected JMenuItem groovyShell;
2396 public void doGroovyCheck()
2398 if (jalview.bin.Cache.groovyJarsPresent())
2400 groovyShell = new JMenuItem();
2401 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2402 groovyShell.addActionListener(new ActionListener()
2405 public void actionPerformed(ActionEvent e)
2407 groovyShell_actionPerformed();
2410 toolsMenu.add(groovyShell);
2411 groovyShell.setVisible(true);
2416 * Accessor method to quickly get all the AlignmentFrames loaded.
2418 * @return an array of AlignFrame, or null if none found
2420 public static AlignFrame[] getAlignFrames()
2422 if (Jalview.isHeadlessMode())
2424 // Desktop.desktop is null in headless mode
2425 return new AlignFrame[] { currentAlignFrame };
2428 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2434 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2436 for (int i = frames.length - 1; i > -1; i--)
2438 if (frames[i] instanceof AlignFrame)
2440 avp.add((AlignFrame) frames[i]);
2442 else if (frames[i] instanceof SplitFrame)
2445 * Also check for a split frame containing an AlignFrame
2447 GSplitFrame sf = (GSplitFrame) frames[i];
2448 if (sf.getTopFrame() instanceof AlignFrame)
2450 avp.add((AlignFrame) sf.getTopFrame());
2452 if (sf.getBottomFrame() instanceof AlignFrame)
2454 avp.add((AlignFrame) sf.getBottomFrame());
2458 if (avp.size() == 0)
2462 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2467 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2471 public GStructureViewer[] getJmols()
2473 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2479 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2481 for (int i = frames.length - 1; i > -1; i--)
2483 if (frames[i] instanceof AppJmol)
2485 GStructureViewer af = (GStructureViewer) frames[i];
2489 if (avp.size() == 0)
2493 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2498 * Add Groovy Support to Jalview
2500 public void groovyShell_actionPerformed()
2502 // use reflection to avoid creating compilation dependency.
2503 if (!jalview.bin.Cache.groovyJarsPresent())
2507 .getString("error.implementation_error_cannot_create_groovyshell"));
2511 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2512 "groovy.ui.Console");
2513 Constructor<?> gccons = gcClass.getConstructor();
2514 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2515 new Class[] { String.class, Object.class });
2516 java.lang.reflect.Method run = gcClass.getMethod("run");
2517 Object gc = gccons.newInstance();
2518 setvar.invoke(gc, new Object[] { "Jalview", this });
2520 } catch (Exception ex)
2522 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2523 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2525 MessageManager.getString("label.couldnt_create_groovy_shell"),
2526 MessageManager.getString("label.groovy_support_failed"),
2527 JOptionPane.ERROR_MESSAGE);
2532 * Progress bars managed by the IProgressIndicator method.
2534 private Hashtable<Long, JPanel> progressBars;
2536 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2541 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2544 public void setProgressBar(String message, long id)
2546 if (progressBars == null)
2548 progressBars = new Hashtable<Long, JPanel>();
2549 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2552 if (progressBars.get(new Long(id)) != null)
2554 JPanel panel = progressBars.remove(new Long(id));
2555 if (progressBarHandlers.contains(new Long(id)))
2557 progressBarHandlers.remove(new Long(id));
2559 removeProgressPanel(panel);
2563 progressBars.put(new Long(id), addProgressPanel(message));
2570 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2571 * jalview.gui.IProgressIndicatorHandler)
2574 public void registerHandler(final long id,
2575 final IProgressIndicatorHandler handler)
2577 if (progressBarHandlers == null
2578 || !progressBars.containsKey(new Long(id)))
2582 .getString("error.call_setprogressbar_before_registering_handler"));
2584 progressBarHandlers.put(new Long(id), handler);
2585 final JPanel progressPanel = progressBars.get(new Long(id));
2586 if (handler.canCancel())
2588 JButton cancel = new JButton(
2589 MessageManager.getString("action.cancel"));
2590 final IProgressIndicator us = this;
2591 cancel.addActionListener(new ActionListener()
2595 public void actionPerformed(ActionEvent e)
2597 handler.cancelActivity(id);
2598 us.setProgressBar(MessageManager.formatMessage(
2599 "label.cancelled_params",
2600 new Object[] { ((JLabel) progressPanel.getComponent(0))
2604 progressPanel.add(cancel, BorderLayout.EAST);
2610 * @return true if any progress bars are still active
2613 public boolean operationInProgress()
2615 if (progressBars != null && progressBars.size() > 0)
2623 * This will return the first AlignFrame holding the given viewport instance.
2624 * It will break if there are more than one AlignFrames viewing a particular
2628 * @return alignFrame for viewport
2630 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2632 if (desktop != null)
2634 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2635 for (int panel = 0; aps != null && panel < aps.length; panel++)
2637 if (aps[panel] != null && aps[panel].av == viewport)
2639 return aps[panel].alignFrame;
2646 public VamsasApplication getVamsasApplication()
2653 * flag set if jalview GUI is being operated programmatically
2655 private boolean inBatchMode = false;
2658 * check if jalview GUI is being operated programmatically
2660 * @return inBatchMode
2662 public boolean isInBatchMode()
2668 * set flag if jalview GUI is being operated programmatically
2670 * @param inBatchMode
2672 public void setInBatchMode(boolean inBatchMode)
2674 this.inBatchMode = inBatchMode;
2677 public void startServiceDiscovery()
2679 startServiceDiscovery(false);
2682 public void startServiceDiscovery(boolean blocking)
2684 boolean alive = true;
2685 Thread t0 = null, t1 = null, t2 = null;
2686 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2689 // todo: changesupport handlers need to be transferred
2690 if (discoverer == null)
2692 discoverer = new jalview.ws.jws1.Discoverer();
2693 // register PCS handler for desktop.
2694 discoverer.addPropertyChangeListener(changeSupport);
2696 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2697 // until we phase out completely
2698 (t0 = new Thread(discoverer)).start();
2701 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2703 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2705 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2707 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2713 // TODO: do rest service discovery
2722 } catch (Exception e)
2725 alive = (t1 != null && t1.isAlive())
2726 || (t2 != null && t2.isAlive())
2727 || (t3 != null && t3.isAlive())
2728 || (t0 != null && t0.isAlive());
2734 * called to check if the service discovery process completed successfully.
2738 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2740 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2742 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2743 .getErrorMessages();
2746 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2748 if (serviceChangedDialog == null)
2750 // only run if we aren't already displaying one of these.
2751 addDialogThread(serviceChangedDialog = new Runnable()
2758 * JalviewDialog jd =new JalviewDialog() {
2760 * @Override protected void cancelPressed() { // TODO
2761 * Auto-generated method stub
2763 * }@Override protected void okPressed() { // TODO
2764 * Auto-generated method stub
2766 * }@Override protected void raiseClosed() { // TODO
2767 * Auto-generated method stub
2769 * } }; jd.initDialogFrame(new
2770 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2771 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2772 * + " or mis-configured HTTP proxy settings.<br/>" +
2773 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2775 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2776 * ), true, true, "Web Service Configuration Problem", 450,
2779 * jd.waitForInput();
2785 "<html><table width=\"450\"><tr><td>"
2787 + "</td></tr></table>"
2788 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2789 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2790 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2791 + " Tools->Preferences dialog box to change them.</p></html>"),
2792 "Web Service Configuration Problem",
2793 JOptionPane.DEFAULT_OPTION,
2794 JOptionPane.ERROR_MESSAGE);
2795 serviceChangedDialog = null;
2804 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2811 private Runnable serviceChangedDialog = null;
2814 * start a thread to open a URL in the configured browser. Pops up a warning
2815 * dialog to the user if there is an exception when calling out to the browser
2820 public static void showUrl(final String url)
2822 showUrl(url, Desktop.instance);
2826 * Like showUrl but allows progress handler to be specified
2830 * (null) or object implementing IProgressIndicator
2832 public static void showUrl(final String url,
2833 final IProgressIndicator progress)
2835 new Thread(new Runnable()
2842 if (progress != null)
2844 progress.setProgressBar(MessageManager.formatMessage(
2845 "status.opening_params", new Object[] { url }), this
2848 jalview.util.BrowserLauncher.openURL(url);
2849 } catch (Exception ex)
2851 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2853 .getString("label.web_browser_not_found_unix"),
2854 MessageManager.getString("label.web_browser_not_found"),
2855 JOptionPane.WARNING_MESSAGE);
2857 ex.printStackTrace();
2859 if (progress != null)
2861 progress.setProgressBar(null, this.hashCode());
2867 public static WsParamSetManager wsparamManager = null;
2869 public static ParamManager getUserParameterStore()
2871 if (wsparamManager == null)
2873 wsparamManager = new WsParamSetManager();
2875 return wsparamManager;
2879 * static hyperlink handler proxy method for use by Jalview's internal windows
2883 public static void hyperlinkUpdate(HyperlinkEvent e)
2885 if (e.getEventType() == EventType.ACTIVATED)
2890 url = e.getURL().toString();
2891 Desktop.showUrl(url);
2892 } catch (Exception x)
2896 if (Cache.log != null)
2898 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2902 System.err.println("Couldn't handle string " + url
2906 // ignore any exceptions due to dud links.
2913 * single thread that handles display of dialogs to user.
2915 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2918 * flag indicating if dialogExecutor should try to acquire a permit
2920 private volatile boolean dialogPause = true;
2925 private java.util.concurrent.Semaphore block = new Semaphore(0);
2928 * add another dialog thread to the queue
2932 public void addDialogThread(final Runnable prompter)
2934 dialogExecutor.submit(new Runnable()
2944 } catch (InterruptedException x)
2949 if (instance == null)
2955 SwingUtilities.invokeAndWait(prompter);
2956 } catch (Exception q)
2958 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2964 public void startDialogQueue()
2966 // set the flag so we don't pause waiting for another permit and semaphore
2967 // the current task to begin
2968 dialogPause = false;
2973 protected void snapShotWindow_actionPerformed(ActionEvent e)
2977 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2978 "View of Desktop", getWidth(), getHeight(), of = new File(
2979 "Jalview_snapshot" + System.currentTimeMillis()
2980 + ".eps"), "View of desktop", null, 0, false);
2983 paintAll(im.getGraphics());
2985 } catch (Exception q)
2987 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2991 Cache.log.info("Successfully written snapshot to file "
2992 + of.getAbsolutePath());
2996 * Explode the views in the given SplitFrame into separate SplitFrame windows.
2997 * This respects (remembers) any previous 'exploded geometry' i.e. the size
2998 * and location last time the view was expanded (if any). However it does not
2999 * remember the split pane divider location - this is set to match the
3000 * 'exploding' frame.
3004 public void explodeViews(SplitFrame sf)
3006 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3007 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3008 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3010 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3012 int viewCount = topPanels.size();
3019 * Processing in reverse order works, forwards order leaves the first panels
3020 * not visible. I don't know why!
3022 for (int i = viewCount - 1; i >= 0; i--)
3025 * Make new top and bottom frames. These take over the respective
3026 * AlignmentPanel objects, including their AlignmentViewports, so the
3027 * cdna/protein relationships between the viewports is carried over to the
3030 * explodedGeometry holds the (x, y) position of the previously exploded
3031 * SplitFrame, and the (width, height) of the AlignFrame component
3033 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3034 AlignFrame newTopFrame = new AlignFrame(topPanel);
3035 newTopFrame.setSize(oldTopFrame.getSize());
3036 newTopFrame.setVisible(true);
3037 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3038 .getExplodedGeometry();
3039 if (geometry != null)
3041 newTopFrame.setSize(geometry.getSize());
3044 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3045 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3046 newBottomFrame.setSize(oldBottomFrame.getSize());
3047 newBottomFrame.setVisible(true);
3048 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3049 .getExplodedGeometry();
3050 if (geometry != null)
3052 newBottomFrame.setSize(geometry.getSize());
3055 topPanel.av.setGatherViewsHere(false);
3056 bottomPanel.av.setGatherViewsHere(false);
3057 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3059 if (geometry != null)
3061 splitFrame.setLocation(geometry.getLocation());
3063 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3067 * Clear references to the panels (now relocated in the new SplitFrames)
3068 * before closing the old SplitFrame.
3071 bottomPanels.clear();
3076 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3077 * back into the given SplitFrame as additional views. Note that the gathered
3078 * frames may themselves have multiple views.
3082 public void gatherViews(GSplitFrame source)
3085 * special handling of explodedGeometry for a view within a SplitFrame: - it
3086 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3087 * height) of the AlignFrame component
3089 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3090 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3091 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3092 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3093 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3094 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3096 myTopFrame.viewport.setGatherViewsHere(true);
3097 myBottomFrame.viewport.setGatherViewsHere(true);
3098 String topViewId = myTopFrame.viewport.getSequenceSetId();
3099 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3101 JInternalFrame[] frames = desktop.getAllFrames();
3102 for (JInternalFrame frame : frames)
3104 if (frame instanceof SplitFrame && frame != source)
3106 SplitFrame sf = (SplitFrame) frame;
3107 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3108 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3109 boolean gatherThis = false;
3110 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3112 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3113 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3114 if (topViewId.equals(topPanel.av.getSequenceSetId())
3115 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3118 topPanel.av.setGatherViewsHere(false);
3119 bottomPanel.av.setGatherViewsHere(false);
3120 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3121 topFrame.getSize()));
3122 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3123 .getLocation(), bottomFrame.getSize()));
3124 myTopFrame.addAlignmentPanel(topPanel, false);
3125 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3131 topFrame.getAlignPanels().clear();
3132 bottomFrame.getAlignPanels().clear();
3139 * The dust settles...give focus to the tab we did this from.
3141 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3145 public static AlignFrame getCurrentAlignFrame()
3147 return currentAlignFrame;
3150 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3152 Desktop.currentAlignFrame = currentAlignFrame;