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.Window;
51 import java.awt.datatransfer.Clipboard;
52 import java.awt.datatransfer.ClipboardOwner;
53 import java.awt.datatransfer.DataFlavor;
54 import java.awt.datatransfer.Transferable;
55 import java.awt.dnd.DnDConstants;
56 import java.awt.dnd.DropTargetDragEvent;
57 import java.awt.dnd.DropTargetDropEvent;
58 import java.awt.dnd.DropTargetEvent;
59 import java.awt.dnd.DropTargetListener;
60 import java.awt.event.ActionEvent;
61 import java.awt.event.ActionListener;
62 import java.awt.event.FocusEvent;
63 import java.awt.event.FocusListener;
64 import java.awt.event.KeyEvent;
65 import java.awt.event.MouseAdapter;
66 import java.awt.event.MouseEvent;
67 import java.awt.event.MouseListener;
68 import java.awt.event.WindowAdapter;
69 import java.awt.event.WindowEvent;
70 import java.beans.PropertyChangeEvent;
71 import java.beans.PropertyChangeListener;
72 import java.beans.PropertyVetoException;
73 import java.io.BufferedInputStream;
75 import java.io.FileOutputStream;
77 import java.util.ArrayList;
78 import java.util.Hashtable;
79 import java.util.List;
80 import java.util.StringTokenizer;
81 import java.util.Vector;
82 import java.util.concurrent.ExecutorService;
83 import java.util.concurrent.Executors;
84 import java.util.concurrent.Semaphore;
86 import javax.swing.AbstractAction;
87 import javax.swing.DefaultDesktopManager;
88 import javax.swing.DesktopManager;
89 import javax.swing.JButton;
90 import javax.swing.JComboBox;
91 import javax.swing.JComponent;
92 import javax.swing.JDesktopPane;
93 import javax.swing.JFrame;
94 import javax.swing.JInternalFrame;
95 import javax.swing.JLabel;
96 import javax.swing.JMenuItem;
97 import javax.swing.JOptionPane;
98 import javax.swing.JPanel;
99 import javax.swing.JPopupMenu;
100 import javax.swing.JProgressBar;
101 import javax.swing.KeyStroke;
102 import javax.swing.SwingUtilities;
103 import javax.swing.event.HyperlinkEvent;
104 import javax.swing.event.HyperlinkEvent.EventType;
105 import javax.swing.event.MenuEvent;
106 import javax.swing.event.MenuListener;
113 * @version $Revision: 1.155 $
115 public class Desktop extends jalview.jbgui.GDesktop implements
116 DropTargetListener, ClipboardOwner, IProgressIndicator,
117 jalview.api.StructureSelectionManagerProvider
120 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
123 * news reader - null if it was never started.
125 private BlogReader jvnews = null;
127 private File projectFile;
131 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
133 public void addJalviewPropertyChangeListener(
134 PropertyChangeListener listener)
136 changeSupport.addJalviewPropertyChangeListener(listener);
140 * @param propertyName
142 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
143 * java.beans.PropertyChangeListener)
145 public void addJalviewPropertyChangeListener(String propertyName,
146 PropertyChangeListener listener)
148 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
152 * @param propertyName
154 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
155 * java.beans.PropertyChangeListener)
157 public void removeJalviewPropertyChangeListener(String propertyName,
158 PropertyChangeListener listener)
160 changeSupport.removeJalviewPropertyChangeListener(propertyName,
164 /** Singleton Desktop instance */
165 public static Desktop instance;
167 public static MyDesktopPane desktop;
169 static int openFrameCount = 0;
171 static final int xOffset = 30;
173 static final int yOffset = 30;
175 public static jalview.ws.jws1.Discoverer discoverer;
177 public static Object[] jalviewClipboard;
179 public static boolean internalCopy = false;
181 static int fileLoadingCount = 0;
183 class MyDesktopManager implements DesktopManager
186 private DesktopManager delegate;
188 public MyDesktopManager(DesktopManager delegate)
190 this.delegate = delegate;
194 public void activateFrame(JInternalFrame f)
198 delegate.activateFrame(f);
199 } catch (NullPointerException npe)
201 Point p = getMousePosition();
202 instance.showPasteMenu(p.x, p.y);
207 public void beginDraggingFrame(JComponent f)
209 delegate.beginDraggingFrame(f);
213 public void beginResizingFrame(JComponent f, int direction)
215 delegate.beginResizingFrame(f, direction);
219 public void closeFrame(JInternalFrame f)
221 delegate.closeFrame(f);
225 public void deactivateFrame(JInternalFrame f)
227 delegate.deactivateFrame(f);
231 public void deiconifyFrame(JInternalFrame f)
233 delegate.deiconifyFrame(f);
237 public void dragFrame(JComponent f, int newX, int newY)
243 delegate.dragFrame(f, newX, newY);
247 public void endDraggingFrame(JComponent f)
249 delegate.endDraggingFrame(f);
253 public void endResizingFrame(JComponent f)
255 delegate.endResizingFrame(f);
259 public void iconifyFrame(JInternalFrame f)
261 delegate.iconifyFrame(f);
265 public void maximizeFrame(JInternalFrame f)
267 delegate.maximizeFrame(f);
271 public void minimizeFrame(JInternalFrame f)
273 delegate.minimizeFrame(f);
277 public void openFrame(JInternalFrame f)
279 delegate.openFrame(f);
283 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
290 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
294 public void setBoundsForFrame(JComponent f, int newX, int newY,
295 int newWidth, int newHeight)
297 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
300 // All other methods, simply delegate
305 * Creates a new Desktop object.
310 * A note to implementors. It is ESSENTIAL that any activities that might
311 * block are spawned off as threads rather than waited for during this
315 doVamsasClientCheck();
317 groovyShell = new JMenuItem();
318 groovyShell.setText(MessageManager.getString("label.groovy_console"));
319 groovyShell.addActionListener(new ActionListener()
322 public void actionPerformed(ActionEvent e)
324 groovyShell_actionPerformed();
327 toolsMenu.add(groovyShell);
328 groovyShell.setVisible(true);
330 doConfigureStructurePrefs();
331 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
332 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
333 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
335 boolean showjconsole = jalview.bin.Cache.getDefault(
336 "SHOW_JAVA_CONSOLE", false);
337 desktop = new MyDesktopPane(selmemusage);
338 if (Platform.isAMac())
340 desktop.setDoubleBuffered(false);
342 showMemusage.setSelected(selmemusage);
343 desktop.setBackground(Color.white);
344 getContentPane().setLayout(new BorderLayout());
345 // alternate config - have scrollbars - see notes in JAL-153
346 // JScrollPane sp = new JScrollPane();
347 // sp.getViewport().setView(desktop);
348 // getContentPane().add(sp, BorderLayout.CENTER);
349 getContentPane().add(desktop, BorderLayout.CENTER);
350 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
352 // This line prevents Windows Look&Feel resizing all new windows to maximum
353 // if previous window was maximised
354 desktop.setDesktopManager(new MyDesktopManager(
355 new DefaultDesktopManager()));
357 Rectangle dims = getLastKnownDimensions("");
364 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
365 setBounds((screenSize.width - 900) / 2,
366 (screenSize.height - 650) / 2, 900, 650);
368 jconsole = new Console(this, showjconsole);
369 // add essential build information
370 jconsole.setHeader("Jalview Version: "
371 + jalview.bin.Cache.getProperty("VERSION") + "\n"
372 + "Jalview Installation: "
373 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
374 + "\n" + "Build Date: "
375 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
376 + "Java version: " + System.getProperty("java.version") + "\n"
377 + System.getProperty("os.arch") + " "
378 + System.getProperty("os.name") + " "
379 + System.getProperty("os.version"));
381 showConsole(showjconsole);
383 showNews.setVisible(false);
385 this.addWindowListener(new WindowAdapter()
388 public void windowClosing(WindowEvent evt)
395 this.addMouseListener(ma = new MouseAdapter()
398 public void mousePressed(MouseEvent evt)
400 if (evt.isPopupTrigger())
402 showPasteMenu(evt.getX(), evt.getY());
406 desktop.addMouseListener(ma);
408 this.addFocusListener(new FocusListener()
412 public void focusLost(FocusEvent e)
414 // TODO Auto-generated method stub
419 public void focusGained(FocusEvent e)
421 Cache.log.debug("Relaying windows after focus gain");
422 // make sure that we sort windows properly after we gain focus
423 instance.relayerWindows();
426 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
427 // Spawn a thread that shows the splashscreen
428 SwingUtilities.invokeLater(new Runnable()
438 // Thread off a new instance of the file chooser - this reduces the time it
439 // takes to open it later on.
440 new Thread(new Runnable()
445 Cache.log.debug("Filechooser init thread started.");
446 new JalviewFileChooser(
447 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
448 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
449 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
450 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
451 Cache.log.debug("Filechooser init thread finished.");
454 // Add the service change listener
455 changeSupport.addJalviewPropertyChangeListener("services",
456 new PropertyChangeListener()
460 public void propertyChange(PropertyChangeEvent evt)
462 Cache.log.debug("Firing service changed event for "
463 + evt.getNewValue());
464 JalviewServicesChanged(evt);
470 public void doConfigureStructurePrefs()
472 // configure services
473 StructureSelectionManager ssm = StructureSelectionManager
474 .getStructureSelectionManager(this);
475 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
477 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
478 Preferences.ADD_TEMPFACT_ANN, true));
479 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
480 Preferences.STRUCT_FROM_PDB, true));
481 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
482 Preferences.USE_RNAVIEW, true));
486 ssm.setAddTempFacAnnot(false);
487 ssm.setProcessSecondaryStructure(false);
488 ssm.setSecStructServices(false);
492 public void checkForNews()
494 final Desktop me = this;
495 // Thread off the news reader, in case there are connection problems.
496 addDialogThread(new Runnable()
501 Cache.log.debug("Starting news thread.");
503 jvnews = new BlogReader(me);
504 showNews.setVisible(true);
505 Cache.log.debug("Completed news thread.");
511 protected void showNews_actionPerformed(ActionEvent e)
513 showNews(showNews.isSelected());
516 void showNews(boolean visible)
519 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
520 showNews.setSelected(visible);
521 if (visible && !jvnews.isVisible())
523 new Thread(new Runnable()
528 long now = System.currentTimeMillis();
529 Desktop.instance.setProgressBar(
530 MessageManager.getString("status.refreshing_news"), now);
531 jvnews.refreshNews();
532 Desktop.instance.setProgressBar(null, now);
541 * recover the last known dimensions for a jalview window
544 * - empty string is desktop, all other windows have unique prefix
545 * @return null or last known dimensions scaled to current geometry (if last
546 * window geom was known)
548 Rectangle getLastKnownDimensions(String windowName)
550 // TODO: lock aspect ratio for scaling desktop Bug #0058199
551 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
552 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
553 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
554 String width = jalview.bin.Cache.getProperty(windowName
556 String height = jalview.bin.Cache.getProperty(windowName
558 if ((x != null) && (y != null) && (width != null) && (height != null))
560 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
561 .parseInt(width), ih = Integer.parseInt(height);
562 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
564 // attempt #1 - try to cope with change in screen geometry - this
565 // version doesn't preserve original jv aspect ratio.
566 // take ratio of current screen size vs original screen size.
567 double sw = ((1f * screenSize.width) / (1f * Integer
568 .parseInt(jalview.bin.Cache
569 .getProperty("SCREENGEOMETRY_WIDTH"))));
570 double sh = ((1f * screenSize.height) / (1f * Integer
571 .parseInt(jalview.bin.Cache
572 .getProperty("SCREENGEOMETRY_HEIGHT"))));
573 // rescale the bounds depending upon the current screen geometry.
574 ix = (int) (ix * sw);
575 iw = (int) (iw * sw);
576 iy = (int) (iy * sh);
577 ih = (int) (ih * sh);
578 while (ix >= screenSize.width)
580 jalview.bin.Cache.log
581 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
582 ix -= screenSize.width;
584 while (iy >= screenSize.height)
586 jalview.bin.Cache.log
587 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
588 iy -= screenSize.height;
590 jalview.bin.Cache.log.debug("Got last known dimensions for "
591 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
594 // return dimensions for new instance
595 return new Rectangle(ix, iy, iw, ih);
600 private void doVamsasClientCheck()
602 if (jalview.bin.Cache.vamsasJarsPresent())
604 setupVamsasDisconnectedGui();
605 VamsasMenu.setVisible(true);
606 final Desktop us = this;
607 VamsasMenu.addMenuListener(new MenuListener()
609 // this listener remembers when the menu was first selected, and
610 // doesn't rebuild the session list until it has been cleared and
612 boolean refresh = true;
615 public void menuCanceled(MenuEvent e)
621 public void menuDeselected(MenuEvent e)
627 public void menuSelected(MenuEvent e)
631 us.buildVamsasStMenu();
636 vamsasStart.setVisible(true);
640 void showPasteMenu(int x, int y)
642 JPopupMenu popup = new JPopupMenu();
643 JMenuItem item = new JMenuItem(
644 MessageManager.getString("label.paste_new_window"));
645 item.addActionListener(new ActionListener()
648 public void actionPerformed(ActionEvent evt)
655 popup.show(this, x, y);
662 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
663 Transferable contents = c.getContents(this);
665 if (contents != null)
667 String file = (String) contents
668 .getTransferData(DataFlavor.stringFlavor);
670 String format = new IdentifyFile().identify(file,
671 FormatAdapter.PASTE);
673 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
676 } catch (Exception ex)
679 .println("Unable to paste alignment from system clipboard:\n"
685 * Adds and opens the given frame to the desktop
696 public static synchronized void addInternalFrame(
697 final JInternalFrame frame, String title, int w, int h)
699 addInternalFrame(frame, title, true, w, h, true);
703 * Add an internal frame to the Jalview desktop
710 * When true, display frame immediately, otherwise, caller must call
711 * setVisible themselves.
717 public static synchronized void addInternalFrame(
718 final JInternalFrame frame, String title, boolean makeVisible,
721 addInternalFrame(frame, title, makeVisible, w, h, true);
725 * Add an internal frame to the Jalview desktop and make it visible
738 public static synchronized void addInternalFrame(
739 final JInternalFrame frame, String title, int w, int h,
742 addInternalFrame(frame, title, true, w, h, resizable);
746 * Add an internal frame to the Jalview desktop
753 * When true, display frame immediately, otherwise, caller must call
754 * setVisible themselves.
762 public static synchronized void addInternalFrame(
763 final JInternalFrame frame, String title, boolean makeVisible,
764 int w, int h, boolean resizable)
767 // TODO: allow callers to determine X and Y position of frame (eg. via
769 // TODO: consider fixing method to update entries in the window submenu with
770 // the current window title
772 frame.setTitle(title);
773 if (frame.getWidth() < 1 || frame.getHeight() < 1)
777 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
778 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
779 // IF JALVIEW IS RUNNING HEADLESS
780 // ///////////////////////////////////////////////
782 || (System.getProperty("java.awt.headless") != null && System
783 .getProperty("java.awt.headless").equals("true")))
790 frame.setVisible(makeVisible);
791 frame.setClosable(true);
792 frame.setResizable(resizable);
793 frame.setMaximizable(resizable);
794 frame.setIconifiable(resizable);
795 if (Platform.isAMac())
797 frame.setIconifiable(false);
798 frame.setFrameIcon(null);
799 // frame.setDesktopIcon(null);
800 frame.setDoubleBuffered(false);
802 if (frame.getX() < 1 && frame.getY() < 1)
804 frame.setLocation(xOffset * openFrameCount, yOffset
805 * ((openFrameCount - 1) % 10) + yOffset);
808 final JMenuItem menuItem = new JMenuItem(title);
809 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
812 public void internalFrameActivated(
813 javax.swing.event.InternalFrameEvent evt)
815 JInternalFrame itf = desktop.getSelectedFrame();
824 public void internalFrameClosed(
825 javax.swing.event.InternalFrameEvent evt)
827 PaintRefresher.RemoveComponent(frame);
829 windowMenu.remove(menuItem);
830 JInternalFrame itf = desktop.getSelectedFrame();
839 menuItem.addActionListener(new ActionListener()
842 public void actionPerformed(ActionEvent e)
846 frame.setSelected(true);
847 frame.setIcon(false);
848 } catch (java.beans.PropertyVetoException ex)
854 menuItem.addMouseListener(new MouseListener()
858 public void mouseReleased(MouseEvent e)
863 public void mousePressed(MouseEvent e)
868 public void mouseExited(MouseEvent e)
872 frame.setSelected(false);
873 } catch (PropertyVetoException e1)
879 public void mouseEntered(MouseEvent e)
883 frame.setSelected(true);
884 } catch (PropertyVetoException e1)
890 public void mouseClicked(MouseEvent e)
896 windowMenu.add(menuItem);
902 frame.setSelected(true);
903 frame.requestFocus();
904 } catch (java.beans.PropertyVetoException ve)
906 } catch (java.lang.ClassCastException cex)
909 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
915 public void lostOwnership(Clipboard clipboard, Transferable contents)
919 Desktop.jalviewClipboard = null;
922 internalCopy = false;
926 public void dragEnter(DropTargetDragEvent evt)
931 public void dragExit(DropTargetEvent evt)
936 public void dragOver(DropTargetDragEvent evt)
941 public void dropActionChanged(DropTargetDragEvent evt)
952 public void drop(DropTargetDropEvent evt)
954 boolean success = true;
955 Transferable t = evt.getTransferable();
956 java.util.List<String> files = new ArrayList<String>();
957 java.util.List<String> protocols = new ArrayList<String>();
961 Desktop.transferFromDropTarget(files, protocols, evt, t);
962 } catch (Exception e)
972 for (int i = 0; i < files.size(); i++)
974 String file = files.get(i).toString();
975 String protocol = (protocols == null) ? FormatAdapter.FILE
976 : (String) protocols.get(i);
977 String format = null;
979 if (file.endsWith(".jar"))
986 format = new IdentifyFile().identify(file, protocol);
989 new FileLoader().LoadFile(file, protocol, format);
992 } catch (Exception ex)
997 evt.dropComplete(success); // need this to ensure input focus is properly
998 // transfered to any new windows created
1008 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1010 JalviewFileChooser chooser = new JalviewFileChooser(
1011 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1012 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1013 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1014 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1016 chooser.setFileView(new JalviewFileView());
1017 chooser.setDialogTitle(MessageManager
1018 .getString("label.open_local_file"));
1019 chooser.setToolTipText(MessageManager.getString("action.open"));
1021 int value = chooser.showOpenDialog(this);
1023 if (value == JalviewFileChooser.APPROVE_OPTION)
1025 String choice = chooser.getSelectedFile().getPath();
1026 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1027 .getSelectedFile().getParent());
1029 String format = null;
1030 if (chooser.getSelectedFormat() != null
1031 && chooser.getSelectedFormat().equals("Jalview"))
1037 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1040 if (viewport != null)
1042 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1047 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1059 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1061 // This construct allows us to have a wider textfield
1063 JLabel label = new JLabel(
1064 MessageManager.getString("label.input_file_url"));
1065 final JComboBox history = new JComboBox();
1067 JPanel panel = new JPanel(new GridLayout(2, 1));
1070 history.setPreferredSize(new Dimension(400, 20));
1071 history.setEditable(true);
1072 history.addItem("http://www.");
1074 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1078 if (historyItems != null)
1080 st = new StringTokenizer(historyItems, "\t");
1082 while (st.hasMoreTokens())
1084 history.addItem(st.nextElement());
1088 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1089 MessageManager.getString("label.input_alignment_from_url"),
1090 JOptionPane.OK_CANCEL_OPTION);
1092 if (reply != JOptionPane.OK_OPTION)
1097 String url = history.getSelectedItem().toString();
1099 if (url.toLowerCase().endsWith(".jar"))
1101 if (viewport != null)
1103 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1108 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1113 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1115 if (format.equals("URL NOT FOUND"))
1117 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1118 MessageManager.formatMessage("label.couldnt_locate",
1119 new Object[] { url }), MessageManager
1120 .getString("label.url_not_found"),
1121 JOptionPane.WARNING_MESSAGE);
1126 if (viewport != null)
1128 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1132 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1138 * Opens the CutAndPaste window for the user to paste an alignment in to
1141 * - if not null, the pasted alignment is added to the current
1142 * alignment; if null, to a new alignment window
1145 public void inputTextboxMenuItem_actionPerformed(
1146 AlignmentViewPanel viewPanel)
1148 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1149 cap.setForInput(viewPanel);
1150 Desktop.addInternalFrame(cap,
1151 MessageManager.getString("label.cut_paste_alignmen_file"),
1161 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1163 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1164 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1166 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1167 getBounds().y, getWidth(), getHeight()));
1169 if (jconsole != null)
1171 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1172 jconsole.stopConsole();
1176 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1179 if (dialogExecutor != null)
1181 dialogExecutor.shutdownNow();
1183 closeAll_actionPerformed(null);
1185 if (groovyConsole != null)
1187 groovyConsole.exit();
1192 private void storeLastKnownDimensions(String string, Rectangle jc)
1194 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1195 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1196 + " height:" + jc.height);
1198 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1199 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1200 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1201 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1211 public void aboutMenuItem_actionPerformed(ActionEvent e)
1213 // StringBuffer message = getAboutMessage(false);
1214 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1216 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1217 new Thread(new Runnable()
1222 new SplashScreen(true);
1227 public StringBuffer getAboutMessage(boolean shortv)
1229 StringBuffer message = new StringBuffer();
1230 message.append("<html>");
1233 message.append("<h1><strong>Version: "
1234 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1235 message.append("<strong>Last Updated: <em>"
1236 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1237 + "</em></strong>");
1243 message.append("<strong>Version "
1244 + jalview.bin.Cache.getProperty("VERSION")
1245 + "; last updated: "
1246 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1249 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1252 message.append("<br>...Checking latest version...</br>");
1254 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1255 .equals(jalview.bin.Cache.getProperty("VERSION")))
1257 boolean red = false;
1258 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1259 .indexOf("automated build") == -1)
1262 // Displayed when code version and jnlp version do not match and code
1263 // version is not a development build
1264 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1267 message.append("<br>!! Version "
1268 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1270 + " is available for download from "
1271 + jalview.bin.Cache.getDefault("www.jalview.org",
1272 "http://www.jalview.org") + " !!");
1275 message.append("</div>");
1278 message.append("<br>Authors: "
1280 .getDefault("AUTHORFNAMES",
1281 "The Jalview Authors (See AUTHORS file for current list)")
1282 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1283 + "<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"
1284 + "<br><br>If you use Jalview, please cite:"
1285 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1286 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1287 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1299 public void documentationMenuItem_actionPerformed(ActionEvent e)
1303 Help.showHelpWindow();
1304 } catch (Exception ex)
1310 public void closeAll_actionPerformed(ActionEvent e)
1312 JInternalFrame[] frames = desktop.getAllFrames();
1313 for (int i = 0; i < frames.length; i++)
1317 frames[i].setClosed(true);
1318 } catch (java.beans.PropertyVetoException ex)
1322 System.out.println("ALL CLOSED");
1323 if (v_client != null)
1325 // TODO clear binding to vamsas document objects on close_all
1329 * reset state of singleton objects as appropriate (clear down session state
1330 * when all windows are closed)
1332 StructureSelectionManager ssm = StructureSelectionManager
1333 .getStructureSelectionManager(this);
1341 public void raiseRelated_actionPerformed(ActionEvent e)
1343 reorderAssociatedWindows(false, false);
1347 public void minimizeAssociated_actionPerformed(ActionEvent e)
1349 reorderAssociatedWindows(true, false);
1352 void closeAssociatedWindows()
1354 reorderAssociatedWindows(false, true);
1360 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1364 protected void garbageCollect_actionPerformed(ActionEvent e)
1366 // We simply collect the garbage
1367 jalview.bin.Cache.log.debug("Collecting garbage...");
1369 jalview.bin.Cache.log.debug("Finished garbage collection.");
1376 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1380 protected void showMemusage_actionPerformed(ActionEvent e)
1382 desktop.showMemoryUsage(showMemusage.isSelected());
1389 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1393 protected void showConsole_actionPerformed(ActionEvent e)
1395 showConsole(showConsole.isSelected());
1398 Console jconsole = null;
1401 * control whether the java console is visible or not
1405 void showConsole(boolean selected)
1407 showConsole.setSelected(selected);
1408 // TODO: decide if we should update properties file
1409 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1411 jconsole.setVisible(selected);
1414 void reorderAssociatedWindows(boolean minimize, boolean close)
1416 JInternalFrame[] frames = desktop.getAllFrames();
1417 if (frames == null || frames.length < 1)
1422 AlignmentViewport source = null, target = null;
1423 if (frames[0] instanceof AlignFrame)
1425 source = ((AlignFrame) frames[0]).getCurrentView();
1427 else if (frames[0] instanceof TreePanel)
1429 source = ((TreePanel) frames[0]).getViewPort();
1431 else if (frames[0] instanceof PCAPanel)
1433 source = ((PCAPanel) frames[0]).av;
1435 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1437 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1442 for (int i = 0; i < frames.length; i++)
1445 if (frames[i] == null)
1449 if (frames[i] instanceof AlignFrame)
1451 target = ((AlignFrame) frames[i]).getCurrentView();
1453 else if (frames[i] instanceof TreePanel)
1455 target = ((TreePanel) frames[i]).getViewPort();
1457 else if (frames[i] instanceof PCAPanel)
1459 target = ((PCAPanel) frames[i]).av;
1461 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1463 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1466 if (source == target)
1472 frames[i].setClosed(true);
1476 frames[i].setIcon(minimize);
1479 frames[i].toFront();
1483 } catch (java.beans.PropertyVetoException ex)
1498 protected void preferences_actionPerformed(ActionEvent e)
1510 public void saveState_actionPerformed(ActionEvent e)
1512 JalviewFileChooser chooser = new JalviewFileChooser(
1513 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1514 new String[] { "jvp" }, new String[] { "Jalview Project" },
1517 chooser.setFileView(new JalviewFileView());
1518 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1520 int value = chooser.showSaveDialog(this);
1522 if (value == JalviewFileChooser.APPROVE_OPTION)
1524 final Desktop me = this;
1525 final java.io.File choice = chooser.getSelectedFile();
1526 setProjectFile(choice);
1528 new Thread(new Runnable()
1533 // TODO: refactor to Jalview desktop session controller action.
1534 setProgressBar(MessageManager.formatMessage(
1535 "label.saving_jalview_project",
1536 new Object[] { choice.getName() }), choice.hashCode());
1537 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1538 choice.getParent());
1539 // TODO catch and handle errors for savestate
1540 // TODO prevent user from messing with the Desktop whilst we're saving
1543 new Jalview2XML().saveState(choice);
1544 } catch (OutOfMemoryError oom)
1546 new OOMWarning("Whilst saving current state to "
1547 + choice.getName(), oom);
1548 } catch (Exception ex)
1551 "Problems whilst trying to save to " + choice.getName(),
1553 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1554 "label.error_whilst_saving_current_state_to",
1555 new Object[] { choice.getName() }), MessageManager
1556 .getString("label.couldnt_save_project"),
1557 JOptionPane.WARNING_MESSAGE);
1559 setProgressBar(null, choice.hashCode());
1565 private void setProjectFile(File choice)
1567 this.projectFile = choice;
1570 public File getProjectFile()
1572 return this.projectFile;
1582 public void loadState_actionPerformed(ActionEvent e)
1584 JalviewFileChooser chooser = new JalviewFileChooser(
1585 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1586 "jvp", "jar" }, new String[] { "Jalview Project",
1587 "Jalview Project (old)" }, "Jalview Project");
1588 chooser.setFileView(new JalviewFileView());
1589 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1591 int value = chooser.showOpenDialog(this);
1593 if (value == JalviewFileChooser.APPROVE_OPTION)
1595 final File selectedFile = chooser.getSelectedFile();
1596 setProjectFile(selectedFile);
1597 final String choice = selectedFile.getAbsolutePath();
1598 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1599 selectedFile.getParent());
1600 new Thread(new Runnable()
1606 MessageManager.formatMessage(
1607 "label.loading_jalview_project",
1608 new Object[] { choice }), choice.hashCode());
1611 new Jalview2XML().loadJalviewAlign(choice);
1612 } catch (OutOfMemoryError oom)
1614 new OOMWarning("Whilst loading project from " + choice, oom);
1615 } catch (Exception ex)
1617 Cache.log.error("Problems whilst loading project from "
1619 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1621 "label.error_whilst_loading_project_from",
1622 new Object[] { choice }), MessageManager
1623 .getString("label.couldnt_load_project"),
1624 JOptionPane.WARNING_MESSAGE);
1626 setProgressBar(null, choice.hashCode());
1633 public void inputSequence_actionPerformed(ActionEvent e)
1635 new SequenceFetcher(this);
1638 JPanel progressPanel;
1640 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1642 public void startLoading(final String fileName)
1644 if (fileLoadingCount == 0)
1646 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1647 "label.loading_file", new Object[] { fileName })));
1652 private JPanel addProgressPanel(String string)
1654 if (progressPanel == null)
1656 progressPanel = new JPanel(new GridLayout(1, 1));
1657 totalProgressCount = 0;
1658 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1660 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1661 JProgressBar progressBar = new JProgressBar();
1662 progressBar.setIndeterminate(true);
1664 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1666 thisprogress.add(progressBar, BorderLayout.CENTER);
1667 progressPanel.add(thisprogress);
1668 ((GridLayout) progressPanel.getLayout())
1669 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1670 ++totalProgressCount;
1671 instance.validate();
1672 return thisprogress;
1675 int totalProgressCount = 0;
1677 private void removeProgressPanel(JPanel progbar)
1679 if (progressPanel != null)
1681 synchronized (progressPanel)
1683 progressPanel.remove(progbar);
1684 GridLayout gl = (GridLayout) progressPanel.getLayout();
1685 gl.setRows(gl.getRows() - 1);
1686 if (--totalProgressCount < 1)
1688 this.getContentPane().remove(progressPanel);
1689 progressPanel = null;
1696 public void stopLoading()
1699 if (fileLoadingCount < 1)
1701 while (fileLoadingPanels.size() > 0)
1703 removeProgressPanel(fileLoadingPanels.remove(0));
1705 fileLoadingPanels.clear();
1706 fileLoadingCount = 0;
1711 public static int getViewCount(String alignmentId)
1713 AlignmentViewport[] aps = getViewports(alignmentId);
1714 return (aps == null) ? 0 : aps.length;
1719 * @param alignmentId
1720 * - if null, all sets are returned
1721 * @return all AlignmentPanels concerning the alignmentId sequence set
1723 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1725 if (Desktop.desktop == null)
1727 // no frames created and in headless mode
1728 // TODO: verify that frames are recoverable when in headless mode
1731 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1732 AlignFrame[] frames = getAlignFrames();
1737 for (AlignFrame af : frames)
1739 for (AlignmentPanel ap : af.alignPanels)
1741 if (alignmentId == null
1742 || alignmentId.equals(ap.av.getSequenceSetId()))
1748 if (aps.size() == 0)
1752 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1757 * get all the viewports on an alignment.
1759 * @param sequenceSetId
1760 * unique alignment id (may be null - all viewports returned in that
1762 * @return all viewports on the alignment bound to sequenceSetId
1764 public static AlignmentViewport[] getViewports(String sequenceSetId)
1766 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1767 if (desktop != null)
1769 AlignFrame[] frames = Desktop.getAlignFrames();
1771 for (AlignFrame afr : frames)
1773 if (sequenceSetId == null
1774 || afr.getViewport().getSequenceSetId()
1775 .equals(sequenceSetId))
1777 if (afr.alignPanels != null)
1779 for (AlignmentPanel ap : afr.alignPanels)
1781 if (sequenceSetId == null
1782 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1790 viewp.add(afr.getViewport());
1794 if (viewp.size() > 0)
1796 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1803 * Explode the views in the given frame into separate AlignFrame
1807 public void explodeViews(AlignFrame af)
1809 int size = af.alignPanels.size();
1815 for (int i = 0; i < size; i++)
1817 AlignmentPanel ap = af.alignPanels.get(i);
1818 AlignFrame newaf = new AlignFrame(ap);
1821 * Restore the view's last exploded frame geometry if known. Multiple
1822 * views from one exploded frame share and restore the same (frame)
1823 * position and size.
1825 Rectangle geometry = ap.av.getExplodedGeometry();
1826 if (geometry != null)
1828 newaf.setBounds(geometry);
1831 ap.av.setGatherViewsHere(false);
1833 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1834 AlignFrame.DEFAULT_HEIGHT);
1837 af.alignPanels.clear();
1838 af.closeMenuItem_actionPerformed(true);
1843 * Gather expanded views (separate AlignFrame's) with the same sequence set
1844 * identifier back in to this frame as additional views, and close the
1845 * expanded views. Note the expanded frames may themselves have multiple
1846 * views. We take the lot.
1850 public void gatherViews(AlignFrame source)
1852 source.viewport.setGatherViewsHere(true);
1853 source.viewport.setExplodedGeometry(source.getBounds());
1854 JInternalFrame[] frames = desktop.getAllFrames();
1855 String viewId = source.viewport.getSequenceSetId();
1857 for (int t = 0; t < frames.length; t++)
1859 if (frames[t] instanceof AlignFrame && frames[t] != source)
1861 AlignFrame af = (AlignFrame) frames[t];
1862 boolean gatherThis = false;
1863 for (int a = 0; a < af.alignPanels.size(); a++)
1865 AlignmentPanel ap = af.alignPanels.get(a);
1866 if (viewId.equals(ap.av.getSequenceSetId()))
1869 ap.av.setGatherViewsHere(false);
1870 ap.av.setExplodedGeometry(af.getBounds());
1871 source.addAlignmentPanel(ap, false);
1877 af.alignPanels.clear();
1878 af.closeMenuItem_actionPerformed(true);
1885 jalview.gui.VamsasApplication v_client = null;
1888 public void vamsasImport_actionPerformed(ActionEvent e)
1890 if (v_client == null)
1892 // Load and try to start a session.
1893 JalviewFileChooser chooser = new JalviewFileChooser(
1894 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1896 chooser.setFileView(new JalviewFileView());
1897 chooser.setDialogTitle(MessageManager
1898 .getString("label.open_saved_vamsas_session"));
1899 chooser.setToolTipText(MessageManager
1900 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1902 int value = chooser.showOpenDialog(this);
1904 if (value == JalviewFileChooser.APPROVE_OPTION)
1906 String fle = chooser.getSelectedFile().toString();
1907 if (!vamsasImport(chooser.getSelectedFile()))
1910 .showInternalMessageDialog(
1912 MessageManager.formatMessage(
1913 "label.couldnt_import_as_vamsas_session",
1914 new Object[] { fle }),
1916 .getString("label.vamsas_document_import_failed"),
1917 JOptionPane.ERROR_MESSAGE);
1923 jalview.bin.Cache.log
1924 .error("Implementation error - load session from a running session is not supported.");
1929 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1932 * @return true if import was a success and a session was started.
1934 public boolean vamsasImport(URL url)
1936 // TODO: create progress bar
1937 if (v_client != null)
1940 jalview.bin.Cache.log
1941 .error("Implementation error - load session from a running session is not supported.");
1947 // copy the URL content to a temporary local file
1948 // TODO: be a bit cleverer here with nio (?!)
1949 File file = File.createTempFile("vdocfromurl", ".vdj");
1950 FileOutputStream fos = new FileOutputStream(file);
1951 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1952 byte[] buffer = new byte[2048];
1954 while ((ln = bis.read(buffer)) > -1)
1956 fos.write(buffer, 0, ln);
1960 v_client = new jalview.gui.VamsasApplication(this, file,
1961 url.toExternalForm());
1962 } catch (Exception ex)
1964 jalview.bin.Cache.log.error(
1965 "Failed to create new vamsas session from contents of URL "
1969 setupVamsasConnectedGui();
1970 v_client.initial_update(); // TODO: thread ?
1971 return v_client.inSession();
1975 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1978 * @return true if import was a success and a session was started.
1980 public boolean vamsasImport(File file)
1982 if (v_client != null)
1985 jalview.bin.Cache.log
1986 .error("Implementation error - load session from a running session is not supported.");
1990 setProgressBar(MessageManager.formatMessage(
1991 "status.importing_vamsas_session_from",
1992 new Object[] { file.getName() }), file.hashCode());
1995 v_client = new jalview.gui.VamsasApplication(this, file, null);
1996 } catch (Exception ex)
1998 setProgressBar(MessageManager.formatMessage(
1999 "status.importing_vamsas_session_from",
2000 new Object[] { file.getName() }), file.hashCode());
2001 jalview.bin.Cache.log.error(
2002 "New vamsas session from existing session file failed:", ex);
2005 setupVamsasConnectedGui();
2006 v_client.initial_update(); // TODO: thread ?
2007 setProgressBar(MessageManager.formatMessage(
2008 "status.importing_vamsas_session_from",
2009 new Object[] { file.getName() }), file.hashCode());
2010 return v_client.inSession();
2013 public boolean joinVamsasSession(String mysesid)
2015 if (v_client != null)
2019 .getString("error.try_join_vamsas_session_another"));
2021 if (mysesid == null)
2024 MessageManager.getString("error.invalid_vamsas_session_id"));
2026 v_client = new VamsasApplication(this, mysesid);
2027 setupVamsasConnectedGui();
2028 v_client.initial_update();
2029 return (v_client.inSession());
2033 public void vamsasStart_actionPerformed(ActionEvent e)
2035 if (v_client == null)
2038 // we just start a default session for moment.
2040 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2041 * getProperty("LAST_DIRECTORY"));
2043 * chooser.setFileView(new JalviewFileView());
2044 * chooser.setDialogTitle("Load Vamsas file");
2045 * chooser.setToolTipText("Import");
2047 * int value = chooser.showOpenDialog(this);
2049 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2050 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2052 v_client = new VamsasApplication(this);
2053 setupVamsasConnectedGui();
2054 v_client.initial_update(); // TODO: thread ?
2058 // store current data in session.
2059 v_client.push_update(); // TODO: thread
2063 protected void setupVamsasConnectedGui()
2065 vamsasStart.setText(MessageManager.getString("label.session_update"));
2066 vamsasSave.setVisible(true);
2067 vamsasStop.setVisible(true);
2068 vamsasImport.setVisible(false); // Document import to existing session is
2069 // not possible for vamsas-client-1.0.
2072 protected void setupVamsasDisconnectedGui()
2074 vamsasSave.setVisible(false);
2075 vamsasStop.setVisible(false);
2076 vamsasImport.setVisible(true);
2077 vamsasStart.setText(MessageManager
2078 .getString("label.new_vamsas_session"));
2082 public void vamsasStop_actionPerformed(ActionEvent e)
2084 if (v_client != null)
2086 v_client.end_session();
2088 setupVamsasDisconnectedGui();
2092 protected void buildVamsasStMenu()
2094 if (v_client == null)
2096 String[] sess = null;
2099 sess = VamsasApplication.getSessionList();
2100 } catch (Exception e)
2102 jalview.bin.Cache.log.warn(
2103 "Problem getting current sessions list.", e);
2108 jalview.bin.Cache.log.debug("Got current sessions list: "
2109 + sess.length + " entries.");
2110 VamsasStMenu.removeAll();
2111 for (int i = 0; i < sess.length; i++)
2113 JMenuItem sessit = new JMenuItem();
2114 sessit.setText(sess[i]);
2115 sessit.setToolTipText(MessageManager.formatMessage(
2116 "label.connect_to_session", new Object[] { sess[i] }));
2117 final Desktop dsktp = this;
2118 final String mysesid = sess[i];
2119 sessit.addActionListener(new ActionListener()
2123 public void actionPerformed(ActionEvent e)
2125 if (dsktp.v_client == null)
2127 Thread rthr = new Thread(new Runnable()
2133 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2134 dsktp.setupVamsasConnectedGui();
2135 dsktp.v_client.initial_update();
2143 VamsasStMenu.add(sessit);
2145 // don't show an empty menu.
2146 VamsasStMenu.setVisible(sess.length > 0);
2151 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2152 VamsasStMenu.removeAll();
2153 VamsasStMenu.setVisible(false);
2158 // Not interested in the content. Just hide ourselves.
2159 VamsasStMenu.setVisible(false);
2164 public void vamsasSave_actionPerformed(ActionEvent e)
2166 if (v_client != null)
2168 JalviewFileChooser chooser = new JalviewFileChooser(
2169 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2170 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2171 new String[] { "Vamsas Document" }, "Vamsas Document");
2173 chooser.setFileView(new JalviewFileView());
2174 chooser.setDialogTitle(MessageManager
2175 .getString("label.save_vamsas_document_archive"));
2177 int value = chooser.showSaveDialog(this);
2179 if (value == JalviewFileChooser.APPROVE_OPTION)
2181 java.io.File choice = chooser.getSelectedFile();
2182 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2183 "label.saving_vamsas_doc",
2184 new Object[] { choice.getName() }));
2185 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2186 String warnmsg = null;
2187 String warnttl = null;
2190 v_client.vclient.storeDocument(choice);
2193 warnttl = "Serious Problem saving Vamsas Document";
2194 warnmsg = ex.toString();
2195 jalview.bin.Cache.log.error("Error Whilst saving document to "
2198 } catch (Exception ex)
2200 warnttl = "Problem saving Vamsas Document.";
2201 warnmsg = ex.toString();
2202 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2206 removeProgressPanel(progpanel);
2207 if (warnmsg != null)
2209 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2211 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2217 JPanel vamUpdate = null;
2220 * hide vamsas user gui bits when a vamsas document event is being handled.
2223 * true to hide gui, false to reveal gui
2225 public void setVamsasUpdate(boolean b)
2227 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2228 + (b ? "in progress" : "finished"));
2230 if (vamUpdate != null)
2232 this.removeProgressPanel(vamUpdate);
2236 vamUpdate = this.addProgressPanel(MessageManager
2237 .getString("label.updating_vamsas_session"));
2239 vamsasStart.setVisible(!b);
2240 vamsasStop.setVisible(!b);
2241 vamsasSave.setVisible(!b);
2244 public JInternalFrame[] getAllFrames()
2246 return desktop.getAllFrames();
2250 * Checks the given url to see if it gives a response indicating that the user
2251 * should be informed of a new questionnaire.
2255 public void checkForQuestionnaire(String url)
2257 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2258 // javax.swing.SwingUtilities.invokeLater(jvq);
2259 new Thread(jvq).start();
2263 * Proxy class for JDesktopPane which optionally displays the current memory
2264 * usage and highlights the desktop area with a red bar if free memory runs
2269 public class MyDesktopPane extends JDesktopPane implements Runnable
2272 private static final float ONE_MB = 1048576f;
2274 boolean showMemoryUsage = false;
2278 java.text.NumberFormat df;
2280 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2283 public MyDesktopPane(boolean showMemoryUsage)
2285 showMemoryUsage(showMemoryUsage);
2288 public void showMemoryUsage(boolean showMemory)
2290 this.showMemoryUsage = showMemory;
2293 Thread worker = new Thread(this);
2298 public boolean isShowMemoryUsage()
2300 return showMemoryUsage;
2306 df = java.text.NumberFormat.getNumberInstance();
2307 df.setMaximumFractionDigits(2);
2308 runtime = Runtime.getRuntime();
2310 while (showMemoryUsage)
2314 maxMemory = runtime.maxMemory() / ONE_MB;
2315 allocatedMemory = runtime.totalMemory() / ONE_MB;
2316 freeMemory = runtime.freeMemory() / ONE_MB;
2317 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2319 percentUsage = (totalFreeMemory / maxMemory) * 100;
2321 // if (percentUsage < 20)
2323 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2325 // instance.set.setBorder(border1);
2328 // sleep after showing usage
2330 } catch (Exception ex)
2332 ex.printStackTrace();
2338 public void paintComponent(Graphics g)
2340 if (showMemoryUsage && g != null && df != null)
2342 if (percentUsage < 20)
2344 g.setColor(Color.red);
2346 FontMetrics fm = g.getFontMetrics();
2349 g.drawString(MessageManager.formatMessage(
2350 "label.memory_stats",
2351 new Object[] { df.format(totalFreeMemory),
2352 df.format(maxMemory), df.format(percentUsage) }), 10,
2353 getHeight() - fm.getHeight());
2360 * fixes stacking order after a modal dialog to ensure windows that should be
2361 * on top actually are
2363 public void relayerWindows()
2368 protected JMenuItem groovyShell;
2371 * Accessor method to quickly get all the AlignmentFrames loaded.
2373 * @return an array of AlignFrame, or null if none found
2375 public static AlignFrame[] getAlignFrames()
2377 if (Jalview.isHeadlessMode())
2379 // Desktop.desktop is null in headless mode
2380 return new AlignFrame[] { Jalview.currentAlignFrame };
2383 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2389 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2391 for (int i = frames.length - 1; i > -1; i--)
2393 if (frames[i] instanceof AlignFrame)
2395 avp.add((AlignFrame) frames[i]);
2397 else if (frames[i] instanceof SplitFrame)
2400 * Also check for a split frame containing an AlignFrame
2402 GSplitFrame sf = (GSplitFrame) frames[i];
2403 if (sf.getTopFrame() instanceof AlignFrame)
2405 avp.add((AlignFrame) sf.getTopFrame());
2407 if (sf.getBottomFrame() instanceof AlignFrame)
2409 avp.add((AlignFrame) sf.getBottomFrame());
2413 if (avp.size() == 0)
2417 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2422 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2426 public GStructureViewer[] getJmols()
2428 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2434 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2436 for (int i = frames.length - 1; i > -1; i--)
2438 if (frames[i] instanceof AppJmol)
2440 GStructureViewer af = (GStructureViewer) frames[i];
2444 if (avp.size() == 0)
2448 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2453 * Add Groovy Support to Jalview
2455 public void groovyShell_actionPerformed()
2459 openGroovyConsole();
2460 } catch (Exception ex)
2462 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2463 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2465 MessageManager.getString("label.couldnt_create_groovy_shell"),
2466 MessageManager.getString("label.groovy_support_failed"),
2467 JOptionPane.ERROR_MESSAGE);
2472 * Open the Groovy console
2474 void openGroovyConsole()
2476 if (groovyConsole == null)
2478 groovyConsole = new groovy.ui.Console();
2479 groovyConsole.setVariable("Jalview", this);
2480 groovyConsole.run();
2483 * We allow only one console at a time, so that AlignFrame menu option
2484 * 'Calculate | Run Groovy script' is unambiguous.
2485 * Disable 'Groovy Console', and enable 'Run script', when the console is
2486 * opened, and the reverse when it is closed
2488 Window window = (Window) groovyConsole.getFrame();
2489 window.addWindowListener(new WindowAdapter()
2492 public void windowClosed(WindowEvent e)
2495 * rebind CMD-Q from Groovy Console to Jalview Quit
2498 enableExecuteGroovy(false);
2504 * show Groovy console window (after close and reopen)
2506 ((Window) groovyConsole.getFrame()).setVisible(true);
2509 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2510 * and disable opening a second console
2512 enableExecuteGroovy(true);
2516 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2517 * binding when opened
2519 protected void addQuitHandler()
2521 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2522 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2523 .getDefaultToolkit().getMenuShortcutKeyMask()),
2525 getRootPane().getActionMap().put("Quit", new AbstractAction()
2528 public void actionPerformed(ActionEvent e)
2536 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2539 * true if Groovy console is open
2541 public void enableExecuteGroovy(boolean enabled)
2544 * disable opening a second Groovy console
2545 * (or re-enable when the console is closed)
2547 groovyShell.setEnabled(!enabled);
2549 AlignFrame[] alignFrames = getAlignFrames();
2550 if (alignFrames != null)
2552 for (AlignFrame af : alignFrames)
2554 af.setGroovyEnabled(enabled);
2560 * Progress bars managed by the IProgressIndicator method.
2562 private Hashtable<Long, JPanel> progressBars;
2564 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2569 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2572 public void setProgressBar(String message, long id)
2574 if (progressBars == null)
2576 progressBars = new Hashtable<Long, JPanel>();
2577 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2580 if (progressBars.get(new Long(id)) != null)
2582 JPanel panel = progressBars.remove(new Long(id));
2583 if (progressBarHandlers.contains(new Long(id)))
2585 progressBarHandlers.remove(new Long(id));
2587 removeProgressPanel(panel);
2591 progressBars.put(new Long(id), addProgressPanel(message));
2598 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2599 * jalview.gui.IProgressIndicatorHandler)
2602 public void registerHandler(final long id,
2603 final IProgressIndicatorHandler handler)
2605 if (progressBarHandlers == null
2606 || !progressBars.containsKey(new Long(id)))
2610 .getString("error.call_setprogressbar_before_registering_handler"));
2612 progressBarHandlers.put(new Long(id), handler);
2613 final JPanel progressPanel = progressBars.get(new Long(id));
2614 if (handler.canCancel())
2616 JButton cancel = new JButton(
2617 MessageManager.getString("action.cancel"));
2618 final IProgressIndicator us = this;
2619 cancel.addActionListener(new ActionListener()
2623 public void actionPerformed(ActionEvent e)
2625 handler.cancelActivity(id);
2626 us.setProgressBar(MessageManager.formatMessage(
2627 "label.cancelled_params",
2628 new Object[] { ((JLabel) progressPanel.getComponent(0))
2632 progressPanel.add(cancel, BorderLayout.EAST);
2638 * @return true if any progress bars are still active
2641 public boolean operationInProgress()
2643 if (progressBars != null && progressBars.size() > 0)
2651 * This will return the first AlignFrame holding the given viewport instance.
2652 * It will break if there are more than one AlignFrames viewing a particular
2656 * @return alignFrame for viewport
2658 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2660 if (desktop != null)
2662 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2663 for (int panel = 0; aps != null && panel < aps.length; panel++)
2665 if (aps[panel] != null && aps[panel].av == viewport)
2667 return aps[panel].alignFrame;
2674 public VamsasApplication getVamsasApplication()
2681 * flag set if jalview GUI is being operated programmatically
2683 private boolean inBatchMode = false;
2686 * check if jalview GUI is being operated programmatically
2688 * @return inBatchMode
2690 public boolean isInBatchMode()
2696 * set flag if jalview GUI is being operated programmatically
2698 * @param inBatchMode
2700 public void setInBatchMode(boolean inBatchMode)
2702 this.inBatchMode = inBatchMode;
2705 public void startServiceDiscovery()
2707 startServiceDiscovery(false);
2710 public void startServiceDiscovery(boolean blocking)
2712 boolean alive = true;
2713 Thread t0 = null, t1 = null, t2 = null;
2714 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2717 // todo: changesupport handlers need to be transferred
2718 if (discoverer == null)
2720 discoverer = new jalview.ws.jws1.Discoverer();
2721 // register PCS handler for desktop.
2722 discoverer.addPropertyChangeListener(changeSupport);
2724 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2725 // until we phase out completely
2726 (t0 = new Thread(discoverer)).start();
2729 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2731 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2733 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2735 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2741 // TODO: do rest service discovery
2750 } catch (Exception e)
2753 alive = (t1 != null && t1.isAlive())
2754 || (t2 != null && t2.isAlive())
2755 || (t3 != null && t3.isAlive())
2756 || (t0 != null && t0.isAlive());
2762 * called to check if the service discovery process completed successfully.
2766 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2768 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2770 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2771 .getErrorMessages();
2774 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2776 if (serviceChangedDialog == null)
2778 // only run if we aren't already displaying one of these.
2779 addDialogThread(serviceChangedDialog = new Runnable()
2786 * JalviewDialog jd =new JalviewDialog() {
2788 * @Override protected void cancelPressed() { // TODO
2789 * Auto-generated method stub
2791 * }@Override protected void okPressed() { // TODO
2792 * Auto-generated method stub
2794 * }@Override protected void raiseClosed() { // TODO
2795 * Auto-generated method stub
2797 * } }; jd.initDialogFrame(new
2798 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2799 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2800 * + " or mis-configured HTTP proxy settings.<br/>" +
2801 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2803 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2804 * ), true, true, "Web Service Configuration Problem", 450,
2807 * jd.waitForInput();
2813 "<html><table width=\"450\"><tr><td>"
2815 + "</td></tr></table>"
2816 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2817 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2818 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2819 + " Tools->Preferences dialog box to change them.</p></html>"),
2820 "Web Service Configuration Problem",
2821 JOptionPane.DEFAULT_OPTION,
2822 JOptionPane.ERROR_MESSAGE);
2823 serviceChangedDialog = null;
2832 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2839 private Runnable serviceChangedDialog = null;
2842 * start a thread to open a URL in the configured browser. Pops up a warning
2843 * dialog to the user if there is an exception when calling out to the browser
2848 public static void showUrl(final String url)
2850 showUrl(url, Desktop.instance);
2854 * Like showUrl but allows progress handler to be specified
2858 * (null) or object implementing IProgressIndicator
2860 public static void showUrl(final String url,
2861 final IProgressIndicator progress)
2863 new Thread(new Runnable()
2870 if (progress != null)
2872 progress.setProgressBar(MessageManager.formatMessage(
2873 "status.opening_params", new Object[] { url }), this
2876 jalview.util.BrowserLauncher.openURL(url);
2877 } catch (Exception ex)
2879 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2881 .getString("label.web_browser_not_found_unix"),
2882 MessageManager.getString("label.web_browser_not_found"),
2883 JOptionPane.WARNING_MESSAGE);
2885 ex.printStackTrace();
2887 if (progress != null)
2889 progress.setProgressBar(null, this.hashCode());
2895 public static WsParamSetManager wsparamManager = null;
2897 public static ParamManager getUserParameterStore()
2899 if (wsparamManager == null)
2901 wsparamManager = new WsParamSetManager();
2903 return wsparamManager;
2907 * static hyperlink handler proxy method for use by Jalview's internal windows
2911 public static void hyperlinkUpdate(HyperlinkEvent e)
2913 if (e.getEventType() == EventType.ACTIVATED)
2918 url = e.getURL().toString();
2919 Desktop.showUrl(url);
2920 } catch (Exception x)
2924 if (Cache.log != null)
2926 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2930 System.err.println("Couldn't handle string " + url
2934 // ignore any exceptions due to dud links.
2941 * single thread that handles display of dialogs to user.
2943 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2946 * flag indicating if dialogExecutor should try to acquire a permit
2948 private volatile boolean dialogPause = true;
2953 private java.util.concurrent.Semaphore block = new Semaphore(0);
2955 private static groovy.ui.Console groovyConsole;
2958 * add another dialog thread to the queue
2962 public void addDialogThread(final Runnable prompter)
2964 dialogExecutor.submit(new Runnable()
2974 } catch (InterruptedException x)
2979 if (instance == null)
2985 SwingUtilities.invokeAndWait(prompter);
2986 } catch (Exception q)
2988 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2994 public void startDialogQueue()
2996 // set the flag so we don't pause waiting for another permit and semaphore
2997 // the current task to begin
2998 dialogPause = false;
3003 protected void snapShotWindow_actionPerformed(ActionEvent e)
3007 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3008 "View of Desktop", getWidth(), getHeight(), of = new File(
3009 "Jalview_snapshot" + System.currentTimeMillis()
3010 + ".eps"), "View of desktop", null, 0, false);
3013 paintAll(im.getGraphics());
3015 } catch (Exception q)
3017 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3021 Cache.log.info("Successfully written snapshot to file "
3022 + of.getAbsolutePath());
3026 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3027 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3028 * and location last time the view was expanded (if any). However it does not
3029 * remember the split pane divider location - this is set to match the
3030 * 'exploding' frame.
3034 public void explodeViews(SplitFrame sf)
3036 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3037 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3038 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3040 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3042 int viewCount = topPanels.size();
3049 * Processing in reverse order works, forwards order leaves the first panels
3050 * not visible. I don't know why!
3052 for (int i = viewCount - 1; i >= 0; i--)
3055 * Make new top and bottom frames. These take over the respective
3056 * AlignmentPanel objects, including their AlignmentViewports, so the
3057 * cdna/protein relationships between the viewports is carried over to the
3060 * explodedGeometry holds the (x, y) position of the previously exploded
3061 * SplitFrame, and the (width, height) of the AlignFrame component
3063 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3064 AlignFrame newTopFrame = new AlignFrame(topPanel);
3065 newTopFrame.setSize(oldTopFrame.getSize());
3066 newTopFrame.setVisible(true);
3067 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3068 .getExplodedGeometry();
3069 if (geometry != null)
3071 newTopFrame.setSize(geometry.getSize());
3074 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3075 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3076 newBottomFrame.setSize(oldBottomFrame.getSize());
3077 newBottomFrame.setVisible(true);
3078 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3079 .getExplodedGeometry();
3080 if (geometry != null)
3082 newBottomFrame.setSize(geometry.getSize());
3085 topPanel.av.setGatherViewsHere(false);
3086 bottomPanel.av.setGatherViewsHere(false);
3087 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3089 if (geometry != null)
3091 splitFrame.setLocation(geometry.getLocation());
3093 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3097 * Clear references to the panels (now relocated in the new SplitFrames)
3098 * before closing the old SplitFrame.
3101 bottomPanels.clear();
3106 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3107 * back into the given SplitFrame as additional views. Note that the gathered
3108 * frames may themselves have multiple views.
3112 public void gatherViews(GSplitFrame source)
3115 * special handling of explodedGeometry for a view within a SplitFrame: - it
3116 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3117 * height) of the AlignFrame component
3119 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3120 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3121 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3122 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3123 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3124 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3126 myTopFrame.viewport.setGatherViewsHere(true);
3127 myBottomFrame.viewport.setGatherViewsHere(true);
3128 String topViewId = myTopFrame.viewport.getSequenceSetId();
3129 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3131 JInternalFrame[] frames = desktop.getAllFrames();
3132 for (JInternalFrame frame : frames)
3134 if (frame instanceof SplitFrame && frame != source)
3136 SplitFrame sf = (SplitFrame) frame;
3137 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3138 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3139 boolean gatherThis = false;
3140 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3142 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3143 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3144 if (topViewId.equals(topPanel.av.getSequenceSetId())
3145 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3148 topPanel.av.setGatherViewsHere(false);
3149 bottomPanel.av.setGatherViewsHere(false);
3150 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3151 topFrame.getSize()));
3152 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3153 .getLocation(), bottomFrame.getSize()));
3154 myTopFrame.addAlignmentPanel(topPanel, false);
3155 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3161 topFrame.getAlignPanels().clear();
3162 bottomFrame.getAlignPanels().clear();
3169 * The dust settles...give focus to the tab we did this from.
3171 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3174 public static groovy.ui.Console getGroovyConsole()
3176 return groovyConsole;
3179 public static void transferFromDropTarget(List<String> files,
3180 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3184 DataFlavor uriListFlavor = new DataFlavor(
3185 "text/uri-list;class=java.lang.String");
3186 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3188 // Works on Windows and MacOSX
3189 Cache.log.debug("Drop handled as javaFileListFlavor");
3190 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3191 for (Object file : (List) t
3192 .getTransferData(DataFlavor.javaFileListFlavor))
3194 files.add(((File)file).toString());
3195 protocols.add(FormatAdapter.FILE);
3200 // Unix like behaviour
3201 boolean added = false;
3203 if (t.isDataFlavorSupported(uriListFlavor))
3205 Cache.log.debug("Drop handled as uriListFlavor");
3206 // This is used by Unix drag system
3207 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3208 data = (String) t.getTransferData(uriListFlavor);
3212 // fallback to text: workaround - on OSX where there's a JVM bug
3213 Cache.log.debug("standard URIListFlavor failed. Trying text");
3214 // try text fallback
3215 data = (String) t.getTransferData(new DataFlavor(
3216 "text/plain;class=java.lang.String"));
3217 if (Cache.log.isDebugEnabled())
3219 Cache.log.debug("fallback returned " + data);
3222 while (protocols.size() < files.size())
3224 Cache.log.debug("Adding missing FILE protocol for "
3225 + files.get(protocols.size()));
3226 protocols.add(FormatAdapter.FILE);
3228 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3229 data, "\r\n"); st.hasMoreTokens();)
3232 String s = st.nextToken();
3233 if (s.startsWith("#"))
3235 // the line is a comment (as per the RFC 2483)
3238 java.net.URI uri = new java.net.URI(s);
3239 if (uri.getScheme().toLowerCase().startsWith("http"))
3241 protocols.add(FormatAdapter.URL);
3242 files.add(uri.toString());
3246 // otherwise preserve old behaviour: catch all for file objects
3247 java.io.File file = new java.io.File(uri);
3248 protocols.add(FormatAdapter.FILE);
3249 files.add(file.toString());
3252 if (Cache.log.isDebugEnabled())
3254 if (data == null || !added)
3257 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3258 for (DataFlavor fl : t.getTransferDataFlavors())
3260 Cache.log.debug("Supported transfer dataflavor: "
3262 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3263 Object df = t.getTransferData(fl);
3266 Cache.log.debug("Retrieves: " + df);
3270 Cache.log.debug("Retrieved nothing");