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())));
366 Rectangle dims = getLastKnownDimensions("");
373 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
374 setBounds((screenSize.width - 900) / 2, (screenSize.height - 650) / 2,
377 jconsole = new Console(this, showjconsole);
378 // add essential build information
380 "Jalview Version: " + jalview.bin.Cache.getProperty("VERSION")
381 + "\n" + "Jalview Installation: "
382 + jalview.bin.Cache.getDefault("INSTALLATION",
384 + "\n" + "Build Date: "
385 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
386 + "\n" + "Java version: "
387 + System.getProperty("java.version") + "\n"
388 + System.getProperty("os.arch") + " "
389 + System.getProperty("os.name") + " "
390 + System.getProperty("os.version"));
392 showConsole(showjconsole);
394 showNews.setVisible(false);
396 experimentalFeatures.setSelected(showExperimental());
398 getIdentifiersOrgData();
402 this.addWindowListener(new WindowAdapter()
405 public void windowClosing(WindowEvent evt)
412 this.addMouseListener(ma = new MouseAdapter()
415 public void mousePressed(MouseEvent evt)
417 if (evt.isPopupTrigger()) // Mac
419 showPasteMenu(evt.getX(), evt.getY());
424 public void mouseReleased(MouseEvent evt)
426 if (evt.isPopupTrigger()) // Windows
428 showPasteMenu(evt.getX(), evt.getY());
432 desktop.addMouseListener(ma);
434 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
435 // Spawn a thread that shows the splashscreen
436 SwingUtilities.invokeLater(new Runnable()
445 // Thread off a new instance of the file chooser - this reduces the time it
446 // takes to open it later on.
447 new Thread(new Runnable()
452 Cache.log.debug("Filechooser init thread started.");
453 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
454 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
456 Cache.log.debug("Filechooser init thread finished.");
459 // Add the service change listener
460 changeSupport.addJalviewPropertyChangeListener("services",
461 new PropertyChangeListener()
465 public void propertyChange(PropertyChangeEvent evt)
467 Cache.log.debug("Firing service changed event for "
468 + evt.getNewValue());
469 JalviewServicesChanged(evt);
476 * Answers true if user preferences to enable experimental features is True
481 public boolean showExperimental()
483 String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
484 Boolean.FALSE.toString());
485 return Boolean.valueOf(experimental).booleanValue();
488 public void doConfigureStructurePrefs()
490 // configure services
491 StructureSelectionManager ssm = StructureSelectionManager
492 .getStructureSelectionManager(this);
493 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
495 ssm.setAddTempFacAnnot(jalview.bin.Cache
496 .getDefault(Preferences.ADD_TEMPFACT_ANN, true));
497 ssm.setProcessSecondaryStructure(jalview.bin.Cache
498 .getDefault(Preferences.STRUCT_FROM_PDB, true));
499 ssm.setSecStructServices(
500 jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW, true));
504 ssm.setAddTempFacAnnot(false);
505 ssm.setProcessSecondaryStructure(false);
506 ssm.setSecStructServices(false);
510 public void checkForNews()
512 final Desktop me = this;
513 // Thread off the news reader, in case there are connection problems.
514 addDialogThread(new Runnable()
519 Cache.log.debug("Starting news thread.");
521 jvnews = new BlogReader(me);
522 showNews.setVisible(true);
523 Cache.log.debug("Completed news thread.");
528 public void getIdentifiersOrgData()
530 // Thread off the identifiers fetcher
531 addDialogThread(new Runnable()
536 Cache.log.debug("Downloading data from identifiers.org");
537 UrlDownloadClient client = new UrlDownloadClient();
540 client.download(IdOrgSettings.getUrl(),
541 IdOrgSettings.getDownloadLocation());
542 } catch (IOException e)
544 Cache.log.debug("Exception downloading identifiers.org data"
552 protected void showNews_actionPerformed(ActionEvent e)
554 showNews(showNews.isSelected());
557 void showNews(boolean visible)
560 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
561 showNews.setSelected(visible);
562 if (visible && !jvnews.isVisible())
564 new Thread(new Runnable()
569 long now = System.currentTimeMillis();
570 Desktop.instance.setProgressBar(
571 MessageManager.getString("status.refreshing_news"),
573 jvnews.refreshNews();
574 Desktop.instance.setProgressBar(null, now);
583 * recover the last known dimensions for a jalview window
586 * - empty string is desktop, all other windows have unique prefix
587 * @return null or last known dimensions scaled to current geometry (if last
588 * window geom was known)
590 Rectangle getLastKnownDimensions(String windowName)
592 // TODO: lock aspect ratio for scaling desktop Bug #0058199
593 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
594 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
595 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
596 String width = jalview.bin.Cache
597 .getProperty(windowName + "SCREEN_WIDTH");
598 String height = jalview.bin.Cache
599 .getProperty(windowName + "SCREEN_HEIGHT");
600 if ((x != null) && (y != null) && (width != null) && (height != null))
602 int ix = Integer.parseInt(x), iy = Integer.parseInt(y),
603 iw = Integer.parseInt(width), ih = Integer.parseInt(height);
604 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
606 // attempt #1 - try to cope with change in screen geometry - this
607 // version doesn't preserve original jv aspect ratio.
608 // take ratio of current screen size vs original screen size.
609 double sw = ((1f * screenSize.width) / (1f * Integer.parseInt(
610 jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
611 double sh = ((1f * screenSize.height) / (1f * Integer.parseInt(
612 jalview.bin.Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
613 // rescale the bounds depending upon the current screen geometry.
614 ix = (int) (ix * sw);
615 iw = (int) (iw * sw);
616 iy = (int) (iy * sh);
617 ih = (int) (ih * sh);
618 while (ix >= screenSize.width)
620 jalview.bin.Cache.log.debug(
621 "Window geometry location recall error: shifting horizontal to within screenbounds.");
622 ix -= screenSize.width;
624 while (iy >= screenSize.height)
626 jalview.bin.Cache.log.debug(
627 "Window geometry location recall error: shifting vertical to within screenbounds.");
628 iy -= screenSize.height;
630 jalview.bin.Cache.log.debug(
631 "Got last known dimensions for " + windowName + ": x:" + ix
632 + " y:" + iy + " width:" + iw + " height:" + ih);
634 // return dimensions for new instance
635 return new Rectangle(ix, iy, iw, ih);
640 private void doVamsasClientCheck()
642 if (jalview.bin.Cache.vamsasJarsPresent())
644 setupVamsasDisconnectedGui();
645 VamsasMenu.setVisible(true);
646 final Desktop us = this;
647 VamsasMenu.addMenuListener(new MenuListener()
649 // this listener remembers when the menu was first selected, and
650 // doesn't rebuild the session list until it has been cleared and
652 boolean refresh = true;
655 public void menuCanceled(MenuEvent e)
661 public void menuDeselected(MenuEvent e)
667 public void menuSelected(MenuEvent e)
671 us.buildVamsasStMenu();
676 vamsasStart.setVisible(true);
680 void showPasteMenu(int x, int y)
682 JPopupMenu popup = new JPopupMenu();
683 JMenuItem item = new JMenuItem(
684 MessageManager.getString("label.paste_new_window"));
685 item.addActionListener(new ActionListener()
688 public void actionPerformed(ActionEvent evt)
695 popup.show(this, x, y);
702 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
703 Transferable contents = c.getContents(this);
705 if (contents != null)
707 String file = (String) contents
708 .getTransferData(DataFlavor.stringFlavor);
710 FileFormatI format = new IdentifyFile().identify(file,
711 DataSourceType.PASTE);
713 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
716 } catch (Exception ex)
719 "Unable to paste alignment from system clipboard:\n" + ex);
724 * Adds and opens the given frame to the desktop
735 public static synchronized void addInternalFrame(
736 final JInternalFrame frame, String title, int w, int h)
738 addInternalFrame(frame, title, true, w, h, true, false);
742 * Add an internal frame to the Jalview desktop
749 * When true, display frame immediately, otherwise, caller must call
750 * setVisible themselves.
756 public static synchronized void addInternalFrame(
757 final JInternalFrame frame, String title, boolean makeVisible,
760 addInternalFrame(frame, title, makeVisible, w, h, true, false);
764 * Add an internal frame to the Jalview desktop and make it visible
777 public static synchronized void addInternalFrame(
778 final JInternalFrame frame, String title, int w, int h,
781 addInternalFrame(frame, title, true, w, h, resizable, false);
785 * Add an internal frame to the Jalview desktop
792 * When true, display frame immediately, otherwise, caller must call
793 * setVisible themselves.
800 * @param ignoreMinSize
801 * Do not set the default minimum size for frame
803 public static synchronized void addInternalFrame(
804 final JInternalFrame frame, String title, boolean makeVisible,
805 int w, int h, boolean resizable, boolean ignoreMinSize)
808 // TODO: allow callers to determine X and Y position of frame (eg. via
810 // TODO: consider fixing method to update entries in the window submenu with
811 // the current window title
813 frame.setTitle(title);
814 if (frame.getWidth() < 1 || frame.getHeight() < 1)
818 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
819 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
820 // IF JALVIEW IS RUNNING HEADLESS
821 // ///////////////////////////////////////////////
822 if (instance == null || (System.getProperty("java.awt.headless") != null
823 && System.getProperty("java.awt.headless").equals("true")))
832 frame.setMinimumSize(
833 new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
835 // Set default dimension for Alignment Frame window.
836 // The Alignment Frame window could be added from a number of places,
838 // I did this here in order not to miss out on any Alignment frame.
839 if (frame instanceof AlignFrame)
841 frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
842 ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
846 frame.setVisible(makeVisible);
847 frame.setClosable(true);
848 frame.setResizable(resizable);
849 frame.setMaximizable(resizable);
850 frame.setIconifiable(resizable);
852 if (frame.getX() < 1 && frame.getY() < 1)
854 frame.setLocation(xOffset * openFrameCount,
855 yOffset * ((openFrameCount - 1) % 10) + yOffset);
859 * add an entry for the new frame in the Window menu
860 * (and remove it when the frame is closed)
862 final JMenuItem menuItem = new JMenuItem(title);
863 frame.addInternalFrameListener(new InternalFrameAdapter()
866 public void internalFrameActivated(InternalFrameEvent evt)
868 JInternalFrame itf = desktop.getSelectedFrame();
871 if (itf instanceof AlignFrame)
873 Jalview.setCurrentAlignFrame((AlignFrame) itf);
880 public void internalFrameClosed(InternalFrameEvent evt)
882 PaintRefresher.RemoveComponent(frame);
885 * defensive check to prevent frames being
886 * added half off the window
888 if (openFrameCount > 0)
894 * ensure no reference to alignFrame retained by menu item listener
896 if (menuItem.getActionListeners().length > 0)
898 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
900 windowMenu.remove(menuItem);
901 JInternalFrame itf = desktop.getSelectedFrame();
904 // itf.requestFocus();
911 menuItem.addActionListener(new ActionListener()
914 public void actionPerformed(ActionEvent e)
918 frame.setSelected(true);
919 frame.setIcon(false);
920 } catch (java.beans.PropertyVetoException ex)
929 windowMenu.add(menuItem);
934 frame.setSelected(true);
935 frame.requestFocus();
936 } catch (java.beans.PropertyVetoException ve)
938 } catch (java.lang.ClassCastException cex)
941 "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
947 public void lostOwnership(Clipboard clipboard, Transferable contents)
951 Desktop.jalviewClipboard = null;
954 internalCopy = false;
958 public void dragEnter(DropTargetDragEvent evt)
963 public void dragExit(DropTargetEvent evt)
968 public void dragOver(DropTargetDragEvent evt)
973 public void dropActionChanged(DropTargetDragEvent evt)
984 public void drop(DropTargetDropEvent evt)
986 boolean success = true;
987 // JAL-1552 - acceptDrop required before getTransferable call for
988 // Java's Transferable for native dnd
989 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
990 Transferable t = evt.getTransferable();
991 List<String> files = new ArrayList<>();
992 List<DataSourceType> protocols = new ArrayList<>();
996 Desktop.transferFromDropTarget(files, protocols, evt, t);
997 } catch (Exception e)
1007 for (int i = 0; i < files.size(); i++)
1009 String file = files.get(i).toString();
1010 DataSourceType protocol = (protocols == null)
1011 ? DataSourceType.FILE
1013 FileFormatI format = null;
1015 if (file.endsWith(".jar"))
1017 format = FileFormat.Jalview;
1022 format = new IdentifyFile().identify(file, protocol);
1025 new FileLoader().LoadFile(file, protocol, format);
1028 } catch (Exception ex)
1033 evt.dropComplete(success); // need this to ensure input focus is properly
1034 // transfered to any new windows created
1044 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1046 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1047 JalviewFileChooser chooser = JalviewFileChooser
1048 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1050 chooser.setFileView(new JalviewFileView());
1051 chooser.setDialogTitle(
1052 MessageManager.getString("label.open_local_file"));
1053 chooser.setToolTipText(MessageManager.getString("action.open"));
1055 int value = chooser.showOpenDialog(this);
1057 if (value == JalviewFileChooser.APPROVE_OPTION)
1059 String choice = chooser.getSelectedFile().getPath();
1060 Cache.setProperty("LAST_DIRECTORY",
1061 chooser.getSelectedFile().getParent());
1063 FileFormatI format = chooser.getSelectedFormat();
1066 * Call IdentifyFile to verify the file contains what its extension implies.
1067 * Skip this step for dynamically added file formats, because
1068 * IdentifyFile does not know how to recognise them.
1070 if (FileFormats.getInstance().isIdentifiable(format))
1074 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1075 } catch (FileFormatException e)
1077 // format = null; //??
1081 if (viewport != null)
1083 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1088 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1100 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1102 // This construct allows us to have a wider textfield
1104 JLabel label = new JLabel(
1105 MessageManager.getString("label.input_file_url"));
1106 final JComboBox history = new JComboBox();
1108 JPanel panel = new JPanel(new GridLayout(2, 1));
1111 history.setPreferredSize(new Dimension(400, 20));
1112 history.setEditable(true);
1113 history.addItem("http://www.");
1115 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1119 if (historyItems != null)
1121 st = new StringTokenizer(historyItems, "\t");
1123 while (st.hasMoreTokens())
1125 history.addItem(st.nextElement());
1129 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1130 MessageManager.getString("label.input_alignment_from_url"),
1131 JvOptionPane.OK_CANCEL_OPTION);
1133 if (reply != JvOptionPane.OK_OPTION)
1138 String url = history.getSelectedItem().toString();
1140 if (url.toLowerCase().endsWith(".jar"))
1142 if (viewport != null)
1144 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1145 FileFormat.Jalview);
1149 new FileLoader().LoadFile(url, DataSourceType.URL,
1150 FileFormat.Jalview);
1155 FileFormatI format = null;
1158 format = new IdentifyFile().identify(url, DataSourceType.URL);
1159 } catch (FileFormatException e)
1161 // TODO revise error handling, distinguish between
1162 // URL not found and response not valid
1167 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1168 MessageManager.formatMessage("label.couldnt_locate",
1171 MessageManager.getString("label.url_not_found"),
1172 JvOptionPane.WARNING_MESSAGE);
1177 if (viewport != null)
1179 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1184 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1190 * Opens the CutAndPaste window for the user to paste an alignment in to
1193 * - if not null, the pasted alignment is added to the current
1194 * alignment; if null, to a new alignment window
1197 public void inputTextboxMenuItem_actionPerformed(
1198 AlignmentViewPanel viewPanel)
1200 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1201 cap.setForInput(viewPanel);
1202 Desktop.addInternalFrame(cap,
1203 MessageManager.getString("label.cut_paste_alignmen_file"), true,
1213 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1214 jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH",
1216 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT",
1217 screen.height + "");
1218 storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
1219 getWidth(), getHeight()));
1221 if (jconsole != null)
1223 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1224 jconsole.stopConsole();
1228 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1231 if (dialogExecutor != null)
1233 dialogExecutor.shutdownNow();
1235 closeAll_actionPerformed(null);
1237 if (groovyConsole != null)
1239 // suppress a possible repeat prompt to save script
1240 groovyConsole.setDirty(false);
1241 groovyConsole.exit();
1246 private void storeLastKnownDimensions(String string, Rectangle jc)
1248 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1249 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1250 + " height:" + jc.height);
1252 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1253 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1254 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1255 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1265 public void aboutMenuItem_actionPerformed(ActionEvent e)
1267 // StringBuffer message = getAboutMessage(false);
1268 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1270 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1271 new Thread(new Runnable()
1276 new SplashScreen(true);
1281 public StringBuffer getAboutMessage(boolean shortv)
1283 StringBuffer message = new StringBuffer();
1284 message.append("<html>");
1287 message.append("<h1><strong>Version: "
1288 + jalview.bin.Cache.getProperty("VERSION")
1289 + "</strong></h1>");
1290 message.append("<strong>Last Updated: <em>"
1291 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1292 + "</em></strong>");
1298 message.append("<strong>Version "
1299 + jalview.bin.Cache.getProperty("VERSION")
1300 + "; last updated: "
1301 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1304 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1305 .equals("Checking"))
1307 message.append("<br>...Checking latest version...</br>");
1309 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1310 .equals(jalview.bin.Cache.getProperty("VERSION")))
1312 boolean red = false;
1313 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1314 .indexOf("automated build") == -1)
1317 // Displayed when code version and jnlp version do not match and code
1318 // version is not a development build
1319 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1322 message.append("<br>!! Version "
1323 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1325 + " is available for download from "
1326 + jalview.bin.Cache.getDefault("www.jalview.org",
1327 "http://www.jalview.org")
1331 message.append("</div>");
1334 message.append("<br>Authors: " + jalview.bin.Cache.getDefault(
1336 "The Jalview Authors (See AUTHORS file for current list)")
1337 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1338 + "<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"
1339 + "<br><br>If you use Jalview, please cite:"
1340 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1341 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1342 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1354 public void documentationMenuItem_actionPerformed(ActionEvent e)
1358 Help.showHelpWindow();
1359 } catch (Exception ex)
1365 public void closeAll_actionPerformed(ActionEvent e)
1367 // TODO show a progress bar while closing?
1368 JInternalFrame[] frames = desktop.getAllFrames();
1369 for (int i = 0; i < frames.length; i++)
1373 frames[i].setClosed(true);
1374 } catch (java.beans.PropertyVetoException ex)
1378 Jalview.setCurrentAlignFrame(null);
1379 System.out.println("ALL CLOSED");
1380 if (v_client != null)
1382 // TODO clear binding to vamsas document objects on close_all
1386 * reset state of singleton objects as appropriate (clear down session state
1387 * when all windows are closed)
1389 StructureSelectionManager ssm = StructureSelectionManager
1390 .getStructureSelectionManager(this);
1399 public void raiseRelated_actionPerformed(ActionEvent e)
1401 reorderAssociatedWindows(false, false);
1405 public void minimizeAssociated_actionPerformed(ActionEvent e)
1407 reorderAssociatedWindows(true, false);
1410 void closeAssociatedWindows()
1412 reorderAssociatedWindows(false, true);
1418 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1422 protected void garbageCollect_actionPerformed(ActionEvent e)
1424 // We simply collect the garbage
1425 jalview.bin.Cache.log.debug("Collecting garbage...");
1427 jalview.bin.Cache.log.debug("Finished garbage collection.");
1434 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1438 protected void showMemusage_actionPerformed(ActionEvent e)
1440 desktop.showMemoryUsage(showMemusage.isSelected());
1447 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1451 protected void showConsole_actionPerformed(ActionEvent e)
1453 showConsole(showConsole.isSelected());
1456 Console jconsole = null;
1459 * control whether the java console is visible or not
1463 void showConsole(boolean selected)
1465 showConsole.setSelected(selected);
1466 // TODO: decide if we should update properties file
1467 Cache.setProperty("SHOW_JAVA_CONSOLE",
1468 Boolean.valueOf(selected).toString());
1469 jconsole.setVisible(selected);
1472 void reorderAssociatedWindows(boolean minimize, boolean close)
1474 JInternalFrame[] frames = desktop.getAllFrames();
1475 if (frames == null || frames.length < 1)
1480 AlignmentViewport source = null, target = null;
1481 if (frames[0] instanceof AlignFrame)
1483 source = ((AlignFrame) frames[0]).getCurrentView();
1485 else if (frames[0] instanceof TreePanel)
1487 source = ((TreePanel) frames[0]).getViewPort();
1489 else if (frames[0] instanceof PCAPanel)
1491 source = ((PCAPanel) frames[0]).av;
1493 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1495 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1500 for (int i = 0; i < frames.length; i++)
1503 if (frames[i] == null)
1507 if (frames[i] instanceof AlignFrame)
1509 target = ((AlignFrame) frames[i]).getCurrentView();
1511 else if (frames[i] instanceof TreePanel)
1513 target = ((TreePanel) frames[i]).getViewPort();
1515 else if (frames[i] instanceof PCAPanel)
1517 target = ((PCAPanel) frames[i]).av;
1519 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1521 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1524 if (source == target)
1530 frames[i].setClosed(true);
1534 frames[i].setIcon(minimize);
1537 frames[i].toFront();
1541 } catch (java.beans.PropertyVetoException ex)
1556 protected void preferences_actionPerformed(ActionEvent e)
1568 public void saveState_actionPerformed(ActionEvent e)
1570 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1573 chooser.setFileView(new JalviewFileView());
1574 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1576 int value = chooser.showSaveDialog(this);
1578 if (value == JalviewFileChooser.APPROVE_OPTION)
1580 final Desktop me = this;
1581 final java.io.File choice = chooser.getSelectedFile();
1582 setProjectFile(choice);
1584 new Thread(new Runnable()
1589 // TODO: refactor to Jalview desktop session controller action.
1590 setProgressBar(MessageManager.formatMessage(
1591 "label.saving_jalview_project", new Object[]
1592 { choice.getName() }), choice.hashCode());
1593 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1594 choice.getParent());
1595 // TODO catch and handle errors for savestate
1596 // TODO prevent user from messing with the Desktop whilst we're saving
1599 new Jalview2XML().saveState(choice);
1600 } catch (OutOfMemoryError oom)
1603 "Whilst saving current state to " + choice.getName(),
1605 } catch (Exception ex)
1608 "Problems whilst trying to save to " + choice.getName(),
1610 JvOptionPane.showMessageDialog(me,
1611 MessageManager.formatMessage(
1612 "label.error_whilst_saving_current_state_to",
1614 { choice.getName() }),
1615 MessageManager.getString("label.couldnt_save_project"),
1616 JvOptionPane.WARNING_MESSAGE);
1618 setProgressBar(null, choice.hashCode());
1624 private void setProjectFile(File choice)
1626 this.projectFile = choice;
1629 public File getProjectFile()
1631 return this.projectFile;
1641 public void loadState_actionPerformed(ActionEvent e)
1643 JalviewFileChooser chooser = new JalviewFileChooser(
1644 Cache.getProperty("LAST_DIRECTORY"), new String[]
1647 { "Jalview Project", "Jalview Project (old)" },
1649 chooser.setFileView(new JalviewFileView());
1650 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1652 int value = chooser.showOpenDialog(this);
1654 if (value == JalviewFileChooser.APPROVE_OPTION)
1656 final File selectedFile = chooser.getSelectedFile();
1657 setProjectFile(selectedFile);
1658 final String choice = selectedFile.getAbsolutePath();
1659 Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1660 new Thread(new Runnable()
1665 setProgressBar(MessageManager.formatMessage(
1666 "label.loading_jalview_project", new Object[]
1667 { choice }), choice.hashCode());
1670 new Jalview2XML().loadJalviewAlign(choice);
1671 } catch (OutOfMemoryError oom)
1673 new OOMWarning("Whilst loading project from " + choice, oom);
1674 } catch (Exception ex)
1677 "Problems whilst loading project from " + choice, ex);
1678 JvOptionPane.showMessageDialog(Desktop.desktop,
1679 MessageManager.formatMessage(
1680 "label.error_whilst_loading_project_from",
1683 MessageManager.getString("label.couldnt_load_project"),
1684 JvOptionPane.WARNING_MESSAGE);
1686 setProgressBar(null, choice.hashCode());
1693 public void inputSequence_actionPerformed(ActionEvent e)
1695 new SequenceFetcher(this);
1698 JPanel progressPanel;
1700 ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
1702 public void startLoading(final String fileName)
1704 if (fileLoadingCount == 0)
1706 fileLoadingPanels.add(addProgressPanel(MessageManager
1707 .formatMessage("label.loading_file", new Object[]
1713 private JPanel addProgressPanel(String string)
1715 if (progressPanel == null)
1717 progressPanel = new JPanel(new GridLayout(1, 1));
1718 totalProgressCount = 0;
1719 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1721 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1722 JProgressBar progressBar = new JProgressBar();
1723 progressBar.setIndeterminate(true);
1725 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1727 thisprogress.add(progressBar, BorderLayout.CENTER);
1728 progressPanel.add(thisprogress);
1729 ((GridLayout) progressPanel.getLayout()).setRows(
1730 ((GridLayout) progressPanel.getLayout()).getRows() + 1);
1731 ++totalProgressCount;
1732 instance.validate();
1733 return thisprogress;
1736 int totalProgressCount = 0;
1738 private void removeProgressPanel(JPanel progbar)
1740 if (progressPanel != null)
1742 synchronized (progressPanel)
1744 progressPanel.remove(progbar);
1745 GridLayout gl = (GridLayout) progressPanel.getLayout();
1746 gl.setRows(gl.getRows() - 1);
1747 if (--totalProgressCount < 1)
1749 this.getContentPane().remove(progressPanel);
1750 progressPanel = null;
1757 public void stopLoading()
1760 if (fileLoadingCount < 1)
1762 while (fileLoadingPanels.size() > 0)
1764 removeProgressPanel(fileLoadingPanels.remove(0));
1766 fileLoadingPanels.clear();
1767 fileLoadingCount = 0;
1772 public static int getViewCount(String alignmentId)
1774 AlignmentViewport[] aps = getViewports(alignmentId);
1775 return (aps == null) ? 0 : aps.length;
1780 * @param alignmentId
1781 * - if null, all sets are returned
1782 * @return all AlignmentPanels concerning the alignmentId sequence set
1784 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1786 if (Desktop.desktop == null)
1788 // no frames created and in headless mode
1789 // TODO: verify that frames are recoverable when in headless mode
1792 List<AlignmentPanel> aps = new ArrayList<>();
1793 AlignFrame[] frames = getAlignFrames();
1798 for (AlignFrame af : frames)
1800 for (AlignmentPanel ap : af.alignPanels)
1802 if (alignmentId == null
1803 || alignmentId.equals(ap.av.getSequenceSetId()))
1809 if (aps.size() == 0)
1813 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1818 * get all the viewports on an alignment.
1820 * @param sequenceSetId
1821 * unique alignment id (may be null - all viewports returned in that
1823 * @return all viewports on the alignment bound to sequenceSetId
1825 public static AlignmentViewport[] getViewports(String sequenceSetId)
1827 List<AlignmentViewport> viewp = new ArrayList<>();
1828 if (desktop != null)
1830 AlignFrame[] frames = Desktop.getAlignFrames();
1832 for (AlignFrame afr : frames)
1834 if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
1835 .equals(sequenceSetId))
1837 if (afr.alignPanels != null)
1839 for (AlignmentPanel ap : afr.alignPanels)
1841 if (sequenceSetId == null
1842 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1850 viewp.add(afr.getViewport());
1854 if (viewp.size() > 0)
1856 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1863 * Explode the views in the given frame into separate AlignFrame
1867 public static void explodeViews(AlignFrame af)
1869 int size = af.alignPanels.size();
1875 for (int i = 0; i < size; i++)
1877 AlignmentPanel ap = af.alignPanels.get(i);
1878 AlignFrame newaf = new AlignFrame(ap);
1881 * Restore the view's last exploded frame geometry if known. Multiple
1882 * views from one exploded frame share and restore the same (frame)
1883 * position and size.
1885 Rectangle geometry = ap.av.getExplodedGeometry();
1886 if (geometry != null)
1888 newaf.setBounds(geometry);
1891 ap.av.setGatherViewsHere(false);
1893 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1894 AlignFrame.DEFAULT_HEIGHT);
1897 af.alignPanels.clear();
1898 af.closeMenuItem_actionPerformed(true);
1903 * Gather expanded views (separate AlignFrame's) with the same sequence set
1904 * identifier back in to this frame as additional views, and close the
1905 * expanded views. Note the expanded frames may themselves have multiple
1906 * views. We take the lot.
1910 public void gatherViews(AlignFrame source)
1912 source.viewport.setGatherViewsHere(true);
1913 source.viewport.setExplodedGeometry(source.getBounds());
1914 JInternalFrame[] frames = desktop.getAllFrames();
1915 String viewId = source.viewport.getSequenceSetId();
1917 for (int t = 0; t < frames.length; t++)
1919 if (frames[t] instanceof AlignFrame && frames[t] != source)
1921 AlignFrame af = (AlignFrame) frames[t];
1922 boolean gatherThis = false;
1923 for (int a = 0; a < af.alignPanels.size(); a++)
1925 AlignmentPanel ap = af.alignPanels.get(a);
1926 if (viewId.equals(ap.av.getSequenceSetId()))
1929 ap.av.setGatherViewsHere(false);
1930 ap.av.setExplodedGeometry(af.getBounds());
1931 source.addAlignmentPanel(ap, false);
1937 af.alignPanels.clear();
1938 af.closeMenuItem_actionPerformed(true);
1945 jalview.gui.VamsasApplication v_client = null;
1948 public void vamsasImport_actionPerformed(ActionEvent e)
1950 if (v_client == null)
1952 // Load and try to start a session.
1953 JalviewFileChooser chooser = new JalviewFileChooser(
1954 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1956 chooser.setFileView(new JalviewFileView());
1957 chooser.setDialogTitle(
1958 MessageManager.getString("label.open_saved_vamsas_session"));
1959 chooser.setToolTipText(MessageManager.getString(
1960 "label.select_vamsas_session_opened_as_new_vamsas_session"));
1962 int value = chooser.showOpenDialog(this);
1964 if (value == JalviewFileChooser.APPROVE_OPTION)
1966 String fle = chooser.getSelectedFile().toString();
1967 if (!vamsasImport(chooser.getSelectedFile()))
1969 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1970 MessageManager.formatMessage(
1971 "label.couldnt_import_as_vamsas_session",
1975 .getString("label.vamsas_document_import_failed"),
1976 JvOptionPane.ERROR_MESSAGE);
1982 jalview.bin.Cache.log.error(
1983 "Implementation error - load session from a running session is not supported.");
1988 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1991 * @return true if import was a success and a session was started.
1993 public boolean vamsasImport(URL url)
1995 // TODO: create progress bar
1996 if (v_client != null)
1999 jalview.bin.Cache.log.error(
2000 "Implementation error - load session from a running session is not supported.");
2006 // copy the URL content to a temporary local file
2007 // TODO: be a bit cleverer here with nio (?!)
2008 File file = File.createTempFile("vdocfromurl", ".vdj");
2009 FileOutputStream fos = new FileOutputStream(file);
2010 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2011 byte[] buffer = new byte[2048];
2013 while ((ln = bis.read(buffer)) > -1)
2015 fos.write(buffer, 0, ln);
2019 v_client = new jalview.gui.VamsasApplication(this, file,
2020 url.toExternalForm());
2021 } catch (Exception ex)
2023 jalview.bin.Cache.log.error(
2024 "Failed to create new vamsas session from contents of URL "
2029 setupVamsasConnectedGui();
2030 v_client.initial_update(); // TODO: thread ?
2031 return v_client.inSession();
2035 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2038 * @return true if import was a success and a session was started.
2040 public boolean vamsasImport(File file)
2042 if (v_client != null)
2045 jalview.bin.Cache.log.error(
2046 "Implementation error - load session from a running session is not supported.");
2050 setProgressBar(MessageManager.formatMessage(
2051 "status.importing_vamsas_session_from", new Object[]
2052 { file.getName() }), file.hashCode());
2055 v_client = new jalview.gui.VamsasApplication(this, file, null);
2056 } catch (Exception ex)
2058 setProgressBar(MessageManager.formatMessage(
2059 "status.importing_vamsas_session_from", new Object[]
2060 { file.getName() }), file.hashCode());
2061 jalview.bin.Cache.log.error(
2062 "New vamsas session from existing session file failed:", ex);
2065 setupVamsasConnectedGui();
2066 v_client.initial_update(); // TODO: thread ?
2067 setProgressBar(MessageManager.formatMessage(
2068 "status.importing_vamsas_session_from", new Object[]
2069 { file.getName() }), file.hashCode());
2070 return v_client.inSession();
2073 public boolean joinVamsasSession(String mysesid)
2075 if (v_client != null)
2077 throw new Error(MessageManager
2078 .getString("error.try_join_vamsas_session_another"));
2080 if (mysesid == null)
2083 MessageManager.getString("error.invalid_vamsas_session_id"));
2085 v_client = new VamsasApplication(this, mysesid);
2086 setupVamsasConnectedGui();
2087 v_client.initial_update();
2088 return (v_client.inSession());
2092 public void vamsasStart_actionPerformed(ActionEvent e)
2094 if (v_client == null)
2097 // we just start a default session for moment.
2099 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2100 * getProperty("LAST_DIRECTORY"));
2102 * chooser.setFileView(new JalviewFileView());
2103 * chooser.setDialogTitle("Load Vamsas file");
2104 * chooser.setToolTipText("Import");
2106 * int value = chooser.showOpenDialog(this);
2108 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2109 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2111 v_client = new VamsasApplication(this);
2112 setupVamsasConnectedGui();
2113 v_client.initial_update(); // TODO: thread ?
2117 // store current data in session.
2118 v_client.push_update(); // TODO: thread
2122 protected void setupVamsasConnectedGui()
2124 vamsasStart.setText(MessageManager.getString("label.session_update"));
2125 vamsasSave.setVisible(true);
2126 vamsasStop.setVisible(true);
2127 vamsasImport.setVisible(false); // Document import to existing session is
2128 // not possible for vamsas-client-1.0.
2131 protected void setupVamsasDisconnectedGui()
2133 vamsasSave.setVisible(false);
2134 vamsasStop.setVisible(false);
2135 vamsasImport.setVisible(true);
2137 .setText(MessageManager.getString("label.new_vamsas_session"));
2141 public void vamsasStop_actionPerformed(ActionEvent e)
2143 if (v_client != null)
2145 v_client.end_session();
2147 setupVamsasDisconnectedGui();
2151 protected void buildVamsasStMenu()
2153 if (v_client == null)
2155 String[] sess = null;
2158 sess = VamsasApplication.getSessionList();
2159 } catch (Exception e)
2161 jalview.bin.Cache.log.warn("Problem getting current sessions list.",
2167 jalview.bin.Cache.log.debug(
2168 "Got current sessions list: " + sess.length + " entries.");
2169 VamsasStMenu.removeAll();
2170 for (int i = 0; i < sess.length; i++)
2172 JMenuItem sessit = new JMenuItem();
2173 sessit.setText(sess[i]);
2174 sessit.setToolTipText(MessageManager
2175 .formatMessage("label.connect_to_session", new Object[]
2177 final Desktop dsktp = this;
2178 final String mysesid = sess[i];
2179 sessit.addActionListener(new ActionListener()
2183 public void actionPerformed(ActionEvent e)
2185 if (dsktp.v_client == null)
2187 Thread rthr = new Thread(new Runnable()
2193 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2194 dsktp.setupVamsasConnectedGui();
2195 dsktp.v_client.initial_update();
2203 VamsasStMenu.add(sessit);
2205 // don't show an empty menu.
2206 VamsasStMenu.setVisible(sess.length > 0);
2211 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2212 VamsasStMenu.removeAll();
2213 VamsasStMenu.setVisible(false);
2218 // Not interested in the content. Just hide ourselves.
2219 VamsasStMenu.setVisible(false);
2224 public void vamsasSave_actionPerformed(ActionEvent e)
2226 if (v_client != null)
2228 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2229 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2232 chooser.setFileView(new JalviewFileView());
2233 chooser.setDialogTitle(MessageManager
2234 .getString("label.save_vamsas_document_archive"));
2236 int value = chooser.showSaveDialog(this);
2238 if (value == JalviewFileChooser.APPROVE_OPTION)
2240 java.io.File choice = chooser.getSelectedFile();
2241 JPanel progpanel = addProgressPanel(MessageManager
2242 .formatMessage("label.saving_vamsas_doc", new Object[]
2243 { choice.getName() }));
2244 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2245 String warnmsg = null;
2246 String warnttl = null;
2249 v_client.vclient.storeDocument(choice);
2252 warnttl = "Serious Problem saving Vamsas Document";
2253 warnmsg = ex.toString();
2254 jalview.bin.Cache.log
2255 .error("Error Whilst saving document to " + choice, ex);
2257 } catch (Exception ex)
2259 warnttl = "Problem saving Vamsas Document.";
2260 warnmsg = ex.toString();
2261 jalview.bin.Cache.log.warn(
2262 "Exception Whilst saving document to " + choice, ex);
2265 removeProgressPanel(progpanel);
2266 if (warnmsg != null)
2268 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2270 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2276 JPanel vamUpdate = null;
2279 * hide vamsas user gui bits when a vamsas document event is being handled.
2282 * true to hide gui, false to reveal gui
2284 public void setVamsasUpdate(boolean b)
2286 Cache.log.debug("Setting gui for Vamsas update "
2287 + (b ? "in progress" : "finished"));
2289 if (vamUpdate != null)
2291 this.removeProgressPanel(vamUpdate);
2295 vamUpdate = this.addProgressPanel(
2296 MessageManager.getString("label.updating_vamsas_session"));
2298 vamsasStart.setVisible(!b);
2299 vamsasStop.setVisible(!b);
2300 vamsasSave.setVisible(!b);
2303 public JInternalFrame[] getAllFrames()
2305 return desktop.getAllFrames();
2309 * Checks the given url to see if it gives a response indicating that the user
2310 * should be informed of a new questionnaire.
2314 public void checkForQuestionnaire(String url)
2316 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2317 // javax.swing.SwingUtilities.invokeLater(jvq);
2318 new Thread(jvq).start();
2321 public void checkURLLinks()
2323 // Thread off the URL link checker
2324 addDialogThread(new Runnable()
2329 if (Cache.getDefault("CHECKURLLINKS", true))
2331 // check what the actual links are - if it's just the default don't
2332 // bother with the warning
2333 List<String> links = Preferences.sequenceUrlLinks
2336 // only need to check links if there is one with a
2337 // SEQUENCE_ID which is not the default EMBL_EBI link
2338 ListIterator<String> li = links.listIterator();
2339 boolean check = false;
2340 List<JLabel> urls = new ArrayList<>();
2341 while (li.hasNext())
2343 String link = li.next();
2344 if (link.contains(SEQUENCE_ID)
2345 && !link.equals(UrlConstants.DEFAULT_STRING))
2348 int barPos = link.indexOf("|");
2349 String urlMsg = barPos == -1 ? link
2350 : link.substring(0, barPos) + ": "
2351 + link.substring(barPos + 1);
2352 urls.add(new JLabel(urlMsg));
2360 // ask user to check in case URL links use old style tokens
2361 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2362 JPanel msgPanel = new JPanel();
2363 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2364 msgPanel.add(Box.createVerticalGlue());
2365 JLabel msg = new JLabel(MessageManager
2366 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2367 JLabel msg2 = new JLabel(MessageManager
2368 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2370 for (JLabel url : urls)
2376 final JCheckBox jcb = new JCheckBox(
2377 MessageManager.getString("label.do_not_display_again"));
2378 jcb.addActionListener(new ActionListener()
2381 public void actionPerformed(ActionEvent e)
2383 // update Cache settings for "don't show this again"
2384 boolean showWarningAgain = !jcb.isSelected();
2385 Cache.setProperty("CHECKURLLINKS",
2386 Boolean.valueOf(showWarningAgain).toString());
2391 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2393 .getString("label.SEQUENCE_ID_no_longer_used"),
2394 JvOptionPane.WARNING_MESSAGE);
2401 * Proxy class for JDesktopPane which optionally displays the current memory
2402 * usage and highlights the desktop area with a red bar if free memory runs
2407 public class MyDesktopPane extends JDesktopPane implements Runnable
2410 private static final float ONE_MB = 1048576f;
2412 boolean showMemoryUsage = false;
2416 java.text.NumberFormat df;
2418 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2421 public MyDesktopPane(boolean showMemoryUsage)
2423 showMemoryUsage(showMemoryUsage);
2426 public void showMemoryUsage(boolean showMemory)
2428 this.showMemoryUsage = showMemory;
2431 Thread worker = new Thread(this);
2437 public boolean isShowMemoryUsage()
2439 return showMemoryUsage;
2445 df = java.text.NumberFormat.getNumberInstance();
2446 df.setMaximumFractionDigits(2);
2447 runtime = Runtime.getRuntime();
2449 while (showMemoryUsage)
2453 maxMemory = runtime.maxMemory() / ONE_MB;
2454 allocatedMemory = runtime.totalMemory() / ONE_MB;
2455 freeMemory = runtime.freeMemory() / ONE_MB;
2456 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2458 percentUsage = (totalFreeMemory / maxMemory) * 100;
2460 // if (percentUsage < 20)
2462 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2464 // instance.set.setBorder(border1);
2467 // sleep after showing usage
2469 } catch (Exception ex)
2471 ex.printStackTrace();
2477 public void paintComponent(Graphics g)
2479 if (showMemoryUsage && g != null && df != null)
2481 if (percentUsage < 20)
2483 g.setColor(Color.red);
2485 FontMetrics fm = g.getFontMetrics();
2488 g.drawString(MessageManager.formatMessage("label.memory_stats",
2490 { df.format(totalFreeMemory), df.format(maxMemory),
2491 df.format(percentUsage) }),
2492 10, getHeight() - fm.getHeight());
2500 * Accessor method to quickly get all the AlignmentFrames loaded.
2502 * @return an array of AlignFrame, or null if none found
2504 public static AlignFrame[] getAlignFrames()
2506 if (Jalview.isHeadlessMode())
2508 // Desktop.desktop is null in headless mode
2509 return new AlignFrame[] { Jalview.currentAlignFrame };
2512 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2518 List<AlignFrame> avp = new ArrayList<>();
2520 for (int i = frames.length - 1; i > -1; i--)
2522 if (frames[i] instanceof AlignFrame)
2524 avp.add((AlignFrame) frames[i]);
2526 else if (frames[i] instanceof SplitFrame)
2529 * Also check for a split frame containing an AlignFrame
2531 GSplitFrame sf = (GSplitFrame) frames[i];
2532 if (sf.getTopFrame() instanceof AlignFrame)
2534 avp.add((AlignFrame) sf.getTopFrame());
2536 if (sf.getBottomFrame() instanceof AlignFrame)
2538 avp.add((AlignFrame) sf.getBottomFrame());
2542 if (avp.size() == 0)
2546 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2551 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2555 public GStructureViewer[] getJmols()
2557 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2563 List<GStructureViewer> avp = new ArrayList<>();
2565 for (int i = frames.length - 1; i > -1; i--)
2567 if (frames[i] instanceof AppJmol)
2569 GStructureViewer af = (GStructureViewer) frames[i];
2573 if (avp.size() == 0)
2577 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2582 * Add Groovy Support to Jalview
2585 public void groovyShell_actionPerformed()
2589 openGroovyConsole();
2590 } catch (Exception ex)
2592 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2593 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2595 MessageManager.getString("label.couldnt_create_groovy_shell"),
2596 MessageManager.getString("label.groovy_support_failed"),
2597 JvOptionPane.ERROR_MESSAGE);
2602 * Open the Groovy console
2604 void openGroovyConsole()
2606 if (groovyConsole == null)
2608 groovyConsole = new groovy.ui.Console();
2609 groovyConsole.setVariable("Jalview", this);
2610 groovyConsole.run();
2613 * We allow only one console at a time, so that AlignFrame menu option
2614 * 'Calculate | Run Groovy script' is unambiguous.
2615 * Disable 'Groovy Console', and enable 'Run script', when the console is
2616 * opened, and the reverse when it is closed
2618 Window window = (Window) groovyConsole.getFrame();
2619 window.addWindowListener(new WindowAdapter()
2622 public void windowClosed(WindowEvent e)
2625 * rebind CMD-Q from Groovy Console to Jalview Quit
2628 enableExecuteGroovy(false);
2634 * show Groovy console window (after close and reopen)
2636 ((Window) groovyConsole.getFrame()).setVisible(true);
2639 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2640 * and disable opening a second console
2642 enableExecuteGroovy(true);
2646 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2647 * binding when opened
2649 protected void addQuitHandler()
2651 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
2652 .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
2653 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
2655 getRootPane().getActionMap().put("Quit", new AbstractAction()
2658 public void actionPerformed(ActionEvent e)
2666 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2669 * true if Groovy console is open
2671 public void enableExecuteGroovy(boolean enabled)
2674 * disable opening a second Groovy console
2675 * (or re-enable when the console is closed)
2677 groovyShell.setEnabled(!enabled);
2679 AlignFrame[] alignFrames = getAlignFrames();
2680 if (alignFrames != null)
2682 for (AlignFrame af : alignFrames)
2684 af.setGroovyEnabled(enabled);
2690 * Progress bars managed by the IProgressIndicator method.
2692 private Hashtable<Long, JPanel> progressBars;
2694 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2699 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2702 public void setProgressBar(String message, long id)
2704 if (progressBars == null)
2706 progressBars = new Hashtable<>();
2707 progressBarHandlers = new Hashtable<>();
2710 if (progressBars.get(new Long(id)) != null)
2712 JPanel panel = progressBars.remove(new Long(id));
2713 if (progressBarHandlers.contains(new Long(id)))
2715 progressBarHandlers.remove(new Long(id));
2717 removeProgressPanel(panel);
2721 progressBars.put(new Long(id), addProgressPanel(message));
2728 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2729 * jalview.gui.IProgressIndicatorHandler)
2732 public void registerHandler(final long id,
2733 final IProgressIndicatorHandler handler)
2735 if (progressBarHandlers == null
2736 || !progressBars.containsKey(new Long(id)))
2738 throw new Error(MessageManager.getString(
2739 "error.call_setprogressbar_before_registering_handler"));
2741 progressBarHandlers.put(new Long(id), handler);
2742 final JPanel progressPanel = progressBars.get(new Long(id));
2743 if (handler.canCancel())
2745 JButton cancel = new JButton(
2746 MessageManager.getString("action.cancel"));
2747 final IProgressIndicator us = this;
2748 cancel.addActionListener(new ActionListener()
2752 public void actionPerformed(ActionEvent e)
2754 handler.cancelActivity(id);
2755 us.setProgressBar(MessageManager
2756 .formatMessage("label.cancelled_params", new Object[]
2757 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2761 progressPanel.add(cancel, BorderLayout.EAST);
2767 * @return true if any progress bars are still active
2770 public boolean operationInProgress()
2772 if (progressBars != null && progressBars.size() > 0)
2780 * This will return the first AlignFrame holding the given viewport instance.
2781 * It will break if there are more than one AlignFrames viewing a particular
2785 * @return alignFrame for viewport
2787 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2789 if (desktop != null)
2791 AlignmentPanel[] aps = getAlignmentPanels(
2792 viewport.getSequenceSetId());
2793 for (int panel = 0; aps != null && panel < aps.length; panel++)
2795 if (aps[panel] != null && aps[panel].av == viewport)
2797 return aps[panel].alignFrame;
2804 public VamsasApplication getVamsasApplication()
2811 * flag set if jalview GUI is being operated programmatically
2813 private boolean inBatchMode = false;
2816 * check if jalview GUI is being operated programmatically
2818 * @return inBatchMode
2820 public boolean isInBatchMode()
2826 * set flag if jalview GUI is being operated programmatically
2828 * @param inBatchMode
2830 public void setInBatchMode(boolean inBatchMode)
2832 this.inBatchMode = inBatchMode;
2835 public void startServiceDiscovery()
2837 startServiceDiscovery(false);
2840 public void startServiceDiscovery(boolean blocking)
2842 boolean alive = true;
2843 Thread t0 = null, t1 = null, t2 = null;
2844 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2847 // todo: changesupport handlers need to be transferred
2848 if (discoverer == null)
2850 discoverer = new jalview.ws.jws1.Discoverer();
2851 // register PCS handler for desktop.
2852 discoverer.addPropertyChangeListener(changeSupport);
2854 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2855 // until we phase out completely
2856 (t0 = new Thread(discoverer)).start();
2859 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2861 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2862 .startDiscoverer(changeSupport);
2866 // TODO: do rest service discovery
2875 } catch (Exception e)
2878 alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
2879 || (t3 != null && t3.isAlive())
2880 || (t0 != null && t0.isAlive());
2886 * called to check if the service discovery process completed successfully.
2890 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2892 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2894 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2895 .getErrorMessages();
2898 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2900 if (serviceChangedDialog == null)
2902 // only run if we aren't already displaying one of these.
2903 addDialogThread(serviceChangedDialog = new Runnable()
2910 * JalviewDialog jd =new JalviewDialog() {
2912 * @Override protected void cancelPressed() { // TODO
2913 * Auto-generated method stub
2915 * }@Override protected void okPressed() { // TODO
2916 * Auto-generated method stub
2918 * }@Override protected void raiseClosed() { // TODO
2919 * Auto-generated method stub
2921 * } }; jd.initDialogFrame(new
2922 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2923 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2924 * + " or mis-configured HTTP proxy settings.<br/>" +
2925 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2927 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2928 * ), true, true, "Web Service Configuration Problem", 450,
2931 * jd.waitForInput();
2933 JvOptionPane.showConfirmDialog(Desktop.desktop,
2934 new JLabel("<html><table width=\"450\"><tr><td>"
2935 + ermsg + "</td></tr></table>"
2936 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2937 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2938 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2939 + " Tools->Preferences dialog box to change them.</p></html>"),
2940 "Web Service Configuration Problem",
2941 JvOptionPane.DEFAULT_OPTION,
2942 JvOptionPane.ERROR_MESSAGE);
2943 serviceChangedDialog = null;
2952 "Errors reported by JABA discovery service. Check web services preferences.\n"
2959 private Runnable serviceChangedDialog = null;
2962 * start a thread to open a URL in the configured browser. Pops up a warning
2963 * dialog to the user if there is an exception when calling out to the browser
2968 public static void showUrl(final String url)
2970 showUrl(url, Desktop.instance);
2974 * Like showUrl but allows progress handler to be specified
2978 * (null) or object implementing IProgressIndicator
2980 public static void showUrl(final String url,
2981 final IProgressIndicator progress)
2983 new Thread(new Runnable()
2990 if (progress != null)
2992 progress.setProgressBar(MessageManager
2993 .formatMessage("status.opening_params", new Object[]
2994 { url }), this.hashCode());
2996 jalview.util.BrowserLauncher.openURL(url);
2997 } catch (Exception ex)
2999 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3001 .getString("label.web_browser_not_found_unix"),
3002 MessageManager.getString("label.web_browser_not_found"),
3003 JvOptionPane.WARNING_MESSAGE);
3005 ex.printStackTrace();
3007 if (progress != null)
3009 progress.setProgressBar(null, this.hashCode());
3015 public static WsParamSetManager wsparamManager = null;
3017 public static ParamManager getUserParameterStore()
3019 if (wsparamManager == null)
3021 wsparamManager = new WsParamSetManager();
3023 return wsparamManager;
3027 * static hyperlink handler proxy method for use by Jalview's internal windows
3031 public static void hyperlinkUpdate(HyperlinkEvent e)
3033 if (e.getEventType() == EventType.ACTIVATED)
3038 url = e.getURL().toString();
3039 Desktop.showUrl(url);
3040 } catch (Exception x)
3044 if (Cache.log != null)
3046 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3051 "Couldn't handle string " + url + " as a URL.");
3054 // ignore any exceptions due to dud links.
3061 * single thread that handles display of dialogs to user.
3063 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3066 * flag indicating if dialogExecutor should try to acquire a permit
3068 private volatile boolean dialogPause = true;
3073 private java.util.concurrent.Semaphore block = new Semaphore(0);
3075 private static groovy.ui.Console groovyConsole;
3078 * add another dialog thread to the queue
3082 public void addDialogThread(final Runnable prompter)
3084 dialogExecutor.submit(new Runnable()
3094 } catch (InterruptedException x)
3099 if (instance == null)
3105 SwingUtilities.invokeAndWait(prompter);
3106 } catch (Exception q)
3108 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3114 public void startDialogQueue()
3116 // set the flag so we don't pause waiting for another permit and semaphore
3117 // the current task to begin
3118 dialogPause = false;
3123 protected void snapShotWindow_actionPerformed(ActionEvent e)
3127 ImageMaker im = new jalview.util.ImageMaker(
3128 this, ImageMaker.TYPE.EPS, "View of Desktop", getWidth(),
3129 getHeight(), of = new File("Jalview_snapshot"
3130 + System.currentTimeMillis() + ".eps"),
3131 "View of desktop", null, 0, false);
3134 paintAll(im.getGraphics());
3136 } catch (Exception q)
3138 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3142 Cache.log.info("Successfully written snapshot to file "
3143 + of.getAbsolutePath());
3147 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3148 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3149 * and location last time the view was expanded (if any). However it does not
3150 * remember the split pane divider location - this is set to match the
3151 * 'exploding' frame.
3155 public void explodeViews(SplitFrame sf)
3157 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3158 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3159 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3161 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3163 int viewCount = topPanels.size();
3170 * Processing in reverse order works, forwards order leaves the first panels
3171 * not visible. I don't know why!
3173 for (int i = viewCount - 1; i >= 0; i--)
3176 * Make new top and bottom frames. These take over the respective
3177 * AlignmentPanel objects, including their AlignmentViewports, so the
3178 * cdna/protein relationships between the viewports is carried over to the
3181 * explodedGeometry holds the (x, y) position of the previously exploded
3182 * SplitFrame, and the (width, height) of the AlignFrame component
3184 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3185 AlignFrame newTopFrame = new AlignFrame(topPanel);
3186 newTopFrame.setSize(oldTopFrame.getSize());
3187 newTopFrame.setVisible(true);
3188 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3189 .getExplodedGeometry();
3190 if (geometry != null)
3192 newTopFrame.setSize(geometry.getSize());
3195 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3196 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3197 newBottomFrame.setSize(oldBottomFrame.getSize());
3198 newBottomFrame.setVisible(true);
3199 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3200 .getExplodedGeometry();
3201 if (geometry != null)
3203 newBottomFrame.setSize(geometry.getSize());
3206 topPanel.av.setGatherViewsHere(false);
3207 bottomPanel.av.setGatherViewsHere(false);
3208 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3210 if (geometry != null)
3212 splitFrame.setLocation(geometry.getLocation());
3214 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3218 * Clear references to the panels (now relocated in the new SplitFrames)
3219 * before closing the old SplitFrame.
3222 bottomPanels.clear();
3227 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3228 * back into the given SplitFrame as additional views. Note that the gathered
3229 * frames may themselves have multiple views.
3233 public void gatherViews(GSplitFrame source)
3236 * special handling of explodedGeometry for a view within a SplitFrame: - it
3237 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3238 * height) of the AlignFrame component
3240 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3241 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3242 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3243 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3244 myBottomFrame.viewport
3245 .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
3246 myBottomFrame.getWidth(), myBottomFrame.getHeight()));
3247 myTopFrame.viewport.setGatherViewsHere(true);
3248 myBottomFrame.viewport.setGatherViewsHere(true);
3249 String topViewId = myTopFrame.viewport.getSequenceSetId();
3250 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3252 JInternalFrame[] frames = desktop.getAllFrames();
3253 for (JInternalFrame frame : frames)
3255 if (frame instanceof SplitFrame && frame != source)
3257 SplitFrame sf = (SplitFrame) frame;
3258 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3259 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3260 boolean gatherThis = false;
3261 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3263 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3264 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3265 if (topViewId.equals(topPanel.av.getSequenceSetId())
3266 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3269 topPanel.av.setGatherViewsHere(false);
3270 bottomPanel.av.setGatherViewsHere(false);
3271 topPanel.av.setExplodedGeometry(
3272 new Rectangle(sf.getLocation(), topFrame.getSize()));
3273 bottomPanel.av.setExplodedGeometry(
3274 new Rectangle(sf.getLocation(), bottomFrame.getSize()));
3275 myTopFrame.addAlignmentPanel(topPanel, false);
3276 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3282 topFrame.getAlignPanels().clear();
3283 bottomFrame.getAlignPanels().clear();
3290 * The dust settles...give focus to the tab we did this from.
3292 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3295 public static groovy.ui.Console getGroovyConsole()
3297 return groovyConsole;
3300 public static void transferFromDropTarget(List<String> files,
3301 List<DataSourceType> protocols, DropTargetDropEvent evt,
3302 Transferable t) throws Exception
3305 DataFlavor uriListFlavor = new DataFlavor(
3306 "text/uri-list;class=java.lang.String");
3307 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3309 // Works on Windows and MacOSX
3310 Cache.log.debug("Drop handled as javaFileListFlavor");
3311 for (Object file : (List) t
3312 .getTransferData(DataFlavor.javaFileListFlavor))
3314 files.add(((File) file).toString());
3315 protocols.add(DataSourceType.FILE);
3320 // Unix like behaviour
3321 boolean added = false;
3323 if (t.isDataFlavorSupported(uriListFlavor))
3325 Cache.log.debug("Drop handled as uriListFlavor");
3326 // This is used by Unix drag system
3327 data = (String) t.getTransferData(uriListFlavor);
3331 // fallback to text: workaround - on OSX where there's a JVM bug
3332 Cache.log.debug("standard URIListFlavor failed. Trying text");
3333 // try text fallback
3334 data = (String) t.getTransferData(
3335 new DataFlavor("text/plain;class=java.lang.String"));
3336 if (Cache.log.isDebugEnabled())
3338 Cache.log.debug("fallback returned " + data);
3341 while (protocols.size() < files.size())
3343 Cache.log.debug("Adding missing FILE protocol for "
3344 + files.get(protocols.size()));
3345 protocols.add(DataSourceType.FILE);
3347 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3348 data, "\r\n"); st.hasMoreTokens();)
3351 String s = st.nextToken();
3352 if (s.startsWith("#"))
3354 // the line is a comment (as per the RFC 2483)
3357 java.net.URI uri = new java.net.URI(s);
3358 if (uri.getScheme().toLowerCase().startsWith("http"))
3360 protocols.add(DataSourceType.URL);
3361 files.add(uri.toString());
3365 // otherwise preserve old behaviour: catch all for file objects
3366 java.io.File file = new java.io.File(uri);
3367 protocols.add(DataSourceType.FILE);
3368 files.add(file.toString());
3371 if (Cache.log.isDebugEnabled())
3373 if (data == null || !added)
3376 "Couldn't resolve drop data. Here are the supported flavors:");
3377 for (DataFlavor fl : t.getTransferDataFlavors())
3380 "Supported transfer dataflavor: " + fl.toString());
3381 Object df = t.getTransferData(fl);
3384 Cache.log.debug("Retrieves: " + df);
3388 Cache.log.debug("Retrieved nothing");
3397 * Sets the Preferences property for experimental features to True or False
3398 * depending on the state of the controlling menu item
3401 protected void showExperimental_actionPerformed(boolean selected)
3403 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));