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()) // Mac
402 showPasteMenu(evt.getX(), evt.getY());
407 public void mouseReleased(MouseEvent evt)
409 if (evt.isPopupTrigger()) // Windows
411 showPasteMenu(evt.getX(), evt.getY());
415 desktop.addMouseListener(ma);
417 this.addFocusListener(new FocusListener()
421 public void focusLost(FocusEvent e)
423 // TODO Auto-generated method stub
428 public void focusGained(FocusEvent e)
430 Cache.log.debug("Relaying windows after focus gain");
431 // make sure that we sort windows properly after we gain focus
432 instance.relayerWindows();
435 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
436 // Spawn a thread that shows the splashscreen
437 SwingUtilities.invokeLater(new Runnable()
447 // Thread off a new instance of the file chooser - this reduces the time it
448 // takes to open it later on.
449 new Thread(new Runnable()
454 Cache.log.debug("Filechooser init thread started.");
455 new JalviewFileChooser(
456 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
457 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
458 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
459 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
460 Cache.log.debug("Filechooser init thread finished.");
463 // Add the service change listener
464 changeSupport.addJalviewPropertyChangeListener("services",
465 new PropertyChangeListener()
469 public void propertyChange(PropertyChangeEvent evt)
471 Cache.log.debug("Firing service changed event for "
472 + evt.getNewValue());
473 JalviewServicesChanged(evt);
479 public void doConfigureStructurePrefs()
481 // configure services
482 StructureSelectionManager ssm = StructureSelectionManager
483 .getStructureSelectionManager(this);
484 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
486 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
487 Preferences.ADD_TEMPFACT_ANN, true));
488 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
489 Preferences.STRUCT_FROM_PDB, true));
490 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
491 Preferences.USE_RNAVIEW, true));
495 ssm.setAddTempFacAnnot(false);
496 ssm.setProcessSecondaryStructure(false);
497 ssm.setSecStructServices(false);
501 public void checkForNews()
503 final Desktop me = this;
504 // Thread off the news reader, in case there are connection problems.
505 addDialogThread(new Runnable()
510 Cache.log.debug("Starting news thread.");
512 jvnews = new BlogReader(me);
513 showNews.setVisible(true);
514 Cache.log.debug("Completed news thread.");
520 protected void showNews_actionPerformed(ActionEvent e)
522 showNews(showNews.isSelected());
525 void showNews(boolean visible)
528 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
529 showNews.setSelected(visible);
530 if (visible && !jvnews.isVisible())
532 new Thread(new Runnable()
537 long now = System.currentTimeMillis();
538 Desktop.instance.setProgressBar(
539 MessageManager.getString("status.refreshing_news"), now);
540 jvnews.refreshNews();
541 Desktop.instance.setProgressBar(null, now);
550 * recover the last known dimensions for a jalview window
553 * - empty string is desktop, all other windows have unique prefix
554 * @return null or last known dimensions scaled to current geometry (if last
555 * window geom was known)
557 Rectangle getLastKnownDimensions(String windowName)
559 // TODO: lock aspect ratio for scaling desktop Bug #0058199
560 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
561 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
562 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
563 String width = jalview.bin.Cache.getProperty(windowName
565 String height = jalview.bin.Cache.getProperty(windowName
567 if ((x != null) && (y != null) && (width != null) && (height != null))
569 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
570 .parseInt(width), ih = Integer.parseInt(height);
571 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
573 // attempt #1 - try to cope with change in screen geometry - this
574 // version doesn't preserve original jv aspect ratio.
575 // take ratio of current screen size vs original screen size.
576 double sw = ((1f * screenSize.width) / (1f * Integer
577 .parseInt(jalview.bin.Cache
578 .getProperty("SCREENGEOMETRY_WIDTH"))));
579 double sh = ((1f * screenSize.height) / (1f * Integer
580 .parseInt(jalview.bin.Cache
581 .getProperty("SCREENGEOMETRY_HEIGHT"))));
582 // rescale the bounds depending upon the current screen geometry.
583 ix = (int) (ix * sw);
584 iw = (int) (iw * sw);
585 iy = (int) (iy * sh);
586 ih = (int) (ih * sh);
587 while (ix >= screenSize.width)
589 jalview.bin.Cache.log
590 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
591 ix -= screenSize.width;
593 while (iy >= screenSize.height)
595 jalview.bin.Cache.log
596 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
597 iy -= screenSize.height;
599 jalview.bin.Cache.log.debug("Got last known dimensions for "
600 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
603 // return dimensions for new instance
604 return new Rectangle(ix, iy, iw, ih);
609 private void doVamsasClientCheck()
611 if (jalview.bin.Cache.vamsasJarsPresent())
613 setupVamsasDisconnectedGui();
614 VamsasMenu.setVisible(true);
615 final Desktop us = this;
616 VamsasMenu.addMenuListener(new MenuListener()
618 // this listener remembers when the menu was first selected, and
619 // doesn't rebuild the session list until it has been cleared and
621 boolean refresh = true;
624 public void menuCanceled(MenuEvent e)
630 public void menuDeselected(MenuEvent e)
636 public void menuSelected(MenuEvent e)
640 us.buildVamsasStMenu();
645 vamsasStart.setVisible(true);
649 void showPasteMenu(int x, int y)
651 JPopupMenu popup = new JPopupMenu();
652 JMenuItem item = new JMenuItem(
653 MessageManager.getString("label.paste_new_window"));
654 item.addActionListener(new ActionListener()
657 public void actionPerformed(ActionEvent evt)
664 popup.show(this, x, y);
671 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
672 Transferable contents = c.getContents(this);
674 if (contents != null)
676 String file = (String) contents
677 .getTransferData(DataFlavor.stringFlavor);
679 String format = new IdentifyFile().identify(file,
680 FormatAdapter.PASTE);
682 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
685 } catch (Exception ex)
688 .println("Unable to paste alignment from system clipboard:\n"
694 * Adds and opens the given frame to the desktop
705 public static synchronized void addInternalFrame(
706 final JInternalFrame frame, String title, int w, int h)
708 addInternalFrame(frame, title, true, w, h, true);
712 * Add an internal frame to the Jalview desktop
719 * When true, display frame immediately, otherwise, caller must call
720 * setVisible themselves.
726 public static synchronized void addInternalFrame(
727 final JInternalFrame frame, String title, boolean makeVisible,
730 addInternalFrame(frame, title, makeVisible, w, h, true);
734 * Add an internal frame to the Jalview desktop and make it visible
747 public static synchronized void addInternalFrame(
748 final JInternalFrame frame, String title, int w, int h,
751 addInternalFrame(frame, title, true, w, h, resizable);
755 * Add an internal frame to the Jalview desktop
762 * When true, display frame immediately, otherwise, caller must call
763 * setVisible themselves.
771 public static synchronized void addInternalFrame(
772 final JInternalFrame frame, String title, boolean makeVisible,
773 int w, int h, boolean resizable)
776 // TODO: allow callers to determine X and Y position of frame (eg. via
778 // TODO: consider fixing method to update entries in the window submenu with
779 // the current window title
781 frame.setTitle(title);
782 if (frame.getWidth() < 1 || frame.getHeight() < 1)
786 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
787 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
788 // IF JALVIEW IS RUNNING HEADLESS
789 // ///////////////////////////////////////////////
791 || (System.getProperty("java.awt.headless") != null && System
792 .getProperty("java.awt.headless").equals("true")))
799 frame.setVisible(makeVisible);
800 frame.setClosable(true);
801 frame.setResizable(resizable);
802 frame.setMaximizable(resizable);
803 frame.setIconifiable(resizable);
804 if (Platform.isAMac())
806 frame.setIconifiable(false);
807 frame.setFrameIcon(null);
808 // frame.setDesktopIcon(null);
809 frame.setDoubleBuffered(false);
811 if (frame.getX() < 1 && frame.getY() < 1)
813 frame.setLocation(xOffset * openFrameCount, yOffset
814 * ((openFrameCount - 1) % 10) + yOffset);
817 final JMenuItem menuItem = new JMenuItem(title);
818 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
821 public void internalFrameActivated(
822 javax.swing.event.InternalFrameEvent evt)
824 JInternalFrame itf = desktop.getSelectedFrame();
833 public void internalFrameClosed(
834 javax.swing.event.InternalFrameEvent evt)
836 PaintRefresher.RemoveComponent(frame);
839 * defensive check to prevent frames being
840 * added half off the window
842 if (openFrameCount > 0)
846 windowMenu.remove(menuItem);
847 JInternalFrame itf = desktop.getSelectedFrame();
856 menuItem.addActionListener(new ActionListener()
859 public void actionPerformed(ActionEvent e)
863 frame.setSelected(true);
864 frame.setIcon(false);
865 } catch (java.beans.PropertyVetoException ex)
871 menuItem.addMouseListener(new MouseListener()
875 public void mouseReleased(MouseEvent e)
880 public void mousePressed(MouseEvent e)
885 public void mouseExited(MouseEvent e)
889 frame.setSelected(false);
890 } catch (PropertyVetoException e1)
896 public void mouseEntered(MouseEvent e)
900 frame.setSelected(true);
901 } catch (PropertyVetoException e1)
907 public void mouseClicked(MouseEvent e)
913 windowMenu.add(menuItem);
919 frame.setSelected(true);
920 frame.requestFocus();
921 } catch (java.beans.PropertyVetoException ve)
923 } catch (java.lang.ClassCastException cex)
926 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
932 public void lostOwnership(Clipboard clipboard, Transferable contents)
936 Desktop.jalviewClipboard = null;
939 internalCopy = false;
943 public void dragEnter(DropTargetDragEvent evt)
948 public void dragExit(DropTargetEvent evt)
953 public void dragOver(DropTargetDragEvent evt)
958 public void dropActionChanged(DropTargetDragEvent evt)
969 public void drop(DropTargetDropEvent evt)
971 boolean success = true;
972 Transferable t = evt.getTransferable();
973 java.util.List<String> files = new ArrayList<String>();
974 java.util.List<String> protocols = new ArrayList<String>();
978 Desktop.transferFromDropTarget(files, protocols, evt, t);
979 } catch (Exception e)
989 for (int i = 0; i < files.size(); i++)
991 String file = files.get(i).toString();
992 String protocol = (protocols == null) ? FormatAdapter.FILE
993 : (String) protocols.get(i);
994 String format = null;
996 if (file.endsWith(".jar"))
1003 format = new IdentifyFile().identify(file, protocol);
1006 new FileLoader().LoadFile(file, protocol, format);
1009 } catch (Exception ex)
1014 evt.dropComplete(success); // need this to ensure input focus is properly
1015 // transfered to any new windows created
1025 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1027 JalviewFileChooser chooser = new JalviewFileChooser(
1028 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1029 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1030 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1031 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1033 chooser.setFileView(new JalviewFileView());
1034 chooser.setDialogTitle(MessageManager
1035 .getString("label.open_local_file"));
1036 chooser.setToolTipText(MessageManager.getString("action.open"));
1038 int value = chooser.showOpenDialog(this);
1040 if (value == JalviewFileChooser.APPROVE_OPTION)
1042 String choice = chooser.getSelectedFile().getPath();
1043 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1044 .getSelectedFile().getParent());
1046 String format = null;
1047 if (chooser.getSelectedFormat() != null
1048 && chooser.getSelectedFormat().equals("Jalview"))
1054 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1057 if (viewport != null)
1059 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1064 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1076 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1078 // This construct allows us to have a wider textfield
1080 JLabel label = new JLabel(
1081 MessageManager.getString("label.input_file_url"));
1082 final JComboBox history = new JComboBox();
1084 JPanel panel = new JPanel(new GridLayout(2, 1));
1087 history.setPreferredSize(new Dimension(400, 20));
1088 history.setEditable(true);
1089 history.addItem("http://www.");
1091 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1095 if (historyItems != null)
1097 st = new StringTokenizer(historyItems, "\t");
1099 while (st.hasMoreTokens())
1101 history.addItem(st.nextElement());
1105 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1106 MessageManager.getString("label.input_alignment_from_url"),
1107 JOptionPane.OK_CANCEL_OPTION);
1109 if (reply != JOptionPane.OK_OPTION)
1114 String url = history.getSelectedItem().toString();
1116 if (url.toLowerCase().endsWith(".jar"))
1118 if (viewport != null)
1120 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1125 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1130 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1132 if (format.equals("URL NOT FOUND"))
1134 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1135 MessageManager.formatMessage("label.couldnt_locate",
1136 new Object[] { url }), MessageManager
1137 .getString("label.url_not_found"),
1138 JOptionPane.WARNING_MESSAGE);
1143 if (viewport != null)
1145 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1149 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1155 * Opens the CutAndPaste window for the user to paste an alignment in to
1158 * - if not null, the pasted alignment is added to the current
1159 * alignment; if null, to a new alignment window
1162 public void inputTextboxMenuItem_actionPerformed(
1163 AlignmentViewPanel viewPanel)
1165 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1166 cap.setForInput(viewPanel);
1167 Desktop.addInternalFrame(cap,
1168 MessageManager.getString("label.cut_paste_alignmen_file"),
1178 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1180 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1181 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1183 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1184 getBounds().y, getWidth(), getHeight()));
1186 if (jconsole != null)
1188 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1189 jconsole.stopConsole();
1193 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1196 if (dialogExecutor != null)
1198 dialogExecutor.shutdownNow();
1200 closeAll_actionPerformed(null);
1202 if (groovyConsole != null)
1204 // suppress a possible repeat prompt to save script
1205 groovyConsole.setDirty(false);
1206 groovyConsole.exit();
1211 private void storeLastKnownDimensions(String string, Rectangle jc)
1213 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1214 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1215 + " height:" + jc.height);
1217 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1218 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1219 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1220 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1230 public void aboutMenuItem_actionPerformed(ActionEvent e)
1232 // StringBuffer message = getAboutMessage(false);
1233 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1235 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1236 new Thread(new Runnable()
1241 new SplashScreen(true);
1246 public StringBuffer getAboutMessage(boolean shortv)
1248 StringBuffer message = new StringBuffer();
1249 message.append("<html>");
1252 message.append("<h1><strong>Version: "
1253 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1254 message.append("<strong>Last Updated: <em>"
1255 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1256 + "</em></strong>");
1262 message.append("<strong>Version "
1263 + jalview.bin.Cache.getProperty("VERSION")
1264 + "; last updated: "
1265 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1268 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1271 message.append("<br>...Checking latest version...</br>");
1273 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1274 .equals(jalview.bin.Cache.getProperty("VERSION")))
1276 boolean red = false;
1277 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1278 .indexOf("automated build") == -1)
1281 // Displayed when code version and jnlp version do not match and code
1282 // version is not a development build
1283 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1286 message.append("<br>!! Version "
1287 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1289 + " is available for download from "
1290 + jalview.bin.Cache.getDefault("www.jalview.org",
1291 "http://www.jalview.org") + " !!");
1294 message.append("</div>");
1297 message.append("<br>Authors: "
1299 .getDefault("AUTHORFNAMES",
1300 "The Jalview Authors (See AUTHORS file for current list)")
1301 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1302 + "<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"
1303 + "<br><br>If you use Jalview, please cite:"
1304 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1305 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1306 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1318 public void documentationMenuItem_actionPerformed(ActionEvent e)
1322 Help.showHelpWindow();
1323 } catch (Exception ex)
1329 public void closeAll_actionPerformed(ActionEvent e)
1331 JInternalFrame[] frames = desktop.getAllFrames();
1332 for (int i = 0; i < frames.length; i++)
1336 frames[i].setClosed(true);
1337 } catch (java.beans.PropertyVetoException ex)
1341 System.out.println("ALL CLOSED");
1342 if (v_client != null)
1344 // TODO clear binding to vamsas document objects on close_all
1348 * reset state of singleton objects as appropriate (clear down session state
1349 * when all windows are closed)
1351 StructureSelectionManager ssm = StructureSelectionManager
1352 .getStructureSelectionManager(this);
1360 public void raiseRelated_actionPerformed(ActionEvent e)
1362 reorderAssociatedWindows(false, false);
1366 public void minimizeAssociated_actionPerformed(ActionEvent e)
1368 reorderAssociatedWindows(true, false);
1371 void closeAssociatedWindows()
1373 reorderAssociatedWindows(false, true);
1379 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1383 protected void garbageCollect_actionPerformed(ActionEvent e)
1385 // We simply collect the garbage
1386 jalview.bin.Cache.log.debug("Collecting garbage...");
1388 jalview.bin.Cache.log.debug("Finished garbage collection.");
1395 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1399 protected void showMemusage_actionPerformed(ActionEvent e)
1401 desktop.showMemoryUsage(showMemusage.isSelected());
1408 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1412 protected void showConsole_actionPerformed(ActionEvent e)
1414 showConsole(showConsole.isSelected());
1417 Console jconsole = null;
1420 * control whether the java console is visible or not
1424 void showConsole(boolean selected)
1426 showConsole.setSelected(selected);
1427 // TODO: decide if we should update properties file
1428 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1430 jconsole.setVisible(selected);
1433 void reorderAssociatedWindows(boolean minimize, boolean close)
1435 JInternalFrame[] frames = desktop.getAllFrames();
1436 if (frames == null || frames.length < 1)
1441 AlignmentViewport source = null, target = null;
1442 if (frames[0] instanceof AlignFrame)
1444 source = ((AlignFrame) frames[0]).getCurrentView();
1446 else if (frames[0] instanceof TreePanel)
1448 source = ((TreePanel) frames[0]).getViewPort();
1450 else if (frames[0] instanceof PCAPanel)
1452 source = ((PCAPanel) frames[0]).av;
1454 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1456 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1461 for (int i = 0; i < frames.length; i++)
1464 if (frames[i] == null)
1468 if (frames[i] instanceof AlignFrame)
1470 target = ((AlignFrame) frames[i]).getCurrentView();
1472 else if (frames[i] instanceof TreePanel)
1474 target = ((TreePanel) frames[i]).getViewPort();
1476 else if (frames[i] instanceof PCAPanel)
1478 target = ((PCAPanel) frames[i]).av;
1480 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1482 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1485 if (source == target)
1491 frames[i].setClosed(true);
1495 frames[i].setIcon(minimize);
1498 frames[i].toFront();
1502 } catch (java.beans.PropertyVetoException ex)
1517 protected void preferences_actionPerformed(ActionEvent e)
1529 public void saveState_actionPerformed(ActionEvent e)
1531 JalviewFileChooser chooser = new JalviewFileChooser(
1532 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1533 new String[] { "jvp" }, new String[] { "Jalview Project" },
1536 chooser.setFileView(new JalviewFileView());
1537 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1539 int value = chooser.showSaveDialog(this);
1541 if (value == JalviewFileChooser.APPROVE_OPTION)
1543 final Desktop me = this;
1544 final java.io.File choice = chooser.getSelectedFile();
1545 setProjectFile(choice);
1547 new Thread(new Runnable()
1552 // TODO: refactor to Jalview desktop session controller action.
1553 setProgressBar(MessageManager.formatMessage(
1554 "label.saving_jalview_project",
1555 new Object[] { choice.getName() }), choice.hashCode());
1556 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1557 choice.getParent());
1558 // TODO catch and handle errors for savestate
1559 // TODO prevent user from messing with the Desktop whilst we're saving
1562 new Jalview2XML().saveState(choice);
1563 } catch (OutOfMemoryError oom)
1565 new OOMWarning("Whilst saving current state to "
1566 + choice.getName(), oom);
1567 } catch (Exception ex)
1570 "Problems whilst trying to save to " + choice.getName(),
1572 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1573 "label.error_whilst_saving_current_state_to",
1574 new Object[] { choice.getName() }), MessageManager
1575 .getString("label.couldnt_save_project"),
1576 JOptionPane.WARNING_MESSAGE);
1578 setProgressBar(null, choice.hashCode());
1584 private void setProjectFile(File choice)
1586 this.projectFile = choice;
1589 public File getProjectFile()
1591 return this.projectFile;
1601 public void loadState_actionPerformed(ActionEvent e)
1603 JalviewFileChooser chooser = new JalviewFileChooser(
1604 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1605 "jvp", "jar" }, new String[] { "Jalview Project",
1606 "Jalview Project (old)" }, "Jalview Project");
1607 chooser.setFileView(new JalviewFileView());
1608 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1610 int value = chooser.showOpenDialog(this);
1612 if (value == JalviewFileChooser.APPROVE_OPTION)
1614 final File selectedFile = chooser.getSelectedFile();
1615 setProjectFile(selectedFile);
1616 final String choice = selectedFile.getAbsolutePath();
1617 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1618 selectedFile.getParent());
1619 new Thread(new Runnable()
1625 MessageManager.formatMessage(
1626 "label.loading_jalview_project",
1627 new Object[] { choice }), choice.hashCode());
1630 new Jalview2XML().loadJalviewAlign(choice);
1631 } catch (OutOfMemoryError oom)
1633 new OOMWarning("Whilst loading project from " + choice, oom);
1634 } catch (Exception ex)
1636 Cache.log.error("Problems whilst loading project from "
1638 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1640 "label.error_whilst_loading_project_from",
1641 new Object[] { choice }), MessageManager
1642 .getString("label.couldnt_load_project"),
1643 JOptionPane.WARNING_MESSAGE);
1645 setProgressBar(null, choice.hashCode());
1652 public void inputSequence_actionPerformed(ActionEvent e)
1654 new SequenceFetcher(this);
1657 JPanel progressPanel;
1659 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1661 public void startLoading(final String fileName)
1663 if (fileLoadingCount == 0)
1665 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1666 "label.loading_file", new Object[] { fileName })));
1671 private JPanel addProgressPanel(String string)
1673 if (progressPanel == null)
1675 progressPanel = new JPanel(new GridLayout(1, 1));
1676 totalProgressCount = 0;
1677 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1679 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1680 JProgressBar progressBar = new JProgressBar();
1681 progressBar.setIndeterminate(true);
1683 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1685 thisprogress.add(progressBar, BorderLayout.CENTER);
1686 progressPanel.add(thisprogress);
1687 ((GridLayout) progressPanel.getLayout())
1688 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1689 ++totalProgressCount;
1690 instance.validate();
1691 return thisprogress;
1694 int totalProgressCount = 0;
1696 private void removeProgressPanel(JPanel progbar)
1698 if (progressPanel != null)
1700 synchronized (progressPanel)
1702 progressPanel.remove(progbar);
1703 GridLayout gl = (GridLayout) progressPanel.getLayout();
1704 gl.setRows(gl.getRows() - 1);
1705 if (--totalProgressCount < 1)
1707 this.getContentPane().remove(progressPanel);
1708 progressPanel = null;
1715 public void stopLoading()
1718 if (fileLoadingCount < 1)
1720 while (fileLoadingPanels.size() > 0)
1722 removeProgressPanel(fileLoadingPanels.remove(0));
1724 fileLoadingPanels.clear();
1725 fileLoadingCount = 0;
1730 public static int getViewCount(String alignmentId)
1732 AlignmentViewport[] aps = getViewports(alignmentId);
1733 return (aps == null) ? 0 : aps.length;
1738 * @param alignmentId
1739 * - if null, all sets are returned
1740 * @return all AlignmentPanels concerning the alignmentId sequence set
1742 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1744 if (Desktop.desktop == null)
1746 // no frames created and in headless mode
1747 // TODO: verify that frames are recoverable when in headless mode
1750 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1751 AlignFrame[] frames = getAlignFrames();
1756 for (AlignFrame af : frames)
1758 for (AlignmentPanel ap : af.alignPanels)
1760 if (alignmentId == null
1761 || alignmentId.equals(ap.av.getSequenceSetId()))
1767 if (aps.size() == 0)
1771 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1776 * get all the viewports on an alignment.
1778 * @param sequenceSetId
1779 * unique alignment id (may be null - all viewports returned in that
1781 * @return all viewports on the alignment bound to sequenceSetId
1783 public static AlignmentViewport[] getViewports(String sequenceSetId)
1785 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1786 if (desktop != null)
1788 AlignFrame[] frames = Desktop.getAlignFrames();
1790 for (AlignFrame afr : frames)
1792 if (sequenceSetId == null
1793 || afr.getViewport().getSequenceSetId()
1794 .equals(sequenceSetId))
1796 if (afr.alignPanels != null)
1798 for (AlignmentPanel ap : afr.alignPanels)
1800 if (sequenceSetId == null
1801 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1809 viewp.add(afr.getViewport());
1813 if (viewp.size() > 0)
1815 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1822 * Explode the views in the given frame into separate AlignFrame
1826 public static void explodeViews(AlignFrame af)
1828 int size = af.alignPanels.size();
1834 for (int i = 0; i < size; i++)
1836 AlignmentPanel ap = af.alignPanels.get(i);
1837 AlignFrame newaf = new AlignFrame(ap);
1840 * Restore the view's last exploded frame geometry if known. Multiple
1841 * views from one exploded frame share and restore the same (frame)
1842 * position and size.
1844 Rectangle geometry = ap.av.getExplodedGeometry();
1845 if (geometry != null)
1847 newaf.setBounds(geometry);
1850 ap.av.setGatherViewsHere(false);
1852 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1853 AlignFrame.DEFAULT_HEIGHT);
1856 af.alignPanels.clear();
1857 af.closeMenuItem_actionPerformed(true);
1862 * Gather expanded views (separate AlignFrame's) with the same sequence set
1863 * identifier back in to this frame as additional views, and close the
1864 * expanded views. Note the expanded frames may themselves have multiple
1865 * views. We take the lot.
1869 public void gatherViews(AlignFrame source)
1871 source.viewport.setGatherViewsHere(true);
1872 source.viewport.setExplodedGeometry(source.getBounds());
1873 JInternalFrame[] frames = desktop.getAllFrames();
1874 String viewId = source.viewport.getSequenceSetId();
1876 for (int t = 0; t < frames.length; t++)
1878 if (frames[t] instanceof AlignFrame && frames[t] != source)
1880 AlignFrame af = (AlignFrame) frames[t];
1881 boolean gatherThis = false;
1882 for (int a = 0; a < af.alignPanels.size(); a++)
1884 AlignmentPanel ap = af.alignPanels.get(a);
1885 if (viewId.equals(ap.av.getSequenceSetId()))
1888 ap.av.setGatherViewsHere(false);
1889 ap.av.setExplodedGeometry(af.getBounds());
1890 source.addAlignmentPanel(ap, false);
1896 af.alignPanels.clear();
1897 af.closeMenuItem_actionPerformed(true);
1904 jalview.gui.VamsasApplication v_client = null;
1907 public void vamsasImport_actionPerformed(ActionEvent e)
1909 if (v_client == null)
1911 // Load and try to start a session.
1912 JalviewFileChooser chooser = new JalviewFileChooser(
1913 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1915 chooser.setFileView(new JalviewFileView());
1916 chooser.setDialogTitle(MessageManager
1917 .getString("label.open_saved_vamsas_session"));
1918 chooser.setToolTipText(MessageManager
1919 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1921 int value = chooser.showOpenDialog(this);
1923 if (value == JalviewFileChooser.APPROVE_OPTION)
1925 String fle = chooser.getSelectedFile().toString();
1926 if (!vamsasImport(chooser.getSelectedFile()))
1929 .showInternalMessageDialog(
1931 MessageManager.formatMessage(
1932 "label.couldnt_import_as_vamsas_session",
1933 new Object[] { fle }),
1935 .getString("label.vamsas_document_import_failed"),
1936 JOptionPane.ERROR_MESSAGE);
1942 jalview.bin.Cache.log
1943 .error("Implementation error - load session from a running session is not supported.");
1948 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1951 * @return true if import was a success and a session was started.
1953 public boolean vamsasImport(URL url)
1955 // TODO: create progress bar
1956 if (v_client != null)
1959 jalview.bin.Cache.log
1960 .error("Implementation error - load session from a running session is not supported.");
1966 // copy the URL content to a temporary local file
1967 // TODO: be a bit cleverer here with nio (?!)
1968 File file = File.createTempFile("vdocfromurl", ".vdj");
1969 FileOutputStream fos = new FileOutputStream(file);
1970 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1971 byte[] buffer = new byte[2048];
1973 while ((ln = bis.read(buffer)) > -1)
1975 fos.write(buffer, 0, ln);
1979 v_client = new jalview.gui.VamsasApplication(this, file,
1980 url.toExternalForm());
1981 } catch (Exception ex)
1983 jalview.bin.Cache.log.error(
1984 "Failed to create new vamsas session from contents of URL "
1988 setupVamsasConnectedGui();
1989 v_client.initial_update(); // TODO: thread ?
1990 return v_client.inSession();
1994 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1997 * @return true if import was a success and a session was started.
1999 public boolean vamsasImport(File file)
2001 if (v_client != null)
2004 jalview.bin.Cache.log
2005 .error("Implementation error - load session from a running session is not supported.");
2009 setProgressBar(MessageManager.formatMessage(
2010 "status.importing_vamsas_session_from",
2011 new Object[] { file.getName() }), file.hashCode());
2014 v_client = new jalview.gui.VamsasApplication(this, file, null);
2015 } catch (Exception ex)
2017 setProgressBar(MessageManager.formatMessage(
2018 "status.importing_vamsas_session_from",
2019 new Object[] { file.getName() }), file.hashCode());
2020 jalview.bin.Cache.log.error(
2021 "New vamsas session from existing session file failed:", ex);
2024 setupVamsasConnectedGui();
2025 v_client.initial_update(); // TODO: thread ?
2026 setProgressBar(MessageManager.formatMessage(
2027 "status.importing_vamsas_session_from",
2028 new Object[] { file.getName() }), file.hashCode());
2029 return v_client.inSession();
2032 public boolean joinVamsasSession(String mysesid)
2034 if (v_client != null)
2038 .getString("error.try_join_vamsas_session_another"));
2040 if (mysesid == null)
2043 MessageManager.getString("error.invalid_vamsas_session_id"));
2045 v_client = new VamsasApplication(this, mysesid);
2046 setupVamsasConnectedGui();
2047 v_client.initial_update();
2048 return (v_client.inSession());
2052 public void vamsasStart_actionPerformed(ActionEvent e)
2054 if (v_client == null)
2057 // we just start a default session for moment.
2059 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2060 * getProperty("LAST_DIRECTORY"));
2062 * chooser.setFileView(new JalviewFileView());
2063 * chooser.setDialogTitle("Load Vamsas file");
2064 * chooser.setToolTipText("Import");
2066 * int value = chooser.showOpenDialog(this);
2068 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2069 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2071 v_client = new VamsasApplication(this);
2072 setupVamsasConnectedGui();
2073 v_client.initial_update(); // TODO: thread ?
2077 // store current data in session.
2078 v_client.push_update(); // TODO: thread
2082 protected void setupVamsasConnectedGui()
2084 vamsasStart.setText(MessageManager.getString("label.session_update"));
2085 vamsasSave.setVisible(true);
2086 vamsasStop.setVisible(true);
2087 vamsasImport.setVisible(false); // Document import to existing session is
2088 // not possible for vamsas-client-1.0.
2091 protected void setupVamsasDisconnectedGui()
2093 vamsasSave.setVisible(false);
2094 vamsasStop.setVisible(false);
2095 vamsasImport.setVisible(true);
2096 vamsasStart.setText(MessageManager
2097 .getString("label.new_vamsas_session"));
2101 public void vamsasStop_actionPerformed(ActionEvent e)
2103 if (v_client != null)
2105 v_client.end_session();
2107 setupVamsasDisconnectedGui();
2111 protected void buildVamsasStMenu()
2113 if (v_client == null)
2115 String[] sess = null;
2118 sess = VamsasApplication.getSessionList();
2119 } catch (Exception e)
2121 jalview.bin.Cache.log.warn(
2122 "Problem getting current sessions list.", e);
2127 jalview.bin.Cache.log.debug("Got current sessions list: "
2128 + sess.length + " entries.");
2129 VamsasStMenu.removeAll();
2130 for (int i = 0; i < sess.length; i++)
2132 JMenuItem sessit = new JMenuItem();
2133 sessit.setText(sess[i]);
2134 sessit.setToolTipText(MessageManager.formatMessage(
2135 "label.connect_to_session", new Object[] { sess[i] }));
2136 final Desktop dsktp = this;
2137 final String mysesid = sess[i];
2138 sessit.addActionListener(new ActionListener()
2142 public void actionPerformed(ActionEvent e)
2144 if (dsktp.v_client == null)
2146 Thread rthr = new Thread(new Runnable()
2152 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2153 dsktp.setupVamsasConnectedGui();
2154 dsktp.v_client.initial_update();
2162 VamsasStMenu.add(sessit);
2164 // don't show an empty menu.
2165 VamsasStMenu.setVisible(sess.length > 0);
2170 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2171 VamsasStMenu.removeAll();
2172 VamsasStMenu.setVisible(false);
2177 // Not interested in the content. Just hide ourselves.
2178 VamsasStMenu.setVisible(false);
2183 public void vamsasSave_actionPerformed(ActionEvent e)
2185 if (v_client != null)
2187 JalviewFileChooser chooser = new JalviewFileChooser(
2188 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2189 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2190 new String[] { "Vamsas Document" }, "Vamsas Document");
2192 chooser.setFileView(new JalviewFileView());
2193 chooser.setDialogTitle(MessageManager
2194 .getString("label.save_vamsas_document_archive"));
2196 int value = chooser.showSaveDialog(this);
2198 if (value == JalviewFileChooser.APPROVE_OPTION)
2200 java.io.File choice = chooser.getSelectedFile();
2201 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2202 "label.saving_vamsas_doc",
2203 new Object[] { choice.getName() }));
2204 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2205 String warnmsg = null;
2206 String warnttl = null;
2209 v_client.vclient.storeDocument(choice);
2212 warnttl = "Serious Problem saving Vamsas Document";
2213 warnmsg = ex.toString();
2214 jalview.bin.Cache.log.error("Error Whilst saving document to "
2217 } catch (Exception ex)
2219 warnttl = "Problem saving Vamsas Document.";
2220 warnmsg = ex.toString();
2221 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2225 removeProgressPanel(progpanel);
2226 if (warnmsg != null)
2228 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2230 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2236 JPanel vamUpdate = null;
2239 * hide vamsas user gui bits when a vamsas document event is being handled.
2242 * true to hide gui, false to reveal gui
2244 public void setVamsasUpdate(boolean b)
2246 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2247 + (b ? "in progress" : "finished"));
2249 if (vamUpdate != null)
2251 this.removeProgressPanel(vamUpdate);
2255 vamUpdate = this.addProgressPanel(MessageManager
2256 .getString("label.updating_vamsas_session"));
2258 vamsasStart.setVisible(!b);
2259 vamsasStop.setVisible(!b);
2260 vamsasSave.setVisible(!b);
2263 public JInternalFrame[] getAllFrames()
2265 return desktop.getAllFrames();
2269 * Checks the given url to see if it gives a response indicating that the user
2270 * should be informed of a new questionnaire.
2274 public void checkForQuestionnaire(String url)
2276 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2277 // javax.swing.SwingUtilities.invokeLater(jvq);
2278 new Thread(jvq).start();
2282 * Proxy class for JDesktopPane which optionally displays the current memory
2283 * usage and highlights the desktop area with a red bar if free memory runs
2288 public class MyDesktopPane extends JDesktopPane implements Runnable
2291 private static final float ONE_MB = 1048576f;
2293 boolean showMemoryUsage = false;
2297 java.text.NumberFormat df;
2299 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2302 public MyDesktopPane(boolean showMemoryUsage)
2304 showMemoryUsage(showMemoryUsage);
2307 public void showMemoryUsage(boolean showMemory)
2309 this.showMemoryUsage = showMemory;
2312 Thread worker = new Thread(this);
2317 public boolean isShowMemoryUsage()
2319 return showMemoryUsage;
2325 df = java.text.NumberFormat.getNumberInstance();
2326 df.setMaximumFractionDigits(2);
2327 runtime = Runtime.getRuntime();
2329 while (showMemoryUsage)
2333 maxMemory = runtime.maxMemory() / ONE_MB;
2334 allocatedMemory = runtime.totalMemory() / ONE_MB;
2335 freeMemory = runtime.freeMemory() / ONE_MB;
2336 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2338 percentUsage = (totalFreeMemory / maxMemory) * 100;
2340 // if (percentUsage < 20)
2342 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2344 // instance.set.setBorder(border1);
2347 // sleep after showing usage
2349 } catch (Exception ex)
2351 ex.printStackTrace();
2357 public void paintComponent(Graphics g)
2359 if (showMemoryUsage && g != null && df != null)
2361 if (percentUsage < 20)
2363 g.setColor(Color.red);
2365 FontMetrics fm = g.getFontMetrics();
2368 g.drawString(MessageManager.formatMessage(
2369 "label.memory_stats",
2370 new Object[] { df.format(totalFreeMemory),
2371 df.format(maxMemory), df.format(percentUsage) }), 10,
2372 getHeight() - fm.getHeight());
2379 * fixes stacking order after a modal dialog to ensure windows that should be
2380 * on top actually are
2382 public void relayerWindows()
2387 protected JMenuItem groovyShell;
2390 * Accessor method to quickly get all the AlignmentFrames loaded.
2392 * @return an array of AlignFrame, or null if none found
2394 public static AlignFrame[] getAlignFrames()
2396 if (Jalview.isHeadlessMode())
2398 // Desktop.desktop is null in headless mode
2399 return new AlignFrame[] { Jalview.currentAlignFrame };
2402 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2408 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2410 for (int i = frames.length - 1; i > -1; i--)
2412 if (frames[i] instanceof AlignFrame)
2414 avp.add((AlignFrame) frames[i]);
2416 else if (frames[i] instanceof SplitFrame)
2419 * Also check for a split frame containing an AlignFrame
2421 GSplitFrame sf = (GSplitFrame) frames[i];
2422 if (sf.getTopFrame() instanceof AlignFrame)
2424 avp.add((AlignFrame) sf.getTopFrame());
2426 if (sf.getBottomFrame() instanceof AlignFrame)
2428 avp.add((AlignFrame) sf.getBottomFrame());
2432 if (avp.size() == 0)
2436 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2441 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2445 public GStructureViewer[] getJmols()
2447 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2453 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2455 for (int i = frames.length - 1; i > -1; i--)
2457 if (frames[i] instanceof AppJmol)
2459 GStructureViewer af = (GStructureViewer) frames[i];
2463 if (avp.size() == 0)
2467 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2472 * Add Groovy Support to Jalview
2474 public void groovyShell_actionPerformed()
2478 openGroovyConsole();
2479 } catch (Exception ex)
2481 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2482 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2484 MessageManager.getString("label.couldnt_create_groovy_shell"),
2485 MessageManager.getString("label.groovy_support_failed"),
2486 JOptionPane.ERROR_MESSAGE);
2491 * Open the Groovy console
2493 void openGroovyConsole()
2495 if (groovyConsole == null)
2497 groovyConsole = new groovy.ui.Console();
2498 groovyConsole.setVariable("Jalview", this);
2499 groovyConsole.run();
2502 * We allow only one console at a time, so that AlignFrame menu option
2503 * 'Calculate | Run Groovy script' is unambiguous.
2504 * Disable 'Groovy Console', and enable 'Run script', when the console is
2505 * opened, and the reverse when it is closed
2507 Window window = (Window) groovyConsole.getFrame();
2508 window.addWindowListener(new WindowAdapter()
2511 public void windowClosed(WindowEvent e)
2514 * rebind CMD-Q from Groovy Console to Jalview Quit
2517 enableExecuteGroovy(false);
2523 * show Groovy console window (after close and reopen)
2525 ((Window) groovyConsole.getFrame()).setVisible(true);
2528 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2529 * and disable opening a second console
2531 enableExecuteGroovy(true);
2535 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2536 * binding when opened
2538 protected void addQuitHandler()
2540 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2541 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2542 .getDefaultToolkit().getMenuShortcutKeyMask()),
2544 getRootPane().getActionMap().put("Quit", new AbstractAction()
2547 public void actionPerformed(ActionEvent e)
2555 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2558 * true if Groovy console is open
2560 public void enableExecuteGroovy(boolean enabled)
2563 * disable opening a second Groovy console
2564 * (or re-enable when the console is closed)
2566 groovyShell.setEnabled(!enabled);
2568 AlignFrame[] alignFrames = getAlignFrames();
2569 if (alignFrames != null)
2571 for (AlignFrame af : alignFrames)
2573 af.setGroovyEnabled(enabled);
2579 * Progress bars managed by the IProgressIndicator method.
2581 private Hashtable<Long, JPanel> progressBars;
2583 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2588 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2591 public void setProgressBar(String message, long id)
2593 if (progressBars == null)
2595 progressBars = new Hashtable<Long, JPanel>();
2596 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2599 if (progressBars.get(new Long(id)) != null)
2601 JPanel panel = progressBars.remove(new Long(id));
2602 if (progressBarHandlers.contains(new Long(id)))
2604 progressBarHandlers.remove(new Long(id));
2606 removeProgressPanel(panel);
2610 progressBars.put(new Long(id), addProgressPanel(message));
2617 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2618 * jalview.gui.IProgressIndicatorHandler)
2621 public void registerHandler(final long id,
2622 final IProgressIndicatorHandler handler)
2624 if (progressBarHandlers == null
2625 || !progressBars.containsKey(new Long(id)))
2629 .getString("error.call_setprogressbar_before_registering_handler"));
2631 progressBarHandlers.put(new Long(id), handler);
2632 final JPanel progressPanel = progressBars.get(new Long(id));
2633 if (handler.canCancel())
2635 JButton cancel = new JButton(
2636 MessageManager.getString("action.cancel"));
2637 final IProgressIndicator us = this;
2638 cancel.addActionListener(new ActionListener()
2642 public void actionPerformed(ActionEvent e)
2644 handler.cancelActivity(id);
2645 us.setProgressBar(MessageManager.formatMessage(
2646 "label.cancelled_params",
2647 new Object[] { ((JLabel) progressPanel.getComponent(0))
2651 progressPanel.add(cancel, BorderLayout.EAST);
2657 * @return true if any progress bars are still active
2660 public boolean operationInProgress()
2662 if (progressBars != null && progressBars.size() > 0)
2670 * This will return the first AlignFrame holding the given viewport instance.
2671 * It will break if there are more than one AlignFrames viewing a particular
2675 * @return alignFrame for viewport
2677 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2679 if (desktop != null)
2681 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2682 for (int panel = 0; aps != null && panel < aps.length; panel++)
2684 if (aps[panel] != null && aps[panel].av == viewport)
2686 return aps[panel].alignFrame;
2693 public VamsasApplication getVamsasApplication()
2700 * flag set if jalview GUI is being operated programmatically
2702 private boolean inBatchMode = false;
2705 * check if jalview GUI is being operated programmatically
2707 * @return inBatchMode
2709 public boolean isInBatchMode()
2715 * set flag if jalview GUI is being operated programmatically
2717 * @param inBatchMode
2719 public void setInBatchMode(boolean inBatchMode)
2721 this.inBatchMode = inBatchMode;
2724 public void startServiceDiscovery()
2726 startServiceDiscovery(false);
2729 public void startServiceDiscovery(boolean blocking)
2731 boolean alive = true;
2732 Thread t0 = null, t1 = null, t2 = null;
2733 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2736 // todo: changesupport handlers need to be transferred
2737 if (discoverer == null)
2739 discoverer = new jalview.ws.jws1.Discoverer();
2740 // register PCS handler for desktop.
2741 discoverer.addPropertyChangeListener(changeSupport);
2743 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2744 // until we phase out completely
2745 (t0 = new Thread(discoverer)).start();
2748 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2750 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2752 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2754 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2760 // TODO: do rest service discovery
2769 } catch (Exception e)
2772 alive = (t1 != null && t1.isAlive())
2773 || (t2 != null && t2.isAlive())
2774 || (t3 != null && t3.isAlive())
2775 || (t0 != null && t0.isAlive());
2781 * called to check if the service discovery process completed successfully.
2785 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2787 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2789 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2790 .getErrorMessages();
2793 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2795 if (serviceChangedDialog == null)
2797 // only run if we aren't already displaying one of these.
2798 addDialogThread(serviceChangedDialog = new Runnable()
2805 * JalviewDialog jd =new JalviewDialog() {
2807 * @Override protected void cancelPressed() { // TODO
2808 * Auto-generated method stub
2810 * }@Override protected void okPressed() { // TODO
2811 * Auto-generated method stub
2813 * }@Override protected void raiseClosed() { // TODO
2814 * Auto-generated method stub
2816 * } }; jd.initDialogFrame(new
2817 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2818 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2819 * + " or mis-configured HTTP proxy settings.<br/>" +
2820 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2822 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2823 * ), true, true, "Web Service Configuration Problem", 450,
2826 * jd.waitForInput();
2832 "<html><table width=\"450\"><tr><td>"
2834 + "</td></tr></table>"
2835 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2836 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2837 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2838 + " Tools->Preferences dialog box to change them.</p></html>"),
2839 "Web Service Configuration Problem",
2840 JOptionPane.DEFAULT_OPTION,
2841 JOptionPane.ERROR_MESSAGE);
2842 serviceChangedDialog = null;
2851 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2858 private Runnable serviceChangedDialog = null;
2861 * start a thread to open a URL in the configured browser. Pops up a warning
2862 * dialog to the user if there is an exception when calling out to the browser
2867 public static void showUrl(final String url)
2869 showUrl(url, Desktop.instance);
2873 * Like showUrl but allows progress handler to be specified
2877 * (null) or object implementing IProgressIndicator
2879 public static void showUrl(final String url,
2880 final IProgressIndicator progress)
2882 new Thread(new Runnable()
2889 if (progress != null)
2891 progress.setProgressBar(MessageManager.formatMessage(
2892 "status.opening_params", new Object[] { url }), this
2895 jalview.util.BrowserLauncher.openURL(url);
2896 } catch (Exception ex)
2898 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2900 .getString("label.web_browser_not_found_unix"),
2901 MessageManager.getString("label.web_browser_not_found"),
2902 JOptionPane.WARNING_MESSAGE);
2904 ex.printStackTrace();
2906 if (progress != null)
2908 progress.setProgressBar(null, this.hashCode());
2914 public static WsParamSetManager wsparamManager = null;
2916 public static ParamManager getUserParameterStore()
2918 if (wsparamManager == null)
2920 wsparamManager = new WsParamSetManager();
2922 return wsparamManager;
2926 * static hyperlink handler proxy method for use by Jalview's internal windows
2930 public static void hyperlinkUpdate(HyperlinkEvent e)
2932 if (e.getEventType() == EventType.ACTIVATED)
2937 url = e.getURL().toString();
2938 Desktop.showUrl(url);
2939 } catch (Exception x)
2943 if (Cache.log != null)
2945 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2949 System.err.println("Couldn't handle string " + url
2953 // ignore any exceptions due to dud links.
2960 * single thread that handles display of dialogs to user.
2962 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2965 * flag indicating if dialogExecutor should try to acquire a permit
2967 private volatile boolean dialogPause = true;
2972 private java.util.concurrent.Semaphore block = new Semaphore(0);
2974 private static groovy.ui.Console groovyConsole;
2977 * add another dialog thread to the queue
2981 public void addDialogThread(final Runnable prompter)
2983 dialogExecutor.submit(new Runnable()
2993 } catch (InterruptedException x)
2998 if (instance == null)
3004 SwingUtilities.invokeAndWait(prompter);
3005 } catch (Exception q)
3007 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3013 public void startDialogQueue()
3015 // set the flag so we don't pause waiting for another permit and semaphore
3016 // the current task to begin
3017 dialogPause = false;
3022 protected void snapShotWindow_actionPerformed(ActionEvent e)
3026 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3027 "View of Desktop", getWidth(), getHeight(), of = new File(
3028 "Jalview_snapshot" + System.currentTimeMillis()
3029 + ".eps"), "View of desktop", null, 0, false);
3032 paintAll(im.getGraphics());
3034 } catch (Exception q)
3036 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3040 Cache.log.info("Successfully written snapshot to file "
3041 + of.getAbsolutePath());
3045 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3046 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3047 * and location last time the view was expanded (if any). However it does not
3048 * remember the split pane divider location - this is set to match the
3049 * 'exploding' frame.
3053 public void explodeViews(SplitFrame sf)
3055 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3056 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3057 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3059 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3061 int viewCount = topPanels.size();
3068 * Processing in reverse order works, forwards order leaves the first panels
3069 * not visible. I don't know why!
3071 for (int i = viewCount - 1; i >= 0; i--)
3074 * Make new top and bottom frames. These take over the respective
3075 * AlignmentPanel objects, including their AlignmentViewports, so the
3076 * cdna/protein relationships between the viewports is carried over to the
3079 * explodedGeometry holds the (x, y) position of the previously exploded
3080 * SplitFrame, and the (width, height) of the AlignFrame component
3082 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3083 AlignFrame newTopFrame = new AlignFrame(topPanel);
3084 newTopFrame.setSize(oldTopFrame.getSize());
3085 newTopFrame.setVisible(true);
3086 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3087 .getExplodedGeometry();
3088 if (geometry != null)
3090 newTopFrame.setSize(geometry.getSize());
3093 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3094 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3095 newBottomFrame.setSize(oldBottomFrame.getSize());
3096 newBottomFrame.setVisible(true);
3097 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3098 .getExplodedGeometry();
3099 if (geometry != null)
3101 newBottomFrame.setSize(geometry.getSize());
3104 topPanel.av.setGatherViewsHere(false);
3105 bottomPanel.av.setGatherViewsHere(false);
3106 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3108 if (geometry != null)
3110 splitFrame.setLocation(geometry.getLocation());
3112 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3116 * Clear references to the panels (now relocated in the new SplitFrames)
3117 * before closing the old SplitFrame.
3120 bottomPanels.clear();
3125 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3126 * back into the given SplitFrame as additional views. Note that the gathered
3127 * frames may themselves have multiple views.
3131 public void gatherViews(GSplitFrame source)
3134 * special handling of explodedGeometry for a view within a SplitFrame: - it
3135 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3136 * height) of the AlignFrame component
3138 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3139 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3140 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3141 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3142 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3143 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3145 myTopFrame.viewport.setGatherViewsHere(true);
3146 myBottomFrame.viewport.setGatherViewsHere(true);
3147 String topViewId = myTopFrame.viewport.getSequenceSetId();
3148 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3150 JInternalFrame[] frames = desktop.getAllFrames();
3151 for (JInternalFrame frame : frames)
3153 if (frame instanceof SplitFrame && frame != source)
3155 SplitFrame sf = (SplitFrame) frame;
3156 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3157 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3158 boolean gatherThis = false;
3159 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3161 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3162 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3163 if (topViewId.equals(topPanel.av.getSequenceSetId())
3164 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3167 topPanel.av.setGatherViewsHere(false);
3168 bottomPanel.av.setGatherViewsHere(false);
3169 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3170 topFrame.getSize()));
3171 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3172 .getLocation(), bottomFrame.getSize()));
3173 myTopFrame.addAlignmentPanel(topPanel, false);
3174 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3180 topFrame.getAlignPanels().clear();
3181 bottomFrame.getAlignPanels().clear();
3188 * The dust settles...give focus to the tab we did this from.
3190 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3193 public static groovy.ui.Console getGroovyConsole()
3195 return groovyConsole;
3198 public static void transferFromDropTarget(List<String> files,
3199 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3203 DataFlavor uriListFlavor = new DataFlavor(
3204 "text/uri-list;class=java.lang.String");
3205 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3207 // Works on Windows and MacOSX
3208 Cache.log.debug("Drop handled as javaFileListFlavor");
3209 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3210 for (Object file : (List) t
3211 .getTransferData(DataFlavor.javaFileListFlavor))
3213 files.add(((File)file).toString());
3214 protocols.add(FormatAdapter.FILE);
3219 // Unix like behaviour
3220 boolean added = false;
3222 if (t.isDataFlavorSupported(uriListFlavor))
3224 Cache.log.debug("Drop handled as uriListFlavor");
3225 // This is used by Unix drag system
3226 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3227 data = (String) t.getTransferData(uriListFlavor);
3231 // fallback to text: workaround - on OSX where there's a JVM bug
3232 Cache.log.debug("standard URIListFlavor failed. Trying text");
3233 // try text fallback
3234 data = (String) t.getTransferData(new DataFlavor(
3235 "text/plain;class=java.lang.String"));
3236 if (Cache.log.isDebugEnabled())
3238 Cache.log.debug("fallback returned " + data);
3241 while (protocols.size() < files.size())
3243 Cache.log.debug("Adding missing FILE protocol for "
3244 + files.get(protocols.size()));
3245 protocols.add(FormatAdapter.FILE);
3247 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3248 data, "\r\n"); st.hasMoreTokens();)
3251 String s = st.nextToken();
3252 if (s.startsWith("#"))
3254 // the line is a comment (as per the RFC 2483)
3257 java.net.URI uri = new java.net.URI(s);
3258 if (uri.getScheme().toLowerCase().startsWith("http"))
3260 protocols.add(FormatAdapter.URL);
3261 files.add(uri.toString());
3265 // otherwise preserve old behaviour: catch all for file objects
3266 java.io.File file = new java.io.File(uri);
3267 protocols.add(FormatAdapter.FILE);
3268 files.add(file.toString());
3271 if (Cache.log.isDebugEnabled())
3273 if (data == null || !added)
3276 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3277 for (DataFlavor fl : t.getTransferDataFlavors())
3279 Cache.log.debug("Supported transfer dataflavor: "
3281 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3282 Object df = t.getTransferData(fl);
3285 Cache.log.debug("Retrieves: " + df);
3289 Cache.log.debug("Retrieved nothing");