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 // suppress a possible repeat prompt to save script
1188 groovyConsole.setDirty(false);
1189 groovyConsole.exit();
1194 private void storeLastKnownDimensions(String string, Rectangle jc)
1196 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1197 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1198 + " height:" + jc.height);
1200 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1201 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1202 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1203 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1213 public void aboutMenuItem_actionPerformed(ActionEvent e)
1215 // StringBuffer message = getAboutMessage(false);
1216 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1218 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1219 new Thread(new Runnable()
1224 new SplashScreen(true);
1229 public StringBuffer getAboutMessage(boolean shortv)
1231 StringBuffer message = new StringBuffer();
1232 message.append("<html>");
1235 message.append("<h1><strong>Version: "
1236 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1237 message.append("<strong>Last Updated: <em>"
1238 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1239 + "</em></strong>");
1245 message.append("<strong>Version "
1246 + jalview.bin.Cache.getProperty("VERSION")
1247 + "; last updated: "
1248 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1251 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1254 message.append("<br>...Checking latest version...</br>");
1256 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1257 .equals(jalview.bin.Cache.getProperty("VERSION")))
1259 boolean red = false;
1260 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1261 .indexOf("automated build") == -1)
1264 // Displayed when code version and jnlp version do not match and code
1265 // version is not a development build
1266 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1269 message.append("<br>!! Version "
1270 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1272 + " is available for download from "
1273 + jalview.bin.Cache.getDefault("www.jalview.org",
1274 "http://www.jalview.org") + " !!");
1277 message.append("</div>");
1280 message.append("<br>Authors: "
1282 .getDefault("AUTHORFNAMES",
1283 "The Jalview Authors (See AUTHORS file for current list)")
1284 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1285 + "<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"
1286 + "<br><br>If you use Jalview, please cite:"
1287 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1288 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1289 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1301 public void documentationMenuItem_actionPerformed(ActionEvent e)
1305 Help.showHelpWindow();
1306 } catch (Exception ex)
1312 public void closeAll_actionPerformed(ActionEvent e)
1314 JInternalFrame[] frames = desktop.getAllFrames();
1315 for (int i = 0; i < frames.length; i++)
1319 frames[i].setClosed(true);
1320 } catch (java.beans.PropertyVetoException ex)
1324 System.out.println("ALL CLOSED");
1325 if (v_client != null)
1327 // TODO clear binding to vamsas document objects on close_all
1331 * reset state of singleton objects as appropriate (clear down session state
1332 * when all windows are closed)
1334 StructureSelectionManager ssm = StructureSelectionManager
1335 .getStructureSelectionManager(this);
1343 public void raiseRelated_actionPerformed(ActionEvent e)
1345 reorderAssociatedWindows(false, false);
1349 public void minimizeAssociated_actionPerformed(ActionEvent e)
1351 reorderAssociatedWindows(true, false);
1354 void closeAssociatedWindows()
1356 reorderAssociatedWindows(false, true);
1362 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1366 protected void garbageCollect_actionPerformed(ActionEvent e)
1368 // We simply collect the garbage
1369 jalview.bin.Cache.log.debug("Collecting garbage...");
1371 jalview.bin.Cache.log.debug("Finished garbage collection.");
1378 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1382 protected void showMemusage_actionPerformed(ActionEvent e)
1384 desktop.showMemoryUsage(showMemusage.isSelected());
1391 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1395 protected void showConsole_actionPerformed(ActionEvent e)
1397 showConsole(showConsole.isSelected());
1400 Console jconsole = null;
1403 * control whether the java console is visible or not
1407 void showConsole(boolean selected)
1409 showConsole.setSelected(selected);
1410 // TODO: decide if we should update properties file
1411 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1413 jconsole.setVisible(selected);
1416 void reorderAssociatedWindows(boolean minimize, boolean close)
1418 JInternalFrame[] frames = desktop.getAllFrames();
1419 if (frames == null || frames.length < 1)
1424 AlignmentViewport source = null, target = null;
1425 if (frames[0] instanceof AlignFrame)
1427 source = ((AlignFrame) frames[0]).getCurrentView();
1429 else if (frames[0] instanceof TreePanel)
1431 source = ((TreePanel) frames[0]).getViewPort();
1433 else if (frames[0] instanceof PCAPanel)
1435 source = ((PCAPanel) frames[0]).av;
1437 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1439 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1444 for (int i = 0; i < frames.length; i++)
1447 if (frames[i] == null)
1451 if (frames[i] instanceof AlignFrame)
1453 target = ((AlignFrame) frames[i]).getCurrentView();
1455 else if (frames[i] instanceof TreePanel)
1457 target = ((TreePanel) frames[i]).getViewPort();
1459 else if (frames[i] instanceof PCAPanel)
1461 target = ((PCAPanel) frames[i]).av;
1463 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1465 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1468 if (source == target)
1474 frames[i].setClosed(true);
1478 frames[i].setIcon(minimize);
1481 frames[i].toFront();
1485 } catch (java.beans.PropertyVetoException ex)
1500 protected void preferences_actionPerformed(ActionEvent e)
1512 public void saveState_actionPerformed(ActionEvent e)
1514 JalviewFileChooser chooser = new JalviewFileChooser(
1515 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1516 new String[] { "jvp" }, new String[] { "Jalview Project" },
1519 chooser.setFileView(new JalviewFileView());
1520 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1522 int value = chooser.showSaveDialog(this);
1524 if (value == JalviewFileChooser.APPROVE_OPTION)
1526 final Desktop me = this;
1527 final java.io.File choice = chooser.getSelectedFile();
1528 setProjectFile(choice);
1530 new Thread(new Runnable()
1535 // TODO: refactor to Jalview desktop session controller action.
1536 setProgressBar(MessageManager.formatMessage(
1537 "label.saving_jalview_project",
1538 new Object[] { choice.getName() }), choice.hashCode());
1539 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1540 choice.getParent());
1541 // TODO catch and handle errors for savestate
1542 // TODO prevent user from messing with the Desktop whilst we're saving
1545 new Jalview2XML().saveState(choice);
1546 } catch (OutOfMemoryError oom)
1548 new OOMWarning("Whilst saving current state to "
1549 + choice.getName(), oom);
1550 } catch (Exception ex)
1553 "Problems whilst trying to save to " + choice.getName(),
1555 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1556 "label.error_whilst_saving_current_state_to",
1557 new Object[] { choice.getName() }), MessageManager
1558 .getString("label.couldnt_save_project"),
1559 JOptionPane.WARNING_MESSAGE);
1561 setProgressBar(null, choice.hashCode());
1567 private void setProjectFile(File choice)
1569 this.projectFile = choice;
1572 public File getProjectFile()
1574 return this.projectFile;
1584 public void loadState_actionPerformed(ActionEvent e)
1586 JalviewFileChooser chooser = new JalviewFileChooser(
1587 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1588 "jvp", "jar" }, new String[] { "Jalview Project",
1589 "Jalview Project (old)" }, "Jalview Project");
1590 chooser.setFileView(new JalviewFileView());
1591 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1593 int value = chooser.showOpenDialog(this);
1595 if (value == JalviewFileChooser.APPROVE_OPTION)
1597 final File selectedFile = chooser.getSelectedFile();
1598 setProjectFile(selectedFile);
1599 final String choice = selectedFile.getAbsolutePath();
1600 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1601 selectedFile.getParent());
1602 new Thread(new Runnable()
1608 MessageManager.formatMessage(
1609 "label.loading_jalview_project",
1610 new Object[] { choice }), choice.hashCode());
1613 new Jalview2XML().loadJalviewAlign(choice);
1614 } catch (OutOfMemoryError oom)
1616 new OOMWarning("Whilst loading project from " + choice, oom);
1617 } catch (Exception ex)
1619 Cache.log.error("Problems whilst loading project from "
1621 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1623 "label.error_whilst_loading_project_from",
1624 new Object[] { choice }), MessageManager
1625 .getString("label.couldnt_load_project"),
1626 JOptionPane.WARNING_MESSAGE);
1628 setProgressBar(null, choice.hashCode());
1635 public void inputSequence_actionPerformed(ActionEvent e)
1637 new SequenceFetcher(this);
1640 JPanel progressPanel;
1642 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1644 public void startLoading(final String fileName)
1646 if (fileLoadingCount == 0)
1648 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1649 "label.loading_file", new Object[] { fileName })));
1654 private JPanel addProgressPanel(String string)
1656 if (progressPanel == null)
1658 progressPanel = new JPanel(new GridLayout(1, 1));
1659 totalProgressCount = 0;
1660 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1662 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1663 JProgressBar progressBar = new JProgressBar();
1664 progressBar.setIndeterminate(true);
1666 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1668 thisprogress.add(progressBar, BorderLayout.CENTER);
1669 progressPanel.add(thisprogress);
1670 ((GridLayout) progressPanel.getLayout())
1671 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1672 ++totalProgressCount;
1673 instance.validate();
1674 return thisprogress;
1677 int totalProgressCount = 0;
1679 private void removeProgressPanel(JPanel progbar)
1681 if (progressPanel != null)
1683 synchronized (progressPanel)
1685 progressPanel.remove(progbar);
1686 GridLayout gl = (GridLayout) progressPanel.getLayout();
1687 gl.setRows(gl.getRows() - 1);
1688 if (--totalProgressCount < 1)
1690 this.getContentPane().remove(progressPanel);
1691 progressPanel = null;
1698 public void stopLoading()
1701 if (fileLoadingCount < 1)
1703 while (fileLoadingPanels.size() > 0)
1705 removeProgressPanel(fileLoadingPanels.remove(0));
1707 fileLoadingPanels.clear();
1708 fileLoadingCount = 0;
1713 public static int getViewCount(String alignmentId)
1715 AlignmentViewport[] aps = getViewports(alignmentId);
1716 return (aps == null) ? 0 : aps.length;
1721 * @param alignmentId
1722 * - if null, all sets are returned
1723 * @return all AlignmentPanels concerning the alignmentId sequence set
1725 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1727 if (Desktop.desktop == null)
1729 // no frames created and in headless mode
1730 // TODO: verify that frames are recoverable when in headless mode
1733 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1734 AlignFrame[] frames = getAlignFrames();
1739 for (AlignFrame af : frames)
1741 for (AlignmentPanel ap : af.alignPanels)
1743 if (alignmentId == null
1744 || alignmentId.equals(ap.av.getSequenceSetId()))
1750 if (aps.size() == 0)
1754 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1759 * get all the viewports on an alignment.
1761 * @param sequenceSetId
1762 * unique alignment id (may be null - all viewports returned in that
1764 * @return all viewports on the alignment bound to sequenceSetId
1766 public static AlignmentViewport[] getViewports(String sequenceSetId)
1768 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1769 if (desktop != null)
1771 AlignFrame[] frames = Desktop.getAlignFrames();
1773 for (AlignFrame afr : frames)
1775 if (sequenceSetId == null
1776 || afr.getViewport().getSequenceSetId()
1777 .equals(sequenceSetId))
1779 if (afr.alignPanels != null)
1781 for (AlignmentPanel ap : afr.alignPanels)
1783 if (sequenceSetId == null
1784 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1792 viewp.add(afr.getViewport());
1796 if (viewp.size() > 0)
1798 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1805 * Explode the views in the given frame into separate AlignFrame
1809 public static void explodeViews(AlignFrame af)
1811 int size = af.alignPanels.size();
1817 for (int i = 0; i < size; i++)
1819 AlignmentPanel ap = af.alignPanels.get(i);
1820 AlignFrame newaf = new AlignFrame(ap);
1823 * Restore the view's last exploded frame geometry if known. Multiple
1824 * views from one exploded frame share and restore the same (frame)
1825 * position and size.
1827 Rectangle geometry = ap.av.getExplodedGeometry();
1828 if (geometry != null)
1830 newaf.setBounds(geometry);
1833 ap.av.setGatherViewsHere(false);
1835 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1836 AlignFrame.DEFAULT_HEIGHT);
1839 af.alignPanels.clear();
1840 af.closeMenuItem_actionPerformed(true);
1845 * Gather expanded views (separate AlignFrame's) with the same sequence set
1846 * identifier back in to this frame as additional views, and close the
1847 * expanded views. Note the expanded frames may themselves have multiple
1848 * views. We take the lot.
1852 public void gatherViews(AlignFrame source)
1854 source.viewport.setGatherViewsHere(true);
1855 source.viewport.setExplodedGeometry(source.getBounds());
1856 JInternalFrame[] frames = desktop.getAllFrames();
1857 String viewId = source.viewport.getSequenceSetId();
1859 for (int t = 0; t < frames.length; t++)
1861 if (frames[t] instanceof AlignFrame && frames[t] != source)
1863 AlignFrame af = (AlignFrame) frames[t];
1864 boolean gatherThis = false;
1865 for (int a = 0; a < af.alignPanels.size(); a++)
1867 AlignmentPanel ap = af.alignPanels.get(a);
1868 if (viewId.equals(ap.av.getSequenceSetId()))
1871 ap.av.setGatherViewsHere(false);
1872 ap.av.setExplodedGeometry(af.getBounds());
1873 source.addAlignmentPanel(ap, false);
1879 af.alignPanels.clear();
1880 af.closeMenuItem_actionPerformed(true);
1887 jalview.gui.VamsasApplication v_client = null;
1890 public void vamsasImport_actionPerformed(ActionEvent e)
1892 if (v_client == null)
1894 // Load and try to start a session.
1895 JalviewFileChooser chooser = new JalviewFileChooser(
1896 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1898 chooser.setFileView(new JalviewFileView());
1899 chooser.setDialogTitle(MessageManager
1900 .getString("label.open_saved_vamsas_session"));
1901 chooser.setToolTipText(MessageManager
1902 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1904 int value = chooser.showOpenDialog(this);
1906 if (value == JalviewFileChooser.APPROVE_OPTION)
1908 String fle = chooser.getSelectedFile().toString();
1909 if (!vamsasImport(chooser.getSelectedFile()))
1912 .showInternalMessageDialog(
1914 MessageManager.formatMessage(
1915 "label.couldnt_import_as_vamsas_session",
1916 new Object[] { fle }),
1918 .getString("label.vamsas_document_import_failed"),
1919 JOptionPane.ERROR_MESSAGE);
1925 jalview.bin.Cache.log
1926 .error("Implementation error - load session from a running session is not supported.");
1931 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1934 * @return true if import was a success and a session was started.
1936 public boolean vamsasImport(URL url)
1938 // TODO: create progress bar
1939 if (v_client != null)
1942 jalview.bin.Cache.log
1943 .error("Implementation error - load session from a running session is not supported.");
1949 // copy the URL content to a temporary local file
1950 // TODO: be a bit cleverer here with nio (?!)
1951 File file = File.createTempFile("vdocfromurl", ".vdj");
1952 FileOutputStream fos = new FileOutputStream(file);
1953 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1954 byte[] buffer = new byte[2048];
1956 while ((ln = bis.read(buffer)) > -1)
1958 fos.write(buffer, 0, ln);
1962 v_client = new jalview.gui.VamsasApplication(this, file,
1963 url.toExternalForm());
1964 } catch (Exception ex)
1966 jalview.bin.Cache.log.error(
1967 "Failed to create new vamsas session from contents of URL "
1971 setupVamsasConnectedGui();
1972 v_client.initial_update(); // TODO: thread ?
1973 return v_client.inSession();
1977 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1980 * @return true if import was a success and a session was started.
1982 public boolean vamsasImport(File file)
1984 if (v_client != null)
1987 jalview.bin.Cache.log
1988 .error("Implementation error - load session from a running session is not supported.");
1992 setProgressBar(MessageManager.formatMessage(
1993 "status.importing_vamsas_session_from",
1994 new Object[] { file.getName() }), file.hashCode());
1997 v_client = new jalview.gui.VamsasApplication(this, file, null);
1998 } catch (Exception ex)
2000 setProgressBar(MessageManager.formatMessage(
2001 "status.importing_vamsas_session_from",
2002 new Object[] { file.getName() }), file.hashCode());
2003 jalview.bin.Cache.log.error(
2004 "New vamsas session from existing session file failed:", ex);
2007 setupVamsasConnectedGui();
2008 v_client.initial_update(); // TODO: thread ?
2009 setProgressBar(MessageManager.formatMessage(
2010 "status.importing_vamsas_session_from",
2011 new Object[] { file.getName() }), file.hashCode());
2012 return v_client.inSession();
2015 public boolean joinVamsasSession(String mysesid)
2017 if (v_client != null)
2021 .getString("error.try_join_vamsas_session_another"));
2023 if (mysesid == null)
2026 MessageManager.getString("error.invalid_vamsas_session_id"));
2028 v_client = new VamsasApplication(this, mysesid);
2029 setupVamsasConnectedGui();
2030 v_client.initial_update();
2031 return (v_client.inSession());
2035 public void vamsasStart_actionPerformed(ActionEvent e)
2037 if (v_client == null)
2040 // we just start a default session for moment.
2042 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2043 * getProperty("LAST_DIRECTORY"));
2045 * chooser.setFileView(new JalviewFileView());
2046 * chooser.setDialogTitle("Load Vamsas file");
2047 * chooser.setToolTipText("Import");
2049 * int value = chooser.showOpenDialog(this);
2051 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2052 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2054 v_client = new VamsasApplication(this);
2055 setupVamsasConnectedGui();
2056 v_client.initial_update(); // TODO: thread ?
2060 // store current data in session.
2061 v_client.push_update(); // TODO: thread
2065 protected void setupVamsasConnectedGui()
2067 vamsasStart.setText(MessageManager.getString("label.session_update"));
2068 vamsasSave.setVisible(true);
2069 vamsasStop.setVisible(true);
2070 vamsasImport.setVisible(false); // Document import to existing session is
2071 // not possible for vamsas-client-1.0.
2074 protected void setupVamsasDisconnectedGui()
2076 vamsasSave.setVisible(false);
2077 vamsasStop.setVisible(false);
2078 vamsasImport.setVisible(true);
2079 vamsasStart.setText(MessageManager
2080 .getString("label.new_vamsas_session"));
2084 public void vamsasStop_actionPerformed(ActionEvent e)
2086 if (v_client != null)
2088 v_client.end_session();
2090 setupVamsasDisconnectedGui();
2094 protected void buildVamsasStMenu()
2096 if (v_client == null)
2098 String[] sess = null;
2101 sess = VamsasApplication.getSessionList();
2102 } catch (Exception e)
2104 jalview.bin.Cache.log.warn(
2105 "Problem getting current sessions list.", e);
2110 jalview.bin.Cache.log.debug("Got current sessions list: "
2111 + sess.length + " entries.");
2112 VamsasStMenu.removeAll();
2113 for (int i = 0; i < sess.length; i++)
2115 JMenuItem sessit = new JMenuItem();
2116 sessit.setText(sess[i]);
2117 sessit.setToolTipText(MessageManager.formatMessage(
2118 "label.connect_to_session", new Object[] { sess[i] }));
2119 final Desktop dsktp = this;
2120 final String mysesid = sess[i];
2121 sessit.addActionListener(new ActionListener()
2125 public void actionPerformed(ActionEvent e)
2127 if (dsktp.v_client == null)
2129 Thread rthr = new Thread(new Runnable()
2135 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2136 dsktp.setupVamsasConnectedGui();
2137 dsktp.v_client.initial_update();
2145 VamsasStMenu.add(sessit);
2147 // don't show an empty menu.
2148 VamsasStMenu.setVisible(sess.length > 0);
2153 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2154 VamsasStMenu.removeAll();
2155 VamsasStMenu.setVisible(false);
2160 // Not interested in the content. Just hide ourselves.
2161 VamsasStMenu.setVisible(false);
2166 public void vamsasSave_actionPerformed(ActionEvent e)
2168 if (v_client != null)
2170 JalviewFileChooser chooser = new JalviewFileChooser(
2171 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2172 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2173 new String[] { "Vamsas Document" }, "Vamsas Document");
2175 chooser.setFileView(new JalviewFileView());
2176 chooser.setDialogTitle(MessageManager
2177 .getString("label.save_vamsas_document_archive"));
2179 int value = chooser.showSaveDialog(this);
2181 if (value == JalviewFileChooser.APPROVE_OPTION)
2183 java.io.File choice = chooser.getSelectedFile();
2184 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2185 "label.saving_vamsas_doc",
2186 new Object[] { choice.getName() }));
2187 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2188 String warnmsg = null;
2189 String warnttl = null;
2192 v_client.vclient.storeDocument(choice);
2195 warnttl = "Serious Problem saving Vamsas Document";
2196 warnmsg = ex.toString();
2197 jalview.bin.Cache.log.error("Error Whilst saving document to "
2200 } catch (Exception ex)
2202 warnttl = "Problem saving Vamsas Document.";
2203 warnmsg = ex.toString();
2204 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2208 removeProgressPanel(progpanel);
2209 if (warnmsg != null)
2211 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2213 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2219 JPanel vamUpdate = null;
2222 * hide vamsas user gui bits when a vamsas document event is being handled.
2225 * true to hide gui, false to reveal gui
2227 public void setVamsasUpdate(boolean b)
2229 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2230 + (b ? "in progress" : "finished"));
2232 if (vamUpdate != null)
2234 this.removeProgressPanel(vamUpdate);
2238 vamUpdate = this.addProgressPanel(MessageManager
2239 .getString("label.updating_vamsas_session"));
2241 vamsasStart.setVisible(!b);
2242 vamsasStop.setVisible(!b);
2243 vamsasSave.setVisible(!b);
2246 public JInternalFrame[] getAllFrames()
2248 return desktop.getAllFrames();
2252 * Checks the given url to see if it gives a response indicating that the user
2253 * should be informed of a new questionnaire.
2257 public void checkForQuestionnaire(String url)
2259 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2260 // javax.swing.SwingUtilities.invokeLater(jvq);
2261 new Thread(jvq).start();
2265 * Proxy class for JDesktopPane which optionally displays the current memory
2266 * usage and highlights the desktop area with a red bar if free memory runs
2271 public class MyDesktopPane extends JDesktopPane implements Runnable
2274 private static final float ONE_MB = 1048576f;
2276 boolean showMemoryUsage = false;
2280 java.text.NumberFormat df;
2282 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2285 public MyDesktopPane(boolean showMemoryUsage)
2287 showMemoryUsage(showMemoryUsage);
2290 public void showMemoryUsage(boolean showMemory)
2292 this.showMemoryUsage = showMemory;
2295 Thread worker = new Thread(this);
2300 public boolean isShowMemoryUsage()
2302 return showMemoryUsage;
2308 df = java.text.NumberFormat.getNumberInstance();
2309 df.setMaximumFractionDigits(2);
2310 runtime = Runtime.getRuntime();
2312 while (showMemoryUsage)
2316 maxMemory = runtime.maxMemory() / ONE_MB;
2317 allocatedMemory = runtime.totalMemory() / ONE_MB;
2318 freeMemory = runtime.freeMemory() / ONE_MB;
2319 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2321 percentUsage = (totalFreeMemory / maxMemory) * 100;
2323 // if (percentUsage < 20)
2325 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2327 // instance.set.setBorder(border1);
2330 // sleep after showing usage
2332 } catch (Exception ex)
2334 ex.printStackTrace();
2340 public void paintComponent(Graphics g)
2342 if (showMemoryUsage && g != null && df != null)
2344 if (percentUsage < 20)
2346 g.setColor(Color.red);
2348 FontMetrics fm = g.getFontMetrics();
2351 g.drawString(MessageManager.formatMessage(
2352 "label.memory_stats",
2353 new Object[] { df.format(totalFreeMemory),
2354 df.format(maxMemory), df.format(percentUsage) }), 10,
2355 getHeight() - fm.getHeight());
2362 * fixes stacking order after a modal dialog to ensure windows that should be
2363 * on top actually are
2365 public void relayerWindows()
2370 protected JMenuItem groovyShell;
2373 * Accessor method to quickly get all the AlignmentFrames loaded.
2375 * @return an array of AlignFrame, or null if none found
2377 public static AlignFrame[] getAlignFrames()
2379 if (Jalview.isHeadlessMode())
2381 // Desktop.desktop is null in headless mode
2382 return new AlignFrame[] { Jalview.currentAlignFrame };
2385 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2391 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2393 for (int i = frames.length - 1; i > -1; i--)
2395 if (frames[i] instanceof AlignFrame)
2397 avp.add((AlignFrame) frames[i]);
2399 else if (frames[i] instanceof SplitFrame)
2402 * Also check for a split frame containing an AlignFrame
2404 GSplitFrame sf = (GSplitFrame) frames[i];
2405 if (sf.getTopFrame() instanceof AlignFrame)
2407 avp.add((AlignFrame) sf.getTopFrame());
2409 if (sf.getBottomFrame() instanceof AlignFrame)
2411 avp.add((AlignFrame) sf.getBottomFrame());
2415 if (avp.size() == 0)
2419 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2424 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2428 public GStructureViewer[] getJmols()
2430 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2436 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2438 for (int i = frames.length - 1; i > -1; i--)
2440 if (frames[i] instanceof AppJmol)
2442 GStructureViewer af = (GStructureViewer) frames[i];
2446 if (avp.size() == 0)
2450 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2455 * Add Groovy Support to Jalview
2457 public void groovyShell_actionPerformed()
2461 openGroovyConsole();
2462 } catch (Exception ex)
2464 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2465 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2467 MessageManager.getString("label.couldnt_create_groovy_shell"),
2468 MessageManager.getString("label.groovy_support_failed"),
2469 JOptionPane.ERROR_MESSAGE);
2474 * Open the Groovy console
2476 void openGroovyConsole()
2478 if (groovyConsole == null)
2480 groovyConsole = new groovy.ui.Console();
2481 groovyConsole.setVariable("Jalview", this);
2482 groovyConsole.run();
2485 * We allow only one console at a time, so that AlignFrame menu option
2486 * 'Calculate | Run Groovy script' is unambiguous.
2487 * Disable 'Groovy Console', and enable 'Run script', when the console is
2488 * opened, and the reverse when it is closed
2490 Window window = (Window) groovyConsole.getFrame();
2491 window.addWindowListener(new WindowAdapter()
2494 public void windowClosed(WindowEvent e)
2497 * rebind CMD-Q from Groovy Console to Jalview Quit
2500 enableExecuteGroovy(false);
2506 * show Groovy console window (after close and reopen)
2508 ((Window) groovyConsole.getFrame()).setVisible(true);
2511 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2512 * and disable opening a second console
2514 enableExecuteGroovy(true);
2518 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2519 * binding when opened
2521 protected void addQuitHandler()
2523 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2524 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2525 .getDefaultToolkit().getMenuShortcutKeyMask()),
2527 getRootPane().getActionMap().put("Quit", new AbstractAction()
2530 public void actionPerformed(ActionEvent e)
2538 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2541 * true if Groovy console is open
2543 public void enableExecuteGroovy(boolean enabled)
2546 * disable opening a second Groovy console
2547 * (or re-enable when the console is closed)
2549 groovyShell.setEnabled(!enabled);
2551 AlignFrame[] alignFrames = getAlignFrames();
2552 if (alignFrames != null)
2554 for (AlignFrame af : alignFrames)
2556 af.setGroovyEnabled(enabled);
2562 * Progress bars managed by the IProgressIndicator method.
2564 private Hashtable<Long, JPanel> progressBars;
2566 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2571 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2574 public void setProgressBar(String message, long id)
2576 if (progressBars == null)
2578 progressBars = new Hashtable<Long, JPanel>();
2579 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2582 if (progressBars.get(new Long(id)) != null)
2584 JPanel panel = progressBars.remove(new Long(id));
2585 if (progressBarHandlers.contains(new Long(id)))
2587 progressBarHandlers.remove(new Long(id));
2589 removeProgressPanel(panel);
2593 progressBars.put(new Long(id), addProgressPanel(message));
2600 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2601 * jalview.gui.IProgressIndicatorHandler)
2604 public void registerHandler(final long id,
2605 final IProgressIndicatorHandler handler)
2607 if (progressBarHandlers == null
2608 || !progressBars.containsKey(new Long(id)))
2612 .getString("error.call_setprogressbar_before_registering_handler"));
2614 progressBarHandlers.put(new Long(id), handler);
2615 final JPanel progressPanel = progressBars.get(new Long(id));
2616 if (handler.canCancel())
2618 JButton cancel = new JButton(
2619 MessageManager.getString("action.cancel"));
2620 final IProgressIndicator us = this;
2621 cancel.addActionListener(new ActionListener()
2625 public void actionPerformed(ActionEvent e)
2627 handler.cancelActivity(id);
2628 us.setProgressBar(MessageManager.formatMessage(
2629 "label.cancelled_params",
2630 new Object[] { ((JLabel) progressPanel.getComponent(0))
2634 progressPanel.add(cancel, BorderLayout.EAST);
2640 * @return true if any progress bars are still active
2643 public boolean operationInProgress()
2645 if (progressBars != null && progressBars.size() > 0)
2653 * This will return the first AlignFrame holding the given viewport instance.
2654 * It will break if there are more than one AlignFrames viewing a particular
2658 * @return alignFrame for viewport
2660 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2662 if (desktop != null)
2664 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2665 for (int panel = 0; aps != null && panel < aps.length; panel++)
2667 if (aps[panel] != null && aps[panel].av == viewport)
2669 return aps[panel].alignFrame;
2676 public VamsasApplication getVamsasApplication()
2683 * flag set if jalview GUI is being operated programmatically
2685 private boolean inBatchMode = false;
2688 * check if jalview GUI is being operated programmatically
2690 * @return inBatchMode
2692 public boolean isInBatchMode()
2698 * set flag if jalview GUI is being operated programmatically
2700 * @param inBatchMode
2702 public void setInBatchMode(boolean inBatchMode)
2704 this.inBatchMode = inBatchMode;
2707 public void startServiceDiscovery()
2709 startServiceDiscovery(false);
2712 public void startServiceDiscovery(boolean blocking)
2714 boolean alive = true;
2715 Thread t0 = null, t1 = null, t2 = null;
2716 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2719 // todo: changesupport handlers need to be transferred
2720 if (discoverer == null)
2722 discoverer = new jalview.ws.jws1.Discoverer();
2723 // register PCS handler for desktop.
2724 discoverer.addPropertyChangeListener(changeSupport);
2726 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2727 // until we phase out completely
2728 (t0 = new Thread(discoverer)).start();
2731 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2733 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2735 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2737 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2743 // TODO: do rest service discovery
2752 } catch (Exception e)
2755 alive = (t1 != null && t1.isAlive())
2756 || (t2 != null && t2.isAlive())
2757 || (t3 != null && t3.isAlive())
2758 || (t0 != null && t0.isAlive());
2764 * called to check if the service discovery process completed successfully.
2768 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2770 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2772 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2773 .getErrorMessages();
2776 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2778 if (serviceChangedDialog == null)
2780 // only run if we aren't already displaying one of these.
2781 addDialogThread(serviceChangedDialog = new Runnable()
2788 * JalviewDialog jd =new JalviewDialog() {
2790 * @Override protected void cancelPressed() { // TODO
2791 * Auto-generated method stub
2793 * }@Override protected void okPressed() { // TODO
2794 * Auto-generated method stub
2796 * }@Override protected void raiseClosed() { // TODO
2797 * Auto-generated method stub
2799 * } }; jd.initDialogFrame(new
2800 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2801 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2802 * + " or mis-configured HTTP proxy settings.<br/>" +
2803 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2805 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2806 * ), true, true, "Web Service Configuration Problem", 450,
2809 * jd.waitForInput();
2815 "<html><table width=\"450\"><tr><td>"
2817 + "</td></tr></table>"
2818 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2819 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2820 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2821 + " Tools->Preferences dialog box to change them.</p></html>"),
2822 "Web Service Configuration Problem",
2823 JOptionPane.DEFAULT_OPTION,
2824 JOptionPane.ERROR_MESSAGE);
2825 serviceChangedDialog = null;
2834 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2841 private Runnable serviceChangedDialog = null;
2844 * start a thread to open a URL in the configured browser. Pops up a warning
2845 * dialog to the user if there is an exception when calling out to the browser
2850 public static void showUrl(final String url)
2852 showUrl(url, Desktop.instance);
2856 * Like showUrl but allows progress handler to be specified
2860 * (null) or object implementing IProgressIndicator
2862 public static void showUrl(final String url,
2863 final IProgressIndicator progress)
2865 new Thread(new Runnable()
2872 if (progress != null)
2874 progress.setProgressBar(MessageManager.formatMessage(
2875 "status.opening_params", new Object[] { url }), this
2878 jalview.util.BrowserLauncher.openURL(url);
2879 } catch (Exception ex)
2881 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2883 .getString("label.web_browser_not_found_unix"),
2884 MessageManager.getString("label.web_browser_not_found"),
2885 JOptionPane.WARNING_MESSAGE);
2887 ex.printStackTrace();
2889 if (progress != null)
2891 progress.setProgressBar(null, this.hashCode());
2897 public static WsParamSetManager wsparamManager = null;
2899 public static ParamManager getUserParameterStore()
2901 if (wsparamManager == null)
2903 wsparamManager = new WsParamSetManager();
2905 return wsparamManager;
2909 * static hyperlink handler proxy method for use by Jalview's internal windows
2913 public static void hyperlinkUpdate(HyperlinkEvent e)
2915 if (e.getEventType() == EventType.ACTIVATED)
2920 url = e.getURL().toString();
2921 Desktop.showUrl(url);
2922 } catch (Exception x)
2926 if (Cache.log != null)
2928 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2932 System.err.println("Couldn't handle string " + url
2936 // ignore any exceptions due to dud links.
2943 * single thread that handles display of dialogs to user.
2945 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2948 * flag indicating if dialogExecutor should try to acquire a permit
2950 private volatile boolean dialogPause = true;
2955 private java.util.concurrent.Semaphore block = new Semaphore(0);
2957 private static groovy.ui.Console groovyConsole;
2960 * add another dialog thread to the queue
2964 public void addDialogThread(final Runnable prompter)
2966 dialogExecutor.submit(new Runnable()
2976 } catch (InterruptedException x)
2981 if (instance == null)
2987 SwingUtilities.invokeAndWait(prompter);
2988 } catch (Exception q)
2990 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2996 public void startDialogQueue()
2998 // set the flag so we don't pause waiting for another permit and semaphore
2999 // the current task to begin
3000 dialogPause = false;
3005 protected void snapShotWindow_actionPerformed(ActionEvent e)
3009 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3010 "View of Desktop", getWidth(), getHeight(), of = new File(
3011 "Jalview_snapshot" + System.currentTimeMillis()
3012 + ".eps"), "View of desktop", null, 0, false);
3015 paintAll(im.getGraphics());
3017 } catch (Exception q)
3019 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3023 Cache.log.info("Successfully written snapshot to file "
3024 + of.getAbsolutePath());
3028 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3029 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3030 * and location last time the view was expanded (if any). However it does not
3031 * remember the split pane divider location - this is set to match the
3032 * 'exploding' frame.
3036 public void explodeViews(SplitFrame sf)
3038 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3039 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3040 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3042 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3044 int viewCount = topPanels.size();
3051 * Processing in reverse order works, forwards order leaves the first panels
3052 * not visible. I don't know why!
3054 for (int i = viewCount - 1; i >= 0; i--)
3057 * Make new top and bottom frames. These take over the respective
3058 * AlignmentPanel objects, including their AlignmentViewports, so the
3059 * cdna/protein relationships between the viewports is carried over to the
3062 * explodedGeometry holds the (x, y) position of the previously exploded
3063 * SplitFrame, and the (width, height) of the AlignFrame component
3065 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3066 AlignFrame newTopFrame = new AlignFrame(topPanel);
3067 newTopFrame.setSize(oldTopFrame.getSize());
3068 newTopFrame.setVisible(true);
3069 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3070 .getExplodedGeometry();
3071 if (geometry != null)
3073 newTopFrame.setSize(geometry.getSize());
3076 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3077 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3078 newBottomFrame.setSize(oldBottomFrame.getSize());
3079 newBottomFrame.setVisible(true);
3080 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3081 .getExplodedGeometry();
3082 if (geometry != null)
3084 newBottomFrame.setSize(geometry.getSize());
3087 topPanel.av.setGatherViewsHere(false);
3088 bottomPanel.av.setGatherViewsHere(false);
3089 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3091 if (geometry != null)
3093 splitFrame.setLocation(geometry.getLocation());
3095 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3099 * Clear references to the panels (now relocated in the new SplitFrames)
3100 * before closing the old SplitFrame.
3103 bottomPanels.clear();
3108 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3109 * back into the given SplitFrame as additional views. Note that the gathered
3110 * frames may themselves have multiple views.
3114 public void gatherViews(GSplitFrame source)
3117 * special handling of explodedGeometry for a view within a SplitFrame: - it
3118 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3119 * height) of the AlignFrame component
3121 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3122 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3123 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3124 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3125 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3126 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3128 myTopFrame.viewport.setGatherViewsHere(true);
3129 myBottomFrame.viewport.setGatherViewsHere(true);
3130 String topViewId = myTopFrame.viewport.getSequenceSetId();
3131 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3133 JInternalFrame[] frames = desktop.getAllFrames();
3134 for (JInternalFrame frame : frames)
3136 if (frame instanceof SplitFrame && frame != source)
3138 SplitFrame sf = (SplitFrame) frame;
3139 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3140 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3141 boolean gatherThis = false;
3142 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3144 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3145 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3146 if (topViewId.equals(topPanel.av.getSequenceSetId())
3147 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3150 topPanel.av.setGatherViewsHere(false);
3151 bottomPanel.av.setGatherViewsHere(false);
3152 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3153 topFrame.getSize()));
3154 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3155 .getLocation(), bottomFrame.getSize()));
3156 myTopFrame.addAlignmentPanel(topPanel, false);
3157 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3163 topFrame.getAlignPanels().clear();
3164 bottomFrame.getAlignPanels().clear();
3171 * The dust settles...give focus to the tab we did this from.
3173 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3176 public static groovy.ui.Console getGroovyConsole()
3178 return groovyConsole;
3181 public static void transferFromDropTarget(List<String> files,
3182 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3186 DataFlavor uriListFlavor = new DataFlavor(
3187 "text/uri-list;class=java.lang.String");
3188 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3190 // Works on Windows and MacOSX
3191 Cache.log.debug("Drop handled as javaFileListFlavor");
3192 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3193 for (Object file : (List) t
3194 .getTransferData(DataFlavor.javaFileListFlavor))
3196 files.add(((File)file).toString());
3197 protocols.add(FormatAdapter.FILE);
3202 // Unix like behaviour
3203 boolean added = false;
3205 if (t.isDataFlavorSupported(uriListFlavor))
3207 Cache.log.debug("Drop handled as uriListFlavor");
3208 // This is used by Unix drag system
3209 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3210 data = (String) t.getTransferData(uriListFlavor);
3214 // fallback to text: workaround - on OSX where there's a JVM bug
3215 Cache.log.debug("standard URIListFlavor failed. Trying text");
3216 // try text fallback
3217 data = (String) t.getTransferData(new DataFlavor(
3218 "text/plain;class=java.lang.String"));
3219 if (Cache.log.isDebugEnabled())
3221 Cache.log.debug("fallback returned " + data);
3224 while (protocols.size() < files.size())
3226 Cache.log.debug("Adding missing FILE protocol for "
3227 + files.get(protocols.size()));
3228 protocols.add(FormatAdapter.FILE);
3230 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3231 data, "\r\n"); st.hasMoreTokens();)
3234 String s = st.nextToken();
3235 if (s.startsWith("#"))
3237 // the line is a comment (as per the RFC 2483)
3240 java.net.URI uri = new java.net.URI(s);
3241 if (uri.getScheme().toLowerCase().startsWith("http"))
3243 protocols.add(FormatAdapter.URL);
3244 files.add(uri.toString());
3248 // otherwise preserve old behaviour: catch all for file objects
3249 java.io.File file = new java.io.File(uri);
3250 protocols.add(FormatAdapter.FILE);
3251 files.add(file.toString());
3254 if (Cache.log.isDebugEnabled())
3256 if (data == null || !added)
3259 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3260 for (DataFlavor fl : t.getTransferDataFlavors())
3262 Cache.log.debug("Supported transfer dataflavor: "
3264 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3265 Object df = t.getTransferData(fl);
3268 Cache.log.debug("Retrieves: " + df);
3272 Cache.log.debug("Retrieved nothing");