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 static jalview.util.UrlConstants.SEQUENCE_ID;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.bin.Cache;
28 import jalview.bin.Jalview;
29 import jalview.io.DataSourceType;
30 import jalview.io.FileFormat;
31 import jalview.io.FileFormatException;
32 import jalview.io.FileFormatI;
33 import jalview.io.FileFormats;
34 import jalview.io.FileLoader;
35 import jalview.io.IdentifyFile;
36 import jalview.io.JalviewFileChooser;
37 import jalview.io.JalviewFileView;
38 import jalview.jbgui.GSplitFrame;
39 import jalview.jbgui.GStructureViewer;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.urls.IdOrgSettings;
42 import jalview.util.ImageMaker;
43 import jalview.util.MessageManager;
44 import jalview.util.Platform;
45 import jalview.util.UrlConstants;
46 import jalview.viewmodel.AlignmentViewport;
47 import jalview.ws.params.ParamManager;
48 import jalview.ws.utils.UrlDownloadClient;
50 import java.awt.BorderLayout;
51 import java.awt.Color;
52 import java.awt.Dimension;
53 import java.awt.FontMetrics;
54 import java.awt.Graphics;
55 import java.awt.GridLayout;
56 import java.awt.Point;
57 import java.awt.Rectangle;
58 import java.awt.Toolkit;
59 import java.awt.Window;
60 import java.awt.datatransfer.Clipboard;
61 import java.awt.datatransfer.ClipboardOwner;
62 import java.awt.datatransfer.DataFlavor;
63 import java.awt.datatransfer.Transferable;
64 import java.awt.dnd.DnDConstants;
65 import java.awt.dnd.DropTargetDragEvent;
66 import java.awt.dnd.DropTargetDropEvent;
67 import java.awt.dnd.DropTargetEvent;
68 import java.awt.dnd.DropTargetListener;
69 import java.awt.event.ActionEvent;
70 import java.awt.event.ActionListener;
71 import java.awt.event.KeyEvent;
72 import java.awt.event.MouseAdapter;
73 import java.awt.event.MouseEvent;
74 import java.awt.event.WindowAdapter;
75 import java.awt.event.WindowEvent;
76 import java.beans.PropertyChangeEvent;
77 import java.beans.PropertyChangeListener;
78 import java.io.BufferedInputStream;
80 import java.io.FileOutputStream;
81 import java.io.IOException;
83 import java.util.ArrayList;
84 import java.util.Hashtable;
85 import java.util.List;
86 import java.util.ListIterator;
87 import java.util.StringTokenizer;
88 import java.util.Vector;
89 import java.util.concurrent.ExecutorService;
90 import java.util.concurrent.Executors;
91 import java.util.concurrent.Semaphore;
93 import javax.swing.AbstractAction;
94 import javax.swing.Box;
95 import javax.swing.BoxLayout;
96 import javax.swing.DefaultDesktopManager;
97 import javax.swing.DesktopManager;
98 import javax.swing.JButton;
99 import javax.swing.JCheckBox;
100 import javax.swing.JComboBox;
101 import javax.swing.JComponent;
102 import javax.swing.JDesktopPane;
103 import javax.swing.JFrame;
104 import javax.swing.JInternalFrame;
105 import javax.swing.JLabel;
106 import javax.swing.JMenuItem;
107 import javax.swing.JPanel;
108 import javax.swing.JPopupMenu;
109 import javax.swing.JProgressBar;
110 import javax.swing.KeyStroke;
111 import javax.swing.SwingUtilities;
112 import javax.swing.event.HyperlinkEvent;
113 import javax.swing.event.HyperlinkEvent.EventType;
114 import javax.swing.event.InternalFrameAdapter;
115 import javax.swing.event.InternalFrameEvent;
116 import javax.swing.event.MenuEvent;
117 import javax.swing.event.MenuListener;
124 * @version $Revision: 1.155 $
126 public class Desktop extends jalview.jbgui.GDesktop
127 implements DropTargetListener, ClipboardOwner, IProgressIndicator,
128 jalview.api.StructureSelectionManagerProvider
130 private static int DEFAULT_MIN_WIDTH = 300;
132 private static int DEFAULT_MIN_HEIGHT = 250;
134 private static int ALIGN_FRAME_DEFAULT_MIN_WIDTH = 600;
136 private static int ALIGN_FRAME_DEFAULT_MIN_HEIGHT = 70;
138 private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES";
140 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
143 * news reader - null if it was never started.
145 private BlogReader jvnews = null;
147 private File projectFile;
151 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
153 public void addJalviewPropertyChangeListener(
154 PropertyChangeListener listener)
156 changeSupport.addJalviewPropertyChangeListener(listener);
160 * @param propertyName
162 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
163 * java.beans.PropertyChangeListener)
165 public void addJalviewPropertyChangeListener(String propertyName,
166 PropertyChangeListener listener)
168 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
172 * @param propertyName
174 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
175 * java.beans.PropertyChangeListener)
177 public void removeJalviewPropertyChangeListener(String propertyName,
178 PropertyChangeListener listener)
180 changeSupport.removeJalviewPropertyChangeListener(propertyName,
184 /** Singleton Desktop instance */
185 public static Desktop instance;
187 public static MyDesktopPane desktop;
189 static int openFrameCount = 0;
191 static final int xOffset = 30;
193 static final int yOffset = 30;
195 public static jalview.ws.jws1.Discoverer discoverer;
197 public static Object[] jalviewClipboard;
199 public static boolean internalCopy = false;
201 static int fileLoadingCount = 0;
203 class MyDesktopManager implements DesktopManager
206 private DesktopManager delegate;
208 public MyDesktopManager(DesktopManager delegate)
210 this.delegate = delegate;
214 public void activateFrame(JInternalFrame f)
218 delegate.activateFrame(f);
219 } catch (NullPointerException npe)
221 Point p = getMousePosition();
222 instance.showPasteMenu(p.x, p.y);
227 public void beginDraggingFrame(JComponent f)
229 delegate.beginDraggingFrame(f);
233 public void beginResizingFrame(JComponent f, int direction)
235 delegate.beginResizingFrame(f, direction);
239 public void closeFrame(JInternalFrame f)
241 delegate.closeFrame(f);
245 public void deactivateFrame(JInternalFrame f)
247 delegate.deactivateFrame(f);
251 public void deiconifyFrame(JInternalFrame f)
253 delegate.deiconifyFrame(f);
257 public void dragFrame(JComponent f, int newX, int newY)
263 delegate.dragFrame(f, newX, newY);
267 public void endDraggingFrame(JComponent f)
269 delegate.endDraggingFrame(f);
274 public void endResizingFrame(JComponent f)
276 delegate.endResizingFrame(f);
281 public void iconifyFrame(JInternalFrame f)
283 delegate.iconifyFrame(f);
287 public void maximizeFrame(JInternalFrame f)
289 delegate.maximizeFrame(f);
293 public void minimizeFrame(JInternalFrame f)
295 delegate.minimizeFrame(f);
299 public void openFrame(JInternalFrame f)
301 delegate.openFrame(f);
305 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
312 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
316 public void setBoundsForFrame(JComponent f, int newX, int newY,
317 int newWidth, int newHeight)
319 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
322 // All other methods, simply delegate
327 * Creates a new Desktop object.
332 * A note to implementors. It is ESSENTIAL that any activities that might
333 * block are spawned off as threads rather than waited for during this
337 doVamsasClientCheck();
339 doConfigureStructurePrefs();
340 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
341 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
342 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
344 boolean showjconsole = jalview.bin.Cache.getDefault("SHOW_JAVA_CONSOLE",
346 desktop = new MyDesktopPane(selmemusage);
347 showMemusage.setSelected(selmemusage);
348 desktop.setBackground(Color.white);
349 getContentPane().setLayout(new BorderLayout());
350 // alternate config - have scrollbars - see notes in JAL-153
351 // JScrollPane sp = new JScrollPane();
352 // sp.getViewport().setView(desktop);
353 // getContentPane().add(sp, BorderLayout.CENTER);
354 getContentPane().add(desktop, BorderLayout.CENTER);
355 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
357 // This line prevents Windows Look&Feel resizing all new windows to maximum
358 // if previous window was maximised
359 desktop.setDesktopManager(
360 new MyDesktopManager(
361 (Platform.isWindows() ? new DefaultDesktopManager()
363 ? new AquaInternalFrameManager(
364 desktop.getDesktopManager())
365 : desktop.getDesktopManager())));
367 Rectangle dims = getLastKnownDimensions("");
374 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
375 setBounds((screenSize.width - 900) / 2, (screenSize.height - 650) / 2,
378 jconsole = new Console(this, showjconsole);
379 // add essential build information
381 "Jalview Version: " + jalview.bin.Cache.getProperty("VERSION")
382 + "\n" + "Jalview Installation: "
383 + jalview.bin.Cache.getDefault("INSTALLATION",
385 + "\n" + "Build Date: "
386 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
387 + "\n" + "Java version: "
388 + System.getProperty("java.version") + "\n"
389 + System.getProperty("os.arch") + " "
390 + System.getProperty("os.name") + " "
391 + System.getProperty("os.version"));
393 showConsole(showjconsole);
395 showNews.setVisible(false);
397 experimentalFeatures.setSelected(showExperimental());
399 getIdentifiersOrgData();
403 this.addWindowListener(new WindowAdapter()
406 public void windowClosing(WindowEvent evt)
413 this.addMouseListener(ma = new MouseAdapter()
416 public void mousePressed(MouseEvent evt)
418 if (evt.isPopupTrigger()) // Mac
420 showPasteMenu(evt.getX(), evt.getY());
425 public void mouseReleased(MouseEvent evt)
427 if (evt.isPopupTrigger()) // Windows
429 showPasteMenu(evt.getX(), evt.getY());
433 desktop.addMouseListener(ma);
435 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
436 // Spawn a thread that shows the splashscreen
437 SwingUtilities.invokeLater(new Runnable()
446 // Thread off a new instance of the file chooser - this reduces the time it
447 // takes to open it later on.
448 new Thread(new Runnable()
453 Cache.log.debug("Filechooser init thread started.");
454 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
455 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
457 Cache.log.debug("Filechooser init thread finished.");
460 // Add the service change listener
461 changeSupport.addJalviewPropertyChangeListener("services",
462 new PropertyChangeListener()
466 public void propertyChange(PropertyChangeEvent evt)
468 Cache.log.debug("Firing service changed event for "
469 + evt.getNewValue());
470 JalviewServicesChanged(evt);
477 * Answers true if user preferences to enable experimental features is True
482 public boolean showExperimental()
484 String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
485 Boolean.FALSE.toString());
486 return Boolean.valueOf(experimental).booleanValue();
489 public void doConfigureStructurePrefs()
491 // configure services
492 StructureSelectionManager ssm = StructureSelectionManager
493 .getStructureSelectionManager(this);
494 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
496 ssm.setAddTempFacAnnot(jalview.bin.Cache
497 .getDefault(Preferences.ADD_TEMPFACT_ANN, true));
498 ssm.setProcessSecondaryStructure(jalview.bin.Cache
499 .getDefault(Preferences.STRUCT_FROM_PDB, true));
500 ssm.setSecStructServices(
501 jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW, true));
505 ssm.setAddTempFacAnnot(false);
506 ssm.setProcessSecondaryStructure(false);
507 ssm.setSecStructServices(false);
511 public void checkForNews()
513 final Desktop me = this;
514 // Thread off the news reader, in case there are connection problems.
515 addDialogThread(new Runnable()
520 Cache.log.debug("Starting news thread.");
522 jvnews = new BlogReader(me);
523 showNews.setVisible(true);
524 Cache.log.debug("Completed news thread.");
529 public void getIdentifiersOrgData()
531 // Thread off the identifiers fetcher
532 addDialogThread(new Runnable()
537 Cache.log.debug("Downloading data from identifiers.org");
538 UrlDownloadClient client = new UrlDownloadClient();
541 client.download(IdOrgSettings.getUrl(),
542 IdOrgSettings.getDownloadLocation());
543 } catch (IOException e)
545 Cache.log.debug("Exception downloading identifiers.org data"
553 protected void showNews_actionPerformed(ActionEvent e)
555 showNews(showNews.isSelected());
558 void showNews(boolean visible)
561 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
562 showNews.setSelected(visible);
563 if (visible && !jvnews.isVisible())
565 new Thread(new Runnable()
570 long now = System.currentTimeMillis();
571 Desktop.instance.setProgressBar(
572 MessageManager.getString("status.refreshing_news"),
574 jvnews.refreshNews();
575 Desktop.instance.setProgressBar(null, now);
584 * recover the last known dimensions for a jalview window
587 * - empty string is desktop, all other windows have unique prefix
588 * @return null or last known dimensions scaled to current geometry (if last
589 * window geom was known)
591 Rectangle getLastKnownDimensions(String windowName)
593 // TODO: lock aspect ratio for scaling desktop Bug #0058199
594 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
595 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
596 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
597 String width = jalview.bin.Cache
598 .getProperty(windowName + "SCREEN_WIDTH");
599 String height = jalview.bin.Cache
600 .getProperty(windowName + "SCREEN_HEIGHT");
601 if ((x != null) && (y != null) && (width != null) && (height != null))
603 int ix = Integer.parseInt(x), iy = Integer.parseInt(y),
604 iw = Integer.parseInt(width), ih = Integer.parseInt(height);
605 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
607 // attempt #1 - try to cope with change in screen geometry - this
608 // version doesn't preserve original jv aspect ratio.
609 // take ratio of current screen size vs original screen size.
610 double sw = ((1f * screenSize.width) / (1f * Integer.parseInt(
611 jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
612 double sh = ((1f * screenSize.height) / (1f * Integer.parseInt(
613 jalview.bin.Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
614 // rescale the bounds depending upon the current screen geometry.
615 ix = (int) (ix * sw);
616 iw = (int) (iw * sw);
617 iy = (int) (iy * sh);
618 ih = (int) (ih * sh);
619 while (ix >= screenSize.width)
621 jalview.bin.Cache.log.debug(
622 "Window geometry location recall error: shifting horizontal to within screenbounds.");
623 ix -= screenSize.width;
625 while (iy >= screenSize.height)
627 jalview.bin.Cache.log.debug(
628 "Window geometry location recall error: shifting vertical to within screenbounds.");
629 iy -= screenSize.height;
631 jalview.bin.Cache.log.debug(
632 "Got last known dimensions for " + windowName + ": x:" + ix
633 + " y:" + iy + " width:" + iw + " height:" + ih);
635 // return dimensions for new instance
636 return new Rectangle(ix, iy, iw, ih);
641 private void doVamsasClientCheck()
643 if (jalview.bin.Cache.vamsasJarsPresent())
645 setupVamsasDisconnectedGui();
646 VamsasMenu.setVisible(true);
647 final Desktop us = this;
648 VamsasMenu.addMenuListener(new MenuListener()
650 // this listener remembers when the menu was first selected, and
651 // doesn't rebuild the session list until it has been cleared and
653 boolean refresh = true;
656 public void menuCanceled(MenuEvent e)
662 public void menuDeselected(MenuEvent e)
668 public void menuSelected(MenuEvent e)
672 us.buildVamsasStMenu();
677 vamsasStart.setVisible(true);
681 void showPasteMenu(int x, int y)
683 JPopupMenu popup = new JPopupMenu();
684 JMenuItem item = new JMenuItem(
685 MessageManager.getString("label.paste_new_window"));
686 item.addActionListener(new ActionListener()
689 public void actionPerformed(ActionEvent evt)
696 popup.show(this, x, y);
703 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
704 Transferable contents = c.getContents(this);
706 if (contents != null)
708 String file = (String) contents
709 .getTransferData(DataFlavor.stringFlavor);
711 FileFormatI format = new IdentifyFile().identify(file,
712 DataSourceType.PASTE);
714 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
717 } catch (Exception ex)
720 "Unable to paste alignment from system clipboard:\n" + ex);
725 * Adds and opens the given frame to the desktop
736 public static synchronized void addInternalFrame(
737 final JInternalFrame frame, String title, int w, int h)
739 addInternalFrame(frame, title, true, w, h, true, false);
743 * Add an internal frame to the Jalview desktop
750 * When true, display frame immediately, otherwise, caller must call
751 * setVisible themselves.
757 public static synchronized void addInternalFrame(
758 final JInternalFrame frame, String title, boolean makeVisible,
761 addInternalFrame(frame, title, makeVisible, w, h, true, false);
765 * Add an internal frame to the Jalview desktop and make it visible
778 public static synchronized void addInternalFrame(
779 final JInternalFrame frame, String title, int w, int h,
782 addInternalFrame(frame, title, true, w, h, resizable, false);
786 * Add an internal frame to the Jalview desktop
793 * When true, display frame immediately, otherwise, caller must call
794 * setVisible themselves.
801 * @param ignoreMinSize
802 * Do not set the default minimum size for frame
804 public static synchronized void addInternalFrame(
805 final JInternalFrame frame, String title, boolean makeVisible,
806 int w, int h, boolean resizable, boolean ignoreMinSize)
809 // TODO: allow callers to determine X and Y position of frame (eg. via
811 // TODO: consider fixing method to update entries in the window submenu with
812 // the current window title
814 frame.setTitle(title);
815 if (frame.getWidth() < 1 || frame.getHeight() < 1)
819 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
820 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
821 // IF JALVIEW IS RUNNING HEADLESS
822 // ///////////////////////////////////////////////
823 if (instance == null || (System.getProperty("java.awt.headless") != null
824 && System.getProperty("java.awt.headless").equals("true")))
833 frame.setMinimumSize(
834 new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
836 // Set default dimension for Alignment Frame window.
837 // The Alignment Frame window could be added from a number of places,
839 // I did this here in order not to miss out on any Alignment frame.
840 if (frame instanceof AlignFrame)
842 frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
843 ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
847 frame.setVisible(makeVisible);
848 frame.setClosable(true);
849 frame.setResizable(resizable);
850 frame.setMaximizable(resizable);
851 frame.setIconifiable(resizable);
853 if (frame.getX() < 1 && frame.getY() < 1)
855 frame.setLocation(xOffset * openFrameCount,
856 yOffset * ((openFrameCount - 1) % 10) + yOffset);
860 * add an entry for the new frame in the Window menu
861 * (and remove it when the frame is closed)
863 final JMenuItem menuItem = new JMenuItem(title);
864 frame.addInternalFrameListener(new InternalFrameAdapter()
867 public void internalFrameActivated(InternalFrameEvent evt)
869 JInternalFrame itf = desktop.getSelectedFrame();
872 if (itf instanceof AlignFrame)
874 Jalview.setCurrentAlignFrame((AlignFrame) itf);
881 public void internalFrameClosed(InternalFrameEvent evt)
883 PaintRefresher.RemoveComponent(frame);
886 * defensive check to prevent frames being
887 * added half off the window
889 if (openFrameCount > 0)
895 * ensure no reference to alignFrame retained by menu item listener
897 if (menuItem.getActionListeners().length > 0)
899 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
901 windowMenu.remove(menuItem);
907 menuItem.addActionListener(new ActionListener()
910 public void actionPerformed(ActionEvent e)
914 frame.setSelected(true);
915 frame.setIcon(false);
916 } catch (java.beans.PropertyVetoException ex)
925 windowMenu.add(menuItem);
930 frame.setSelected(true);
931 frame.requestFocus();
932 } catch (java.beans.PropertyVetoException ve)
934 } catch (java.lang.ClassCastException cex)
937 "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
943 public void lostOwnership(Clipboard clipboard, Transferable contents)
947 Desktop.jalviewClipboard = null;
950 internalCopy = false;
954 public void dragEnter(DropTargetDragEvent evt)
959 public void dragExit(DropTargetEvent evt)
964 public void dragOver(DropTargetDragEvent evt)
969 public void dropActionChanged(DropTargetDragEvent evt)
980 public void drop(DropTargetDropEvent evt)
982 boolean success = true;
983 // JAL-1552 - acceptDrop required before getTransferable call for
984 // Java's Transferable for native dnd
985 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
986 Transferable t = evt.getTransferable();
987 List<String> files = new ArrayList<>();
988 List<DataSourceType> protocols = new ArrayList<>();
992 Desktop.transferFromDropTarget(files, protocols, evt, t);
993 } catch (Exception e)
1003 for (int i = 0; i < files.size(); i++)
1005 String file = files.get(i).toString();
1006 DataSourceType protocol = (protocols == null)
1007 ? DataSourceType.FILE
1009 FileFormatI format = null;
1011 if (file.endsWith(".jar"))
1013 format = FileFormat.Jalview;
1018 format = new IdentifyFile().identify(file, protocol);
1021 new FileLoader().LoadFile(file, protocol, format);
1024 } catch (Exception ex)
1029 evt.dropComplete(success); // need this to ensure input focus is properly
1030 // transfered to any new windows created
1040 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1042 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1043 JalviewFileChooser chooser = JalviewFileChooser
1044 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1046 chooser.setFileView(new JalviewFileView());
1047 chooser.setDialogTitle(
1048 MessageManager.getString("label.open_local_file"));
1049 chooser.setToolTipText(MessageManager.getString("action.open"));
1051 int value = chooser.showOpenDialog(this);
1053 if (value == JalviewFileChooser.APPROVE_OPTION)
1055 String choice = chooser.getSelectedFile().getPath();
1056 Cache.setProperty("LAST_DIRECTORY",
1057 chooser.getSelectedFile().getParent());
1059 FileFormatI format = chooser.getSelectedFormat();
1062 * Call IdentifyFile to verify the file contains what its extension implies.
1063 * Skip this step for dynamically added file formats, because
1064 * IdentifyFile does not know how to recognise them.
1066 if (FileFormats.getInstance().isIdentifiable(format))
1070 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1071 } catch (FileFormatException e)
1073 // format = null; //??
1077 if (viewport != null)
1079 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1084 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1096 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1098 // This construct allows us to have a wider textfield
1100 JLabel label = new JLabel(
1101 MessageManager.getString("label.input_file_url"));
1102 final JComboBox history = new JComboBox();
1104 JPanel panel = new JPanel(new GridLayout(2, 1));
1107 history.setPreferredSize(new Dimension(400, 20));
1108 history.setEditable(true);
1109 history.addItem("http://www.");
1111 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1115 if (historyItems != null)
1117 st = new StringTokenizer(historyItems, "\t");
1119 while (st.hasMoreTokens())
1121 history.addItem(st.nextElement());
1125 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1126 MessageManager.getString("label.input_alignment_from_url"),
1127 JvOptionPane.OK_CANCEL_OPTION);
1129 if (reply != JvOptionPane.OK_OPTION)
1134 String url = history.getSelectedItem().toString();
1136 if (url.toLowerCase().endsWith(".jar"))
1138 if (viewport != null)
1140 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1141 FileFormat.Jalview);
1145 new FileLoader().LoadFile(url, DataSourceType.URL,
1146 FileFormat.Jalview);
1151 FileFormatI format = null;
1154 format = new IdentifyFile().identify(url, DataSourceType.URL);
1155 } catch (FileFormatException e)
1157 // TODO revise error handling, distinguish between
1158 // URL not found and response not valid
1163 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1164 MessageManager.formatMessage("label.couldnt_locate",
1167 MessageManager.getString("label.url_not_found"),
1168 JvOptionPane.WARNING_MESSAGE);
1173 if (viewport != null)
1175 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1180 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1186 * Opens the CutAndPaste window for the user to paste an alignment in to
1189 * - if not null, the pasted alignment is added to the current
1190 * alignment; if null, to a new alignment window
1193 public void inputTextboxMenuItem_actionPerformed(
1194 AlignmentViewPanel viewPanel)
1196 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1197 cap.setForInput(viewPanel);
1198 Desktop.addInternalFrame(cap,
1199 MessageManager.getString("label.cut_paste_alignmen_file"), true,
1209 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1210 jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH",
1212 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT",
1213 screen.height + "");
1214 storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
1215 getWidth(), getHeight()));
1217 if (jconsole != null)
1219 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1220 jconsole.stopConsole();
1224 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1227 if (dialogExecutor != null)
1229 dialogExecutor.shutdownNow();
1231 closeAll_actionPerformed(null);
1233 if (groovyConsole != null)
1235 // suppress a possible repeat prompt to save script
1236 groovyConsole.setDirty(false);
1237 groovyConsole.exit();
1242 private void storeLastKnownDimensions(String string, Rectangle jc)
1244 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1245 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1246 + " height:" + jc.height);
1248 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1249 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1250 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1251 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1261 public void aboutMenuItem_actionPerformed(ActionEvent e)
1263 // StringBuffer message = getAboutMessage(false);
1264 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1266 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1267 new Thread(new Runnable()
1272 new SplashScreen(true);
1277 public StringBuffer getAboutMessage(boolean shortv)
1279 StringBuffer message = new StringBuffer();
1280 message.append("<html>");
1283 message.append("<h1><strong>Version: "
1284 + jalview.bin.Cache.getProperty("VERSION")
1285 + "</strong></h1>");
1286 message.append("<strong>Last Updated: <em>"
1287 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1288 + "</em></strong>");
1294 message.append("<strong>Version "
1295 + jalview.bin.Cache.getProperty("VERSION")
1296 + "; last updated: "
1297 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1300 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1301 .equals("Checking"))
1303 message.append("<br>...Checking latest version...</br>");
1305 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1306 .equals(jalview.bin.Cache.getProperty("VERSION")))
1308 boolean red = false;
1309 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1310 .indexOf("automated build") == -1)
1313 // Displayed when code version and jnlp version do not match and code
1314 // version is not a development build
1315 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1318 message.append("<br>!! Version "
1319 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1321 + " is available for download from "
1322 + jalview.bin.Cache.getDefault("www.jalview.org",
1323 "http://www.jalview.org")
1327 message.append("</div>");
1330 message.append("<br>Authors: " + jalview.bin.Cache.getDefault(
1332 "The Jalview Authors (See AUTHORS file for current list)")
1333 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1334 + "<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"
1335 + "<br><br>If you use Jalview, please cite:"
1336 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1337 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1338 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1350 public void documentationMenuItem_actionPerformed(ActionEvent e)
1354 Help.showHelpWindow();
1355 } catch (Exception ex)
1361 public void closeAll_actionPerformed(ActionEvent e)
1363 // TODO show a progress bar while closing?
1364 JInternalFrame[] frames = desktop.getAllFrames();
1365 for (int i = 0; i < frames.length; i++)
1369 frames[i].setClosed(true);
1370 } catch (java.beans.PropertyVetoException ex)
1374 Jalview.setCurrentAlignFrame(null);
1375 System.out.println("ALL CLOSED");
1376 if (v_client != null)
1378 // TODO clear binding to vamsas document objects on close_all
1382 * reset state of singleton objects as appropriate (clear down session state
1383 * when all windows are closed)
1385 StructureSelectionManager ssm = StructureSelectionManager
1386 .getStructureSelectionManager(this);
1395 public void raiseRelated_actionPerformed(ActionEvent e)
1397 reorderAssociatedWindows(false, false);
1401 public void minimizeAssociated_actionPerformed(ActionEvent e)
1403 reorderAssociatedWindows(true, false);
1406 void closeAssociatedWindows()
1408 reorderAssociatedWindows(false, true);
1414 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1418 protected void garbageCollect_actionPerformed(ActionEvent e)
1420 // We simply collect the garbage
1421 jalview.bin.Cache.log.debug("Collecting garbage...");
1423 jalview.bin.Cache.log.debug("Finished garbage collection.");
1430 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1434 protected void showMemusage_actionPerformed(ActionEvent e)
1436 desktop.showMemoryUsage(showMemusage.isSelected());
1443 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1447 protected void showConsole_actionPerformed(ActionEvent e)
1449 showConsole(showConsole.isSelected());
1452 Console jconsole = null;
1455 * control whether the java console is visible or not
1459 void showConsole(boolean selected)
1461 showConsole.setSelected(selected);
1462 // TODO: decide if we should update properties file
1463 Cache.setProperty("SHOW_JAVA_CONSOLE",
1464 Boolean.valueOf(selected).toString());
1465 jconsole.setVisible(selected);
1468 void reorderAssociatedWindows(boolean minimize, boolean close)
1470 JInternalFrame[] frames = desktop.getAllFrames();
1471 if (frames == null || frames.length < 1)
1476 AlignmentViewport source = null, target = null;
1477 if (frames[0] instanceof AlignFrame)
1479 source = ((AlignFrame) frames[0]).getCurrentView();
1481 else if (frames[0] instanceof TreePanel)
1483 source = ((TreePanel) frames[0]).getViewPort();
1485 else if (frames[0] instanceof PCAPanel)
1487 source = ((PCAPanel) frames[0]).av;
1489 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1491 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1496 for (int i = 0; i < frames.length; i++)
1499 if (frames[i] == null)
1503 if (frames[i] instanceof AlignFrame)
1505 target = ((AlignFrame) frames[i]).getCurrentView();
1507 else if (frames[i] instanceof TreePanel)
1509 target = ((TreePanel) frames[i]).getViewPort();
1511 else if (frames[i] instanceof PCAPanel)
1513 target = ((PCAPanel) frames[i]).av;
1515 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1517 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1520 if (source == target)
1526 frames[i].setClosed(true);
1530 frames[i].setIcon(minimize);
1533 frames[i].toFront();
1537 } catch (java.beans.PropertyVetoException ex)
1552 protected void preferences_actionPerformed(ActionEvent e)
1564 public void saveState_actionPerformed(ActionEvent e)
1566 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1569 chooser.setFileView(new JalviewFileView());
1570 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1572 int value = chooser.showSaveDialog(this);
1574 if (value == JalviewFileChooser.APPROVE_OPTION)
1576 final Desktop me = this;
1577 final java.io.File choice = chooser.getSelectedFile();
1578 setProjectFile(choice);
1580 new Thread(new Runnable()
1585 // TODO: refactor to Jalview desktop session controller action.
1586 setProgressBar(MessageManager.formatMessage(
1587 "label.saving_jalview_project", new Object[]
1588 { choice.getName() }), choice.hashCode());
1589 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1590 choice.getParent());
1591 // TODO catch and handle errors for savestate
1592 // TODO prevent user from messing with the Desktop whilst we're saving
1595 new Jalview2XML().saveState(choice);
1596 } catch (OutOfMemoryError oom)
1599 "Whilst saving current state to " + choice.getName(),
1601 } catch (Exception ex)
1604 "Problems whilst trying to save to " + choice.getName(),
1606 JvOptionPane.showMessageDialog(me,
1607 MessageManager.formatMessage(
1608 "label.error_whilst_saving_current_state_to",
1610 { choice.getName() }),
1611 MessageManager.getString("label.couldnt_save_project"),
1612 JvOptionPane.WARNING_MESSAGE);
1614 setProgressBar(null, choice.hashCode());
1620 private void setProjectFile(File choice)
1622 this.projectFile = choice;
1625 public File getProjectFile()
1627 return this.projectFile;
1637 public void loadState_actionPerformed(ActionEvent e)
1639 JalviewFileChooser chooser = new JalviewFileChooser(
1640 Cache.getProperty("LAST_DIRECTORY"), new String[]
1643 { "Jalview Project", "Jalview Project (old)" },
1645 chooser.setFileView(new JalviewFileView());
1646 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1648 int value = chooser.showOpenDialog(this);
1650 if (value == JalviewFileChooser.APPROVE_OPTION)
1652 final File selectedFile = chooser.getSelectedFile();
1653 setProjectFile(selectedFile);
1654 final String choice = selectedFile.getAbsolutePath();
1655 Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1656 new Thread(new Runnable()
1661 setProgressBar(MessageManager.formatMessage(
1662 "label.loading_jalview_project", new Object[]
1663 { choice }), choice.hashCode());
1666 new Jalview2XML().loadJalviewAlign(choice);
1667 } catch (OutOfMemoryError oom)
1669 new OOMWarning("Whilst loading project from " + choice, oom);
1670 } catch (Exception ex)
1673 "Problems whilst loading project from " + choice, ex);
1674 JvOptionPane.showMessageDialog(Desktop.desktop,
1675 MessageManager.formatMessage(
1676 "label.error_whilst_loading_project_from",
1679 MessageManager.getString("label.couldnt_load_project"),
1680 JvOptionPane.WARNING_MESSAGE);
1682 setProgressBar(null, choice.hashCode());
1689 public void inputSequence_actionPerformed(ActionEvent e)
1691 new SequenceFetcher(this);
1694 JPanel progressPanel;
1696 ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
1698 public void startLoading(final String fileName)
1700 if (fileLoadingCount == 0)
1702 fileLoadingPanels.add(addProgressPanel(MessageManager
1703 .formatMessage("label.loading_file", new Object[]
1709 private JPanel addProgressPanel(String string)
1711 if (progressPanel == null)
1713 progressPanel = new JPanel(new GridLayout(1, 1));
1714 totalProgressCount = 0;
1715 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1717 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1718 JProgressBar progressBar = new JProgressBar();
1719 progressBar.setIndeterminate(true);
1721 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1723 thisprogress.add(progressBar, BorderLayout.CENTER);
1724 progressPanel.add(thisprogress);
1725 ((GridLayout) progressPanel.getLayout()).setRows(
1726 ((GridLayout) progressPanel.getLayout()).getRows() + 1);
1727 ++totalProgressCount;
1728 instance.validate();
1729 return thisprogress;
1732 int totalProgressCount = 0;
1734 private void removeProgressPanel(JPanel progbar)
1736 if (progressPanel != null)
1738 synchronized (progressPanel)
1740 progressPanel.remove(progbar);
1741 GridLayout gl = (GridLayout) progressPanel.getLayout();
1742 gl.setRows(gl.getRows() - 1);
1743 if (--totalProgressCount < 1)
1745 this.getContentPane().remove(progressPanel);
1746 progressPanel = null;
1753 public void stopLoading()
1756 if (fileLoadingCount < 1)
1758 while (fileLoadingPanels.size() > 0)
1760 removeProgressPanel(fileLoadingPanels.remove(0));
1762 fileLoadingPanels.clear();
1763 fileLoadingCount = 0;
1768 public static int getViewCount(String alignmentId)
1770 AlignmentViewport[] aps = getViewports(alignmentId);
1771 return (aps == null) ? 0 : aps.length;
1776 * @param alignmentId
1777 * - if null, all sets are returned
1778 * @return all AlignmentPanels concerning the alignmentId sequence set
1780 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1782 if (Desktop.desktop == null)
1784 // no frames created and in headless mode
1785 // TODO: verify that frames are recoverable when in headless mode
1788 List<AlignmentPanel> aps = new ArrayList<>();
1789 AlignFrame[] frames = getAlignFrames();
1794 for (AlignFrame af : frames)
1796 for (AlignmentPanel ap : af.alignPanels)
1798 if (alignmentId == null
1799 || alignmentId.equals(ap.av.getSequenceSetId()))
1805 if (aps.size() == 0)
1809 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1814 * get all the viewports on an alignment.
1816 * @param sequenceSetId
1817 * unique alignment id (may be null - all viewports returned in that
1819 * @return all viewports on the alignment bound to sequenceSetId
1821 public static AlignmentViewport[] getViewports(String sequenceSetId)
1823 List<AlignmentViewport> viewp = new ArrayList<>();
1824 if (desktop != null)
1826 AlignFrame[] frames = Desktop.getAlignFrames();
1828 for (AlignFrame afr : frames)
1830 if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
1831 .equals(sequenceSetId))
1833 if (afr.alignPanels != null)
1835 for (AlignmentPanel ap : afr.alignPanels)
1837 if (sequenceSetId == null
1838 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1846 viewp.add(afr.getViewport());
1850 if (viewp.size() > 0)
1852 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1859 * Explode the views in the given frame into separate AlignFrame
1863 public static void explodeViews(AlignFrame af)
1865 int size = af.alignPanels.size();
1871 for (int i = 0; i < size; i++)
1873 AlignmentPanel ap = af.alignPanels.get(i);
1874 AlignFrame newaf = new AlignFrame(ap);
1877 * Restore the view's last exploded frame geometry if known. Multiple
1878 * views from one exploded frame share and restore the same (frame)
1879 * position and size.
1881 Rectangle geometry = ap.av.getExplodedGeometry();
1882 if (geometry != null)
1884 newaf.setBounds(geometry);
1887 ap.av.setGatherViewsHere(false);
1889 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1890 AlignFrame.DEFAULT_HEIGHT);
1893 af.alignPanels.clear();
1894 af.closeMenuItem_actionPerformed(true);
1899 * Gather expanded views (separate AlignFrame's) with the same sequence set
1900 * identifier back in to this frame as additional views, and close the
1901 * expanded views. Note the expanded frames may themselves have multiple
1902 * views. We take the lot.
1906 public void gatherViews(AlignFrame source)
1908 source.viewport.setGatherViewsHere(true);
1909 source.viewport.setExplodedGeometry(source.getBounds());
1910 JInternalFrame[] frames = desktop.getAllFrames();
1911 String viewId = source.viewport.getSequenceSetId();
1913 for (int t = 0; t < frames.length; t++)
1915 if (frames[t] instanceof AlignFrame && frames[t] != source)
1917 AlignFrame af = (AlignFrame) frames[t];
1918 boolean gatherThis = false;
1919 for (int a = 0; a < af.alignPanels.size(); a++)
1921 AlignmentPanel ap = af.alignPanels.get(a);
1922 if (viewId.equals(ap.av.getSequenceSetId()))
1925 ap.av.setGatherViewsHere(false);
1926 ap.av.setExplodedGeometry(af.getBounds());
1927 source.addAlignmentPanel(ap, false);
1933 af.alignPanels.clear();
1934 af.closeMenuItem_actionPerformed(true);
1941 jalview.gui.VamsasApplication v_client = null;
1944 public void vamsasImport_actionPerformed(ActionEvent e)
1946 if (v_client == null)
1948 // Load and try to start a session.
1949 JalviewFileChooser chooser = new JalviewFileChooser(
1950 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1952 chooser.setFileView(new JalviewFileView());
1953 chooser.setDialogTitle(
1954 MessageManager.getString("label.open_saved_vamsas_session"));
1955 chooser.setToolTipText(MessageManager.getString(
1956 "label.select_vamsas_session_opened_as_new_vamsas_session"));
1958 int value = chooser.showOpenDialog(this);
1960 if (value == JalviewFileChooser.APPROVE_OPTION)
1962 String fle = chooser.getSelectedFile().toString();
1963 if (!vamsasImport(chooser.getSelectedFile()))
1965 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1966 MessageManager.formatMessage(
1967 "label.couldnt_import_as_vamsas_session",
1971 .getString("label.vamsas_document_import_failed"),
1972 JvOptionPane.ERROR_MESSAGE);
1978 jalview.bin.Cache.log.error(
1979 "Implementation error - load session from a running session is not supported.");
1984 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1987 * @return true if import was a success and a session was started.
1989 public boolean vamsasImport(URL url)
1991 // TODO: create progress bar
1992 if (v_client != null)
1995 jalview.bin.Cache.log.error(
1996 "Implementation error - load session from a running session is not supported.");
2002 // copy the URL content to a temporary local file
2003 // TODO: be a bit cleverer here with nio (?!)
2004 File file = File.createTempFile("vdocfromurl", ".vdj");
2005 FileOutputStream fos = new FileOutputStream(file);
2006 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2007 byte[] buffer = new byte[2048];
2009 while ((ln = bis.read(buffer)) > -1)
2011 fos.write(buffer, 0, ln);
2015 v_client = new jalview.gui.VamsasApplication(this, file,
2016 url.toExternalForm());
2017 } catch (Exception ex)
2019 jalview.bin.Cache.log.error(
2020 "Failed to create new vamsas session from contents of URL "
2025 setupVamsasConnectedGui();
2026 v_client.initial_update(); // TODO: thread ?
2027 return v_client.inSession();
2031 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2034 * @return true if import was a success and a session was started.
2036 public boolean vamsasImport(File file)
2038 if (v_client != null)
2041 jalview.bin.Cache.log.error(
2042 "Implementation error - load session from a running session is not supported.");
2046 setProgressBar(MessageManager.formatMessage(
2047 "status.importing_vamsas_session_from", new Object[]
2048 { file.getName() }), file.hashCode());
2051 v_client = new jalview.gui.VamsasApplication(this, file, null);
2052 } catch (Exception ex)
2054 setProgressBar(MessageManager.formatMessage(
2055 "status.importing_vamsas_session_from", new Object[]
2056 { file.getName() }), file.hashCode());
2057 jalview.bin.Cache.log.error(
2058 "New vamsas session from existing session file failed:", ex);
2061 setupVamsasConnectedGui();
2062 v_client.initial_update(); // TODO: thread ?
2063 setProgressBar(MessageManager.formatMessage(
2064 "status.importing_vamsas_session_from", new Object[]
2065 { file.getName() }), file.hashCode());
2066 return v_client.inSession();
2069 public boolean joinVamsasSession(String mysesid)
2071 if (v_client != null)
2073 throw new Error(MessageManager
2074 .getString("error.try_join_vamsas_session_another"));
2076 if (mysesid == null)
2079 MessageManager.getString("error.invalid_vamsas_session_id"));
2081 v_client = new VamsasApplication(this, mysesid);
2082 setupVamsasConnectedGui();
2083 v_client.initial_update();
2084 return (v_client.inSession());
2088 public void vamsasStart_actionPerformed(ActionEvent e)
2090 if (v_client == null)
2093 // we just start a default session for moment.
2095 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2096 * getProperty("LAST_DIRECTORY"));
2098 * chooser.setFileView(new JalviewFileView());
2099 * chooser.setDialogTitle("Load Vamsas file");
2100 * chooser.setToolTipText("Import");
2102 * int value = chooser.showOpenDialog(this);
2104 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2105 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2107 v_client = new VamsasApplication(this);
2108 setupVamsasConnectedGui();
2109 v_client.initial_update(); // TODO: thread ?
2113 // store current data in session.
2114 v_client.push_update(); // TODO: thread
2118 protected void setupVamsasConnectedGui()
2120 vamsasStart.setText(MessageManager.getString("label.session_update"));
2121 vamsasSave.setVisible(true);
2122 vamsasStop.setVisible(true);
2123 vamsasImport.setVisible(false); // Document import to existing session is
2124 // not possible for vamsas-client-1.0.
2127 protected void setupVamsasDisconnectedGui()
2129 vamsasSave.setVisible(false);
2130 vamsasStop.setVisible(false);
2131 vamsasImport.setVisible(true);
2133 .setText(MessageManager.getString("label.new_vamsas_session"));
2137 public void vamsasStop_actionPerformed(ActionEvent e)
2139 if (v_client != null)
2141 v_client.end_session();
2143 setupVamsasDisconnectedGui();
2147 protected void buildVamsasStMenu()
2149 if (v_client == null)
2151 String[] sess = null;
2154 sess = VamsasApplication.getSessionList();
2155 } catch (Exception e)
2157 jalview.bin.Cache.log.warn("Problem getting current sessions list.",
2163 jalview.bin.Cache.log.debug(
2164 "Got current sessions list: " + sess.length + " entries.");
2165 VamsasStMenu.removeAll();
2166 for (int i = 0; i < sess.length; i++)
2168 JMenuItem sessit = new JMenuItem();
2169 sessit.setText(sess[i]);
2170 sessit.setToolTipText(MessageManager
2171 .formatMessage("label.connect_to_session", new Object[]
2173 final Desktop dsktp = this;
2174 final String mysesid = sess[i];
2175 sessit.addActionListener(new ActionListener()
2179 public void actionPerformed(ActionEvent e)
2181 if (dsktp.v_client == null)
2183 Thread rthr = new Thread(new Runnable()
2189 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2190 dsktp.setupVamsasConnectedGui();
2191 dsktp.v_client.initial_update();
2199 VamsasStMenu.add(sessit);
2201 // don't show an empty menu.
2202 VamsasStMenu.setVisible(sess.length > 0);
2207 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2208 VamsasStMenu.removeAll();
2209 VamsasStMenu.setVisible(false);
2214 // Not interested in the content. Just hide ourselves.
2215 VamsasStMenu.setVisible(false);
2220 public void vamsasSave_actionPerformed(ActionEvent e)
2222 if (v_client != null)
2224 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2225 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2228 chooser.setFileView(new JalviewFileView());
2229 chooser.setDialogTitle(MessageManager
2230 .getString("label.save_vamsas_document_archive"));
2232 int value = chooser.showSaveDialog(this);
2234 if (value == JalviewFileChooser.APPROVE_OPTION)
2236 java.io.File choice = chooser.getSelectedFile();
2237 JPanel progpanel = addProgressPanel(MessageManager
2238 .formatMessage("label.saving_vamsas_doc", new Object[]
2239 { choice.getName() }));
2240 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2241 String warnmsg = null;
2242 String warnttl = null;
2245 v_client.vclient.storeDocument(choice);
2248 warnttl = "Serious Problem saving Vamsas Document";
2249 warnmsg = ex.toString();
2250 jalview.bin.Cache.log
2251 .error("Error Whilst saving document to " + choice, ex);
2253 } catch (Exception ex)
2255 warnttl = "Problem saving Vamsas Document.";
2256 warnmsg = ex.toString();
2257 jalview.bin.Cache.log.warn(
2258 "Exception Whilst saving document to " + choice, ex);
2261 removeProgressPanel(progpanel);
2262 if (warnmsg != null)
2264 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2266 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2272 JPanel vamUpdate = null;
2275 * hide vamsas user gui bits when a vamsas document event is being handled.
2278 * true to hide gui, false to reveal gui
2280 public void setVamsasUpdate(boolean b)
2282 Cache.log.debug("Setting gui for Vamsas update "
2283 + (b ? "in progress" : "finished"));
2285 if (vamUpdate != null)
2287 this.removeProgressPanel(vamUpdate);
2291 vamUpdate = this.addProgressPanel(
2292 MessageManager.getString("label.updating_vamsas_session"));
2294 vamsasStart.setVisible(!b);
2295 vamsasStop.setVisible(!b);
2296 vamsasSave.setVisible(!b);
2299 public JInternalFrame[] getAllFrames()
2301 return desktop.getAllFrames();
2305 * Checks the given url to see if it gives a response indicating that the user
2306 * should be informed of a new questionnaire.
2310 public void checkForQuestionnaire(String url)
2312 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2313 // javax.swing.SwingUtilities.invokeLater(jvq);
2314 new Thread(jvq).start();
2317 public void checkURLLinks()
2319 // Thread off the URL link checker
2320 addDialogThread(new Runnable()
2325 if (Cache.getDefault("CHECKURLLINKS", true))
2327 // check what the actual links are - if it's just the default don't
2328 // bother with the warning
2329 List<String> links = Preferences.sequenceUrlLinks
2332 // only need to check links if there is one with a
2333 // SEQUENCE_ID which is not the default EMBL_EBI link
2334 ListIterator<String> li = links.listIterator();
2335 boolean check = false;
2336 List<JLabel> urls = new ArrayList<>();
2337 while (li.hasNext())
2339 String link = li.next();
2340 if (link.contains(SEQUENCE_ID)
2341 && !UrlConstants.isDefaultString(link))
2344 int barPos = link.indexOf("|");
2345 String urlMsg = barPos == -1 ? link
2346 : link.substring(0, barPos) + ": "
2347 + link.substring(barPos + 1);
2348 urls.add(new JLabel(urlMsg));
2356 // ask user to check in case URL links use old style tokens
2357 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2358 JPanel msgPanel = new JPanel();
2359 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2360 msgPanel.add(Box.createVerticalGlue());
2361 JLabel msg = new JLabel(MessageManager
2362 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2363 JLabel msg2 = new JLabel(MessageManager
2364 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2366 for (JLabel url : urls)
2372 final JCheckBox jcb = new JCheckBox(
2373 MessageManager.getString("label.do_not_display_again"));
2374 jcb.addActionListener(new ActionListener()
2377 public void actionPerformed(ActionEvent e)
2379 // update Cache settings for "don't show this again"
2380 boolean showWarningAgain = !jcb.isSelected();
2381 Cache.setProperty("CHECKURLLINKS",
2382 Boolean.valueOf(showWarningAgain).toString());
2387 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2389 .getString("label.SEQUENCE_ID_no_longer_used"),
2390 JvOptionPane.WARNING_MESSAGE);
2397 * Proxy class for JDesktopPane which optionally displays the current memory
2398 * usage and highlights the desktop area with a red bar if free memory runs
2403 public class MyDesktopPane extends JDesktopPane implements Runnable
2406 private static final float ONE_MB = 1048576f;
2408 boolean showMemoryUsage = false;
2412 java.text.NumberFormat df;
2414 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2417 public MyDesktopPane(boolean showMemoryUsage)
2419 showMemoryUsage(showMemoryUsage);
2422 public void showMemoryUsage(boolean showMemory)
2424 this.showMemoryUsage = showMemory;
2427 Thread worker = new Thread(this);
2433 public boolean isShowMemoryUsage()
2435 return showMemoryUsage;
2441 df = java.text.NumberFormat.getNumberInstance();
2442 df.setMaximumFractionDigits(2);
2443 runtime = Runtime.getRuntime();
2445 while (showMemoryUsage)
2449 maxMemory = runtime.maxMemory() / ONE_MB;
2450 allocatedMemory = runtime.totalMemory() / ONE_MB;
2451 freeMemory = runtime.freeMemory() / ONE_MB;
2452 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2454 percentUsage = (totalFreeMemory / maxMemory) * 100;
2456 // if (percentUsage < 20)
2458 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2460 // instance.set.setBorder(border1);
2463 // sleep after showing usage
2465 } catch (Exception ex)
2467 ex.printStackTrace();
2473 public void paintComponent(Graphics g)
2475 if (showMemoryUsage && g != null && df != null)
2477 if (percentUsage < 20)
2479 g.setColor(Color.red);
2481 FontMetrics fm = g.getFontMetrics();
2484 g.drawString(MessageManager.formatMessage("label.memory_stats",
2486 { df.format(totalFreeMemory), df.format(maxMemory),
2487 df.format(percentUsage) }),
2488 10, getHeight() - fm.getHeight());
2496 * Accessor method to quickly get all the AlignmentFrames loaded.
2498 * @return an array of AlignFrame, or null if none found
2500 public static AlignFrame[] getAlignFrames()
2502 if (Jalview.isHeadlessMode())
2504 // Desktop.desktop is null in headless mode
2505 return new AlignFrame[] { Jalview.currentAlignFrame };
2508 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2514 List<AlignFrame> avp = new ArrayList<>();
2516 for (int i = frames.length - 1; i > -1; i--)
2518 if (frames[i] instanceof AlignFrame)
2520 avp.add((AlignFrame) frames[i]);
2522 else if (frames[i] instanceof SplitFrame)
2525 * Also check for a split frame containing an AlignFrame
2527 GSplitFrame sf = (GSplitFrame) frames[i];
2528 if (sf.getTopFrame() instanceof AlignFrame)
2530 avp.add((AlignFrame) sf.getTopFrame());
2532 if (sf.getBottomFrame() instanceof AlignFrame)
2534 avp.add((AlignFrame) sf.getBottomFrame());
2538 if (avp.size() == 0)
2542 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2547 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2551 public GStructureViewer[] getJmols()
2553 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2559 List<GStructureViewer> avp = new ArrayList<>();
2561 for (int i = frames.length - 1; i > -1; i--)
2563 if (frames[i] instanceof AppJmol)
2565 GStructureViewer af = (GStructureViewer) frames[i];
2569 if (avp.size() == 0)
2573 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2578 * Add Groovy Support to Jalview
2581 public void groovyShell_actionPerformed()
2585 openGroovyConsole();
2586 } catch (Exception ex)
2588 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2589 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2591 MessageManager.getString("label.couldnt_create_groovy_shell"),
2592 MessageManager.getString("label.groovy_support_failed"),
2593 JvOptionPane.ERROR_MESSAGE);
2598 * Open the Groovy console
2600 void openGroovyConsole()
2602 if (groovyConsole == null)
2604 groovyConsole = new groovy.ui.Console();
2605 groovyConsole.setVariable("Jalview", this);
2606 groovyConsole.run();
2609 * We allow only one console at a time, so that AlignFrame menu option
2610 * 'Calculate | Run Groovy script' is unambiguous.
2611 * Disable 'Groovy Console', and enable 'Run script', when the console is
2612 * opened, and the reverse when it is closed
2614 Window window = (Window) groovyConsole.getFrame();
2615 window.addWindowListener(new WindowAdapter()
2618 public void windowClosed(WindowEvent e)
2621 * rebind CMD-Q from Groovy Console to Jalview Quit
2624 enableExecuteGroovy(false);
2630 * show Groovy console window (after close and reopen)
2632 ((Window) groovyConsole.getFrame()).setVisible(true);
2635 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2636 * and disable opening a second console
2638 enableExecuteGroovy(true);
2642 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2643 * binding when opened
2645 protected void addQuitHandler()
2647 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
2648 .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
2649 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
2651 getRootPane().getActionMap().put("Quit", new AbstractAction()
2654 public void actionPerformed(ActionEvent e)
2662 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2665 * true if Groovy console is open
2667 public void enableExecuteGroovy(boolean enabled)
2670 * disable opening a second Groovy console
2671 * (or re-enable when the console is closed)
2673 groovyShell.setEnabled(!enabled);
2675 AlignFrame[] alignFrames = getAlignFrames();
2676 if (alignFrames != null)
2678 for (AlignFrame af : alignFrames)
2680 af.setGroovyEnabled(enabled);
2686 * Progress bars managed by the IProgressIndicator method.
2688 private Hashtable<Long, JPanel> progressBars;
2690 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2695 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2698 public void setProgressBar(String message, long id)
2700 if (progressBars == null)
2702 progressBars = new Hashtable<>();
2703 progressBarHandlers = new Hashtable<>();
2706 if (progressBars.get(new Long(id)) != null)
2708 JPanel panel = progressBars.remove(new Long(id));
2709 if (progressBarHandlers.contains(new Long(id)))
2711 progressBarHandlers.remove(new Long(id));
2713 removeProgressPanel(panel);
2717 progressBars.put(new Long(id), addProgressPanel(message));
2724 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2725 * jalview.gui.IProgressIndicatorHandler)
2728 public void registerHandler(final long id,
2729 final IProgressIndicatorHandler handler)
2731 if (progressBarHandlers == null
2732 || !progressBars.containsKey(new Long(id)))
2734 throw new Error(MessageManager.getString(
2735 "error.call_setprogressbar_before_registering_handler"));
2737 progressBarHandlers.put(new Long(id), handler);
2738 final JPanel progressPanel = progressBars.get(new Long(id));
2739 if (handler.canCancel())
2741 JButton cancel = new JButton(
2742 MessageManager.getString("action.cancel"));
2743 final IProgressIndicator us = this;
2744 cancel.addActionListener(new ActionListener()
2748 public void actionPerformed(ActionEvent e)
2750 handler.cancelActivity(id);
2751 us.setProgressBar(MessageManager
2752 .formatMessage("label.cancelled_params", new Object[]
2753 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2757 progressPanel.add(cancel, BorderLayout.EAST);
2763 * @return true if any progress bars are still active
2766 public boolean operationInProgress()
2768 if (progressBars != null && progressBars.size() > 0)
2776 * This will return the first AlignFrame holding the given viewport instance.
2777 * It will break if there are more than one AlignFrames viewing a particular
2781 * @return alignFrame for viewport
2783 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2785 if (desktop != null)
2787 AlignmentPanel[] aps = getAlignmentPanels(
2788 viewport.getSequenceSetId());
2789 for (int panel = 0; aps != null && panel < aps.length; panel++)
2791 if (aps[panel] != null && aps[panel].av == viewport)
2793 return aps[panel].alignFrame;
2800 public VamsasApplication getVamsasApplication()
2807 * flag set if jalview GUI is being operated programmatically
2809 private boolean inBatchMode = false;
2812 * check if jalview GUI is being operated programmatically
2814 * @return inBatchMode
2816 public boolean isInBatchMode()
2822 * set flag if jalview GUI is being operated programmatically
2824 * @param inBatchMode
2826 public void setInBatchMode(boolean inBatchMode)
2828 this.inBatchMode = inBatchMode;
2831 public void startServiceDiscovery()
2833 startServiceDiscovery(false);
2836 public void startServiceDiscovery(boolean blocking)
2838 boolean alive = true;
2839 Thread t0 = null, t1 = null, t2 = null;
2840 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2843 // todo: changesupport handlers need to be transferred
2844 if (discoverer == null)
2846 discoverer = new jalview.ws.jws1.Discoverer();
2847 // register PCS handler for desktop.
2848 discoverer.addPropertyChangeListener(changeSupport);
2850 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2851 // until we phase out completely
2852 (t0 = new Thread(discoverer)).start();
2855 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2857 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2858 .startDiscoverer(changeSupport);
2862 // TODO: do rest service discovery
2871 } catch (Exception e)
2874 alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
2875 || (t3 != null && t3.isAlive())
2876 || (t0 != null && t0.isAlive());
2882 * called to check if the service discovery process completed successfully.
2886 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2888 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2890 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2891 .getErrorMessages();
2894 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2896 if (serviceChangedDialog == null)
2898 // only run if we aren't already displaying one of these.
2899 addDialogThread(serviceChangedDialog = new Runnable()
2906 * JalviewDialog jd =new JalviewDialog() {
2908 * @Override protected void cancelPressed() { // TODO
2909 * Auto-generated method stub
2911 * }@Override protected void okPressed() { // TODO
2912 * Auto-generated method stub
2914 * }@Override protected void raiseClosed() { // TODO
2915 * Auto-generated method stub
2917 * } }; jd.initDialogFrame(new
2918 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2919 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2920 * + " or mis-configured HTTP proxy settings.<br/>" +
2921 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2923 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2924 * ), true, true, "Web Service Configuration Problem", 450,
2927 * jd.waitForInput();
2929 JvOptionPane.showConfirmDialog(Desktop.desktop,
2930 new JLabel("<html><table width=\"450\"><tr><td>"
2931 + ermsg + "</td></tr></table>"
2932 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2933 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2934 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2935 + " Tools->Preferences dialog box to change them.</p></html>"),
2936 "Web Service Configuration Problem",
2937 JvOptionPane.DEFAULT_OPTION,
2938 JvOptionPane.ERROR_MESSAGE);
2939 serviceChangedDialog = null;
2948 "Errors reported by JABA discovery service. Check web services preferences.\n"
2955 private Runnable serviceChangedDialog = null;
2958 * start a thread to open a URL in the configured browser. Pops up a warning
2959 * dialog to the user if there is an exception when calling out to the browser
2964 public static void showUrl(final String url)
2966 showUrl(url, Desktop.instance);
2970 * Like showUrl but allows progress handler to be specified
2974 * (null) or object implementing IProgressIndicator
2976 public static void showUrl(final String url,
2977 final IProgressIndicator progress)
2979 new Thread(new Runnable()
2986 if (progress != null)
2988 progress.setProgressBar(MessageManager
2989 .formatMessage("status.opening_params", new Object[]
2990 { url }), this.hashCode());
2992 jalview.util.BrowserLauncher.openURL(url);
2993 } catch (Exception ex)
2995 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2997 .getString("label.web_browser_not_found_unix"),
2998 MessageManager.getString("label.web_browser_not_found"),
2999 JvOptionPane.WARNING_MESSAGE);
3001 ex.printStackTrace();
3003 if (progress != null)
3005 progress.setProgressBar(null, this.hashCode());
3011 public static WsParamSetManager wsparamManager = null;
3013 public static ParamManager getUserParameterStore()
3015 if (wsparamManager == null)
3017 wsparamManager = new WsParamSetManager();
3019 return wsparamManager;
3023 * static hyperlink handler proxy method for use by Jalview's internal windows
3027 public static void hyperlinkUpdate(HyperlinkEvent e)
3029 if (e.getEventType() == EventType.ACTIVATED)
3034 url = e.getURL().toString();
3035 Desktop.showUrl(url);
3036 } catch (Exception x)
3040 if (Cache.log != null)
3042 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3047 "Couldn't handle string " + url + " as a URL.");
3050 // ignore any exceptions due to dud links.
3057 * single thread that handles display of dialogs to user.
3059 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3062 * flag indicating if dialogExecutor should try to acquire a permit
3064 private volatile boolean dialogPause = true;
3069 private java.util.concurrent.Semaphore block = new Semaphore(0);
3071 private static groovy.ui.Console groovyConsole;
3074 * add another dialog thread to the queue
3078 public void addDialogThread(final Runnable prompter)
3080 dialogExecutor.submit(new Runnable()
3090 } catch (InterruptedException x)
3095 if (instance == null)
3101 SwingUtilities.invokeAndWait(prompter);
3102 } catch (Exception q)
3104 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3110 public void startDialogQueue()
3112 // set the flag so we don't pause waiting for another permit and semaphore
3113 // the current task to begin
3114 dialogPause = false;
3119 protected void snapShotWindow_actionPerformed(ActionEvent e)
3123 ImageMaker im = new jalview.util.ImageMaker(
3124 this, ImageMaker.TYPE.EPS, "View of Desktop", getWidth(),
3125 getHeight(), of = new File("Jalview_snapshot"
3126 + System.currentTimeMillis() + ".eps"),
3127 "View of desktop", null, 0, false);
3130 paintAll(im.getGraphics());
3132 } catch (Exception q)
3134 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3138 Cache.log.info("Successfully written snapshot to file "
3139 + of.getAbsolutePath());
3143 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3144 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3145 * and location last time the view was expanded (if any). However it does not
3146 * remember the split pane divider location - this is set to match the
3147 * 'exploding' frame.
3151 public void explodeViews(SplitFrame sf)
3153 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3154 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3155 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3157 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3159 int viewCount = topPanels.size();
3166 * Processing in reverse order works, forwards order leaves the first panels
3167 * not visible. I don't know why!
3169 for (int i = viewCount - 1; i >= 0; i--)
3172 * Make new top and bottom frames. These take over the respective
3173 * AlignmentPanel objects, including their AlignmentViewports, so the
3174 * cdna/protein relationships between the viewports is carried over to the
3177 * explodedGeometry holds the (x, y) position of the previously exploded
3178 * SplitFrame, and the (width, height) of the AlignFrame component
3180 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3181 AlignFrame newTopFrame = new AlignFrame(topPanel);
3182 newTopFrame.setSize(oldTopFrame.getSize());
3183 newTopFrame.setVisible(true);
3184 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3185 .getExplodedGeometry();
3186 if (geometry != null)
3188 newTopFrame.setSize(geometry.getSize());
3191 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3192 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3193 newBottomFrame.setSize(oldBottomFrame.getSize());
3194 newBottomFrame.setVisible(true);
3195 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3196 .getExplodedGeometry();
3197 if (geometry != null)
3199 newBottomFrame.setSize(geometry.getSize());
3202 topPanel.av.setGatherViewsHere(false);
3203 bottomPanel.av.setGatherViewsHere(false);
3204 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3206 if (geometry != null)
3208 splitFrame.setLocation(geometry.getLocation());
3210 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3214 * Clear references to the panels (now relocated in the new SplitFrames)
3215 * before closing the old SplitFrame.
3218 bottomPanels.clear();
3223 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3224 * back into the given SplitFrame as additional views. Note that the gathered
3225 * frames may themselves have multiple views.
3229 public void gatherViews(GSplitFrame source)
3232 * special handling of explodedGeometry for a view within a SplitFrame: - it
3233 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3234 * height) of the AlignFrame component
3236 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3237 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3238 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3239 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3240 myBottomFrame.viewport
3241 .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
3242 myBottomFrame.getWidth(), myBottomFrame.getHeight()));
3243 myTopFrame.viewport.setGatherViewsHere(true);
3244 myBottomFrame.viewport.setGatherViewsHere(true);
3245 String topViewId = myTopFrame.viewport.getSequenceSetId();
3246 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3248 JInternalFrame[] frames = desktop.getAllFrames();
3249 for (JInternalFrame frame : frames)
3251 if (frame instanceof SplitFrame && frame != source)
3253 SplitFrame sf = (SplitFrame) frame;
3254 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3255 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3256 boolean gatherThis = false;
3257 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3259 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3260 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3261 if (topViewId.equals(topPanel.av.getSequenceSetId())
3262 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3265 topPanel.av.setGatherViewsHere(false);
3266 bottomPanel.av.setGatherViewsHere(false);
3267 topPanel.av.setExplodedGeometry(
3268 new Rectangle(sf.getLocation(), topFrame.getSize()));
3269 bottomPanel.av.setExplodedGeometry(
3270 new Rectangle(sf.getLocation(), bottomFrame.getSize()));
3271 myTopFrame.addAlignmentPanel(topPanel, false);
3272 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3278 topFrame.getAlignPanels().clear();
3279 bottomFrame.getAlignPanels().clear();
3286 * The dust settles...give focus to the tab we did this from.
3288 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3291 public static groovy.ui.Console getGroovyConsole()
3293 return groovyConsole;
3296 public static void transferFromDropTarget(List<String> files,
3297 List<DataSourceType> protocols, DropTargetDropEvent evt,
3298 Transferable t) throws Exception
3301 DataFlavor uriListFlavor = new DataFlavor(
3302 "text/uri-list;class=java.lang.String");
3303 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3305 // Works on Windows and MacOSX
3306 Cache.log.debug("Drop handled as javaFileListFlavor");
3307 for (Object file : (List) t
3308 .getTransferData(DataFlavor.javaFileListFlavor))
3310 files.add(((File) file).toString());
3311 protocols.add(DataSourceType.FILE);
3316 // Unix like behaviour
3317 boolean added = false;
3319 if (t.isDataFlavorSupported(uriListFlavor))
3321 Cache.log.debug("Drop handled as uriListFlavor");
3322 // This is used by Unix drag system
3323 data = (String) t.getTransferData(uriListFlavor);
3327 // fallback to text: workaround - on OSX where there's a JVM bug
3328 Cache.log.debug("standard URIListFlavor failed. Trying text");
3329 // try text fallback
3330 data = (String) t.getTransferData(
3331 new DataFlavor("text/plain;class=java.lang.String"));
3332 if (Cache.log.isDebugEnabled())
3334 Cache.log.debug("fallback returned " + data);
3337 while (protocols.size() < files.size())
3339 Cache.log.debug("Adding missing FILE protocol for "
3340 + files.get(protocols.size()));
3341 protocols.add(DataSourceType.FILE);
3343 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3344 data, "\r\n"); st.hasMoreTokens();)
3347 String s = st.nextToken();
3348 if (s.startsWith("#"))
3350 // the line is a comment (as per the RFC 2483)
3353 java.net.URI uri = new java.net.URI(s);
3354 if (uri.getScheme().toLowerCase().startsWith("http"))
3356 protocols.add(DataSourceType.URL);
3357 files.add(uri.toString());
3361 // otherwise preserve old behaviour: catch all for file objects
3362 java.io.File file = new java.io.File(uri);
3363 protocols.add(DataSourceType.FILE);
3364 files.add(file.toString());
3367 if (Cache.log.isDebugEnabled())
3369 if (data == null || !added)
3372 "Couldn't resolve drop data. Here are the supported flavors:");
3373 for (DataFlavor fl : t.getTransferDataFlavors())
3376 "Supported transfer dataflavor: " + fl.toString());
3377 Object df = t.getTransferData(fl);
3380 Cache.log.debug("Retrieves: " + df);
3384 Cache.log.debug("Retrieved nothing");
3393 * Sets the Preferences property for experimental features to True or False
3394 * depending on the state of the controlling menu item
3397 protected void showExperimental_actionPerformed(boolean selected)
3399 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));