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);
902 JInternalFrame itf = desktop.getSelectedFrame();
905 // itf.requestFocus();
912 menuItem.addActionListener(new ActionListener()
915 public void actionPerformed(ActionEvent e)
919 frame.setSelected(true);
920 frame.setIcon(false);
921 } catch (java.beans.PropertyVetoException ex)
930 windowMenu.add(menuItem);
935 frame.setSelected(true);
936 frame.requestFocus();
937 } catch (java.beans.PropertyVetoException ve)
939 } catch (java.lang.ClassCastException cex)
942 "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
948 public void lostOwnership(Clipboard clipboard, Transferable contents)
952 Desktop.jalviewClipboard = null;
955 internalCopy = false;
959 public void dragEnter(DropTargetDragEvent evt)
964 public void dragExit(DropTargetEvent evt)
969 public void dragOver(DropTargetDragEvent evt)
974 public void dropActionChanged(DropTargetDragEvent evt)
985 public void drop(DropTargetDropEvent evt)
987 boolean success = true;
988 // JAL-1552 - acceptDrop required before getTransferable call for
989 // Java's Transferable for native dnd
990 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
991 Transferable t = evt.getTransferable();
992 List<String> files = new ArrayList<>();
993 List<DataSourceType> protocols = new ArrayList<>();
997 Desktop.transferFromDropTarget(files, protocols, evt, t);
998 } catch (Exception e)
1000 e.printStackTrace();
1008 for (int i = 0; i < files.size(); i++)
1010 String file = files.get(i).toString();
1011 DataSourceType protocol = (protocols == null)
1012 ? DataSourceType.FILE
1014 FileFormatI format = null;
1016 if (file.endsWith(".jar"))
1018 format = FileFormat.Jalview;
1023 format = new IdentifyFile().identify(file, protocol);
1026 new FileLoader().LoadFile(file, protocol, format);
1029 } catch (Exception ex)
1034 evt.dropComplete(success); // need this to ensure input focus is properly
1035 // transfered to any new windows created
1045 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1047 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1048 JalviewFileChooser chooser = JalviewFileChooser
1049 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1051 chooser.setFileView(new JalviewFileView());
1052 chooser.setDialogTitle(
1053 MessageManager.getString("label.open_local_file"));
1054 chooser.setToolTipText(MessageManager.getString("action.open"));
1056 int value = chooser.showOpenDialog(this);
1058 if (value == JalviewFileChooser.APPROVE_OPTION)
1060 String choice = chooser.getSelectedFile().getPath();
1061 Cache.setProperty("LAST_DIRECTORY",
1062 chooser.getSelectedFile().getParent());
1064 FileFormatI format = chooser.getSelectedFormat();
1067 * Call IdentifyFile to verify the file contains what its extension implies.
1068 * Skip this step for dynamically added file formats, because
1069 * IdentifyFile does not know how to recognise them.
1071 if (FileFormats.getInstance().isIdentifiable(format))
1075 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1076 } catch (FileFormatException e)
1078 // format = null; //??
1082 if (viewport != null)
1084 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1089 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1101 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1103 // This construct allows us to have a wider textfield
1105 JLabel label = new JLabel(
1106 MessageManager.getString("label.input_file_url"));
1107 final JComboBox history = new JComboBox();
1109 JPanel panel = new JPanel(new GridLayout(2, 1));
1112 history.setPreferredSize(new Dimension(400, 20));
1113 history.setEditable(true);
1114 history.addItem("http://www.");
1116 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1120 if (historyItems != null)
1122 st = new StringTokenizer(historyItems, "\t");
1124 while (st.hasMoreTokens())
1126 history.addItem(st.nextElement());
1130 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1131 MessageManager.getString("label.input_alignment_from_url"),
1132 JvOptionPane.OK_CANCEL_OPTION);
1134 if (reply != JvOptionPane.OK_OPTION)
1139 String url = history.getSelectedItem().toString();
1141 if (url.toLowerCase().endsWith(".jar"))
1143 if (viewport != null)
1145 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1146 FileFormat.Jalview);
1150 new FileLoader().LoadFile(url, DataSourceType.URL,
1151 FileFormat.Jalview);
1156 FileFormatI format = null;
1159 format = new IdentifyFile().identify(url, DataSourceType.URL);
1160 } catch (FileFormatException e)
1162 // TODO revise error handling, distinguish between
1163 // URL not found and response not valid
1168 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1169 MessageManager.formatMessage("label.couldnt_locate",
1172 MessageManager.getString("label.url_not_found"),
1173 JvOptionPane.WARNING_MESSAGE);
1178 if (viewport != null)
1180 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1185 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1191 * Opens the CutAndPaste window for the user to paste an alignment in to
1194 * - if not null, the pasted alignment is added to the current
1195 * alignment; if null, to a new alignment window
1198 public void inputTextboxMenuItem_actionPerformed(
1199 AlignmentViewPanel viewPanel)
1201 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1202 cap.setForInput(viewPanel);
1203 Desktop.addInternalFrame(cap,
1204 MessageManager.getString("label.cut_paste_alignmen_file"), true,
1214 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1215 jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH",
1217 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT",
1218 screen.height + "");
1219 storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
1220 getWidth(), getHeight()));
1222 if (jconsole != null)
1224 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1225 jconsole.stopConsole();
1229 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1232 if (dialogExecutor != null)
1234 dialogExecutor.shutdownNow();
1236 closeAll_actionPerformed(null);
1238 if (groovyConsole != null)
1240 // suppress a possible repeat prompt to save script
1241 groovyConsole.setDirty(false);
1242 groovyConsole.exit();
1247 private void storeLastKnownDimensions(String string, Rectangle jc)
1249 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1250 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1251 + " height:" + jc.height);
1253 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1254 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1255 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1256 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1266 public void aboutMenuItem_actionPerformed(ActionEvent e)
1268 // StringBuffer message = getAboutMessage(false);
1269 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1271 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1272 new Thread(new Runnable()
1277 new SplashScreen(true);
1282 public StringBuffer getAboutMessage(boolean shortv)
1284 StringBuffer message = new StringBuffer();
1285 message.append("<html>");
1288 message.append("<h1><strong>Version: "
1289 + jalview.bin.Cache.getProperty("VERSION")
1290 + "</strong></h1>");
1291 message.append("<strong>Last Updated: <em>"
1292 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1293 + "</em></strong>");
1299 message.append("<strong>Version "
1300 + jalview.bin.Cache.getProperty("VERSION")
1301 + "; last updated: "
1302 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1305 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1306 .equals("Checking"))
1308 message.append("<br>...Checking latest version...</br>");
1310 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1311 .equals(jalview.bin.Cache.getProperty("VERSION")))
1313 boolean red = false;
1314 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1315 .indexOf("automated build") == -1)
1318 // Displayed when code version and jnlp version do not match and code
1319 // version is not a development build
1320 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1323 message.append("<br>!! Version "
1324 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1326 + " is available for download from "
1327 + jalview.bin.Cache.getDefault("www.jalview.org",
1328 "http://www.jalview.org")
1332 message.append("</div>");
1335 message.append("<br>Authors: " + jalview.bin.Cache.getDefault(
1337 "The Jalview Authors (See AUTHORS file for current list)")
1338 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1339 + "<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"
1340 + "<br><br>If you use Jalview, please cite:"
1341 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1342 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1343 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1355 public void documentationMenuItem_actionPerformed(ActionEvent e)
1359 Help.showHelpWindow();
1360 } catch (Exception ex)
1366 public void closeAll_actionPerformed(ActionEvent e)
1368 // TODO show a progress bar while closing?
1369 JInternalFrame[] frames = desktop.getAllFrames();
1370 for (int i = 0; i < frames.length; i++)
1374 frames[i].setClosed(true);
1375 } catch (java.beans.PropertyVetoException ex)
1379 Jalview.setCurrentAlignFrame(null);
1380 System.out.println("ALL CLOSED");
1381 if (v_client != null)
1383 // TODO clear binding to vamsas document objects on close_all
1387 * reset state of singleton objects as appropriate (clear down session state
1388 * when all windows are closed)
1390 StructureSelectionManager ssm = StructureSelectionManager
1391 .getStructureSelectionManager(this);
1400 public void raiseRelated_actionPerformed(ActionEvent e)
1402 reorderAssociatedWindows(false, false);
1406 public void minimizeAssociated_actionPerformed(ActionEvent e)
1408 reorderAssociatedWindows(true, false);
1411 void closeAssociatedWindows()
1413 reorderAssociatedWindows(false, true);
1419 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1423 protected void garbageCollect_actionPerformed(ActionEvent e)
1425 // We simply collect the garbage
1426 jalview.bin.Cache.log.debug("Collecting garbage...");
1428 jalview.bin.Cache.log.debug("Finished garbage collection.");
1435 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1439 protected void showMemusage_actionPerformed(ActionEvent e)
1441 desktop.showMemoryUsage(showMemusage.isSelected());
1448 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1452 protected void showConsole_actionPerformed(ActionEvent e)
1454 showConsole(showConsole.isSelected());
1457 Console jconsole = null;
1460 * control whether the java console is visible or not
1464 void showConsole(boolean selected)
1466 showConsole.setSelected(selected);
1467 // TODO: decide if we should update properties file
1468 Cache.setProperty("SHOW_JAVA_CONSOLE",
1469 Boolean.valueOf(selected).toString());
1470 jconsole.setVisible(selected);
1473 void reorderAssociatedWindows(boolean minimize, boolean close)
1475 JInternalFrame[] frames = desktop.getAllFrames();
1476 if (frames == null || frames.length < 1)
1481 AlignmentViewport source = null, target = null;
1482 if (frames[0] instanceof AlignFrame)
1484 source = ((AlignFrame) frames[0]).getCurrentView();
1486 else if (frames[0] instanceof TreePanel)
1488 source = ((TreePanel) frames[0]).getViewPort();
1490 else if (frames[0] instanceof PCAPanel)
1492 source = ((PCAPanel) frames[0]).av;
1494 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1496 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1501 for (int i = 0; i < frames.length; i++)
1504 if (frames[i] == null)
1508 if (frames[i] instanceof AlignFrame)
1510 target = ((AlignFrame) frames[i]).getCurrentView();
1512 else if (frames[i] instanceof TreePanel)
1514 target = ((TreePanel) frames[i]).getViewPort();
1516 else if (frames[i] instanceof PCAPanel)
1518 target = ((PCAPanel) frames[i]).av;
1520 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1522 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1525 if (source == target)
1531 frames[i].setClosed(true);
1535 frames[i].setIcon(minimize);
1538 frames[i].toFront();
1542 } catch (java.beans.PropertyVetoException ex)
1557 protected void preferences_actionPerformed(ActionEvent e)
1569 public void saveState_actionPerformed(ActionEvent e)
1571 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1574 chooser.setFileView(new JalviewFileView());
1575 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1577 int value = chooser.showSaveDialog(this);
1579 if (value == JalviewFileChooser.APPROVE_OPTION)
1581 final Desktop me = this;
1582 final java.io.File choice = chooser.getSelectedFile();
1583 setProjectFile(choice);
1585 new Thread(new Runnable()
1590 // TODO: refactor to Jalview desktop session controller action.
1591 setProgressBar(MessageManager.formatMessage(
1592 "label.saving_jalview_project", new Object[]
1593 { choice.getName() }), choice.hashCode());
1594 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1595 choice.getParent());
1596 // TODO catch and handle errors for savestate
1597 // TODO prevent user from messing with the Desktop whilst we're saving
1600 new Jalview2XML().saveState(choice);
1601 } catch (OutOfMemoryError oom)
1604 "Whilst saving current state to " + choice.getName(),
1606 } catch (Exception ex)
1609 "Problems whilst trying to save to " + choice.getName(),
1611 JvOptionPane.showMessageDialog(me,
1612 MessageManager.formatMessage(
1613 "label.error_whilst_saving_current_state_to",
1615 { choice.getName() }),
1616 MessageManager.getString("label.couldnt_save_project"),
1617 JvOptionPane.WARNING_MESSAGE);
1619 setProgressBar(null, choice.hashCode());
1625 private void setProjectFile(File choice)
1627 this.projectFile = choice;
1630 public File getProjectFile()
1632 return this.projectFile;
1642 public void loadState_actionPerformed(ActionEvent e)
1644 JalviewFileChooser chooser = new JalviewFileChooser(
1645 Cache.getProperty("LAST_DIRECTORY"), new String[]
1648 { "Jalview Project", "Jalview Project (old)" },
1650 chooser.setFileView(new JalviewFileView());
1651 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1653 int value = chooser.showOpenDialog(this);
1655 if (value == JalviewFileChooser.APPROVE_OPTION)
1657 final File selectedFile = chooser.getSelectedFile();
1658 setProjectFile(selectedFile);
1659 final String choice = selectedFile.getAbsolutePath();
1660 Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1661 new Thread(new Runnable()
1666 setProgressBar(MessageManager.formatMessage(
1667 "label.loading_jalview_project", new Object[]
1668 { choice }), choice.hashCode());
1671 new Jalview2XML().loadJalviewAlign(choice);
1672 } catch (OutOfMemoryError oom)
1674 new OOMWarning("Whilst loading project from " + choice, oom);
1675 } catch (Exception ex)
1678 "Problems whilst loading project from " + choice, ex);
1679 JvOptionPane.showMessageDialog(Desktop.desktop,
1680 MessageManager.formatMessage(
1681 "label.error_whilst_loading_project_from",
1684 MessageManager.getString("label.couldnt_load_project"),
1685 JvOptionPane.WARNING_MESSAGE);
1687 setProgressBar(null, choice.hashCode());
1694 public void inputSequence_actionPerformed(ActionEvent e)
1696 new SequenceFetcher(this);
1699 JPanel progressPanel;
1701 ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
1703 public void startLoading(final String fileName)
1705 if (fileLoadingCount == 0)
1707 fileLoadingPanels.add(addProgressPanel(MessageManager
1708 .formatMessage("label.loading_file", new Object[]
1714 private JPanel addProgressPanel(String string)
1716 if (progressPanel == null)
1718 progressPanel = new JPanel(new GridLayout(1, 1));
1719 totalProgressCount = 0;
1720 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1722 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1723 JProgressBar progressBar = new JProgressBar();
1724 progressBar.setIndeterminate(true);
1726 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1728 thisprogress.add(progressBar, BorderLayout.CENTER);
1729 progressPanel.add(thisprogress);
1730 ((GridLayout) progressPanel.getLayout()).setRows(
1731 ((GridLayout) progressPanel.getLayout()).getRows() + 1);
1732 ++totalProgressCount;
1733 instance.validate();
1734 return thisprogress;
1737 int totalProgressCount = 0;
1739 private void removeProgressPanel(JPanel progbar)
1741 if (progressPanel != null)
1743 synchronized (progressPanel)
1745 progressPanel.remove(progbar);
1746 GridLayout gl = (GridLayout) progressPanel.getLayout();
1747 gl.setRows(gl.getRows() - 1);
1748 if (--totalProgressCount < 1)
1750 this.getContentPane().remove(progressPanel);
1751 progressPanel = null;
1758 public void stopLoading()
1761 if (fileLoadingCount < 1)
1763 while (fileLoadingPanels.size() > 0)
1765 removeProgressPanel(fileLoadingPanels.remove(0));
1767 fileLoadingPanels.clear();
1768 fileLoadingCount = 0;
1773 public static int getViewCount(String alignmentId)
1775 AlignmentViewport[] aps = getViewports(alignmentId);
1776 return (aps == null) ? 0 : aps.length;
1781 * @param alignmentId
1782 * - if null, all sets are returned
1783 * @return all AlignmentPanels concerning the alignmentId sequence set
1785 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1787 if (Desktop.desktop == null)
1789 // no frames created and in headless mode
1790 // TODO: verify that frames are recoverable when in headless mode
1793 List<AlignmentPanel> aps = new ArrayList<>();
1794 AlignFrame[] frames = getAlignFrames();
1799 for (AlignFrame af : frames)
1801 for (AlignmentPanel ap : af.alignPanels)
1803 if (alignmentId == null
1804 || alignmentId.equals(ap.av.getSequenceSetId()))
1810 if (aps.size() == 0)
1814 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1819 * get all the viewports on an alignment.
1821 * @param sequenceSetId
1822 * unique alignment id (may be null - all viewports returned in that
1824 * @return all viewports on the alignment bound to sequenceSetId
1826 public static AlignmentViewport[] getViewports(String sequenceSetId)
1828 List<AlignmentViewport> viewp = new ArrayList<>();
1829 if (desktop != null)
1831 AlignFrame[] frames = Desktop.getAlignFrames();
1833 for (AlignFrame afr : frames)
1835 if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
1836 .equals(sequenceSetId))
1838 if (afr.alignPanels != null)
1840 for (AlignmentPanel ap : afr.alignPanels)
1842 if (sequenceSetId == null
1843 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1851 viewp.add(afr.getViewport());
1855 if (viewp.size() > 0)
1857 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1864 * Explode the views in the given frame into separate AlignFrame
1868 public static void explodeViews(AlignFrame af)
1870 int size = af.alignPanels.size();
1876 for (int i = 0; i < size; i++)
1878 AlignmentPanel ap = af.alignPanels.get(i);
1879 AlignFrame newaf = new AlignFrame(ap);
1882 * Restore the view's last exploded frame geometry if known. Multiple
1883 * views from one exploded frame share and restore the same (frame)
1884 * position and size.
1886 Rectangle geometry = ap.av.getExplodedGeometry();
1887 if (geometry != null)
1889 newaf.setBounds(geometry);
1892 ap.av.setGatherViewsHere(false);
1894 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1895 AlignFrame.DEFAULT_HEIGHT);
1898 af.alignPanels.clear();
1899 af.closeMenuItem_actionPerformed(true);
1904 * Gather expanded views (separate AlignFrame's) with the same sequence set
1905 * identifier back in to this frame as additional views, and close the
1906 * expanded views. Note the expanded frames may themselves have multiple
1907 * views. We take the lot.
1911 public void gatherViews(AlignFrame source)
1913 source.viewport.setGatherViewsHere(true);
1914 source.viewport.setExplodedGeometry(source.getBounds());
1915 JInternalFrame[] frames = desktop.getAllFrames();
1916 String viewId = source.viewport.getSequenceSetId();
1918 for (int t = 0; t < frames.length; t++)
1920 if (frames[t] instanceof AlignFrame && frames[t] != source)
1922 AlignFrame af = (AlignFrame) frames[t];
1923 boolean gatherThis = false;
1924 for (int a = 0; a < af.alignPanels.size(); a++)
1926 AlignmentPanel ap = af.alignPanels.get(a);
1927 if (viewId.equals(ap.av.getSequenceSetId()))
1930 ap.av.setGatherViewsHere(false);
1931 ap.av.setExplodedGeometry(af.getBounds());
1932 source.addAlignmentPanel(ap, false);
1938 af.alignPanels.clear();
1939 af.closeMenuItem_actionPerformed(true);
1946 jalview.gui.VamsasApplication v_client = null;
1949 public void vamsasImport_actionPerformed(ActionEvent e)
1951 if (v_client == null)
1953 // Load and try to start a session.
1954 JalviewFileChooser chooser = new JalviewFileChooser(
1955 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1957 chooser.setFileView(new JalviewFileView());
1958 chooser.setDialogTitle(
1959 MessageManager.getString("label.open_saved_vamsas_session"));
1960 chooser.setToolTipText(MessageManager.getString(
1961 "label.select_vamsas_session_opened_as_new_vamsas_session"));
1963 int value = chooser.showOpenDialog(this);
1965 if (value == JalviewFileChooser.APPROVE_OPTION)
1967 String fle = chooser.getSelectedFile().toString();
1968 if (!vamsasImport(chooser.getSelectedFile()))
1970 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1971 MessageManager.formatMessage(
1972 "label.couldnt_import_as_vamsas_session",
1976 .getString("label.vamsas_document_import_failed"),
1977 JvOptionPane.ERROR_MESSAGE);
1983 jalview.bin.Cache.log.error(
1984 "Implementation error - load session from a running session is not supported.");
1989 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1992 * @return true if import was a success and a session was started.
1994 public boolean vamsasImport(URL url)
1996 // TODO: create progress bar
1997 if (v_client != null)
2000 jalview.bin.Cache.log.error(
2001 "Implementation error - load session from a running session is not supported.");
2007 // copy the URL content to a temporary local file
2008 // TODO: be a bit cleverer here with nio (?!)
2009 File file = File.createTempFile("vdocfromurl", ".vdj");
2010 FileOutputStream fos = new FileOutputStream(file);
2011 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2012 byte[] buffer = new byte[2048];
2014 while ((ln = bis.read(buffer)) > -1)
2016 fos.write(buffer, 0, ln);
2020 v_client = new jalview.gui.VamsasApplication(this, file,
2021 url.toExternalForm());
2022 } catch (Exception ex)
2024 jalview.bin.Cache.log.error(
2025 "Failed to create new vamsas session from contents of URL "
2030 setupVamsasConnectedGui();
2031 v_client.initial_update(); // TODO: thread ?
2032 return v_client.inSession();
2036 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2039 * @return true if import was a success and a session was started.
2041 public boolean vamsasImport(File file)
2043 if (v_client != null)
2046 jalview.bin.Cache.log.error(
2047 "Implementation error - load session from a running session is not supported.");
2051 setProgressBar(MessageManager.formatMessage(
2052 "status.importing_vamsas_session_from", new Object[]
2053 { file.getName() }), file.hashCode());
2056 v_client = new jalview.gui.VamsasApplication(this, file, null);
2057 } catch (Exception ex)
2059 setProgressBar(MessageManager.formatMessage(
2060 "status.importing_vamsas_session_from", new Object[]
2061 { file.getName() }), file.hashCode());
2062 jalview.bin.Cache.log.error(
2063 "New vamsas session from existing session file failed:", ex);
2066 setupVamsasConnectedGui();
2067 v_client.initial_update(); // TODO: thread ?
2068 setProgressBar(MessageManager.formatMessage(
2069 "status.importing_vamsas_session_from", new Object[]
2070 { file.getName() }), file.hashCode());
2071 return v_client.inSession();
2074 public boolean joinVamsasSession(String mysesid)
2076 if (v_client != null)
2078 throw new Error(MessageManager
2079 .getString("error.try_join_vamsas_session_another"));
2081 if (mysesid == null)
2084 MessageManager.getString("error.invalid_vamsas_session_id"));
2086 v_client = new VamsasApplication(this, mysesid);
2087 setupVamsasConnectedGui();
2088 v_client.initial_update();
2089 return (v_client.inSession());
2093 public void vamsasStart_actionPerformed(ActionEvent e)
2095 if (v_client == null)
2098 // we just start a default session for moment.
2100 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2101 * getProperty("LAST_DIRECTORY"));
2103 * chooser.setFileView(new JalviewFileView());
2104 * chooser.setDialogTitle("Load Vamsas file");
2105 * chooser.setToolTipText("Import");
2107 * int value = chooser.showOpenDialog(this);
2109 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2110 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2112 v_client = new VamsasApplication(this);
2113 setupVamsasConnectedGui();
2114 v_client.initial_update(); // TODO: thread ?
2118 // store current data in session.
2119 v_client.push_update(); // TODO: thread
2123 protected void setupVamsasConnectedGui()
2125 vamsasStart.setText(MessageManager.getString("label.session_update"));
2126 vamsasSave.setVisible(true);
2127 vamsasStop.setVisible(true);
2128 vamsasImport.setVisible(false); // Document import to existing session is
2129 // not possible for vamsas-client-1.0.
2132 protected void setupVamsasDisconnectedGui()
2134 vamsasSave.setVisible(false);
2135 vamsasStop.setVisible(false);
2136 vamsasImport.setVisible(true);
2138 .setText(MessageManager.getString("label.new_vamsas_session"));
2142 public void vamsasStop_actionPerformed(ActionEvent e)
2144 if (v_client != null)
2146 v_client.end_session();
2148 setupVamsasDisconnectedGui();
2152 protected void buildVamsasStMenu()
2154 if (v_client == null)
2156 String[] sess = null;
2159 sess = VamsasApplication.getSessionList();
2160 } catch (Exception e)
2162 jalview.bin.Cache.log.warn("Problem getting current sessions list.",
2168 jalview.bin.Cache.log.debug(
2169 "Got current sessions list: " + sess.length + " entries.");
2170 VamsasStMenu.removeAll();
2171 for (int i = 0; i < sess.length; i++)
2173 JMenuItem sessit = new JMenuItem();
2174 sessit.setText(sess[i]);
2175 sessit.setToolTipText(MessageManager
2176 .formatMessage("label.connect_to_session", new Object[]
2178 final Desktop dsktp = this;
2179 final String mysesid = sess[i];
2180 sessit.addActionListener(new ActionListener()
2184 public void actionPerformed(ActionEvent e)
2186 if (dsktp.v_client == null)
2188 Thread rthr = new Thread(new Runnable()
2194 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2195 dsktp.setupVamsasConnectedGui();
2196 dsktp.v_client.initial_update();
2204 VamsasStMenu.add(sessit);
2206 // don't show an empty menu.
2207 VamsasStMenu.setVisible(sess.length > 0);
2212 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2213 VamsasStMenu.removeAll();
2214 VamsasStMenu.setVisible(false);
2219 // Not interested in the content. Just hide ourselves.
2220 VamsasStMenu.setVisible(false);
2225 public void vamsasSave_actionPerformed(ActionEvent e)
2227 if (v_client != null)
2229 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2230 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2233 chooser.setFileView(new JalviewFileView());
2234 chooser.setDialogTitle(MessageManager
2235 .getString("label.save_vamsas_document_archive"));
2237 int value = chooser.showSaveDialog(this);
2239 if (value == JalviewFileChooser.APPROVE_OPTION)
2241 java.io.File choice = chooser.getSelectedFile();
2242 JPanel progpanel = addProgressPanel(MessageManager
2243 .formatMessage("label.saving_vamsas_doc", new Object[]
2244 { choice.getName() }));
2245 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2246 String warnmsg = null;
2247 String warnttl = null;
2250 v_client.vclient.storeDocument(choice);
2253 warnttl = "Serious Problem saving Vamsas Document";
2254 warnmsg = ex.toString();
2255 jalview.bin.Cache.log
2256 .error("Error Whilst saving document to " + choice, ex);
2258 } catch (Exception ex)
2260 warnttl = "Problem saving Vamsas Document.";
2261 warnmsg = ex.toString();
2262 jalview.bin.Cache.log.warn(
2263 "Exception Whilst saving document to " + choice, ex);
2266 removeProgressPanel(progpanel);
2267 if (warnmsg != null)
2269 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2271 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2277 JPanel vamUpdate = null;
2280 * hide vamsas user gui bits when a vamsas document event is being handled.
2283 * true to hide gui, false to reveal gui
2285 public void setVamsasUpdate(boolean b)
2287 Cache.log.debug("Setting gui for Vamsas update "
2288 + (b ? "in progress" : "finished"));
2290 if (vamUpdate != null)
2292 this.removeProgressPanel(vamUpdate);
2296 vamUpdate = this.addProgressPanel(
2297 MessageManager.getString("label.updating_vamsas_session"));
2299 vamsasStart.setVisible(!b);
2300 vamsasStop.setVisible(!b);
2301 vamsasSave.setVisible(!b);
2304 public JInternalFrame[] getAllFrames()
2306 return desktop.getAllFrames();
2310 * Checks the given url to see if it gives a response indicating that the user
2311 * should be informed of a new questionnaire.
2315 public void checkForQuestionnaire(String url)
2317 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2318 // javax.swing.SwingUtilities.invokeLater(jvq);
2319 new Thread(jvq).start();
2322 public void checkURLLinks()
2324 // Thread off the URL link checker
2325 addDialogThread(new Runnable()
2330 if (Cache.getDefault("CHECKURLLINKS", true))
2332 // check what the actual links are - if it's just the default don't
2333 // bother with the warning
2334 List<String> links = Preferences.sequenceUrlLinks
2337 // only need to check links if there is one with a
2338 // SEQUENCE_ID which is not the default EMBL_EBI link
2339 ListIterator<String> li = links.listIterator();
2340 boolean check = false;
2341 List<JLabel> urls = new ArrayList<>();
2342 while (li.hasNext())
2344 String link = li.next();
2345 if (link.contains(SEQUENCE_ID)
2346 && !link.equals(UrlConstants.DEFAULT_STRING))
2349 int barPos = link.indexOf("|");
2350 String urlMsg = barPos == -1 ? link
2351 : link.substring(0, barPos) + ": "
2352 + link.substring(barPos + 1);
2353 urls.add(new JLabel(urlMsg));
2361 // ask user to check in case URL links use old style tokens
2362 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2363 JPanel msgPanel = new JPanel();
2364 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2365 msgPanel.add(Box.createVerticalGlue());
2366 JLabel msg = new JLabel(MessageManager
2367 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2368 JLabel msg2 = new JLabel(MessageManager
2369 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2371 for (JLabel url : urls)
2377 final JCheckBox jcb = new JCheckBox(
2378 MessageManager.getString("label.do_not_display_again"));
2379 jcb.addActionListener(new ActionListener()
2382 public void actionPerformed(ActionEvent e)
2384 // update Cache settings for "don't show this again"
2385 boolean showWarningAgain = !jcb.isSelected();
2386 Cache.setProperty("CHECKURLLINKS",
2387 Boolean.valueOf(showWarningAgain).toString());
2392 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2394 .getString("label.SEQUENCE_ID_no_longer_used"),
2395 JvOptionPane.WARNING_MESSAGE);
2402 * Proxy class for JDesktopPane which optionally displays the current memory
2403 * usage and highlights the desktop area with a red bar if free memory runs
2408 public class MyDesktopPane extends JDesktopPane implements Runnable
2411 private static final float ONE_MB = 1048576f;
2413 boolean showMemoryUsage = false;
2417 java.text.NumberFormat df;
2419 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2422 public MyDesktopPane(boolean showMemoryUsage)
2424 showMemoryUsage(showMemoryUsage);
2427 public void showMemoryUsage(boolean showMemory)
2429 this.showMemoryUsage = showMemory;
2432 Thread worker = new Thread(this);
2438 public boolean isShowMemoryUsage()
2440 return showMemoryUsage;
2446 df = java.text.NumberFormat.getNumberInstance();
2447 df.setMaximumFractionDigits(2);
2448 runtime = Runtime.getRuntime();
2450 while (showMemoryUsage)
2454 maxMemory = runtime.maxMemory() / ONE_MB;
2455 allocatedMemory = runtime.totalMemory() / ONE_MB;
2456 freeMemory = runtime.freeMemory() / ONE_MB;
2457 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2459 percentUsage = (totalFreeMemory / maxMemory) * 100;
2461 // if (percentUsage < 20)
2463 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2465 // instance.set.setBorder(border1);
2468 // sleep after showing usage
2470 } catch (Exception ex)
2472 ex.printStackTrace();
2478 public void paintComponent(Graphics g)
2480 if (showMemoryUsage && g != null && df != null)
2482 if (percentUsage < 20)
2484 g.setColor(Color.red);
2486 FontMetrics fm = g.getFontMetrics();
2489 g.drawString(MessageManager.formatMessage("label.memory_stats",
2491 { df.format(totalFreeMemory), df.format(maxMemory),
2492 df.format(percentUsage) }),
2493 10, getHeight() - fm.getHeight());
2501 * Accessor method to quickly get all the AlignmentFrames loaded.
2503 * @return an array of AlignFrame, or null if none found
2505 public static AlignFrame[] getAlignFrames()
2507 if (Jalview.isHeadlessMode())
2509 // Desktop.desktop is null in headless mode
2510 return new AlignFrame[] { Jalview.currentAlignFrame };
2513 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2519 List<AlignFrame> avp = new ArrayList<>();
2521 for (int i = frames.length - 1; i > -1; i--)
2523 if (frames[i] instanceof AlignFrame)
2525 avp.add((AlignFrame) frames[i]);
2527 else if (frames[i] instanceof SplitFrame)
2530 * Also check for a split frame containing an AlignFrame
2532 GSplitFrame sf = (GSplitFrame) frames[i];
2533 if (sf.getTopFrame() instanceof AlignFrame)
2535 avp.add((AlignFrame) sf.getTopFrame());
2537 if (sf.getBottomFrame() instanceof AlignFrame)
2539 avp.add((AlignFrame) sf.getBottomFrame());
2543 if (avp.size() == 0)
2547 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2552 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2556 public GStructureViewer[] getJmols()
2558 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2564 List<GStructureViewer> avp = new ArrayList<>();
2566 for (int i = frames.length - 1; i > -1; i--)
2568 if (frames[i] instanceof AppJmol)
2570 GStructureViewer af = (GStructureViewer) frames[i];
2574 if (avp.size() == 0)
2578 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2583 * Add Groovy Support to Jalview
2586 public void groovyShell_actionPerformed()
2590 openGroovyConsole();
2591 } catch (Exception ex)
2593 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2594 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2596 MessageManager.getString("label.couldnt_create_groovy_shell"),
2597 MessageManager.getString("label.groovy_support_failed"),
2598 JvOptionPane.ERROR_MESSAGE);
2603 * Open the Groovy console
2605 void openGroovyConsole()
2607 if (groovyConsole == null)
2609 groovyConsole = new groovy.ui.Console();
2610 groovyConsole.setVariable("Jalview", this);
2611 groovyConsole.run();
2614 * We allow only one console at a time, so that AlignFrame menu option
2615 * 'Calculate | Run Groovy script' is unambiguous.
2616 * Disable 'Groovy Console', and enable 'Run script', when the console is
2617 * opened, and the reverse when it is closed
2619 Window window = (Window) groovyConsole.getFrame();
2620 window.addWindowListener(new WindowAdapter()
2623 public void windowClosed(WindowEvent e)
2626 * rebind CMD-Q from Groovy Console to Jalview Quit
2629 enableExecuteGroovy(false);
2635 * show Groovy console window (after close and reopen)
2637 ((Window) groovyConsole.getFrame()).setVisible(true);
2640 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2641 * and disable opening a second console
2643 enableExecuteGroovy(true);
2647 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2648 * binding when opened
2650 protected void addQuitHandler()
2652 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
2653 .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
2654 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
2656 getRootPane().getActionMap().put("Quit", new AbstractAction()
2659 public void actionPerformed(ActionEvent e)
2667 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2670 * true if Groovy console is open
2672 public void enableExecuteGroovy(boolean enabled)
2675 * disable opening a second Groovy console
2676 * (or re-enable when the console is closed)
2678 groovyShell.setEnabled(!enabled);
2680 AlignFrame[] alignFrames = getAlignFrames();
2681 if (alignFrames != null)
2683 for (AlignFrame af : alignFrames)
2685 af.setGroovyEnabled(enabled);
2691 * Progress bars managed by the IProgressIndicator method.
2693 private Hashtable<Long, JPanel> progressBars;
2695 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2700 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2703 public void setProgressBar(String message, long id)
2705 if (progressBars == null)
2707 progressBars = new Hashtable<>();
2708 progressBarHandlers = new Hashtable<>();
2711 if (progressBars.get(new Long(id)) != null)
2713 JPanel panel = progressBars.remove(new Long(id));
2714 if (progressBarHandlers.contains(new Long(id)))
2716 progressBarHandlers.remove(new Long(id));
2718 removeProgressPanel(panel);
2722 progressBars.put(new Long(id), addProgressPanel(message));
2729 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2730 * jalview.gui.IProgressIndicatorHandler)
2733 public void registerHandler(final long id,
2734 final IProgressIndicatorHandler handler)
2736 if (progressBarHandlers == null
2737 || !progressBars.containsKey(new Long(id)))
2739 throw new Error(MessageManager.getString(
2740 "error.call_setprogressbar_before_registering_handler"));
2742 progressBarHandlers.put(new Long(id), handler);
2743 final JPanel progressPanel = progressBars.get(new Long(id));
2744 if (handler.canCancel())
2746 JButton cancel = new JButton(
2747 MessageManager.getString("action.cancel"));
2748 final IProgressIndicator us = this;
2749 cancel.addActionListener(new ActionListener()
2753 public void actionPerformed(ActionEvent e)
2755 handler.cancelActivity(id);
2756 us.setProgressBar(MessageManager
2757 .formatMessage("label.cancelled_params", new Object[]
2758 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2762 progressPanel.add(cancel, BorderLayout.EAST);
2768 * @return true if any progress bars are still active
2771 public boolean operationInProgress()
2773 if (progressBars != null && progressBars.size() > 0)
2781 * This will return the first AlignFrame holding the given viewport instance.
2782 * It will break if there are more than one AlignFrames viewing a particular
2786 * @return alignFrame for viewport
2788 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2790 if (desktop != null)
2792 AlignmentPanel[] aps = getAlignmentPanels(
2793 viewport.getSequenceSetId());
2794 for (int panel = 0; aps != null && panel < aps.length; panel++)
2796 if (aps[panel] != null && aps[panel].av == viewport)
2798 return aps[panel].alignFrame;
2805 public VamsasApplication getVamsasApplication()
2812 * flag set if jalview GUI is being operated programmatically
2814 private boolean inBatchMode = false;
2817 * check if jalview GUI is being operated programmatically
2819 * @return inBatchMode
2821 public boolean isInBatchMode()
2827 * set flag if jalview GUI is being operated programmatically
2829 * @param inBatchMode
2831 public void setInBatchMode(boolean inBatchMode)
2833 this.inBatchMode = inBatchMode;
2836 public void startServiceDiscovery()
2838 startServiceDiscovery(false);
2841 public void startServiceDiscovery(boolean blocking)
2843 boolean alive = true;
2844 Thread t0 = null, t1 = null, t2 = null;
2845 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2848 // todo: changesupport handlers need to be transferred
2849 if (discoverer == null)
2851 discoverer = new jalview.ws.jws1.Discoverer();
2852 // register PCS handler for desktop.
2853 discoverer.addPropertyChangeListener(changeSupport);
2855 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2856 // until we phase out completely
2857 (t0 = new Thread(discoverer)).start();
2860 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2862 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2863 .startDiscoverer(changeSupport);
2867 // TODO: do rest service discovery
2876 } catch (Exception e)
2879 alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
2880 || (t3 != null && t3.isAlive())
2881 || (t0 != null && t0.isAlive());
2887 * called to check if the service discovery process completed successfully.
2891 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2893 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2895 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2896 .getErrorMessages();
2899 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2901 if (serviceChangedDialog == null)
2903 // only run if we aren't already displaying one of these.
2904 addDialogThread(serviceChangedDialog = new Runnable()
2911 * JalviewDialog jd =new JalviewDialog() {
2913 * @Override protected void cancelPressed() { // TODO
2914 * Auto-generated method stub
2916 * }@Override protected void okPressed() { // TODO
2917 * Auto-generated method stub
2919 * }@Override protected void raiseClosed() { // TODO
2920 * Auto-generated method stub
2922 * } }; jd.initDialogFrame(new
2923 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2924 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2925 * + " or mis-configured HTTP proxy settings.<br/>" +
2926 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2928 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2929 * ), true, true, "Web Service Configuration Problem", 450,
2932 * jd.waitForInput();
2934 JvOptionPane.showConfirmDialog(Desktop.desktop,
2935 new JLabel("<html><table width=\"450\"><tr><td>"
2936 + ermsg + "</td></tr></table>"
2937 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2938 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2939 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2940 + " Tools->Preferences dialog box to change them.</p></html>"),
2941 "Web Service Configuration Problem",
2942 JvOptionPane.DEFAULT_OPTION,
2943 JvOptionPane.ERROR_MESSAGE);
2944 serviceChangedDialog = null;
2953 "Errors reported by JABA discovery service. Check web services preferences.\n"
2960 private Runnable serviceChangedDialog = null;
2963 * start a thread to open a URL in the configured browser. Pops up a warning
2964 * dialog to the user if there is an exception when calling out to the browser
2969 public static void showUrl(final String url)
2971 showUrl(url, Desktop.instance);
2975 * Like showUrl but allows progress handler to be specified
2979 * (null) or object implementing IProgressIndicator
2981 public static void showUrl(final String url,
2982 final IProgressIndicator progress)
2984 new Thread(new Runnable()
2991 if (progress != null)
2993 progress.setProgressBar(MessageManager
2994 .formatMessage("status.opening_params", new Object[]
2995 { url }), this.hashCode());
2997 jalview.util.BrowserLauncher.openURL(url);
2998 } catch (Exception ex)
3000 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3002 .getString("label.web_browser_not_found_unix"),
3003 MessageManager.getString("label.web_browser_not_found"),
3004 JvOptionPane.WARNING_MESSAGE);
3006 ex.printStackTrace();
3008 if (progress != null)
3010 progress.setProgressBar(null, this.hashCode());
3016 public static WsParamSetManager wsparamManager = null;
3018 public static ParamManager getUserParameterStore()
3020 if (wsparamManager == null)
3022 wsparamManager = new WsParamSetManager();
3024 return wsparamManager;
3028 * static hyperlink handler proxy method for use by Jalview's internal windows
3032 public static void hyperlinkUpdate(HyperlinkEvent e)
3034 if (e.getEventType() == EventType.ACTIVATED)
3039 url = e.getURL().toString();
3040 Desktop.showUrl(url);
3041 } catch (Exception x)
3045 if (Cache.log != null)
3047 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3052 "Couldn't handle string " + url + " as a URL.");
3055 // ignore any exceptions due to dud links.
3062 * single thread that handles display of dialogs to user.
3064 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3067 * flag indicating if dialogExecutor should try to acquire a permit
3069 private volatile boolean dialogPause = true;
3074 private java.util.concurrent.Semaphore block = new Semaphore(0);
3076 private static groovy.ui.Console groovyConsole;
3079 * add another dialog thread to the queue
3083 public void addDialogThread(final Runnable prompter)
3085 dialogExecutor.submit(new Runnable()
3095 } catch (InterruptedException x)
3100 if (instance == null)
3106 SwingUtilities.invokeAndWait(prompter);
3107 } catch (Exception q)
3109 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3115 public void startDialogQueue()
3117 // set the flag so we don't pause waiting for another permit and semaphore
3118 // the current task to begin
3119 dialogPause = false;
3124 protected void snapShotWindow_actionPerformed(ActionEvent e)
3128 ImageMaker im = new jalview.util.ImageMaker(
3129 this, ImageMaker.TYPE.EPS, "View of Desktop", getWidth(),
3130 getHeight(), of = new File("Jalview_snapshot"
3131 + System.currentTimeMillis() + ".eps"),
3132 "View of desktop", null, 0, false);
3135 paintAll(im.getGraphics());
3137 } catch (Exception q)
3139 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3143 Cache.log.info("Successfully written snapshot to file "
3144 + of.getAbsolutePath());
3148 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3149 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3150 * and location last time the view was expanded (if any). However it does not
3151 * remember the split pane divider location - this is set to match the
3152 * 'exploding' frame.
3156 public void explodeViews(SplitFrame sf)
3158 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3159 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3160 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3162 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3164 int viewCount = topPanels.size();
3171 * Processing in reverse order works, forwards order leaves the first panels
3172 * not visible. I don't know why!
3174 for (int i = viewCount - 1; i >= 0; i--)
3177 * Make new top and bottom frames. These take over the respective
3178 * AlignmentPanel objects, including their AlignmentViewports, so the
3179 * cdna/protein relationships between the viewports is carried over to the
3182 * explodedGeometry holds the (x, y) position of the previously exploded
3183 * SplitFrame, and the (width, height) of the AlignFrame component
3185 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3186 AlignFrame newTopFrame = new AlignFrame(topPanel);
3187 newTopFrame.setSize(oldTopFrame.getSize());
3188 newTopFrame.setVisible(true);
3189 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3190 .getExplodedGeometry();
3191 if (geometry != null)
3193 newTopFrame.setSize(geometry.getSize());
3196 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3197 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3198 newBottomFrame.setSize(oldBottomFrame.getSize());
3199 newBottomFrame.setVisible(true);
3200 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3201 .getExplodedGeometry();
3202 if (geometry != null)
3204 newBottomFrame.setSize(geometry.getSize());
3207 topPanel.av.setGatherViewsHere(false);
3208 bottomPanel.av.setGatherViewsHere(false);
3209 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3211 if (geometry != null)
3213 splitFrame.setLocation(geometry.getLocation());
3215 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3219 * Clear references to the panels (now relocated in the new SplitFrames)
3220 * before closing the old SplitFrame.
3223 bottomPanels.clear();
3228 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3229 * back into the given SplitFrame as additional views. Note that the gathered
3230 * frames may themselves have multiple views.
3234 public void gatherViews(GSplitFrame source)
3237 * special handling of explodedGeometry for a view within a SplitFrame: - it
3238 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3239 * height) of the AlignFrame component
3241 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3242 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3243 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3244 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3245 myBottomFrame.viewport
3246 .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
3247 myBottomFrame.getWidth(), myBottomFrame.getHeight()));
3248 myTopFrame.viewport.setGatherViewsHere(true);
3249 myBottomFrame.viewport.setGatherViewsHere(true);
3250 String topViewId = myTopFrame.viewport.getSequenceSetId();
3251 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3253 JInternalFrame[] frames = desktop.getAllFrames();
3254 for (JInternalFrame frame : frames)
3256 if (frame instanceof SplitFrame && frame != source)
3258 SplitFrame sf = (SplitFrame) frame;
3259 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3260 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3261 boolean gatherThis = false;
3262 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3264 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3265 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3266 if (topViewId.equals(topPanel.av.getSequenceSetId())
3267 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3270 topPanel.av.setGatherViewsHere(false);
3271 bottomPanel.av.setGatherViewsHere(false);
3272 topPanel.av.setExplodedGeometry(
3273 new Rectangle(sf.getLocation(), topFrame.getSize()));
3274 bottomPanel.av.setExplodedGeometry(
3275 new Rectangle(sf.getLocation(), bottomFrame.getSize()));
3276 myTopFrame.addAlignmentPanel(topPanel, false);
3277 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3283 topFrame.getAlignPanels().clear();
3284 bottomFrame.getAlignPanels().clear();
3291 * The dust settles...give focus to the tab we did this from.
3293 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3296 public static groovy.ui.Console getGroovyConsole()
3298 return groovyConsole;
3301 public static void transferFromDropTarget(List<String> files,
3302 List<DataSourceType> protocols, DropTargetDropEvent evt,
3303 Transferable t) throws Exception
3306 DataFlavor uriListFlavor = new DataFlavor(
3307 "text/uri-list;class=java.lang.String");
3308 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3310 // Works on Windows and MacOSX
3311 Cache.log.debug("Drop handled as javaFileListFlavor");
3312 for (Object file : (List) t
3313 .getTransferData(DataFlavor.javaFileListFlavor))
3315 files.add(((File) file).toString());
3316 protocols.add(DataSourceType.FILE);
3321 // Unix like behaviour
3322 boolean added = false;
3324 if (t.isDataFlavorSupported(uriListFlavor))
3326 Cache.log.debug("Drop handled as uriListFlavor");
3327 // This is used by Unix drag system
3328 data = (String) t.getTransferData(uriListFlavor);
3332 // fallback to text: workaround - on OSX where there's a JVM bug
3333 Cache.log.debug("standard URIListFlavor failed. Trying text");
3334 // try text fallback
3335 data = (String) t.getTransferData(
3336 new DataFlavor("text/plain;class=java.lang.String"));
3337 if (Cache.log.isDebugEnabled())
3339 Cache.log.debug("fallback returned " + data);
3342 while (protocols.size() < files.size())
3344 Cache.log.debug("Adding missing FILE protocol for "
3345 + files.get(protocols.size()));
3346 protocols.add(DataSourceType.FILE);
3348 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3349 data, "\r\n"); st.hasMoreTokens();)
3352 String s = st.nextToken();
3353 if (s.startsWith("#"))
3355 // the line is a comment (as per the RFC 2483)
3358 java.net.URI uri = new java.net.URI(s);
3359 if (uri.getScheme().toLowerCase().startsWith("http"))
3361 protocols.add(DataSourceType.URL);
3362 files.add(uri.toString());
3366 // otherwise preserve old behaviour: catch all for file objects
3367 java.io.File file = new java.io.File(uri);
3368 protocols.add(DataSourceType.FILE);
3369 files.add(file.toString());
3372 if (Cache.log.isDebugEnabled())
3374 if (data == null || !added)
3377 "Couldn't resolve drop data. Here are the supported flavors:");
3378 for (DataFlavor fl : t.getTransferDataFlavors())
3381 "Supported transfer dataflavor: " + fl.toString());
3382 Object df = t.getTransferData(fl);
3385 Cache.log.debug("Retrieves: " + df);
3389 Cache.log.debug("Retrieved nothing");
3398 * Sets the Preferences property for experimental features to True or False
3399 * depending on the state of the controlling menu item
3402 protected void showExperimental_actionPerformed(boolean selected)
3404 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));