2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.io.FileLoader;
25 import jalview.io.FormatAdapter;
26 import jalview.io.IdentifyFile;
27 import jalview.io.JalviewFileChooser;
28 import jalview.io.JalviewFileView;
29 import jalview.structure.StructureSelectionManager;
30 import jalview.util.ImageMaker;
31 import jalview.util.MessageManager;
32 import jalview.ws.params.ParamManager;
34 import java.awt.BorderLayout;
35 import java.awt.Color;
36 import java.awt.Dimension;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics;
39 import java.awt.GridLayout;
40 import java.awt.Point;
41 import java.awt.Rectangle;
42 import java.awt.Toolkit;
43 import java.awt.datatransfer.Clipboard;
44 import java.awt.datatransfer.ClipboardOwner;
45 import java.awt.datatransfer.DataFlavor;
46 import java.awt.datatransfer.Transferable;
47 import java.awt.dnd.DnDConstants;
48 import java.awt.dnd.DropTargetDragEvent;
49 import java.awt.dnd.DropTargetDropEvent;
50 import java.awt.dnd.DropTargetEvent;
51 import java.awt.dnd.DropTargetListener;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.ActionListener;
54 import java.awt.event.FocusEvent;
55 import java.awt.event.FocusListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.WindowAdapter;
60 import java.awt.event.WindowEvent;
61 import java.beans.PropertyChangeEvent;
62 import java.beans.PropertyChangeListener;
63 import java.beans.PropertyVetoException;
64 import java.io.BufferedInputStream;
66 import java.io.FileOutputStream;
67 import java.lang.reflect.Constructor;
69 import java.util.ArrayList;
70 import java.util.Hashtable;
71 import java.util.StringTokenizer;
72 import java.util.Vector;
73 import java.util.concurrent.ExecutorService;
74 import java.util.concurrent.Executors;
75 import java.util.concurrent.Semaphore;
77 import javax.swing.DefaultDesktopManager;
78 import javax.swing.DesktopManager;
79 import javax.swing.JButton;
80 import javax.swing.JComboBox;
81 import javax.swing.JComponent;
82 import javax.swing.JDesktopPane;
83 import javax.swing.JFrame;
84 import javax.swing.JInternalFrame;
85 import javax.swing.JLabel;
86 import javax.swing.JMenuItem;
87 import javax.swing.JOptionPane;
88 import javax.swing.JPanel;
89 import javax.swing.JPopupMenu;
90 import javax.swing.JProgressBar;
91 import javax.swing.SwingUtilities;
92 import javax.swing.event.HyperlinkEvent;
93 import javax.swing.event.HyperlinkEvent.EventType;
94 import javax.swing.event.MenuEvent;
95 import javax.swing.event.MenuListener;
102 * @version $Revision: 1.155 $
104 public class Desktop extends jalview.jbgui.GDesktop implements
105 DropTargetListener, ClipboardOwner, IProgressIndicator,
106 jalview.api.StructureSelectionManagerProvider
109 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
112 * news reader - null if it was never started.
114 private BlogReader jvnews = null;
118 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void addJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
139 * @param propertyName
141 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
142 * java.beans.PropertyChangeListener)
144 public void removeJalviewPropertyChangeListener(String propertyName,
145 PropertyChangeListener listener)
147 changeSupport.removeJalviewPropertyChangeListener(propertyName,
151 /** Singleton Desktop instance */
152 public static Desktop instance;
154 public static MyDesktopPane desktop;
156 static int openFrameCount = 0;
158 static final int xOffset = 30;
160 static final int yOffset = 30;
162 private static final int THREE = 3;
164 public static jalview.ws.jws1.Discoverer discoverer;
166 public static Object[] jalviewClipboard;
168 public static boolean internalCopy = false;
170 static int fileLoadingCount = 0;
172 class MyDesktopManager implements DesktopManager
175 private DesktopManager delegate;
177 public MyDesktopManager(DesktopManager delegate)
179 this.delegate = delegate;
182 public void activateFrame(JInternalFrame f)
186 delegate.activateFrame(f);
187 } catch (NullPointerException npe)
189 Point p = getMousePosition();
190 instance.showPasteMenu(p.x, p.y);
194 public void beginDraggingFrame(JComponent f)
196 delegate.beginDraggingFrame(f);
199 public void beginResizingFrame(JComponent f, int direction)
201 delegate.beginResizingFrame(f, direction);
204 public void closeFrame(JInternalFrame f)
206 delegate.closeFrame(f);
209 public void deactivateFrame(JInternalFrame f)
211 delegate.deactivateFrame(f);
214 public void deiconifyFrame(JInternalFrame f)
216 delegate.deiconifyFrame(f);
219 public void dragFrame(JComponent f, int newX, int newY)
225 delegate.dragFrame(f, newX, newY);
228 public void endDraggingFrame(JComponent f)
230 delegate.endDraggingFrame(f);
233 public void endResizingFrame(JComponent f)
235 delegate.endResizingFrame(f);
238 public void iconifyFrame(JInternalFrame f)
240 delegate.iconifyFrame(f);
243 public void maximizeFrame(JInternalFrame f)
245 delegate.maximizeFrame(f);
248 public void minimizeFrame(JInternalFrame f)
250 delegate.minimizeFrame(f);
253 public void openFrame(JInternalFrame f)
255 delegate.openFrame(f);
258 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
261 Rectangle b = desktop.getBounds();
266 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
269 public void setBoundsForFrame(JComponent f, int newX, int newY,
270 int newWidth, int newHeight)
272 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
275 // All other methods, simply delegate
280 * Creates a new Desktop object.
285 * A note to implementors. It is ESSENTIAL that any activities that might
286 * block are spawned off as threads rather than waited for during this
290 doVamsasClientCheck();
292 doConfigureStructurePrefs();
293 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
294 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
295 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
297 boolean showjconsole = jalview.bin.Cache.getDefault(
298 "SHOW_JAVA_CONSOLE", false);
299 desktop = new MyDesktopPane(selmemusage);
300 showMemusage.setSelected(selmemusage);
301 desktop.setBackground(Color.white);
302 getContentPane().setLayout(new BorderLayout());
303 // alternate config - have scrollbars - see notes in JAL-153
304 // JScrollPane sp = new JScrollPane();
305 // sp.getViewport().setView(desktop);
306 // getContentPane().add(sp, BorderLayout.CENTER);
307 getContentPane().add(desktop, BorderLayout.CENTER);
308 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
310 // This line prevents Windows Look&Feel resizing all new windows to maximum
311 // if previous window was maximised
312 desktop.setDesktopManager(new MyDesktopManager(
313 new DefaultDesktopManager()));
315 Rectangle dims = getLastKnownDimensions("");
322 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
323 setBounds((screenSize.width - 900) / 2,
324 (screenSize.height - 650) / 2, 900, 650);
326 jconsole = new Console(this, showjconsole);
327 // add essential build information
328 jconsole.setHeader("Jalview Version: "
329 + jalview.bin.Cache.getProperty("VERSION") + "\n"
330 + "Jalview Installation: "
331 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
334 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
335 + "Java version: " + System.getProperty("java.version") + "\n"
336 + System.getProperty("os.arch") + " "
337 + System.getProperty("os.name") + " "
338 + System.getProperty("os.version"));
340 showConsole(showjconsole);
342 showNews.setVisible(false);
344 this.addWindowListener(new WindowAdapter()
346 public void windowClosing(WindowEvent evt)
353 this.addMouseListener(ma = new MouseAdapter()
355 public void mousePressed(MouseEvent evt)
357 if (SwingUtilities.isRightMouseButton(evt))
359 showPasteMenu(evt.getX(), evt.getY());
363 desktop.addMouseListener(ma);
365 this.addFocusListener(new FocusListener()
369 public void focusLost(FocusEvent e)
371 // TODO Auto-generated method stub
376 public void focusGained(FocusEvent e)
378 Cache.log.debug("Relaying windows after focus gain");
379 // make sure that we sort windows properly after we gain focus
380 instance.relayerWindows();
383 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
384 // Spawn a thread that shows the splashscreen
385 SwingUtilities.invokeLater(new Runnable()
394 // Thread off a new instance of the file chooser - this reduces the time it
395 // takes to open it later on.
396 new Thread(new Runnable()
400 Cache.log.debug("Filechooser init thread started.");
401 JalviewFileChooser chooser = new JalviewFileChooser(
402 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
403 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
404 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
405 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
406 Cache.log.debug("Filechooser init thread finished.");
409 // Add the service change listener
410 changeSupport.addJalviewPropertyChangeListener("services",
411 new PropertyChangeListener()
415 public void propertyChange(PropertyChangeEvent evt)
417 Cache.log.debug("Firing service changed event for "
418 + evt.getNewValue());
419 JalviewServicesChanged(evt);
425 public void doConfigureStructurePrefs()
427 // configure services
428 StructureSelectionManager ssm = StructureSelectionManager
429 .getStructureSelectionManager(this);
430 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
432 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
433 Preferences.ADD_TEMPFACT_ANN, true));
434 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
435 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
440 ssm.setAddTempFacAnnot(false);
441 ssm.setProcessSecondaryStructure(false);
442 ssm.setSecStructServices(false);
446 public void checkForNews()
448 final Desktop me = this;
449 // Thread off the news reader, in case there are connection problems.
450 addDialogThread(new Runnable()
455 Cache.log.debug("Starting news thread.");
457 jvnews = new BlogReader(me);
458 showNews.setVisible(true);
459 Cache.log.debug("Completed news thread.");
464 protected void showNews_actionPerformed(ActionEvent e)
466 showNews(showNews.isSelected());
469 void showNews(boolean visible)
472 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
473 showNews.setSelected(visible);
474 if (visible && !jvnews.isVisible())
476 new Thread(new Runnable()
481 long instance = System.currentTimeMillis();
482 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
483 jvnews.refreshNews();
484 Desktop.instance.setProgressBar(null, instance);
493 * recover the last known dimensions for a jalview window
496 * - empty string is desktop, all other windows have unique prefix
497 * @return null or last known dimensions scaled to current geometry (if last
498 * window geom was known)
500 Rectangle getLastKnownDimensions(String windowName)
502 // TODO: lock aspect ratio for scaling desktop Bug #0058199
503 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
504 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
505 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
506 String width = jalview.bin.Cache.getProperty(windowName
508 String height = jalview.bin.Cache.getProperty(windowName
510 if ((x != null) && (y != null) && (width != null) && (height != null))
512 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
513 .parseInt(width), ih = Integer.parseInt(height);
514 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
516 // attempt #1 - try to cope with change in screen geometry - this
517 // version doesn't preserve original jv aspect ratio.
518 // take ratio of current screen size vs original screen size.
519 double sw = ((1f * screenSize.width) / (1f * Integer
520 .parseInt(jalview.bin.Cache
521 .getProperty("SCREENGEOMETRY_WIDTH"))));
522 double sh = ((1f * screenSize.height) / (1f * Integer
523 .parseInt(jalview.bin.Cache
524 .getProperty("SCREENGEOMETRY_HEIGHT"))));
525 // rescale the bounds depending upon the current screen geometry.
526 ix = (int) (ix * sw);
527 iw = (int) (iw * sw);
528 iy = (int) (iy * sh);
529 ih = (int) (ih * sh);
530 while (ix >= screenSize.width)
532 jalview.bin.Cache.log
533 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
534 ix -= screenSize.width;
536 while (iy >= screenSize.height)
538 jalview.bin.Cache.log
539 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
540 iy -= screenSize.height;
542 jalview.bin.Cache.log.debug("Got last known dimensions for "
543 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
546 // return dimensions for new instance
547 return new Rectangle(ix, iy, iw, ih);
552 private void doVamsasClientCheck()
554 if (jalview.bin.Cache.vamsasJarsPresent())
556 setupVamsasDisconnectedGui();
557 VamsasMenu.setVisible(true);
558 final Desktop us = this;
559 VamsasMenu.addMenuListener(new MenuListener()
561 // this listener remembers when the menu was first selected, and
562 // doesn't rebuild the session list until it has been cleared and
564 boolean refresh = true;
566 public void menuCanceled(MenuEvent e)
571 public void menuDeselected(MenuEvent e)
576 public void menuSelected(MenuEvent e)
580 us.buildVamsasStMenu();
585 vamsasStart.setVisible(true);
589 void showPasteMenu(int x, int y)
591 JPopupMenu popup = new JPopupMenu();
592 JMenuItem item = new JMenuItem(
593 MessageManager.getString("label.paste_new_window"));
594 item.addActionListener(new ActionListener()
596 public void actionPerformed(ActionEvent evt)
603 popup.show(this, x, y);
610 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
611 Transferable contents = c.getContents(this);
613 if (contents != null)
615 String file = (String) contents
616 .getTransferData(DataFlavor.stringFlavor);
618 String format = new IdentifyFile().Identify(file,
619 FormatAdapter.PASTE);
621 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
624 } catch (Exception ex)
627 .println("Unable to paste alignment from system clipboard:\n"
633 * Adds and opens the given frame to the desktop
644 public static synchronized void addInternalFrame(
645 final JInternalFrame frame, String title, int w, int h)
647 addInternalFrame(frame, title, true, w, h, true);
652 * Add an internal frame to the Jalview desktop
659 * When true, display frame immediately, otherwise, caller must call
660 * setVisible themselves.
666 public static synchronized void addInternalFrame(
667 final JInternalFrame frame, String title, boolean makeVisible,
670 addInternalFrame(frame, title, makeVisible, w, h, true);
674 * Add an internal frame to the Jalview desktop and make it visible
687 public static synchronized void addInternalFrame(
688 final JInternalFrame frame, String title, int w, int h,
691 addInternalFrame(frame, title, true, w, h, resizable);
695 * Add an internal frame to the Jalview desktop
702 * When true, display frame immediately, otherwise, caller must call
703 * setVisible themselves.
711 public static synchronized void addInternalFrame(
712 final JInternalFrame frame, String title, boolean makeVisible,
713 int w, int h, boolean resizable)
716 // TODO: allow callers to determine X and Y position of frame (eg. via
718 // TODO: consider fixing method to update entries in the window submenu with
719 // the current window title
721 frame.setTitle(title);
722 if (frame.getWidth() < 1 || frame.getHeight() < 1)
726 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
727 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
728 // IF JALVIEW IS RUNNING HEADLESS
729 // ///////////////////////////////////////////////
731 || (System.getProperty("java.awt.headless") != null && System
732 .getProperty("java.awt.headless").equals("true")))
739 frame.setVisible(makeVisible);
740 frame.setClosable(true);
741 frame.setResizable(resizable);
742 frame.setMaximizable(resizable);
743 frame.setIconifiable(resizable);
744 frame.setFrameIcon(null);
746 if (frame.getX() < 1 && frame.getY() < 1)
748 frame.setLocation(xOffset * openFrameCount, yOffset
749 * ((openFrameCount - 1) % 10) + yOffset);
752 final JMenuItem menuItem = new JMenuItem(title);
753 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
755 public void internalFrameActivated(
756 javax.swing.event.InternalFrameEvent evt)
758 JInternalFrame itf = desktop.getSelectedFrame();
766 public void internalFrameClosed(
767 javax.swing.event.InternalFrameEvent evt)
769 PaintRefresher.RemoveComponent(frame);
771 windowMenu.remove(menuItem);
772 JInternalFrame itf = desktop.getSelectedFrame();
781 menuItem.addActionListener(new ActionListener()
783 public void actionPerformed(ActionEvent e)
787 frame.setSelected(true);
788 frame.setIcon(false);
789 } catch (java.beans.PropertyVetoException ex)
795 menuItem.addMouseListener(new MouseListener()
799 public void mouseReleased(MouseEvent e)
804 public void mousePressed(MouseEvent e)
809 public void mouseExited(MouseEvent e)
813 frame.setSelected(false);
814 } catch (PropertyVetoException e1)
820 public void mouseEntered(MouseEvent e)
824 frame.setSelected(true);
825 } catch (PropertyVetoException e1)
831 public void mouseClicked(MouseEvent e)
837 windowMenu.add(menuItem);
843 frame.setSelected(true);
844 frame.requestFocus();
845 } catch (java.beans.PropertyVetoException ve)
847 } catch (java.lang.ClassCastException cex)
850 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
855 public void lostOwnership(Clipboard clipboard, Transferable contents)
859 Desktop.jalviewClipboard = null;
862 internalCopy = false;
865 public void dragEnter(DropTargetDragEvent evt)
869 public void dragExit(DropTargetEvent evt)
873 public void dragOver(DropTargetDragEvent evt)
877 public void dropActionChanged(DropTargetDragEvent evt)
887 public void drop(DropTargetDropEvent evt)
889 boolean success = true;
890 Transferable t = evt.getTransferable();
891 java.util.List files = null;
892 java.util.List protocols = null;
896 DataFlavor uriListFlavor = new DataFlavor(
897 "text/uri-list;class=java.lang.String");
898 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
900 // Works on Windows and MacOSX
901 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
902 files = (java.util.List) t
903 .getTransferData(DataFlavor.javaFileListFlavor);
905 else if (t.isDataFlavorSupported(uriListFlavor))
907 // This is used by Unix drag system
908 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
909 String data = (String) t.getTransferData(uriListFlavor);
910 files = new java.util.ArrayList(1);
911 protocols = new java.util.ArrayList(1);
912 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
913 data, "\r\n"); st.hasMoreTokens();)
915 String s = st.nextToken();
916 if (s.startsWith("#"))
918 // the line is a comment (as per the RFC 2483)
921 java.net.URI uri = new java.net.URI(s);
922 if (uri.getScheme().toLowerCase().startsWith("http"))
924 protocols.add(FormatAdapter.URL);
925 files.add(uri.toString());
929 // otherwise preserve old behaviour: catch all for file objects
930 java.io.File file = new java.io.File(uri);
931 protocols.add(FormatAdapter.FILE);
932 files.add(file.toString());
936 } catch (Exception e)
945 for (int i = 0; i < files.size(); i++)
947 String file = files.get(i).toString();
948 String protocol = (protocols == null) ? FormatAdapter.FILE
949 : (String) protocols.get(i);
950 String format = null;
952 if (file.endsWith(".jar"))
959 format = new IdentifyFile().Identify(file, protocol);
962 new FileLoader().LoadFile(file, protocol, format);
965 } catch (Exception ex)
970 evt.dropComplete(success); // need this to ensure input focus is properly
971 // transfered to any new windows created
980 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
982 JalviewFileChooser chooser = new JalviewFileChooser(
983 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
984 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
985 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
986 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
988 chooser.setFileView(new JalviewFileView());
989 chooser.setDialogTitle(MessageManager
990 .getString("label.open_local_file"));
991 chooser.setToolTipText(MessageManager.getString("action.open"));
993 int value = chooser.showOpenDialog(this);
995 if (value == JalviewFileChooser.APPROVE_OPTION)
997 String choice = chooser.getSelectedFile().getPath();
998 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
999 .getSelectedFile().getParent());
1001 String format = null;
1002 if (chooser.getSelectedFormat() != null
1003 && chooser.getSelectedFormat().equals("Jalview"))
1009 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1012 if (viewport != null)
1014 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1019 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1030 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1032 // This construct allows us to have a wider textfield
1034 JLabel label = new JLabel(
1035 MessageManager.getString("label.input_file_url"));
1036 final JComboBox history = new JComboBox();
1038 JPanel panel = new JPanel(new GridLayout(2, 1));
1041 history.setPreferredSize(new Dimension(400, 20));
1042 history.setEditable(true);
1043 history.addItem("http://www.");
1045 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1049 if (historyItems != null)
1051 st = new StringTokenizer(historyItems, "\t");
1053 while (st.hasMoreTokens())
1055 history.addItem(st.nextElement());
1059 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1060 MessageManager.getString("label.input_alignment_from_url"),
1061 JOptionPane.OK_CANCEL_OPTION);
1063 if (reply != JOptionPane.OK_OPTION)
1068 String url = history.getSelectedItem().toString();
1070 if (url.toLowerCase().endsWith(".jar"))
1072 if (viewport != null)
1074 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1079 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1084 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1086 if (format.equals("URL NOT FOUND"))
1088 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1089 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1090 JOptionPane.WARNING_MESSAGE);
1095 if (viewport != null)
1097 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1101 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1112 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1114 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1115 cap.setForInput(viewport);
1116 Desktop.addInternalFrame(cap,
1117 MessageManager.getString("label.cut_paste_alignmen_file"),
1126 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1128 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1129 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1131 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1132 getBounds().y, getWidth(), getHeight()));
1134 if (jconsole != null)
1136 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1137 jconsole.stopConsole();
1141 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1144 if (dialogExecutor != null)
1146 dialogExecutor.shutdownNow();
1152 private void storeLastKnownDimensions(String string, Rectangle jc)
1154 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1155 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1156 + " height:" + jc.height);
1158 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1159 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1160 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1161 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1170 public void aboutMenuItem_actionPerformed(ActionEvent e)
1172 // StringBuffer message = getAboutMessage(false);
1173 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1175 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1176 new Thread(new Runnable()
1180 new SplashScreen(true);
1185 public StringBuffer getAboutMessage(boolean shortv)
1187 StringBuffer message = new StringBuffer();
1188 message.append("<html>");
1191 message.append("<h1><strong>Version: "
1192 + jalview.bin.Cache.getProperty("VERSION")
1193 + "</strong></h1>");
1194 message.append("<strong>Last Updated: <em>"
1195 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1196 + "</em></strong>");
1202 message.append("<strong>Version "
1203 + jalview.bin.Cache.getProperty("VERSION")
1204 + "; last updated: "
1205 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1208 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1211 message.append("<br>...Checking latest version...</br>");
1213 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1214 .equals(jalview.bin.Cache.getProperty("VERSION")))
1216 boolean red = false;
1217 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1218 .indexOf("automated build") == -1)
1221 // Displayed when code version and jnlp version do not match and code
1222 // version is not a development build
1223 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1226 message.append("<br>!! Version "
1227 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1229 + " is available for download from "
1230 + jalview.bin.Cache.getDefault("www.jalview.org",
1231 "http://www.jalview.org") + " !!");
1234 message.append("</div>");
1237 message.append("<br>Authors: "
1241 "The Jalview Authors (See AUTHORS file for current list)")
1242 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1243 + "<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"
1244 + "<br><br>If you use Jalview, please cite:"
1245 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1246 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1247 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1258 public void documentationMenuItem_actionPerformed(ActionEvent e)
1262 Help.showHelpWindow();
1263 } catch (Exception ex)
1268 public void closeAll_actionPerformed(ActionEvent e)
1270 JInternalFrame[] frames = desktop.getAllFrames();
1271 for (int i = 0; i < frames.length; i++)
1275 frames[i].setClosed(true);
1276 } catch (java.beans.PropertyVetoException ex)
1280 System.out.println("ALL CLOSED");
1281 if (v_client != null)
1283 // TODO clear binding to vamsas document objects on close_all
1288 public void raiseRelated_actionPerformed(ActionEvent e)
1290 reorderAssociatedWindows(false, false);
1293 public void minimizeAssociated_actionPerformed(ActionEvent e)
1295 reorderAssociatedWindows(true, false);
1298 void closeAssociatedWindows()
1300 reorderAssociatedWindows(false, true);
1306 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1309 protected void garbageCollect_actionPerformed(ActionEvent e)
1311 // We simply collect the garbage
1312 jalview.bin.Cache.log.debug("Collecting garbage...");
1314 jalview.bin.Cache.log.debug("Finished garbage collection.");
1321 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1324 protected void showMemusage_actionPerformed(ActionEvent e)
1326 desktop.showMemoryUsage(showMemusage.isSelected());
1333 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1336 protected void showConsole_actionPerformed(ActionEvent e)
1338 showConsole(showConsole.isSelected());
1341 Console jconsole = null;
1344 * control whether the java console is visible or not
1348 void showConsole(boolean selected)
1350 showConsole.setSelected(selected);
1351 // TODO: decide if we should update properties file
1352 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1354 jconsole.setVisible(selected);
1357 void reorderAssociatedWindows(boolean minimize, boolean close)
1359 JInternalFrame[] frames = desktop.getAllFrames();
1360 if (frames == null || frames.length < 1)
1365 AlignViewport source = null, target = null;
1366 if (frames[0] instanceof AlignFrame)
1368 source = ((AlignFrame) frames[0]).getCurrentView();
1370 else if (frames[0] instanceof TreePanel)
1372 source = ((TreePanel) frames[0]).getViewPort();
1374 else if (frames[0] instanceof PCAPanel)
1376 source = ((PCAPanel) frames[0]).av;
1378 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1380 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1385 for (int i = 0; i < frames.length; i++)
1388 if (frames[i] == null)
1392 if (frames[i] instanceof AlignFrame)
1394 target = ((AlignFrame) frames[i]).getCurrentView();
1396 else if (frames[i] instanceof TreePanel)
1398 target = ((TreePanel) frames[i]).getViewPort();
1400 else if (frames[i] instanceof PCAPanel)
1402 target = ((PCAPanel) frames[i]).av;
1404 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1406 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1409 if (source == target)
1415 frames[i].setClosed(true);
1419 frames[i].setIcon(minimize);
1422 frames[i].toFront();
1426 } catch (java.beans.PropertyVetoException ex)
1440 protected void preferences_actionPerformed(ActionEvent e)
1451 public void saveState_actionPerformed(ActionEvent e)
1453 JalviewFileChooser chooser = new JalviewFileChooser(
1454 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1455 { "jvp" }, new String[]
1456 { "Jalview Project" }, "Jalview Project");
1458 chooser.setFileView(new JalviewFileView());
1459 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1461 int value = chooser.showSaveDialog(this);
1463 if (value == JalviewFileChooser.APPROVE_OPTION)
1465 final Desktop me = this;
1466 final java.io.File choice = chooser.getSelectedFile();
1467 new Thread(new Runnable()
1472 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1474 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1475 choice.getParent());
1476 // TODO catch and handle errors for savestate
1477 // TODO prevent user from messing with the Desktop whilst we're saving
1480 new Jalview2XML().SaveState(choice);
1481 } catch (OutOfMemoryError oom)
1483 new OOMWarning("Whilst saving current state to "
1484 + choice.getName(), oom);
1485 } catch (Exception ex)
1488 "Problems whilst trying to save to " + choice.getName(),
1490 JOptionPane.showMessageDialog(
1492 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1493 MessageManager.getString("label.couldnt_save_project"),
1494 JOptionPane.WARNING_MESSAGE);
1496 setProgressBar(null, choice.hashCode());
1508 public void loadState_actionPerformed(ActionEvent e)
1510 JalviewFileChooser chooser = new JalviewFileChooser(
1511 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1512 { "jvp", "jar" }, new String[]
1513 { "Jalview Project", "Jalview Project (old)" },
1515 chooser.setFileView(new JalviewFileView());
1516 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1518 int value = chooser.showOpenDialog(this);
1520 if (value == JalviewFileChooser.APPROVE_OPTION)
1522 final String choice = chooser.getSelectedFile().getAbsolutePath();
1523 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1524 .getSelectedFile().getParent());
1525 new Thread(new Runnable()
1529 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1533 new Jalview2XML().LoadJalviewAlign(choice);
1534 } catch (OutOfMemoryError oom)
1536 new OOMWarning("Whilst loading project from " + choice, oom);
1537 } catch (Exception ex)
1539 Cache.log.error("Problems whilst loading project from "
1541 JOptionPane.showMessageDialog(Desktop.desktop,
1542 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1543 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1545 setProgressBar(null, choice.hashCode());
1551 public void inputSequence_actionPerformed(ActionEvent e)
1553 new SequenceFetcher(this);
1556 JPanel progressPanel;
1558 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1560 public void startLoading(final String fileName)
1562 if (fileLoadingCount == 0)
1564 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1569 private JPanel addProgressPanel(String string)
1571 if (progressPanel == null)
1573 progressPanel = new JPanel(new GridLayout(1, 1));
1574 totalProgressCount = 0;
1575 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1577 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1578 JProgressBar progressBar = new JProgressBar();
1579 progressBar.setIndeterminate(true);
1581 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1583 thisprogress.add(progressBar, BorderLayout.CENTER);
1584 progressPanel.add(thisprogress);
1585 ((GridLayout) progressPanel.getLayout())
1586 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1587 ++totalProgressCount;
1588 instance.validate();
1589 return thisprogress;
1592 int totalProgressCount = 0;
1594 private void removeProgressPanel(JPanel progbar)
1596 if (progressPanel != null)
1598 synchronized (progressPanel)
1600 progressPanel.remove(progbar);
1601 GridLayout gl = (GridLayout) progressPanel.getLayout();
1602 gl.setRows(gl.getRows() - 1);
1603 if (--totalProgressCount < 1)
1605 this.getContentPane().remove(progressPanel);
1606 progressPanel = null;
1613 public void stopLoading()
1616 if (fileLoadingCount < 1)
1618 while (fileLoadingPanels.size() > 0)
1620 removeProgressPanel(fileLoadingPanels.remove(0));
1622 fileLoadingPanels.clear();
1623 fileLoadingCount = 0;
1628 public static int getViewCount(String alignmentId)
1630 AlignViewport[] aps = getViewports(alignmentId);
1631 return (aps == null) ? 0 : aps.length;
1636 * @param alignmentId
1637 * @return all AlignmentPanels concerning the alignmentId sequence set
1639 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1642 if (Desktop.desktop == null)
1644 // no frames created and in headless mode
1645 // TODO: verify that frames are recoverable when in headless mode
1648 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1649 ArrayList aps = new ArrayList();
1650 for (int t = 0; t < frames.length; t++)
1652 if (frames[t] instanceof AlignFrame)
1654 AlignFrame af = (AlignFrame) frames[t];
1655 for (int a = 0; a < af.alignPanels.size(); a++)
1657 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1658 .elementAt(a)).av.getSequenceSetId()))
1660 aps.add(af.alignPanels.elementAt(a));
1665 if (aps.size() == 0)
1669 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1670 for (int t = 0; t < vap.length; t++)
1672 vap[t] = (AlignmentPanel) aps.get(t);
1678 * get all the viewports on an alignment.
1680 * @param sequenceSetId
1681 * unique alignment id
1682 * @return all viewports on the alignment bound to sequenceSetId
1684 public static AlignViewport[] getViewports(String sequenceSetId)
1686 Vector viewp = new Vector();
1687 if (desktop != null)
1689 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1691 for (int t = 0; t < frames.length; t++)
1693 if (frames[t] instanceof AlignFrame)
1695 AlignFrame afr = ((AlignFrame) frames[t]);
1696 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1698 if (afr.alignPanels != null)
1700 for (int a = 0; a < afr.alignPanels.size(); a++)
1702 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1703 .elementAt(a)).av.getSequenceSetId()))
1705 viewp.addElement(((AlignmentPanel) afr.alignPanels
1712 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1717 if (viewp.size() > 0)
1719 AlignViewport[] vp = new AlignViewport[viewp.size()];
1727 public void explodeViews(AlignFrame af)
1729 int size = af.alignPanels.size();
1735 for (int i = 0; i < size; i++)
1737 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1738 AlignFrame newaf = new AlignFrame(ap);
1739 if (ap.av.explodedPosition != null
1740 && !ap.av.explodedPosition.equals(af.getBounds()))
1742 newaf.setBounds(ap.av.explodedPosition);
1745 ap.av.gatherViewsHere = false;
1747 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1748 AlignFrame.DEFAULT_HEIGHT);
1751 af.alignPanels.clear();
1752 af.closeMenuItem_actionPerformed(true);
1756 public void gatherViews(AlignFrame source)
1758 source.viewport.gatherViewsHere = true;
1759 source.viewport.explodedPosition = source.getBounds();
1760 JInternalFrame[] frames = desktop.getAllFrames();
1761 String viewId = source.viewport.getSequenceSetId();
1763 for (int t = 0; t < frames.length; t++)
1765 if (frames[t] instanceof AlignFrame && frames[t] != source)
1767 AlignFrame af = (AlignFrame) frames[t];
1768 boolean gatherThis = false;
1769 for (int a = 0; a < af.alignPanels.size(); a++)
1771 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1772 if (viewId.equals(ap.av.getSequenceSetId()))
1775 ap.av.gatherViewsHere = false;
1776 ap.av.explodedPosition = af.getBounds();
1777 source.addAlignmentPanel(ap, false);
1783 af.alignPanels.clear();
1784 af.closeMenuItem_actionPerformed(true);
1791 jalview.gui.VamsasApplication v_client = null;
1793 public void vamsasImport_actionPerformed(ActionEvent e)
1795 if (v_client == null)
1797 // Load and try to start a session.
1798 JalviewFileChooser chooser = new JalviewFileChooser(
1799 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1801 chooser.setFileView(new JalviewFileView());
1802 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1803 chooser.setToolTipText(MessageManager
1804 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1806 int value = chooser.showOpenDialog(this);
1808 if (value == JalviewFileChooser.APPROVE_OPTION)
1810 String fle = chooser.getSelectedFile().toString();
1811 if (!vamsasImport(chooser.getSelectedFile()))
1814 .showInternalMessageDialog(
1816 MessageManager.formatMessage(
1817 "label.couldnt_import_as_vamsas_session",
1821 .getString("label.vamsas_document_import_failed"),
1822 JOptionPane.ERROR_MESSAGE);
1828 jalview.bin.Cache.log
1829 .error("Implementation error - load session from a running session is not supported.");
1834 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1837 * @return true if import was a success and a session was started.
1839 public boolean vamsasImport(URL url)
1841 // TODO: create progress bar
1842 if (v_client != null)
1845 jalview.bin.Cache.log
1846 .error("Implementation error - load session from a running session is not supported.");
1852 // copy the URL content to a temporary local file
1853 // TODO: be a bit cleverer here with nio (?!)
1854 File file = File.createTempFile("vdocfromurl", ".vdj");
1855 FileOutputStream fos = new FileOutputStream(file);
1856 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1857 byte[] buffer = new byte[2048];
1859 while ((ln = bis.read(buffer)) > -1)
1861 fos.write(buffer, 0, ln);
1865 v_client = new jalview.gui.VamsasApplication(this, file,
1866 url.toExternalForm());
1867 } catch (Exception ex)
1869 jalview.bin.Cache.log.error(
1870 "Failed to create new vamsas session from contents of URL "
1874 setupVamsasConnectedGui();
1875 v_client.initial_update(); // TODO: thread ?
1876 return v_client.inSession();
1880 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1883 * @return true if import was a success and a session was started.
1885 public boolean vamsasImport(File file)
1887 if (v_client != null)
1890 jalview.bin.Cache.log
1891 .error("Implementation error - load session from a running session is not supported.");
1895 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1899 v_client = new jalview.gui.VamsasApplication(this, file, null);
1900 } catch (Exception ex)
1902 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1904 jalview.bin.Cache.log.error(
1905 "New vamsas session from existing session file failed:", ex);
1908 setupVamsasConnectedGui();
1909 v_client.initial_update(); // TODO: thread ?
1910 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1912 return v_client.inSession();
1915 public boolean joinVamsasSession(String mysesid)
1917 if (v_client != null)
1919 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1921 if (mysesid == null)
1923 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1925 v_client = new VamsasApplication(this, mysesid);
1926 setupVamsasConnectedGui();
1927 v_client.initial_update();
1928 return (v_client.inSession());
1931 public void vamsasStart_actionPerformed(ActionEvent e)
1933 if (v_client == null)
1936 // we just start a default session for moment.
1938 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1939 * getProperty("LAST_DIRECTORY"));
1941 * chooser.setFileView(new JalviewFileView());
1942 * chooser.setDialogTitle("Load Vamsas file");
1943 * chooser.setToolTipText("Import");
1945 * int value = chooser.showOpenDialog(this);
1947 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1948 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1950 v_client = new VamsasApplication(this);
1951 setupVamsasConnectedGui();
1952 v_client.initial_update(); // TODO: thread ?
1956 // store current data in session.
1957 v_client.push_update(); // TODO: thread
1961 protected void setupVamsasConnectedGui()
1963 vamsasStart.setText(MessageManager.getString("label.session_update"));
1964 vamsasSave.setVisible(true);
1965 vamsasStop.setVisible(true);
1966 vamsasImport.setVisible(false); // Document import to existing session is
1967 // not possible for vamsas-client-1.0.
1970 protected void setupVamsasDisconnectedGui()
1972 vamsasSave.setVisible(false);
1973 vamsasStop.setVisible(false);
1974 vamsasImport.setVisible(true);
1975 vamsasStart.setText(MessageManager
1976 .getString("label.new_vamsas_session"));
1979 public void vamsasStop_actionPerformed(ActionEvent e)
1981 if (v_client != null)
1983 v_client.end_session();
1985 setupVamsasDisconnectedGui();
1989 protected void buildVamsasStMenu()
1991 if (v_client == null)
1993 String[] sess = null;
1996 sess = VamsasApplication.getSessionList();
1997 } catch (Exception e)
1999 jalview.bin.Cache.log.warn(
2000 "Problem getting current sessions list.", e);
2005 jalview.bin.Cache.log.debug("Got current sessions list: "
2006 + sess.length + " entries.");
2007 VamsasStMenu.removeAll();
2008 for (int i = 0; i < sess.length; i++)
2010 JMenuItem sessit = new JMenuItem();
2011 sessit.setText(sess[i]);
2012 sessit.setToolTipText(MessageManager.formatMessage(
2013 "label.connect_to_session", new String[]
2015 final Desktop dsktp = this;
2016 final String mysesid = sess[i];
2017 sessit.addActionListener(new ActionListener()
2020 public void actionPerformed(ActionEvent e)
2022 if (dsktp.v_client == null)
2024 Thread rthr = new Thread(new Runnable()
2029 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2030 dsktp.setupVamsasConnectedGui();
2031 dsktp.v_client.initial_update();
2039 VamsasStMenu.add(sessit);
2041 // don't show an empty menu.
2042 VamsasStMenu.setVisible(sess.length > 0);
2047 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2048 VamsasStMenu.removeAll();
2049 VamsasStMenu.setVisible(false);
2054 // Not interested in the content. Just hide ourselves.
2055 VamsasStMenu.setVisible(false);
2059 public void vamsasSave_actionPerformed(ActionEvent e)
2061 if (v_client != null)
2063 JalviewFileChooser chooser = new JalviewFileChooser(
2064 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2065 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2067 { "Vamsas Document" }, "Vamsas Document");
2069 chooser.setFileView(new JalviewFileView());
2070 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2072 int value = chooser.showSaveDialog(this);
2074 if (value == JalviewFileChooser.APPROVE_OPTION)
2076 java.io.File choice = chooser.getSelectedFile();
2077 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2078 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2079 String warnmsg = null;
2080 String warnttl = null;
2083 v_client.vclient.storeDocument(choice);
2086 warnttl = "Serious Problem saving Vamsas Document";
2087 warnmsg = ex.toString();
2088 jalview.bin.Cache.log.error("Error Whilst saving document to "
2091 } catch (Exception ex)
2093 warnttl = "Problem saving Vamsas Document.";
2094 warnmsg = ex.toString();
2095 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2099 removeProgressPanel(progpanel);
2100 if (warnmsg != null)
2102 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2104 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2110 JPanel vamUpdate = null;
2113 * hide vamsas user gui bits when a vamsas document event is being handled.
2116 * true to hide gui, false to reveal gui
2118 public void setVamsasUpdate(boolean b)
2120 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2121 + (b ? "in progress" : "finished"));
2123 if (vamUpdate != null)
2125 this.removeProgressPanel(vamUpdate);
2129 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2131 vamsasStart.setVisible(!b);
2132 vamsasStop.setVisible(!b);
2133 vamsasSave.setVisible(!b);
2136 public JInternalFrame[] getAllFrames()
2138 return desktop.getAllFrames();
2142 * Checks the given url to see if it gives a response indicating that the user
2143 * should be informed of a new questionnaire.
2147 public void checkForQuestionnaire(String url)
2149 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2150 // javax.swing.SwingUtilities.invokeLater(jvq);
2151 new Thread(jvq).start();
2155 * Proxy class for JDesktopPane which optionally displays the current memory
2156 * usage and highlights the desktop area with a red bar if free memory runs
2161 public class MyDesktopPane extends JDesktopPane implements Runnable
2164 boolean showMemoryUsage = false;
2168 java.text.NumberFormat df;
2170 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2173 public MyDesktopPane(boolean showMemoryUsage)
2175 showMemoryUsage(showMemoryUsage);
2178 public void showMemoryUsage(boolean showMemoryUsage)
2180 this.showMemoryUsage = showMemoryUsage;
2181 if (showMemoryUsage)
2183 Thread worker = new Thread(this);
2188 public boolean isShowMemoryUsage()
2190 return showMemoryUsage;
2195 df = java.text.NumberFormat.getNumberInstance();
2196 df.setMaximumFractionDigits(2);
2197 runtime = Runtime.getRuntime();
2199 while (showMemoryUsage)
2203 maxMemory = runtime.maxMemory() / 1048576f;
2204 allocatedMemory = runtime.totalMemory() / 1048576f;
2205 freeMemory = runtime.freeMemory() / 1048576f;
2206 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2208 percentUsage = (totalFreeMemory / maxMemory) * 100;
2210 // if (percentUsage < 20)
2212 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2214 // instance.set.setBorder(border1);
2217 // sleep after showing usage
2219 } catch (Exception ex)
2221 ex.printStackTrace();
2226 public void paintComponent(Graphics g)
2228 if (showMemoryUsage && g != null && df != null)
2230 if (percentUsage < 20)
2232 g.setColor(Color.red);
2234 FontMetrics fm = g.getFontMetrics();
2237 g.drawString(MessageManager.formatMessage(
2238 "label.memory_stats",
2240 { df.format(totalFreeMemory), df.format(maxMemory),
2241 df.format(percentUsage) }), 10,
2242 getHeight() - fm.getHeight());
2249 * fixes stacking order after a modal dialog to ensure windows that should be
2250 * on top actually are
2252 public void relayerWindows()
2257 protected JMenuItem groovyShell;
2259 public void doGroovyCheck()
2261 if (jalview.bin.Cache.groovyJarsPresent())
2263 groovyShell = new JMenuItem();
2264 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2265 groovyShell.addActionListener(new ActionListener()
2267 public void actionPerformed(ActionEvent e)
2269 groovyShell_actionPerformed(e);
2272 toolsMenu.add(groovyShell);
2273 groovyShell.setVisible(true);
2278 * Accessor method to quickly get all the AlignmentFrames loaded.
2280 public static AlignFrame[] getAlignframes()
2282 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2288 Vector avp = new Vector();
2292 for (int i = frames.length - 1; i > -1; i--)
2294 if (frames[i] instanceof AlignFrame)
2296 AlignFrame af = (AlignFrame) frames[i];
2300 } catch (Exception ex)
2302 ex.printStackTrace();
2304 if (avp.size() == 0)
2308 AlignFrame afs[] = new AlignFrame[avp.size()];
2309 for (int i = 0, j = avp.size(); i < j; i++)
2311 afs[i] = (AlignFrame) avp.elementAt(i);
2317 public AppJmol[] getJmols()
2319 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2325 Vector avp = new Vector();
2329 for (int i = frames.length - 1; i > -1; i--)
2331 if (frames[i] instanceof AppJmol)
2333 AppJmol af = (AppJmol) frames[i];
2337 } catch (Exception ex)
2339 ex.printStackTrace();
2341 if (avp.size() == 0)
2345 AppJmol afs[] = new AppJmol[avp.size()];
2346 for (int i = 0, j = avp.size(); i < j; i++)
2348 afs[i] = (AppJmol) avp.elementAt(i);
2355 * Add Groovy Support to Jalview
2357 public void groovyShell_actionPerformed(ActionEvent e)
2359 // use reflection to avoid creating compilation dependency.
2360 if (!jalview.bin.Cache.groovyJarsPresent())
2362 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2366 Class gcClass = Desktop.class.getClassLoader().loadClass(
2367 "groovy.ui.Console");
2368 Constructor gccons = gcClass.getConstructor(null);
2369 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2371 { String.class, Object.class });
2372 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2373 Object gc = gccons.newInstance(null);
2374 setvar.invoke(gc, new Object[]
2375 { "Jalview", this });
2376 run.invoke(gc, null);
2377 } catch (Exception ex)
2379 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2381 .showInternalMessageDialog(
2384 MessageManager.getString("label.couldnt_create_groovy_shell"),
2385 MessageManager.getString("label.groovy_support_failed"),
2386 JOptionPane.ERROR_MESSAGE);
2391 * Progress bars managed by the IProgressIndicator method.
2393 private Hashtable<Long, JPanel> progressBars;
2395 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2400 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2402 public void setProgressBar(String message, long id)
2404 if (progressBars == null)
2406 progressBars = new Hashtable<Long, JPanel>();
2407 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2410 if (progressBars.get(new Long(id)) != null)
2412 JPanel progressPanel = progressBars.remove(new Long(id));
2413 if (progressBarHandlers.contains(new Long(id)))
2415 progressBarHandlers.remove(new Long(id));
2417 removeProgressPanel(progressPanel);
2421 progressBars.put(new Long(id), addProgressPanel(message));
2428 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2429 * jalview.gui.IProgressIndicatorHandler)
2431 public void registerHandler(final long id,
2432 final IProgressIndicatorHandler handler)
2434 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2436 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2438 progressBarHandlers.put(new Long(id), handler);
2439 final JPanel progressPanel = progressBars.get(new Long(id));
2440 if (handler.canCancel())
2442 JButton cancel = new JButton(
2443 MessageManager.getString("action.cancel"));
2444 final IProgressIndicator us = this;
2445 cancel.addActionListener(new ActionListener()
2448 public void actionPerformed(ActionEvent e)
2450 handler.cancelActivity(id);
2451 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2454 progressPanel.add(cancel, BorderLayout.EAST);
2460 * @return true if any progress bars are still active
2463 public boolean operationInProgress()
2465 if (progressBars != null && progressBars.size() > 0)
2473 * This will return the first AlignFrame viewing AlignViewport av. It will
2474 * break if there are more than one AlignFrames viewing a particular av. This
2477 * @return alignFrame for av
2479 public static AlignFrame getAlignFrameFor(AlignViewport av)
2481 if (desktop != null)
2483 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2484 for (int panel = 0; aps != null && panel < aps.length; panel++)
2486 if (aps[panel] != null && aps[panel].av == av)
2488 return aps[panel].alignFrame;
2495 public VamsasApplication getVamsasApplication()
2502 * flag set if jalview GUI is being operated programmatically
2504 private boolean inBatchMode = false;
2507 * check if jalview GUI is being operated programmatically
2509 * @return inBatchMode
2511 public boolean isInBatchMode()
2517 * set flag if jalview GUI is being operated programmatically
2519 * @param inBatchMode
2521 public void setInBatchMode(boolean inBatchMode)
2523 this.inBatchMode = inBatchMode;
2526 public void startServiceDiscovery()
2528 startServiceDiscovery(false);
2531 public void startServiceDiscovery(boolean blocking)
2533 boolean alive = true;
2534 Thread t0 = null, t1 = null, t2 = null;
2535 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2538 // todo: changesupport handlers need to be transferred
2539 if (discoverer == null)
2541 discoverer = new jalview.ws.jws1.Discoverer();
2542 // register PCS handler for desktop.
2543 discoverer.addPropertyChangeListener(changeSupport);
2545 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2546 // until we phase out completely
2547 (t0 = new Thread(discoverer)).start();
2550 // ENFIN services are EOLed as of Jalview 2.8.1 release
2555 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2557 // EnfinEnvision web service menu entries are rebuild every time the
2558 // menu is shown, so no changeSupport events are needed.
2559 jalview.ws.EnfinEnvision2OneWay.getInstance();
2560 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2563 } catch (Exception e)
2566 .info("Exception when trying to launch Envision2 workflow discovery.",
2568 Cache.log.info(e.getStackTrace());
2572 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2574 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2576 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2578 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2584 // TODO: do rest service discovery
2593 } catch (Exception e)
2596 alive = (t1 != null && t1.isAlive())
2597 || (t2 != null && t2.isAlive())
2598 || (t3 != null && t3.isAlive())
2599 || (t0 != null && t0.isAlive());
2605 * called to check if the service discovery process completed successfully.
2609 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2611 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2613 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2614 .getErrorMessages();
2617 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2619 if (serviceChangedDialog == null)
2621 // only run if we aren't already displaying one of these.
2622 addDialogThread(serviceChangedDialog = new Runnable()
2628 * JalviewDialog jd =new JalviewDialog() {
2630 * @Override protected void cancelPressed() { // TODO
2631 * Auto-generated method stub
2633 * }@Override protected void okPressed() { // TODO
2634 * Auto-generated method stub
2636 * }@Override protected void raiseClosed() { // TODO
2637 * Auto-generated method stub
2639 * } }; jd.initDialogFrame(new
2640 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2641 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2642 * + " or mis-configured HTTP proxy settings.<br/>" +
2643 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2645 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2646 * ), true, true, "Web Service Configuration Problem", 450,
2649 * jd.waitForInput();
2655 "<html><table width=\"450\"><tr><td>"
2657 + "</td></tr></table>"
2658 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2659 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2660 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2661 + " Tools->Preferences dialog box to change them.</p></html>"),
2662 "Web Service Configuration Problem",
2663 JOptionPane.DEFAULT_OPTION,
2664 JOptionPane.ERROR_MESSAGE);
2665 serviceChangedDialog = null;
2674 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2681 private Runnable serviceChangedDialog = null;
2684 * start a thread to open a URL in the configured browser. Pops up a warning
2685 * dialog to the user if there is an exception when calling out to the browser
2690 public static void showUrl(final String url)
2692 showUrl(url, Desktop.instance);
2696 * Like showUrl but allows progress handler to be specified
2700 * (null) or object implementing IProgressIndicator
2702 public static void showUrl(final String url,
2703 final IProgressIndicator progress)
2705 new Thread(new Runnable()
2711 if (progress != null)
2713 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2715 jalview.util.BrowserLauncher.openURL(url);
2716 } catch (Exception ex)
2719 .showInternalMessageDialog(
2721 MessageManager.getString("label.web_browser_not_found_unix"),
2722 MessageManager.getString("label.web_browser_not_found"),
2723 JOptionPane.WARNING_MESSAGE);
2725 ex.printStackTrace();
2727 if (progress != null)
2729 progress.setProgressBar(null, this.hashCode());
2735 public static WsParamSetManager wsparamManager = null;
2737 public static ParamManager getUserParameterStore()
2739 if (wsparamManager == null)
2741 wsparamManager = new WsParamSetManager();
2743 return wsparamManager;
2747 * static hyperlink handler proxy method for use by Jalview's internal windows
2751 public static void hyperlinkUpdate(HyperlinkEvent e)
2753 if (e.getEventType() == EventType.ACTIVATED)
2758 url = e.getURL().toString();
2759 Desktop.showUrl(url);
2760 } catch (Exception x)
2764 if (Cache.log != null)
2766 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2770 System.err.println("Couldn't handle string " + url
2774 // ignore any exceptions due to dud links.
2781 * single thread that handles display of dialogs to user.
2783 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2786 * flag indicating if dialogExecutor should try to acquire a permit
2788 private volatile boolean dialogPause = true;
2793 private java.util.concurrent.Semaphore block = new Semaphore(0);
2796 * add another dialog thread to the queue
2800 public void addDialogThread(final Runnable prompter)
2802 dialogExecutor.submit(new Runnable()
2811 } catch (InterruptedException x)
2816 if (instance == null)
2822 SwingUtilities.invokeAndWait(prompter);
2823 } catch (Exception q)
2825 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2831 public void startDialogQueue()
2833 // set the flag so we don't pause waiting for another permit and semaphore
2834 // the current task to begin
2835 dialogPause = false;
2839 protected void snapShotWindow_actionPerformed(ActionEvent e)
2843 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2844 "View of Desktop", getWidth(), getHeight(), of = new File(
2845 "Jalview_snapshot" + System.currentTimeMillis()
2846 + ".eps"), "View of desktop");
2848 paintAll(im.getGraphics());
2850 } catch (Exception q)
2852 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2855 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());