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.UrlConstants;
45 import jalview.viewmodel.AlignmentViewport;
46 import jalview.ws.params.ParamManager;
47 import jalview.ws.utils.UrlDownloadClient;
49 import java.awt.BorderLayout;
50 import java.awt.Color;
51 import java.awt.Dimension;
52 import java.awt.FontMetrics;
53 import java.awt.Graphics;
54 import java.awt.GridLayout;
55 import java.awt.Point;
56 import java.awt.Rectangle;
57 import java.awt.Toolkit;
58 import java.awt.Window;
59 import java.awt.datatransfer.Clipboard;
60 import java.awt.datatransfer.ClipboardOwner;
61 import java.awt.datatransfer.DataFlavor;
62 import java.awt.datatransfer.Transferable;
63 import java.awt.dnd.DnDConstants;
64 import java.awt.dnd.DropTargetDragEvent;
65 import java.awt.dnd.DropTargetDropEvent;
66 import java.awt.dnd.DropTargetEvent;
67 import java.awt.dnd.DropTargetListener;
68 import java.awt.event.ActionEvent;
69 import java.awt.event.ActionListener;
70 import java.awt.event.FocusEvent;
71 import java.awt.event.FocusListener;
72 import java.awt.event.KeyEvent;
73 import java.awt.event.MouseAdapter;
74 import java.awt.event.MouseEvent;
75 import java.awt.event.WindowAdapter;
76 import java.awt.event.WindowEvent;
77 import java.beans.PropertyChangeEvent;
78 import java.beans.PropertyChangeListener;
79 import java.io.BufferedInputStream;
81 import java.io.FileOutputStream;
82 import java.io.IOException;
84 import java.util.ArrayList;
85 import java.util.Hashtable;
86 import java.util.List;
87 import java.util.ListIterator;
88 import java.util.StringTokenizer;
89 import java.util.Vector;
90 import java.util.concurrent.ExecutorService;
91 import java.util.concurrent.Executors;
92 import java.util.concurrent.Semaphore;
94 import javax.swing.AbstractAction;
95 import javax.swing.Box;
96 import javax.swing.BoxLayout;
97 import javax.swing.DefaultDesktopManager;
98 import javax.swing.DesktopManager;
99 import javax.swing.JButton;
100 import javax.swing.JCheckBox;
101 import javax.swing.JComboBox;
102 import javax.swing.JComponent;
103 import javax.swing.JDesktopPane;
104 import javax.swing.JFrame;
105 import javax.swing.JInternalFrame;
106 import javax.swing.JLabel;
107 import javax.swing.JMenuItem;
108 import javax.swing.JPanel;
109 import javax.swing.JPopupMenu;
110 import javax.swing.JProgressBar;
111 import javax.swing.KeyStroke;
112 import javax.swing.SwingUtilities;
113 import javax.swing.event.HyperlinkEvent;
114 import javax.swing.event.HyperlinkEvent.EventType;
115 import javax.swing.event.InternalFrameAdapter;
116 import javax.swing.event.InternalFrameEvent;
117 import javax.swing.event.MenuEvent;
118 import javax.swing.event.MenuListener;
125 * @version $Revision: 1.155 $
127 public class Desktop extends jalview.jbgui.GDesktop
128 implements DropTargetListener, ClipboardOwner, IProgressIndicator,
129 jalview.api.StructureSelectionManagerProvider
131 private static int DEFAULT_MIN_WIDTH = 300;
133 private static int DEFAULT_MIN_HEIGHT = 250;
135 private static int ALIGN_FRAME_DEFAULT_MIN_WIDTH = 600;
137 private static int ALIGN_FRAME_DEFAULT_MIN_HEIGHT = 70;
139 private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES";
141 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
144 * news reader - null if it was never started.
146 private BlogReader jvnews = null;
148 private File projectFile;
152 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
154 public void addJalviewPropertyChangeListener(
155 PropertyChangeListener listener)
157 changeSupport.addJalviewPropertyChangeListener(listener);
161 * @param propertyName
163 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
164 * java.beans.PropertyChangeListener)
166 public void addJalviewPropertyChangeListener(String propertyName,
167 PropertyChangeListener listener)
169 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
173 * @param propertyName
175 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
176 * java.beans.PropertyChangeListener)
178 public void removeJalviewPropertyChangeListener(String propertyName,
179 PropertyChangeListener listener)
181 changeSupport.removeJalviewPropertyChangeListener(propertyName,
185 /** Singleton Desktop instance */
186 public static Desktop instance;
188 public static MyDesktopPane desktop;
190 static int openFrameCount = 0;
192 static final int xOffset = 30;
194 static final int yOffset = 30;
196 public static jalview.ws.jws1.Discoverer discoverer;
198 public static Object[] jalviewClipboard;
200 public static boolean internalCopy = false;
202 static int fileLoadingCount = 0;
204 class MyDesktopManager implements DesktopManager
207 private DesktopManager delegate;
209 public MyDesktopManager(DesktopManager delegate)
211 this.delegate = delegate;
215 public void activateFrame(JInternalFrame f)
219 delegate.activateFrame(f);
220 } catch (NullPointerException npe)
222 Point p = getMousePosition();
223 instance.showPasteMenu(p.x, p.y);
228 public void beginDraggingFrame(JComponent f)
230 delegate.beginDraggingFrame(f);
234 public void beginResizingFrame(JComponent f, int direction)
236 delegate.beginResizingFrame(f, direction);
240 public void closeFrame(JInternalFrame f)
242 delegate.closeFrame(f);
246 public void deactivateFrame(JInternalFrame f)
248 delegate.deactivateFrame(f);
252 public void deiconifyFrame(JInternalFrame f)
254 delegate.deiconifyFrame(f);
258 public void dragFrame(JComponent f, int newX, int newY)
264 delegate.dragFrame(f, newX, newY);
268 public void endDraggingFrame(JComponent f)
270 delegate.endDraggingFrame(f);
275 public void endResizingFrame(JComponent f)
277 delegate.endResizingFrame(f);
282 public void iconifyFrame(JInternalFrame f)
284 delegate.iconifyFrame(f);
288 public void maximizeFrame(JInternalFrame f)
290 delegate.maximizeFrame(f);
294 public void minimizeFrame(JInternalFrame f)
296 delegate.minimizeFrame(f);
300 public void openFrame(JInternalFrame f)
302 delegate.openFrame(f);
306 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
313 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
317 public void setBoundsForFrame(JComponent f, int newX, int newY,
318 int newWidth, int newHeight)
320 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
323 // All other methods, simply delegate
328 * Creates a new Desktop object.
333 * A note to implementors. It is ESSENTIAL that any activities that might
334 * block are spawned off as threads rather than waited for during this
338 doVamsasClientCheck();
340 doConfigureStructurePrefs();
341 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
342 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
343 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
345 boolean showjconsole = jalview.bin.Cache.getDefault("SHOW_JAVA_CONSOLE",
347 desktop = new MyDesktopPane(selmemusage);
348 showMemusage.setSelected(selmemusage);
349 desktop.setBackground(Color.white);
350 getContentPane().setLayout(new BorderLayout());
351 // alternate config - have scrollbars - see notes in JAL-153
352 // JScrollPane sp = new JScrollPane();
353 // sp.getViewport().setView(desktop);
354 // getContentPane().add(sp, BorderLayout.CENTER);
355 getContentPane().add(desktop, BorderLayout.CENTER);
356 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
358 // This line prevents Windows Look&Feel resizing all new windows to maximum
359 // if previous window was maximised
360 desktop.setDesktopManager(
361 new MyDesktopManager(new DefaultDesktopManager()));
363 Rectangle dims = getLastKnownDimensions("");
370 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
371 setBounds((screenSize.width - 900) / 2, (screenSize.height - 650) / 2,
374 jconsole = new Console(this, showjconsole);
375 // add essential build information
377 "Jalview Version: " + jalview.bin.Cache.getProperty("VERSION")
378 + "\n" + "Jalview Installation: "
379 + jalview.bin.Cache.getDefault("INSTALLATION",
381 + "\n" + "Build Date: "
382 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
383 + "\n" + "Java version: "
384 + System.getProperty("java.version") + "\n"
385 + System.getProperty("os.arch") + " "
386 + System.getProperty("os.name") + " "
387 + System.getProperty("os.version"));
389 showConsole(showjconsole);
391 showNews.setVisible(false);
393 experimentalFeatures.setSelected(showExperimental());
395 getIdentifiersOrgData();
399 this.addWindowListener(new WindowAdapter()
402 public void windowClosing(WindowEvent evt)
409 this.addMouseListener(ma = new MouseAdapter()
412 public void mousePressed(MouseEvent evt)
414 if (evt.isPopupTrigger()) // Mac
416 showPasteMenu(evt.getX(), evt.getY());
421 public void mouseReleased(MouseEvent evt)
423 if (evt.isPopupTrigger()) // Windows
425 showPasteMenu(evt.getX(), evt.getY());
429 desktop.addMouseListener(ma);
431 this.addFocusListener(new FocusListener()
435 public void focusLost(FocusEvent e)
437 // TODO Auto-generated method stub
442 public void focusGained(FocusEvent e)
444 Cache.log.debug("Relaying windows after focus gain");
445 // make sure that we sort windows properly after we gain focus
446 instance.relayerWindows();
449 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
450 // Spawn a thread that shows the splashscreen
451 SwingUtilities.invokeLater(new Runnable()
460 // Thread off a new instance of the file chooser - this reduces the time it
461 // takes to open it later on.
462 new Thread(new Runnable()
467 Cache.log.debug("Filechooser init thread started.");
468 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
469 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
471 Cache.log.debug("Filechooser init thread finished.");
474 // Add the service change listener
475 changeSupport.addJalviewPropertyChangeListener("services",
476 new PropertyChangeListener()
480 public void propertyChange(PropertyChangeEvent evt)
482 Cache.log.debug("Firing service changed event for "
483 + evt.getNewValue());
484 JalviewServicesChanged(evt);
491 * Answers true if user preferences to enable experimental features is True
496 public boolean showExperimental()
498 String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
499 Boolean.FALSE.toString());
500 return Boolean.valueOf(experimental).booleanValue();
503 public void doConfigureStructurePrefs()
505 // configure services
506 StructureSelectionManager ssm = StructureSelectionManager
507 .getStructureSelectionManager(this);
508 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
510 ssm.setAddTempFacAnnot(jalview.bin.Cache
511 .getDefault(Preferences.ADD_TEMPFACT_ANN, true));
512 ssm.setProcessSecondaryStructure(jalview.bin.Cache
513 .getDefault(Preferences.STRUCT_FROM_PDB, true));
514 ssm.setSecStructServices(
515 jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW, true));
519 ssm.setAddTempFacAnnot(false);
520 ssm.setProcessSecondaryStructure(false);
521 ssm.setSecStructServices(false);
525 public void checkForNews()
527 final Desktop me = this;
528 // Thread off the news reader, in case there are connection problems.
529 addDialogThread(new Runnable()
534 Cache.log.debug("Starting news thread.");
536 jvnews = new BlogReader(me);
537 showNews.setVisible(true);
538 Cache.log.debug("Completed news thread.");
543 public void getIdentifiersOrgData()
545 // Thread off the identifiers fetcher
546 addDialogThread(new Runnable()
551 Cache.log.debug("Downloading data from identifiers.org");
552 UrlDownloadClient client = new UrlDownloadClient();
555 client.download(IdOrgSettings.getUrl(),
556 IdOrgSettings.getDownloadLocation());
557 } catch (IOException e)
559 Cache.log.debug("Exception downloading identifiers.org data"
567 protected void showNews_actionPerformed(ActionEvent e)
569 showNews(showNews.isSelected());
572 void showNews(boolean visible)
575 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
576 showNews.setSelected(visible);
577 if (visible && !jvnews.isVisible())
579 new Thread(new Runnable()
584 long now = System.currentTimeMillis();
585 Desktop.instance.setProgressBar(
586 MessageManager.getString("status.refreshing_news"),
588 jvnews.refreshNews();
589 Desktop.instance.setProgressBar(null, now);
598 * recover the last known dimensions for a jalview window
601 * - empty string is desktop, all other windows have unique prefix
602 * @return null or last known dimensions scaled to current geometry (if last
603 * window geom was known)
605 Rectangle getLastKnownDimensions(String windowName)
607 // TODO: lock aspect ratio for scaling desktop Bug #0058199
608 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
609 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
610 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
611 String width = jalview.bin.Cache
612 .getProperty(windowName + "SCREEN_WIDTH");
613 String height = jalview.bin.Cache
614 .getProperty(windowName + "SCREEN_HEIGHT");
615 if ((x != null) && (y != null) && (width != null) && (height != null))
617 int ix = Integer.parseInt(x), iy = Integer.parseInt(y),
618 iw = Integer.parseInt(width), ih = Integer.parseInt(height);
619 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
621 // attempt #1 - try to cope with change in screen geometry - this
622 // version doesn't preserve original jv aspect ratio.
623 // take ratio of current screen size vs original screen size.
624 double sw = ((1f * screenSize.width) / (1f * Integer.parseInt(
625 jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
626 double sh = ((1f * screenSize.height) / (1f * Integer.parseInt(
627 jalview.bin.Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
628 // rescale the bounds depending upon the current screen geometry.
629 ix = (int) (ix * sw);
630 iw = (int) (iw * sw);
631 iy = (int) (iy * sh);
632 ih = (int) (ih * sh);
633 while (ix >= screenSize.width)
635 jalview.bin.Cache.log.debug(
636 "Window geometry location recall error: shifting horizontal to within screenbounds.");
637 ix -= screenSize.width;
639 while (iy >= screenSize.height)
641 jalview.bin.Cache.log.debug(
642 "Window geometry location recall error: shifting vertical to within screenbounds.");
643 iy -= screenSize.height;
645 jalview.bin.Cache.log.debug(
646 "Got last known dimensions for " + windowName + ": x:" + ix
647 + " y:" + iy + " width:" + iw + " height:" + ih);
649 // return dimensions for new instance
650 return new Rectangle(ix, iy, iw, ih);
655 private void doVamsasClientCheck()
657 if (jalview.bin.Cache.vamsasJarsPresent())
659 setupVamsasDisconnectedGui();
660 VamsasMenu.setVisible(true);
661 final Desktop us = this;
662 VamsasMenu.addMenuListener(new MenuListener()
664 // this listener remembers when the menu was first selected, and
665 // doesn't rebuild the session list until it has been cleared and
667 boolean refresh = true;
670 public void menuCanceled(MenuEvent e)
676 public void menuDeselected(MenuEvent e)
682 public void menuSelected(MenuEvent e)
686 us.buildVamsasStMenu();
691 vamsasStart.setVisible(true);
695 void showPasteMenu(int x, int y)
697 JPopupMenu popup = new JPopupMenu();
698 JMenuItem item = new JMenuItem(
699 MessageManager.getString("label.paste_new_window"));
700 item.addActionListener(new ActionListener()
703 public void actionPerformed(ActionEvent evt)
710 popup.show(this, x, y);
717 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
718 Transferable contents = c.getContents(this);
720 if (contents != null)
722 String file = (String) contents
723 .getTransferData(DataFlavor.stringFlavor);
725 FileFormatI format = new IdentifyFile().identify(file,
726 DataSourceType.PASTE);
728 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
731 } catch (Exception ex)
734 "Unable to paste alignment from system clipboard:\n" + ex);
739 * Adds and opens the given frame to the desktop
750 public static synchronized void addInternalFrame(
751 final JInternalFrame frame, String title, int w, int h)
753 addInternalFrame(frame, title, true, w, h, true, false);
757 * Add an internal frame to the Jalview desktop
764 * When true, display frame immediately, otherwise, caller must call
765 * setVisible themselves.
771 public static synchronized void addInternalFrame(
772 final JInternalFrame frame, String title, boolean makeVisible,
775 addInternalFrame(frame, title, makeVisible, w, h, true, false);
779 * Add an internal frame to the Jalview desktop and make it visible
792 public static synchronized void addInternalFrame(
793 final JInternalFrame frame, String title, int w, int h,
796 addInternalFrame(frame, title, true, w, h, resizable, false);
800 * Add an internal frame to the Jalview desktop
807 * When true, display frame immediately, otherwise, caller must call
808 * setVisible themselves.
815 * @param ignoreMinSize
816 * Do not set the default minimum size for frame
818 public static synchronized void addInternalFrame(
819 final JInternalFrame frame, String title, boolean makeVisible,
820 int w, int h, boolean resizable, boolean ignoreMinSize)
823 // TODO: allow callers to determine X and Y position of frame (eg. via
825 // TODO: consider fixing method to update entries in the window submenu with
826 // the current window title
828 frame.setTitle(title);
829 if (frame.getWidth() < 1 || frame.getHeight() < 1)
833 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
834 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
835 // IF JALVIEW IS RUNNING HEADLESS
836 // ///////////////////////////////////////////////
837 if (instance == null || (System.getProperty("java.awt.headless") != null
838 && System.getProperty("java.awt.headless").equals("true")))
847 frame.setMinimumSize(
848 new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
850 // Set default dimension for Alignment Frame window.
851 // The Alignment Frame window could be added from a number of places,
853 // I did this here in order not to miss out on any Alignment frame.
854 if (frame instanceof AlignFrame)
856 frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
857 ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
861 frame.setVisible(makeVisible);
862 frame.setClosable(true);
863 frame.setResizable(resizable);
864 frame.setMaximizable(resizable);
865 frame.setIconifiable(resizable);
867 if (frame.getX() < 1 && frame.getY() < 1)
869 frame.setLocation(xOffset * openFrameCount,
870 yOffset * ((openFrameCount - 1) % 10) + yOffset);
874 * add an entry for the new frame in the Window menu
875 * (and remove it when the frame is closed)
877 final JMenuItem menuItem = new JMenuItem(title);
878 frame.addInternalFrameListener(new InternalFrameAdapter()
881 public void internalFrameActivated(InternalFrameEvent evt)
883 JInternalFrame itf = desktop.getSelectedFrame();
891 public void internalFrameClosed(InternalFrameEvent evt)
893 PaintRefresher.RemoveComponent(frame);
896 * defensive check to prevent frames being
897 * added half off the window
899 if (openFrameCount > 0)
905 * ensure no reference to alignFrame retained by menu item listener
907 if (menuItem.getActionListeners().length > 0)
909 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
911 windowMenu.remove(menuItem);
912 JInternalFrame itf = desktop.getSelectedFrame();
916 if (itf instanceof AlignFrame)
918 Jalview.setCurrentAlignFrame((AlignFrame) itf);
925 menuItem.addActionListener(new ActionListener()
928 public void actionPerformed(ActionEvent e)
932 frame.setSelected(true);
933 frame.setIcon(false);
934 } catch (java.beans.PropertyVetoException ex)
943 windowMenu.add(menuItem);
948 frame.setSelected(true);
949 frame.requestFocus();
950 } catch (java.beans.PropertyVetoException ve)
952 } catch (java.lang.ClassCastException cex)
955 "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
961 public void lostOwnership(Clipboard clipboard, Transferable contents)
965 Desktop.jalviewClipboard = null;
968 internalCopy = false;
972 public void dragEnter(DropTargetDragEvent evt)
977 public void dragExit(DropTargetEvent evt)
982 public void dragOver(DropTargetDragEvent evt)
987 public void dropActionChanged(DropTargetDragEvent evt)
998 public void drop(DropTargetDropEvent evt)
1000 boolean success = true;
1001 // JAL-1552 - acceptDrop required before getTransferable call for
1002 // Java's Transferable for native dnd
1003 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
1004 Transferable t = evt.getTransferable();
1005 List<String> files = new ArrayList<>();
1006 List<DataSourceType> protocols = new ArrayList<>();
1010 Desktop.transferFromDropTarget(files, protocols, evt, t);
1011 } catch (Exception e)
1013 e.printStackTrace();
1021 for (int i = 0; i < files.size(); i++)
1023 String file = files.get(i).toString();
1024 DataSourceType protocol = (protocols == null)
1025 ? DataSourceType.FILE
1027 FileFormatI format = null;
1029 if (file.endsWith(".jar"))
1031 format = FileFormat.Jalview;
1036 format = new IdentifyFile().identify(file, protocol);
1039 new FileLoader().LoadFile(file, protocol, format);
1042 } catch (Exception ex)
1047 evt.dropComplete(success); // need this to ensure input focus is properly
1048 // transfered to any new windows created
1058 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1060 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1061 JalviewFileChooser chooser = JalviewFileChooser
1062 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1064 chooser.setFileView(new JalviewFileView());
1065 chooser.setDialogTitle(
1066 MessageManager.getString("label.open_local_file"));
1067 chooser.setToolTipText(MessageManager.getString("action.open"));
1069 int value = chooser.showOpenDialog(this);
1071 if (value == JalviewFileChooser.APPROVE_OPTION)
1073 String choice = chooser.getSelectedFile().getPath();
1074 Cache.setProperty("LAST_DIRECTORY",
1075 chooser.getSelectedFile().getParent());
1077 FileFormatI format = chooser.getSelectedFormat();
1080 * Call IdentifyFile to verify the file contains what its extension implies.
1081 * Skip this step for dynamically added file formats, because
1082 * IdentifyFile does not know how to recognise them.
1084 if (FileFormats.getInstance().isIdentifiable(format))
1088 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1089 } catch (FileFormatException e)
1091 // format = null; //??
1095 if (viewport != null)
1097 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1102 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1114 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1116 // This construct allows us to have a wider textfield
1118 JLabel label = new JLabel(
1119 MessageManager.getString("label.input_file_url"));
1120 final JComboBox history = new JComboBox();
1122 JPanel panel = new JPanel(new GridLayout(2, 1));
1125 history.setPreferredSize(new Dimension(400, 20));
1126 history.setEditable(true);
1127 history.addItem("http://www.");
1129 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1133 if (historyItems != null)
1135 st = new StringTokenizer(historyItems, "\t");
1137 while (st.hasMoreTokens())
1139 history.addItem(st.nextElement());
1143 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1144 MessageManager.getString("label.input_alignment_from_url"),
1145 JvOptionPane.OK_CANCEL_OPTION);
1147 if (reply != JvOptionPane.OK_OPTION)
1152 String url = history.getSelectedItem().toString();
1154 if (url.toLowerCase().endsWith(".jar"))
1156 if (viewport != null)
1158 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1159 FileFormat.Jalview);
1163 new FileLoader().LoadFile(url, DataSourceType.URL,
1164 FileFormat.Jalview);
1169 FileFormatI format = null;
1172 format = new IdentifyFile().identify(url, DataSourceType.URL);
1173 } catch (FileFormatException e)
1175 // TODO revise error handling, distinguish between
1176 // URL not found and response not valid
1181 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1182 MessageManager.formatMessage("label.couldnt_locate",
1185 MessageManager.getString("label.url_not_found"),
1186 JvOptionPane.WARNING_MESSAGE);
1191 if (viewport != null)
1193 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1198 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1204 * Opens the CutAndPaste window for the user to paste an alignment in to
1207 * - if not null, the pasted alignment is added to the current
1208 * alignment; if null, to a new alignment window
1211 public void inputTextboxMenuItem_actionPerformed(
1212 AlignmentViewPanel viewPanel)
1214 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1215 cap.setForInput(viewPanel);
1216 Desktop.addInternalFrame(cap,
1217 MessageManager.getString("label.cut_paste_alignmen_file"), true,
1227 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1228 jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH",
1230 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT",
1231 screen.height + "");
1232 storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
1233 getWidth(), getHeight()));
1235 if (jconsole != null)
1237 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1238 jconsole.stopConsole();
1242 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1245 if (dialogExecutor != null)
1247 dialogExecutor.shutdownNow();
1249 closeAll_actionPerformed(null);
1251 if (groovyConsole != null)
1253 // suppress a possible repeat prompt to save script
1254 groovyConsole.setDirty(false);
1255 groovyConsole.exit();
1260 private void storeLastKnownDimensions(String string, Rectangle jc)
1262 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1263 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1264 + " height:" + jc.height);
1266 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1267 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1268 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1269 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1279 public void aboutMenuItem_actionPerformed(ActionEvent e)
1281 // StringBuffer message = getAboutMessage(false);
1282 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1284 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1285 new Thread(new Runnable()
1290 new SplashScreen(true);
1295 public StringBuffer getAboutMessage(boolean shortv)
1297 StringBuffer message = new StringBuffer();
1298 message.append("<html>");
1301 message.append("<h1><strong>Version: "
1302 + jalview.bin.Cache.getProperty("VERSION")
1303 + "</strong></h1>");
1304 message.append("<strong>Last Updated: <em>"
1305 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1306 + "</em></strong>");
1312 message.append("<strong>Version "
1313 + jalview.bin.Cache.getProperty("VERSION")
1314 + "; last updated: "
1315 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1318 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1319 .equals("Checking"))
1321 message.append("<br>...Checking latest version...</br>");
1323 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1324 .equals(jalview.bin.Cache.getProperty("VERSION")))
1326 boolean red = false;
1327 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1328 .indexOf("automated build") == -1)
1331 // Displayed when code version and jnlp version do not match and code
1332 // version is not a development build
1333 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1336 message.append("<br>!! Version "
1337 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1339 + " is available for download from "
1340 + jalview.bin.Cache.getDefault("www.jalview.org",
1341 "http://www.jalview.org")
1345 message.append("</div>");
1348 message.append("<br>Authors: " + jalview.bin.Cache.getDefault(
1350 "The Jalview Authors (See AUTHORS file for current list)")
1351 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1352 + "<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"
1353 + "<br><br>If you use Jalview, please cite:"
1354 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1355 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1356 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1368 public void documentationMenuItem_actionPerformed(ActionEvent e)
1372 Help.showHelpWindow();
1373 } catch (Exception ex)
1379 public void closeAll_actionPerformed(ActionEvent e)
1381 // TODO show a progress bar while closing?
1382 JInternalFrame[] frames = desktop.getAllFrames();
1383 for (int i = 0; i < frames.length; i++)
1387 frames[i].setClosed(true);
1388 } catch (java.beans.PropertyVetoException ex)
1392 Jalview.setCurrentAlignFrame(null);
1393 System.out.println("ALL CLOSED");
1394 if (v_client != null)
1396 // TODO clear binding to vamsas document objects on close_all
1400 * reset state of singleton objects as appropriate (clear down session state
1401 * when all windows are closed)
1403 StructureSelectionManager ssm = StructureSelectionManager
1404 .getStructureSelectionManager(this);
1413 public void raiseRelated_actionPerformed(ActionEvent e)
1415 reorderAssociatedWindows(false, false);
1419 public void minimizeAssociated_actionPerformed(ActionEvent e)
1421 reorderAssociatedWindows(true, false);
1424 void closeAssociatedWindows()
1426 reorderAssociatedWindows(false, true);
1432 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1436 protected void garbageCollect_actionPerformed(ActionEvent e)
1438 // We simply collect the garbage
1439 jalview.bin.Cache.log.debug("Collecting garbage...");
1441 jalview.bin.Cache.log.debug("Finished garbage collection.");
1448 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1452 protected void showMemusage_actionPerformed(ActionEvent e)
1454 desktop.showMemoryUsage(showMemusage.isSelected());
1461 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1465 protected void showConsole_actionPerformed(ActionEvent e)
1467 showConsole(showConsole.isSelected());
1470 Console jconsole = null;
1473 * control whether the java console is visible or not
1477 void showConsole(boolean selected)
1479 showConsole.setSelected(selected);
1480 // TODO: decide if we should update properties file
1481 Cache.setProperty("SHOW_JAVA_CONSOLE",
1482 Boolean.valueOf(selected).toString());
1483 jconsole.setVisible(selected);
1486 void reorderAssociatedWindows(boolean minimize, boolean close)
1488 JInternalFrame[] frames = desktop.getAllFrames();
1489 if (frames == null || frames.length < 1)
1494 AlignmentViewport source = null, target = null;
1495 if (frames[0] instanceof AlignFrame)
1497 source = ((AlignFrame) frames[0]).getCurrentView();
1499 else if (frames[0] instanceof TreePanel)
1501 source = ((TreePanel) frames[0]).getViewPort();
1503 else if (frames[0] instanceof PCAPanel)
1505 source = ((PCAPanel) frames[0]).av;
1507 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1509 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1514 for (int i = 0; i < frames.length; i++)
1517 if (frames[i] == null)
1521 if (frames[i] instanceof AlignFrame)
1523 target = ((AlignFrame) frames[i]).getCurrentView();
1525 else if (frames[i] instanceof TreePanel)
1527 target = ((TreePanel) frames[i]).getViewPort();
1529 else if (frames[i] instanceof PCAPanel)
1531 target = ((PCAPanel) frames[i]).av;
1533 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1535 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1538 if (source == target)
1544 frames[i].setClosed(true);
1548 frames[i].setIcon(minimize);
1551 frames[i].toFront();
1555 } catch (java.beans.PropertyVetoException ex)
1570 protected void preferences_actionPerformed(ActionEvent e)
1582 public void saveState_actionPerformed(ActionEvent e)
1584 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1587 chooser.setFileView(new JalviewFileView());
1588 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1590 int value = chooser.showSaveDialog(this);
1592 if (value == JalviewFileChooser.APPROVE_OPTION)
1594 final Desktop me = this;
1595 final java.io.File choice = chooser.getSelectedFile();
1596 setProjectFile(choice);
1598 new Thread(new Runnable()
1603 // TODO: refactor to Jalview desktop session controller action.
1604 setProgressBar(MessageManager.formatMessage(
1605 "label.saving_jalview_project", new Object[]
1606 { choice.getName() }), choice.hashCode());
1607 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1608 choice.getParent());
1609 // TODO catch and handle errors for savestate
1610 // TODO prevent user from messing with the Desktop whilst we're saving
1613 new Jalview2XML().saveState(choice);
1614 } catch (OutOfMemoryError oom)
1617 "Whilst saving current state to " + choice.getName(),
1619 } catch (Exception ex)
1622 "Problems whilst trying to save to " + choice.getName(),
1624 JvOptionPane.showMessageDialog(me,
1625 MessageManager.formatMessage(
1626 "label.error_whilst_saving_current_state_to",
1628 { choice.getName() }),
1629 MessageManager.getString("label.couldnt_save_project"),
1630 JvOptionPane.WARNING_MESSAGE);
1632 setProgressBar(null, choice.hashCode());
1638 private void setProjectFile(File choice)
1640 this.projectFile = choice;
1643 public File getProjectFile()
1645 return this.projectFile;
1655 public void loadState_actionPerformed(ActionEvent e)
1657 JalviewFileChooser chooser = new JalviewFileChooser(
1658 Cache.getProperty("LAST_DIRECTORY"), new String[]
1661 { "Jalview Project", "Jalview Project (old)" },
1663 chooser.setFileView(new JalviewFileView());
1664 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1666 int value = chooser.showOpenDialog(this);
1668 if (value == JalviewFileChooser.APPROVE_OPTION)
1670 final File selectedFile = chooser.getSelectedFile();
1671 setProjectFile(selectedFile);
1672 final String choice = selectedFile.getAbsolutePath();
1673 Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1674 new Thread(new Runnable()
1679 setProgressBar(MessageManager.formatMessage(
1680 "label.loading_jalview_project", new Object[]
1681 { choice }), choice.hashCode());
1684 new Jalview2XML().loadJalviewAlign(choice);
1685 } catch (OutOfMemoryError oom)
1687 new OOMWarning("Whilst loading project from " + choice, oom);
1688 } catch (Exception ex)
1691 "Problems whilst loading project from " + choice, ex);
1692 JvOptionPane.showMessageDialog(Desktop.desktop,
1693 MessageManager.formatMessage(
1694 "label.error_whilst_loading_project_from",
1697 MessageManager.getString("label.couldnt_load_project"),
1698 JvOptionPane.WARNING_MESSAGE);
1700 setProgressBar(null, choice.hashCode());
1707 public void inputSequence_actionPerformed(ActionEvent e)
1709 new SequenceFetcher(this);
1712 JPanel progressPanel;
1714 ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
1716 public void startLoading(final String fileName)
1718 if (fileLoadingCount == 0)
1720 fileLoadingPanels.add(addProgressPanel(MessageManager
1721 .formatMessage("label.loading_file", new Object[]
1727 private JPanel addProgressPanel(String string)
1729 if (progressPanel == null)
1731 progressPanel = new JPanel(new GridLayout(1, 1));
1732 totalProgressCount = 0;
1733 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1735 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1736 JProgressBar progressBar = new JProgressBar();
1737 progressBar.setIndeterminate(true);
1739 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1741 thisprogress.add(progressBar, BorderLayout.CENTER);
1742 progressPanel.add(thisprogress);
1743 ((GridLayout) progressPanel.getLayout()).setRows(
1744 ((GridLayout) progressPanel.getLayout()).getRows() + 1);
1745 ++totalProgressCount;
1746 instance.validate();
1747 return thisprogress;
1750 int totalProgressCount = 0;
1752 private void removeProgressPanel(JPanel progbar)
1754 if (progressPanel != null)
1756 synchronized (progressPanel)
1758 progressPanel.remove(progbar);
1759 GridLayout gl = (GridLayout) progressPanel.getLayout();
1760 gl.setRows(gl.getRows() - 1);
1761 if (--totalProgressCount < 1)
1763 this.getContentPane().remove(progressPanel);
1764 progressPanel = null;
1771 public void stopLoading()
1774 if (fileLoadingCount < 1)
1776 while (fileLoadingPanels.size() > 0)
1778 removeProgressPanel(fileLoadingPanels.remove(0));
1780 fileLoadingPanels.clear();
1781 fileLoadingCount = 0;
1786 public static int getViewCount(String alignmentId)
1788 AlignmentViewport[] aps = getViewports(alignmentId);
1789 return (aps == null) ? 0 : aps.length;
1794 * @param alignmentId
1795 * - if null, all sets are returned
1796 * @return all AlignmentPanels concerning the alignmentId sequence set
1798 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1800 if (Desktop.desktop == null)
1802 // no frames created and in headless mode
1803 // TODO: verify that frames are recoverable when in headless mode
1806 List<AlignmentPanel> aps = new ArrayList<>();
1807 AlignFrame[] frames = getAlignFrames();
1812 for (AlignFrame af : frames)
1814 for (AlignmentPanel ap : af.alignPanels)
1816 if (alignmentId == null
1817 || alignmentId.equals(ap.av.getSequenceSetId()))
1823 if (aps.size() == 0)
1827 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1832 * get all the viewports on an alignment.
1834 * @param sequenceSetId
1835 * unique alignment id (may be null - all viewports returned in that
1837 * @return all viewports on the alignment bound to sequenceSetId
1839 public static AlignmentViewport[] getViewports(String sequenceSetId)
1841 List<AlignmentViewport> viewp = new ArrayList<>();
1842 if (desktop != null)
1844 AlignFrame[] frames = Desktop.getAlignFrames();
1846 for (AlignFrame afr : frames)
1848 if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
1849 .equals(sequenceSetId))
1851 if (afr.alignPanels != null)
1853 for (AlignmentPanel ap : afr.alignPanels)
1855 if (sequenceSetId == null
1856 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1864 viewp.add(afr.getViewport());
1868 if (viewp.size() > 0)
1870 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1877 * Explode the views in the given frame into separate AlignFrame
1881 public static void explodeViews(AlignFrame af)
1883 int size = af.alignPanels.size();
1889 for (int i = 0; i < size; i++)
1891 AlignmentPanel ap = af.alignPanels.get(i);
1892 AlignFrame newaf = new AlignFrame(ap);
1895 * Restore the view's last exploded frame geometry if known. Multiple
1896 * views from one exploded frame share and restore the same (frame)
1897 * position and size.
1899 Rectangle geometry = ap.av.getExplodedGeometry();
1900 if (geometry != null)
1902 newaf.setBounds(geometry);
1905 ap.av.setGatherViewsHere(false);
1907 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1908 AlignFrame.DEFAULT_HEIGHT);
1911 af.alignPanels.clear();
1912 af.closeMenuItem_actionPerformed(true);
1917 * Gather expanded views (separate AlignFrame's) with the same sequence set
1918 * identifier back in to this frame as additional views, and close the
1919 * expanded views. Note the expanded frames may themselves have multiple
1920 * views. We take the lot.
1924 public void gatherViews(AlignFrame source)
1926 source.viewport.setGatherViewsHere(true);
1927 source.viewport.setExplodedGeometry(source.getBounds());
1928 JInternalFrame[] frames = desktop.getAllFrames();
1929 String viewId = source.viewport.getSequenceSetId();
1931 for (int t = 0; t < frames.length; t++)
1933 if (frames[t] instanceof AlignFrame && frames[t] != source)
1935 AlignFrame af = (AlignFrame) frames[t];
1936 boolean gatherThis = false;
1937 for (int a = 0; a < af.alignPanels.size(); a++)
1939 AlignmentPanel ap = af.alignPanels.get(a);
1940 if (viewId.equals(ap.av.getSequenceSetId()))
1943 ap.av.setGatherViewsHere(false);
1944 ap.av.setExplodedGeometry(af.getBounds());
1945 source.addAlignmentPanel(ap, false);
1951 af.alignPanels.clear();
1952 af.closeMenuItem_actionPerformed(true);
1959 jalview.gui.VamsasApplication v_client = null;
1962 public void vamsasImport_actionPerformed(ActionEvent e)
1964 if (v_client == null)
1966 // Load and try to start a session.
1967 JalviewFileChooser chooser = new JalviewFileChooser(
1968 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1970 chooser.setFileView(new JalviewFileView());
1971 chooser.setDialogTitle(
1972 MessageManager.getString("label.open_saved_vamsas_session"));
1973 chooser.setToolTipText(MessageManager.getString(
1974 "label.select_vamsas_session_opened_as_new_vamsas_session"));
1976 int value = chooser.showOpenDialog(this);
1978 if (value == JalviewFileChooser.APPROVE_OPTION)
1980 String fle = chooser.getSelectedFile().toString();
1981 if (!vamsasImport(chooser.getSelectedFile()))
1983 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1984 MessageManager.formatMessage(
1985 "label.couldnt_import_as_vamsas_session",
1989 .getString("label.vamsas_document_import_failed"),
1990 JvOptionPane.ERROR_MESSAGE);
1996 jalview.bin.Cache.log.error(
1997 "Implementation error - load session from a running session is not supported.");
2002 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2005 * @return true if import was a success and a session was started.
2007 public boolean vamsasImport(URL url)
2009 // TODO: create progress bar
2010 if (v_client != null)
2013 jalview.bin.Cache.log.error(
2014 "Implementation error - load session from a running session is not supported.");
2020 // copy the URL content to a temporary local file
2021 // TODO: be a bit cleverer here with nio (?!)
2022 File file = File.createTempFile("vdocfromurl", ".vdj");
2023 FileOutputStream fos = new FileOutputStream(file);
2024 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2025 byte[] buffer = new byte[2048];
2027 while ((ln = bis.read(buffer)) > -1)
2029 fos.write(buffer, 0, ln);
2033 v_client = new jalview.gui.VamsasApplication(this, file,
2034 url.toExternalForm());
2035 } catch (Exception ex)
2037 jalview.bin.Cache.log.error(
2038 "Failed to create new vamsas session from contents of URL "
2043 setupVamsasConnectedGui();
2044 v_client.initial_update(); // TODO: thread ?
2045 return v_client.inSession();
2049 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2052 * @return true if import was a success and a session was started.
2054 public boolean vamsasImport(File file)
2056 if (v_client != null)
2059 jalview.bin.Cache.log.error(
2060 "Implementation error - load session from a running session is not supported.");
2064 setProgressBar(MessageManager.formatMessage(
2065 "status.importing_vamsas_session_from", new Object[]
2066 { file.getName() }), file.hashCode());
2069 v_client = new jalview.gui.VamsasApplication(this, file, null);
2070 } catch (Exception ex)
2072 setProgressBar(MessageManager.formatMessage(
2073 "status.importing_vamsas_session_from", new Object[]
2074 { file.getName() }), file.hashCode());
2075 jalview.bin.Cache.log.error(
2076 "New vamsas session from existing session file failed:", ex);
2079 setupVamsasConnectedGui();
2080 v_client.initial_update(); // TODO: thread ?
2081 setProgressBar(MessageManager.formatMessage(
2082 "status.importing_vamsas_session_from", new Object[]
2083 { file.getName() }), file.hashCode());
2084 return v_client.inSession();
2087 public boolean joinVamsasSession(String mysesid)
2089 if (v_client != null)
2091 throw new Error(MessageManager
2092 .getString("error.try_join_vamsas_session_another"));
2094 if (mysesid == null)
2097 MessageManager.getString("error.invalid_vamsas_session_id"));
2099 v_client = new VamsasApplication(this, mysesid);
2100 setupVamsasConnectedGui();
2101 v_client.initial_update();
2102 return (v_client.inSession());
2106 public void vamsasStart_actionPerformed(ActionEvent e)
2108 if (v_client == null)
2111 // we just start a default session for moment.
2113 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2114 * getProperty("LAST_DIRECTORY"));
2116 * chooser.setFileView(new JalviewFileView());
2117 * chooser.setDialogTitle("Load Vamsas file");
2118 * chooser.setToolTipText("Import");
2120 * int value = chooser.showOpenDialog(this);
2122 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2123 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2125 v_client = new VamsasApplication(this);
2126 setupVamsasConnectedGui();
2127 v_client.initial_update(); // TODO: thread ?
2131 // store current data in session.
2132 v_client.push_update(); // TODO: thread
2136 protected void setupVamsasConnectedGui()
2138 vamsasStart.setText(MessageManager.getString("label.session_update"));
2139 vamsasSave.setVisible(true);
2140 vamsasStop.setVisible(true);
2141 vamsasImport.setVisible(false); // Document import to existing session is
2142 // not possible for vamsas-client-1.0.
2145 protected void setupVamsasDisconnectedGui()
2147 vamsasSave.setVisible(false);
2148 vamsasStop.setVisible(false);
2149 vamsasImport.setVisible(true);
2151 .setText(MessageManager.getString("label.new_vamsas_session"));
2155 public void vamsasStop_actionPerformed(ActionEvent e)
2157 if (v_client != null)
2159 v_client.end_session();
2161 setupVamsasDisconnectedGui();
2165 protected void buildVamsasStMenu()
2167 if (v_client == null)
2169 String[] sess = null;
2172 sess = VamsasApplication.getSessionList();
2173 } catch (Exception e)
2175 jalview.bin.Cache.log.warn("Problem getting current sessions list.",
2181 jalview.bin.Cache.log.debug(
2182 "Got current sessions list: " + sess.length + " entries.");
2183 VamsasStMenu.removeAll();
2184 for (int i = 0; i < sess.length; i++)
2186 JMenuItem sessit = new JMenuItem();
2187 sessit.setText(sess[i]);
2188 sessit.setToolTipText(MessageManager
2189 .formatMessage("label.connect_to_session", new Object[]
2191 final Desktop dsktp = this;
2192 final String mysesid = sess[i];
2193 sessit.addActionListener(new ActionListener()
2197 public void actionPerformed(ActionEvent e)
2199 if (dsktp.v_client == null)
2201 Thread rthr = new Thread(new Runnable()
2207 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2208 dsktp.setupVamsasConnectedGui();
2209 dsktp.v_client.initial_update();
2217 VamsasStMenu.add(sessit);
2219 // don't show an empty menu.
2220 VamsasStMenu.setVisible(sess.length > 0);
2225 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2226 VamsasStMenu.removeAll();
2227 VamsasStMenu.setVisible(false);
2232 // Not interested in the content. Just hide ourselves.
2233 VamsasStMenu.setVisible(false);
2238 public void vamsasSave_actionPerformed(ActionEvent e)
2240 if (v_client != null)
2242 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2243 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2246 chooser.setFileView(new JalviewFileView());
2247 chooser.setDialogTitle(MessageManager
2248 .getString("label.save_vamsas_document_archive"));
2250 int value = chooser.showSaveDialog(this);
2252 if (value == JalviewFileChooser.APPROVE_OPTION)
2254 java.io.File choice = chooser.getSelectedFile();
2255 JPanel progpanel = addProgressPanel(MessageManager
2256 .formatMessage("label.saving_vamsas_doc", new Object[]
2257 { choice.getName() }));
2258 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2259 String warnmsg = null;
2260 String warnttl = null;
2263 v_client.vclient.storeDocument(choice);
2266 warnttl = "Serious Problem saving Vamsas Document";
2267 warnmsg = ex.toString();
2268 jalview.bin.Cache.log
2269 .error("Error Whilst saving document to " + choice, ex);
2271 } catch (Exception ex)
2273 warnttl = "Problem saving Vamsas Document.";
2274 warnmsg = ex.toString();
2275 jalview.bin.Cache.log.warn(
2276 "Exception Whilst saving document to " + choice, ex);
2279 removeProgressPanel(progpanel);
2280 if (warnmsg != null)
2282 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2284 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2290 JPanel vamUpdate = null;
2293 * hide vamsas user gui bits when a vamsas document event is being handled.
2296 * true to hide gui, false to reveal gui
2298 public void setVamsasUpdate(boolean b)
2300 Cache.log.debug("Setting gui for Vamsas update "
2301 + (b ? "in progress" : "finished"));
2303 if (vamUpdate != null)
2305 this.removeProgressPanel(vamUpdate);
2309 vamUpdate = this.addProgressPanel(
2310 MessageManager.getString("label.updating_vamsas_session"));
2312 vamsasStart.setVisible(!b);
2313 vamsasStop.setVisible(!b);
2314 vamsasSave.setVisible(!b);
2317 public JInternalFrame[] getAllFrames()
2319 return desktop.getAllFrames();
2323 * Checks the given url to see if it gives a response indicating that the user
2324 * should be informed of a new questionnaire.
2328 public void checkForQuestionnaire(String url)
2330 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2331 // javax.swing.SwingUtilities.invokeLater(jvq);
2332 new Thread(jvq).start();
2335 public void checkURLLinks()
2337 // Thread off the URL link checker
2338 addDialogThread(new Runnable()
2343 if (Cache.getDefault("CHECKURLLINKS", true))
2345 // check what the actual links are - if it's just the default don't
2346 // bother with the warning
2347 List<String> links = Preferences.sequenceUrlLinks
2350 // only need to check links if there is one with a
2351 // SEQUENCE_ID which is not the default EMBL_EBI link
2352 ListIterator<String> li = links.listIterator();
2353 boolean check = false;
2354 List<JLabel> urls = new ArrayList<>();
2355 while (li.hasNext())
2357 String link = li.next();
2358 if (link.contains(SEQUENCE_ID)
2359 && !link.equals(UrlConstants.DEFAULT_STRING))
2362 int barPos = link.indexOf("|");
2363 String urlMsg = barPos == -1 ? link
2364 : link.substring(0, barPos) + ": "
2365 + link.substring(barPos + 1);
2366 urls.add(new JLabel(urlMsg));
2374 // ask user to check in case URL links use old style tokens
2375 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2376 JPanel msgPanel = new JPanel();
2377 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2378 msgPanel.add(Box.createVerticalGlue());
2379 JLabel msg = new JLabel(MessageManager
2380 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2381 JLabel msg2 = new JLabel(MessageManager
2382 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2384 for (JLabel url : urls)
2390 final JCheckBox jcb = new JCheckBox(
2391 MessageManager.getString("label.do_not_display_again"));
2392 jcb.addActionListener(new ActionListener()
2395 public void actionPerformed(ActionEvent e)
2397 // update Cache settings for "don't show this again"
2398 boolean showWarningAgain = !jcb.isSelected();
2399 Cache.setProperty("CHECKURLLINKS",
2400 Boolean.valueOf(showWarningAgain).toString());
2405 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2407 .getString("label.SEQUENCE_ID_no_longer_used"),
2408 JvOptionPane.WARNING_MESSAGE);
2415 * Proxy class for JDesktopPane which optionally displays the current memory
2416 * usage and highlights the desktop area with a red bar if free memory runs
2421 public class MyDesktopPane extends JDesktopPane implements Runnable
2424 private static final float ONE_MB = 1048576f;
2426 boolean showMemoryUsage = false;
2430 java.text.NumberFormat df;
2432 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2435 public MyDesktopPane(boolean showMemoryUsage)
2437 showMemoryUsage(showMemoryUsage);
2440 public void showMemoryUsage(boolean showMemory)
2442 this.showMemoryUsage = showMemory;
2445 Thread worker = new Thread(this);
2450 public boolean isShowMemoryUsage()
2452 return showMemoryUsage;
2458 df = java.text.NumberFormat.getNumberInstance();
2459 df.setMaximumFractionDigits(2);
2460 runtime = Runtime.getRuntime();
2462 while (showMemoryUsage)
2466 maxMemory = runtime.maxMemory() / ONE_MB;
2467 allocatedMemory = runtime.totalMemory() / ONE_MB;
2468 freeMemory = runtime.freeMemory() / ONE_MB;
2469 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2471 percentUsage = (totalFreeMemory / maxMemory) * 100;
2473 // if (percentUsage < 20)
2475 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2477 // instance.set.setBorder(border1);
2480 // sleep after showing usage
2482 } catch (Exception ex)
2484 ex.printStackTrace();
2490 public void paintComponent(Graphics g)
2492 if (showMemoryUsage && g != null && df != null)
2494 if (percentUsage < 20)
2496 g.setColor(Color.red);
2498 FontMetrics fm = g.getFontMetrics();
2501 g.drawString(MessageManager.formatMessage("label.memory_stats",
2503 { df.format(totalFreeMemory), df.format(maxMemory),
2504 df.format(percentUsage) }),
2505 10, getHeight() - fm.getHeight());
2512 * fixes stacking order after a modal dialog to ensure windows that should be
2513 * on top actually are
2515 public void relayerWindows()
2521 * Accessor method to quickly get all the AlignmentFrames loaded.
2523 * @return an array of AlignFrame, or null if none found
2525 public static AlignFrame[] getAlignFrames()
2527 if (Jalview.isHeadlessMode())
2529 // Desktop.desktop is null in headless mode
2530 return new AlignFrame[] { Jalview.currentAlignFrame };
2533 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2539 List<AlignFrame> avp = new ArrayList<>();
2541 for (int i = frames.length - 1; i > -1; i--)
2543 if (frames[i] instanceof AlignFrame)
2545 avp.add((AlignFrame) frames[i]);
2547 else if (frames[i] instanceof SplitFrame)
2550 * Also check for a split frame containing an AlignFrame
2552 GSplitFrame sf = (GSplitFrame) frames[i];
2553 if (sf.getTopFrame() instanceof AlignFrame)
2555 avp.add((AlignFrame) sf.getTopFrame());
2557 if (sf.getBottomFrame() instanceof AlignFrame)
2559 avp.add((AlignFrame) sf.getBottomFrame());
2563 if (avp.size() == 0)
2567 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2572 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2576 public GStructureViewer[] getJmols()
2578 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2584 List<GStructureViewer> avp = new ArrayList<>();
2586 for (int i = frames.length - 1; i > -1; i--)
2588 if (frames[i] instanceof AppJmol)
2590 GStructureViewer af = (GStructureViewer) frames[i];
2594 if (avp.size() == 0)
2598 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2603 * Add Groovy Support to Jalview
2606 public void groovyShell_actionPerformed()
2610 openGroovyConsole();
2611 } catch (Exception ex)
2613 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2614 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2616 MessageManager.getString("label.couldnt_create_groovy_shell"),
2617 MessageManager.getString("label.groovy_support_failed"),
2618 JvOptionPane.ERROR_MESSAGE);
2623 * Open the Groovy console
2625 void openGroovyConsole()
2627 if (groovyConsole == null)
2629 groovyConsole = new groovy.ui.Console();
2630 groovyConsole.setVariable("Jalview", this);
2631 groovyConsole.run();
2634 * We allow only one console at a time, so that AlignFrame menu option
2635 * 'Calculate | Run Groovy script' is unambiguous.
2636 * Disable 'Groovy Console', and enable 'Run script', when the console is
2637 * opened, and the reverse when it is closed
2639 Window window = (Window) groovyConsole.getFrame();
2640 window.addWindowListener(new WindowAdapter()
2643 public void windowClosed(WindowEvent e)
2646 * rebind CMD-Q from Groovy Console to Jalview Quit
2649 enableExecuteGroovy(false);
2655 * show Groovy console window (after close and reopen)
2657 ((Window) groovyConsole.getFrame()).setVisible(true);
2660 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2661 * and disable opening a second console
2663 enableExecuteGroovy(true);
2667 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2668 * binding when opened
2670 protected void addQuitHandler()
2672 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
2673 .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
2674 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
2676 getRootPane().getActionMap().put("Quit", new AbstractAction()
2679 public void actionPerformed(ActionEvent e)
2687 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2690 * true if Groovy console is open
2692 public void enableExecuteGroovy(boolean enabled)
2695 * disable opening a second Groovy console
2696 * (or re-enable when the console is closed)
2698 groovyShell.setEnabled(!enabled);
2700 AlignFrame[] alignFrames = getAlignFrames();
2701 if (alignFrames != null)
2703 for (AlignFrame af : alignFrames)
2705 af.setGroovyEnabled(enabled);
2711 * Progress bars managed by the IProgressIndicator method.
2713 private Hashtable<Long, JPanel> progressBars;
2715 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2720 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2723 public void setProgressBar(String message, long id)
2725 if (progressBars == null)
2727 progressBars = new Hashtable<>();
2728 progressBarHandlers = new Hashtable<>();
2731 if (progressBars.get(new Long(id)) != null)
2733 JPanel panel = progressBars.remove(new Long(id));
2734 if (progressBarHandlers.contains(new Long(id)))
2736 progressBarHandlers.remove(new Long(id));
2738 removeProgressPanel(panel);
2742 progressBars.put(new Long(id), addProgressPanel(message));
2749 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2750 * jalview.gui.IProgressIndicatorHandler)
2753 public void registerHandler(final long id,
2754 final IProgressIndicatorHandler handler)
2756 if (progressBarHandlers == null
2757 || !progressBars.containsKey(new Long(id)))
2759 throw new Error(MessageManager.getString(
2760 "error.call_setprogressbar_before_registering_handler"));
2762 progressBarHandlers.put(new Long(id), handler);
2763 final JPanel progressPanel = progressBars.get(new Long(id));
2764 if (handler.canCancel())
2766 JButton cancel = new JButton(
2767 MessageManager.getString("action.cancel"));
2768 final IProgressIndicator us = this;
2769 cancel.addActionListener(new ActionListener()
2773 public void actionPerformed(ActionEvent e)
2775 handler.cancelActivity(id);
2776 us.setProgressBar(MessageManager
2777 .formatMessage("label.cancelled_params", new Object[]
2778 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2782 progressPanel.add(cancel, BorderLayout.EAST);
2788 * @return true if any progress bars are still active
2791 public boolean operationInProgress()
2793 if (progressBars != null && progressBars.size() > 0)
2801 * This will return the first AlignFrame holding the given viewport instance.
2802 * It will break if there are more than one AlignFrames viewing a particular
2806 * @return alignFrame for viewport
2808 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2810 if (desktop != null)
2812 AlignmentPanel[] aps = getAlignmentPanels(
2813 viewport.getSequenceSetId());
2814 for (int panel = 0; aps != null && panel < aps.length; panel++)
2816 if (aps[panel] != null && aps[panel].av == viewport)
2818 return aps[panel].alignFrame;
2825 public VamsasApplication getVamsasApplication()
2832 * flag set if jalview GUI is being operated programmatically
2834 private boolean inBatchMode = false;
2837 * check if jalview GUI is being operated programmatically
2839 * @return inBatchMode
2841 public boolean isInBatchMode()
2847 * set flag if jalview GUI is being operated programmatically
2849 * @param inBatchMode
2851 public void setInBatchMode(boolean inBatchMode)
2853 this.inBatchMode = inBatchMode;
2856 public void startServiceDiscovery()
2858 startServiceDiscovery(false);
2861 public void startServiceDiscovery(boolean blocking)
2863 boolean alive = true;
2864 Thread t0 = null, t1 = null, t2 = null;
2865 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2868 // todo: changesupport handlers need to be transferred
2869 if (discoverer == null)
2871 discoverer = new jalview.ws.jws1.Discoverer();
2872 // register PCS handler for desktop.
2873 discoverer.addPropertyChangeListener(changeSupport);
2875 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2876 // until we phase out completely
2877 (t0 = new Thread(discoverer)).start();
2880 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2882 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2883 .startDiscoverer(changeSupport);
2887 // TODO: do rest service discovery
2896 } catch (Exception e)
2899 alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
2900 || (t3 != null && t3.isAlive())
2901 || (t0 != null && t0.isAlive());
2907 * called to check if the service discovery process completed successfully.
2911 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2913 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2915 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2916 .getErrorMessages();
2919 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2921 if (serviceChangedDialog == null)
2923 // only run if we aren't already displaying one of these.
2924 addDialogThread(serviceChangedDialog = new Runnable()
2931 * JalviewDialog jd =new JalviewDialog() {
2933 * @Override protected void cancelPressed() { // TODO
2934 * Auto-generated method stub
2936 * }@Override protected void okPressed() { // TODO
2937 * Auto-generated method stub
2939 * }@Override protected void raiseClosed() { // TODO
2940 * Auto-generated method stub
2942 * } }; jd.initDialogFrame(new
2943 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2944 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2945 * + " or mis-configured HTTP proxy settings.<br/>" +
2946 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2948 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2949 * ), true, true, "Web Service Configuration Problem", 450,
2952 * jd.waitForInput();
2954 JvOptionPane.showConfirmDialog(Desktop.desktop,
2955 new JLabel("<html><table width=\"450\"><tr><td>"
2956 + ermsg + "</td></tr></table>"
2957 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2958 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2959 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2960 + " Tools->Preferences dialog box to change them.</p></html>"),
2961 "Web Service Configuration Problem",
2962 JvOptionPane.DEFAULT_OPTION,
2963 JvOptionPane.ERROR_MESSAGE);
2964 serviceChangedDialog = null;
2973 "Errors reported by JABA discovery service. Check web services preferences.\n"
2980 private Runnable serviceChangedDialog = null;
2983 * start a thread to open a URL in the configured browser. Pops up a warning
2984 * dialog to the user if there is an exception when calling out to the browser
2989 public static void showUrl(final String url)
2991 showUrl(url, Desktop.instance);
2995 * Like showUrl but allows progress handler to be specified
2999 * (null) or object implementing IProgressIndicator
3001 public static void showUrl(final String url,
3002 final IProgressIndicator progress)
3004 new Thread(new Runnable()
3011 if (progress != null)
3013 progress.setProgressBar(MessageManager
3014 .formatMessage("status.opening_params", new Object[]
3015 { url }), this.hashCode());
3017 jalview.util.BrowserLauncher.openURL(url);
3018 } catch (Exception ex)
3020 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3022 .getString("label.web_browser_not_found_unix"),
3023 MessageManager.getString("label.web_browser_not_found"),
3024 JvOptionPane.WARNING_MESSAGE);
3026 ex.printStackTrace();
3028 if (progress != null)
3030 progress.setProgressBar(null, this.hashCode());
3036 public static WsParamSetManager wsparamManager = null;
3038 public static ParamManager getUserParameterStore()
3040 if (wsparamManager == null)
3042 wsparamManager = new WsParamSetManager();
3044 return wsparamManager;
3048 * static hyperlink handler proxy method for use by Jalview's internal windows
3052 public static void hyperlinkUpdate(HyperlinkEvent e)
3054 if (e.getEventType() == EventType.ACTIVATED)
3059 url = e.getURL().toString();
3060 Desktop.showUrl(url);
3061 } catch (Exception x)
3065 if (Cache.log != null)
3067 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3072 "Couldn't handle string " + url + " as a URL.");
3075 // ignore any exceptions due to dud links.
3082 * single thread that handles display of dialogs to user.
3084 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3087 * flag indicating if dialogExecutor should try to acquire a permit
3089 private volatile boolean dialogPause = true;
3094 private java.util.concurrent.Semaphore block = new Semaphore(0);
3096 private static groovy.ui.Console groovyConsole;
3099 * add another dialog thread to the queue
3103 public void addDialogThread(final Runnable prompter)
3105 dialogExecutor.submit(new Runnable()
3115 } catch (InterruptedException x)
3120 if (instance == null)
3126 SwingUtilities.invokeAndWait(prompter);
3127 } catch (Exception q)
3129 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3135 public void startDialogQueue()
3137 // set the flag so we don't pause waiting for another permit and semaphore
3138 // the current task to begin
3139 dialogPause = false;
3144 protected void snapShotWindow_actionPerformed(ActionEvent e)
3148 ImageMaker im = new jalview.util.ImageMaker(
3149 this, ImageMaker.TYPE.EPS, "View of Desktop", getWidth(),
3150 getHeight(), of = new File("Jalview_snapshot"
3151 + System.currentTimeMillis() + ".eps"),
3152 "View of desktop", null, 0, false);
3155 paintAll(im.getGraphics());
3157 } catch (Exception q)
3159 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3163 Cache.log.info("Successfully written snapshot to file "
3164 + of.getAbsolutePath());
3168 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3169 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3170 * and location last time the view was expanded (if any). However it does not
3171 * remember the split pane divider location - this is set to match the
3172 * 'exploding' frame.
3176 public void explodeViews(SplitFrame sf)
3178 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3179 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3180 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3182 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3184 int viewCount = topPanels.size();
3191 * Processing in reverse order works, forwards order leaves the first panels
3192 * not visible. I don't know why!
3194 for (int i = viewCount - 1; i >= 0; i--)
3197 * Make new top and bottom frames. These take over the respective
3198 * AlignmentPanel objects, including their AlignmentViewports, so the
3199 * cdna/protein relationships between the viewports is carried over to the
3202 * explodedGeometry holds the (x, y) position of the previously exploded
3203 * SplitFrame, and the (width, height) of the AlignFrame component
3205 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3206 AlignFrame newTopFrame = new AlignFrame(topPanel);
3207 newTopFrame.setSize(oldTopFrame.getSize());
3208 newTopFrame.setVisible(true);
3209 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3210 .getExplodedGeometry();
3211 if (geometry != null)
3213 newTopFrame.setSize(geometry.getSize());
3216 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3217 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3218 newBottomFrame.setSize(oldBottomFrame.getSize());
3219 newBottomFrame.setVisible(true);
3220 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3221 .getExplodedGeometry();
3222 if (geometry != null)
3224 newBottomFrame.setSize(geometry.getSize());
3227 topPanel.av.setGatherViewsHere(false);
3228 bottomPanel.av.setGatherViewsHere(false);
3229 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3231 if (geometry != null)
3233 splitFrame.setLocation(geometry.getLocation());
3235 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3239 * Clear references to the panels (now relocated in the new SplitFrames)
3240 * before closing the old SplitFrame.
3243 bottomPanels.clear();
3248 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3249 * back into the given SplitFrame as additional views. Note that the gathered
3250 * frames may themselves have multiple views.
3254 public void gatherViews(GSplitFrame source)
3257 * special handling of explodedGeometry for a view within a SplitFrame: - it
3258 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3259 * height) of the AlignFrame component
3261 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3262 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3263 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3264 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3265 myBottomFrame.viewport
3266 .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
3267 myBottomFrame.getWidth(), myBottomFrame.getHeight()));
3268 myTopFrame.viewport.setGatherViewsHere(true);
3269 myBottomFrame.viewport.setGatherViewsHere(true);
3270 String topViewId = myTopFrame.viewport.getSequenceSetId();
3271 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3273 JInternalFrame[] frames = desktop.getAllFrames();
3274 for (JInternalFrame frame : frames)
3276 if (frame instanceof SplitFrame && frame != source)
3278 SplitFrame sf = (SplitFrame) frame;
3279 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3280 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3281 boolean gatherThis = false;
3282 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3284 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3285 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3286 if (topViewId.equals(topPanel.av.getSequenceSetId())
3287 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3290 topPanel.av.setGatherViewsHere(false);
3291 bottomPanel.av.setGatherViewsHere(false);
3292 topPanel.av.setExplodedGeometry(
3293 new Rectangle(sf.getLocation(), topFrame.getSize()));
3294 bottomPanel.av.setExplodedGeometry(
3295 new Rectangle(sf.getLocation(), bottomFrame.getSize()));
3296 myTopFrame.addAlignmentPanel(topPanel, false);
3297 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3303 topFrame.getAlignPanels().clear();
3304 bottomFrame.getAlignPanels().clear();
3311 * The dust settles...give focus to the tab we did this from.
3313 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3316 public static groovy.ui.Console getGroovyConsole()
3318 return groovyConsole;
3321 public static void transferFromDropTarget(List<String> files,
3322 List<DataSourceType> protocols, DropTargetDropEvent evt,
3323 Transferable t) throws Exception
3326 DataFlavor uriListFlavor = new DataFlavor(
3327 "text/uri-list;class=java.lang.String");
3328 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3330 // Works on Windows and MacOSX
3331 Cache.log.debug("Drop handled as javaFileListFlavor");
3332 for (Object file : (List) t
3333 .getTransferData(DataFlavor.javaFileListFlavor))
3335 files.add(((File) file).toString());
3336 protocols.add(DataSourceType.FILE);
3341 // Unix like behaviour
3342 boolean added = false;
3344 if (t.isDataFlavorSupported(uriListFlavor))
3346 Cache.log.debug("Drop handled as uriListFlavor");
3347 // This is used by Unix drag system
3348 data = (String) t.getTransferData(uriListFlavor);
3352 // fallback to text: workaround - on OSX where there's a JVM bug
3353 Cache.log.debug("standard URIListFlavor failed. Trying text");
3354 // try text fallback
3355 data = (String) t.getTransferData(
3356 new DataFlavor("text/plain;class=java.lang.String"));
3357 if (Cache.log.isDebugEnabled())
3359 Cache.log.debug("fallback returned " + data);
3362 while (protocols.size() < files.size())
3364 Cache.log.debug("Adding missing FILE protocol for "
3365 + files.get(protocols.size()));
3366 protocols.add(DataSourceType.FILE);
3368 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3369 data, "\r\n"); st.hasMoreTokens();)
3372 String s = st.nextToken();
3373 if (s.startsWith("#"))
3375 // the line is a comment (as per the RFC 2483)
3378 java.net.URI uri = new java.net.URI(s);
3379 if (uri.getScheme().toLowerCase().startsWith("http"))
3381 protocols.add(DataSourceType.URL);
3382 files.add(uri.toString());
3386 // otherwise preserve old behaviour: catch all for file objects
3387 java.io.File file = new java.io.File(uri);
3388 protocols.add(DataSourceType.FILE);
3389 files.add(file.toString());
3392 if (Cache.log.isDebugEnabled())
3394 if (data == null || !added)
3397 "Couldn't resolve drop data. Here are the supported flavors:");
3398 for (DataFlavor fl : t.getTransferDataFlavors())
3401 "Supported transfer dataflavor: " + fl.toString());
3402 Object df = t.getTransferData(fl);
3405 Cache.log.debug("Retrieves: " + df);
3409 Cache.log.debug("Retrieved nothing");
3418 * Sets the Preferences property for experimental features to True or False
3419 * depending on the state of the controlling menu item
3422 protected void showExperimental_actionPerformed(boolean selected)
3424 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));