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.util.ImageMaker;
30 import jalview.util.MessageManager;
31 import jalview.ws.params.ParamManager;
33 import java.awt.BorderLayout;
34 import java.awt.Color;
35 import java.awt.Dimension;
36 import java.awt.FontMetrics;
37 import java.awt.Graphics;
38 import java.awt.GridLayout;
39 import java.awt.Point;
40 import java.awt.Rectangle;
41 import java.awt.Toolkit;
42 import java.awt.datatransfer.Clipboard;
43 import java.awt.datatransfer.ClipboardOwner;
44 import java.awt.datatransfer.DataFlavor;
45 import java.awt.datatransfer.Transferable;
46 import java.awt.dnd.DnDConstants;
47 import java.awt.dnd.DropTargetDragEvent;
48 import java.awt.dnd.DropTargetDropEvent;
49 import java.awt.dnd.DropTargetEvent;
50 import java.awt.dnd.DropTargetListener;
51 import java.awt.event.ActionEvent;
52 import java.awt.event.ActionListener;
53 import java.awt.event.FocusEvent;
54 import java.awt.event.FocusListener;
55 import java.awt.event.MouseAdapter;
56 import java.awt.event.MouseEvent;
57 import java.awt.event.MouseListener;
58 import java.awt.event.WindowAdapter;
59 import java.awt.event.WindowEvent;
60 import java.beans.PropertyChangeEvent;
61 import java.beans.PropertyChangeListener;
62 import java.beans.PropertyVetoException;
63 import java.io.BufferedInputStream;
65 import java.io.FileOutputStream;
66 import java.lang.reflect.Constructor;
68 import java.util.ArrayList;
69 import java.util.Hashtable;
70 import java.util.StringTokenizer;
71 import java.util.Vector;
72 import java.util.concurrent.ExecutorService;
73 import java.util.concurrent.Executors;
74 import java.util.concurrent.Semaphore;
76 import javax.swing.DefaultDesktopManager;
77 import javax.swing.DesktopManager;
78 import javax.swing.JButton;
79 import javax.swing.JComboBox;
80 import javax.swing.JComponent;
81 import javax.swing.JDesktopPane;
82 import javax.swing.JFrame;
83 import javax.swing.JInternalFrame;
84 import javax.swing.JLabel;
85 import javax.swing.JMenuItem;
86 import javax.swing.JOptionPane;
87 import javax.swing.JPanel;
88 import javax.swing.JPopupMenu;
89 import javax.swing.JProgressBar;
90 import javax.swing.SwingUtilities;
91 import javax.swing.event.HyperlinkEvent;
92 import javax.swing.event.MenuEvent;
93 import javax.swing.event.MenuListener;
94 import javax.swing.event.HyperlinkEvent.EventType;
101 * @version $Revision: 1.155 $
103 public class Desktop extends jalview.jbgui.GDesktop implements
104 DropTargetListener, ClipboardOwner, IProgressIndicator,
105 jalview.api.StructureSelectionManagerProvider
108 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
111 * news reader - null if it was never started.
113 private BlogReader jvnews = null;
117 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
119 public void addJalviewPropertyChangeListener(
120 PropertyChangeListener listener)
122 changeSupport.addJalviewPropertyChangeListener(listener);
126 * @param propertyName
128 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
129 * java.beans.PropertyChangeListener)
131 public void addJalviewPropertyChangeListener(String propertyName,
132 PropertyChangeListener listener)
134 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
138 * @param propertyName
140 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
141 * java.beans.PropertyChangeListener)
143 public void removeJalviewPropertyChangeListener(String propertyName,
144 PropertyChangeListener listener)
146 changeSupport.removeJalviewPropertyChangeListener(propertyName,
150 /** Singleton Desktop instance */
151 public static Desktop instance;
153 public static MyDesktopPane desktop;
155 static int openFrameCount = 0;
157 static final int xOffset = 30;
159 static final int yOffset = 30;
161 public static jalview.ws.jws1.Discoverer discoverer;
163 public static Object[] jalviewClipboard;
165 public static boolean internalCopy = false;
167 static int fileLoadingCount = 0;
169 class MyDesktopManager implements DesktopManager
172 private DesktopManager delegate;
174 public MyDesktopManager(DesktopManager delegate)
176 this.delegate = delegate;
179 public void activateFrame(JInternalFrame f)
183 delegate.activateFrame(f);
184 } catch (NullPointerException npe)
186 Point p = getMousePosition();
187 instance.showPasteMenu(p.x, p.y);
191 public void beginDraggingFrame(JComponent f)
193 delegate.beginDraggingFrame(f);
196 public void beginResizingFrame(JComponent f, int direction)
198 delegate.beginResizingFrame(f, direction);
201 public void closeFrame(JInternalFrame f)
203 delegate.closeFrame(f);
206 public void deactivateFrame(JInternalFrame f)
208 delegate.deactivateFrame(f);
211 public void deiconifyFrame(JInternalFrame f)
213 delegate.deiconifyFrame(f);
216 public void dragFrame(JComponent f, int newX, int newY)
222 delegate.dragFrame(f, newX, newY);
225 public void endDraggingFrame(JComponent f)
227 delegate.endDraggingFrame(f);
230 public void endResizingFrame(JComponent f)
232 delegate.endResizingFrame(f);
235 public void iconifyFrame(JInternalFrame f)
237 delegate.iconifyFrame(f);
240 public void maximizeFrame(JInternalFrame f)
242 delegate.maximizeFrame(f);
245 public void minimizeFrame(JInternalFrame f)
247 delegate.minimizeFrame(f);
250 public void openFrame(JInternalFrame f)
252 delegate.openFrame(f);
255 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
258 Rectangle b = desktop.getBounds();
263 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
266 public void setBoundsForFrame(JComponent f, int newX, int newY,
267 int newWidth, int newHeight)
269 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
272 // All other methods, simply delegate
277 * Creates a new Desktop object.
282 * A note to implementors. It is ESSENTIAL that any activities that might
283 * block are spawned off as threads rather than waited for during this
287 doVamsasClientCheck();
290 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
291 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
292 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
294 boolean showjconsole = jalview.bin.Cache.getDefault(
295 "SHOW_JAVA_CONSOLE", false);
296 desktop = new MyDesktopPane(selmemusage);
297 showMemusage.setSelected(selmemusage);
298 desktop.setBackground(Color.white);
299 getContentPane().setLayout(new BorderLayout());
300 // alternate config - have scrollbars - see notes in JAL-153
301 // JScrollPane sp = new JScrollPane();
302 // sp.getViewport().setView(desktop);
303 // getContentPane().add(sp, BorderLayout.CENTER);
304 getContentPane().add(desktop, BorderLayout.CENTER);
305 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
307 // This line prevents Windows Look&Feel resizing all new windows to maximum
308 // if previous window was maximised
309 desktop.setDesktopManager(new MyDesktopManager(
310 new DefaultDesktopManager()));
312 Rectangle dims = getLastKnownDimensions("");
319 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
320 setBounds((int) (screenSize.width - 900) / 2,
321 (int) (screenSize.height - 650) / 2, 900, 650);
323 jconsole = new Console(this, showjconsole);
324 // add essential build information
325 jconsole.setHeader("Jalview Desktop "
326 + jalview.bin.Cache.getProperty("VERSION") + "\n"
328 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
329 + "Java version: " + System.getProperty("java.version") + "\n"
330 + System.getProperty("os.arch") + " "
331 + System.getProperty("os.name") + " "
332 + System.getProperty("os.version"));
334 showConsole(showjconsole);
336 showNews.setVisible(false);
338 this.addWindowListener(new WindowAdapter()
340 public void windowClosing(WindowEvent evt)
347 this.addMouseListener(ma = new MouseAdapter()
349 public void mousePressed(MouseEvent evt)
351 if (SwingUtilities.isRightMouseButton(evt))
353 showPasteMenu(evt.getX(), evt.getY());
357 desktop.addMouseListener(ma);
359 this.addFocusListener(new FocusListener()
363 public void focusLost(FocusEvent e)
365 // TODO Auto-generated method stub
370 public void focusGained(FocusEvent e)
372 Cache.log.debug("Relaying windows after focus gain");
373 // make sure that we sort windows properly after we gain focus
374 instance.relayerWindows();
377 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
378 // Spawn a thread that shows the splashscreen
379 SwingUtilities.invokeLater(new Runnable()
388 // Thread off a new instance of the file chooser - this reduces the time it
389 // takes to open it later on.
390 new Thread(new Runnable()
394 Cache.log.debug("Filechooser init thread started.");
395 JalviewFileChooser chooser = new JalviewFileChooser(
396 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
397 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
398 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
399 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
400 Cache.log.debug("Filechooser init thread finished.");
403 // Add the service change listener
404 changeSupport.addJalviewPropertyChangeListener("services",
405 new PropertyChangeListener()
409 public void propertyChange(PropertyChangeEvent evt)
411 Cache.log.debug("Firing service changed event for "
412 + evt.getNewValue());
413 JalviewServicesChanged(evt);
419 public void checkForNews()
421 final Desktop me = this;
422 // Thread off the news reader, in case there are connection problems.
423 addDialogThread(new Runnable()
428 Cache.log.debug("Starting news thread.");
430 jvnews = new BlogReader(me);
431 showNews.setVisible(true);
432 Cache.log.debug("Completed news thread.");
437 protected void showNews_actionPerformed(ActionEvent e)
439 showNews(showNews.isSelected());
442 void showNews(boolean visible)
445 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
446 showNews.setSelected(visible);
447 if (visible && !jvnews.isVisible())
449 new Thread(new Runnable()
454 long instance = System.currentTimeMillis();
455 Desktop.instance.setProgressBar("Refreshing news", instance);
456 jvnews.refreshNews();
457 Desktop.instance.setProgressBar(null, instance);
466 * recover the last known dimensions for a jalview window
469 * - empty string is desktop, all other windows have unique prefix
470 * @return null or last known dimensions scaled to current geometry (if last
471 * window geom was known)
473 Rectangle getLastKnownDimensions(String windowName)
475 // TODO: lock aspect ratio for scaling desktop Bug #0058199
476 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
477 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
478 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
479 String width = jalview.bin.Cache.getProperty(windowName
481 String height = jalview.bin.Cache.getProperty(windowName
483 if ((x != null) && (y != null) && (width != null) && (height != null))
485 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
486 .parseInt(width), ih = Integer.parseInt(height);
487 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
489 // attempt #1 - try to cope with change in screen geometry - this
490 // version doesn't preserve original jv aspect ratio.
491 // take ratio of current screen size vs original screen size.
492 double sw = ((1f * screenSize.width) / (1f * Integer
493 .parseInt(jalview.bin.Cache
494 .getProperty("SCREENGEOMETRY_WIDTH"))));
495 double sh = ((1f * screenSize.height) / (1f * Integer
496 .parseInt(jalview.bin.Cache
497 .getProperty("SCREENGEOMETRY_HEIGHT"))));
498 // rescale the bounds depending upon the current screen geometry.
499 ix = (int) (ix * sw);
500 iw = (int) (iw * sw);
501 iy = (int) (iy * sh);
502 ih = (int) (ih * sh);
503 while (ix >= screenSize.width)
505 jalview.bin.Cache.log
506 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
507 ix -= screenSize.width;
509 while (iy >= screenSize.height)
511 jalview.bin.Cache.log
512 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
513 iy -= screenSize.height;
515 jalview.bin.Cache.log.debug("Got last known dimensions for "
516 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
519 // return dimensions for new instance
520 return new Rectangle(ix, iy, iw, ih);
525 private void doVamsasClientCheck()
527 if (jalview.bin.Cache.vamsasJarsPresent())
529 setupVamsasDisconnectedGui();
530 VamsasMenu.setVisible(true);
531 final Desktop us = this;
532 VamsasMenu.addMenuListener(new MenuListener()
534 // this listener remembers when the menu was first selected, and
535 // doesn't rebuild the session list until it has been cleared and
537 boolean refresh = true;
539 public void menuCanceled(MenuEvent e)
544 public void menuDeselected(MenuEvent e)
549 public void menuSelected(MenuEvent e)
553 us.buildVamsasStMenu();
558 vamsasStart.setVisible(true);
562 void showPasteMenu(int x, int y)
564 JPopupMenu popup = new JPopupMenu();
565 JMenuItem item = new JMenuItem(
566 MessageManager.getString("label.paste_new_window"));
567 item.addActionListener(new ActionListener()
569 public void actionPerformed(ActionEvent evt)
576 popup.show(this, x, y);
583 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
584 Transferable contents = c.getContents(this);
586 if (contents != null)
588 String file = (String) contents
589 .getTransferData(DataFlavor.stringFlavor);
591 String format = new IdentifyFile().Identify(file,
592 FormatAdapter.PASTE);
594 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
597 } catch (Exception ex)
600 .println("Unable to paste alignment from system clipboard:\n"
606 * Adds and opens the given frame to the desktop
617 public static synchronized void addInternalFrame(
618 final JInternalFrame frame, String title, int w, int h)
620 addInternalFrame(frame, title, w, h, true);
637 public static synchronized void addInternalFrame(
638 final JInternalFrame frame, String title, int w, int h,
642 // TODO: allow callers to determine X and Y position of frame (eg. via
644 // TODO: consider fixing method to update entries in the window submenu with
645 // the current window title
647 frame.setTitle(title);
648 if (frame.getWidth() < 1 || frame.getHeight() < 1)
652 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
653 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
654 // IF JALVIEW IS RUNNING HEADLESS
655 // ///////////////////////////////////////////////
657 || (System.getProperty("java.awt.headless") != null && System
658 .getProperty("java.awt.headless").equals("true")))
665 frame.setVisible(true);
666 frame.setClosable(true);
667 frame.setResizable(resizable);
668 frame.setMaximizable(resizable);
669 frame.setIconifiable(resizable);
670 frame.setFrameIcon(null);
672 if (frame.getX() < 1 && frame.getY() < 1)
674 frame.setLocation(xOffset * openFrameCount, yOffset
675 * ((openFrameCount - 1) % 10) + yOffset);
678 final JMenuItem menuItem = new JMenuItem(title);
679 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
681 public void internalFrameActivated(
682 javax.swing.event.InternalFrameEvent evt)
684 JInternalFrame itf = desktop.getSelectedFrame();
692 public void internalFrameClosed(
693 javax.swing.event.InternalFrameEvent evt)
695 PaintRefresher.RemoveComponent(frame);
697 windowMenu.remove(menuItem);
698 JInternalFrame itf = desktop.getSelectedFrame();
707 menuItem.addActionListener(new ActionListener()
709 public void actionPerformed(ActionEvent e)
713 frame.setSelected(true);
714 frame.setIcon(false);
715 } catch (java.beans.PropertyVetoException ex)
721 menuItem.addMouseListener(new MouseListener()
725 public void mouseReleased(MouseEvent e)
730 public void mousePressed(MouseEvent e)
735 public void mouseExited(MouseEvent e)
739 frame.setSelected(false);
740 } catch (PropertyVetoException e1)
746 public void mouseEntered(MouseEvent e)
750 frame.setSelected(true);
751 } catch (PropertyVetoException e1)
757 public void mouseClicked(MouseEvent e)
763 windowMenu.add(menuItem);
769 frame.setSelected(true);
770 frame.requestFocus();
771 } catch (java.beans.PropertyVetoException ve)
773 } catch (java.lang.ClassCastException cex)
776 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
781 public void lostOwnership(Clipboard clipboard, Transferable contents)
785 Desktop.jalviewClipboard = null;
788 internalCopy = false;
791 public void dragEnter(DropTargetDragEvent evt)
795 public void dragExit(DropTargetEvent evt)
799 public void dragOver(DropTargetDragEvent evt)
803 public void dropActionChanged(DropTargetDragEvent evt)
813 public void drop(DropTargetDropEvent evt)
815 boolean success = true;
816 Transferable t = evt.getTransferable();
817 java.util.List files = null;
818 java.util.List protocols = null;
822 DataFlavor uriListFlavor = new DataFlavor(
823 "text/uri-list;class=java.lang.String");
824 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
826 // Works on Windows and MacOSX
827 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
828 files = (java.util.List) t
829 .getTransferData(DataFlavor.javaFileListFlavor);
831 else if (t.isDataFlavorSupported(uriListFlavor))
833 // This is used by Unix drag system
834 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
835 String data = (String) t.getTransferData(uriListFlavor);
836 files = new java.util.ArrayList(1);
837 protocols = new java.util.ArrayList(1);
838 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
839 data, "\r\n"); st.hasMoreTokens();)
841 String s = st.nextToken();
842 if (s.startsWith("#"))
844 // the line is a comment (as per the RFC 2483)
847 java.net.URI uri = new java.net.URI(s);
848 if (uri.getScheme().toLowerCase().startsWith("http"))
850 protocols.add(FormatAdapter.URL);
851 files.add(uri.toString());
855 // otherwise preserve old behaviour: catch all for file objects
856 java.io.File file = new java.io.File(uri);
857 protocols.add(FormatAdapter.FILE);
858 files.add(file.toString());
862 } catch (Exception e)
871 for (int i = 0; i < files.size(); i++)
873 String file = files.get(i).toString();
874 String protocol = (protocols == null) ? FormatAdapter.FILE
875 : (String) protocols.get(i);
876 String format = null;
878 if (file.endsWith(".jar"))
885 format = new IdentifyFile().Identify(file, protocol);
888 new FileLoader().LoadFile(file, protocol, format);
891 } catch (Exception ex)
896 evt.dropComplete(success); // need this to ensure input focus is properly
897 // transfered to any new windows created
906 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
908 JalviewFileChooser chooser = new JalviewFileChooser(
909 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
910 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
911 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
912 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
914 chooser.setFileView(new JalviewFileView());
915 chooser.setDialogTitle(MessageManager
916 .getString("label.open_local_file"));
917 chooser.setToolTipText(MessageManager.getString("action.open"));
919 int value = chooser.showOpenDialog(this);
921 if (value == JalviewFileChooser.APPROVE_OPTION)
923 String choice = chooser.getSelectedFile().getPath();
924 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
925 .getSelectedFile().getParent());
927 String format = null;
928 if (chooser.getSelectedFormat() != null
929 && chooser.getSelectedFormat().equals("Jalview"))
935 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
938 if (viewport != null)
940 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
945 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
956 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
958 // This construct allows us to have a wider textfield
960 JLabel label = new JLabel(
961 MessageManager.getString("label.input_file_url"));
962 final JComboBox history = new JComboBox();
964 JPanel panel = new JPanel(new GridLayout(2, 1));
967 history.setPreferredSize(new Dimension(400, 20));
968 history.setEditable(true);
969 history.addItem("http://www.");
971 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
975 if (historyItems != null)
977 st = new StringTokenizer(historyItems, "\t");
979 while (st.hasMoreTokens())
981 history.addItem(st.nextElement());
985 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
986 MessageManager.getString("label.input_alignment_from_url"),
987 JOptionPane.OK_CANCEL_OPTION);
989 if (reply != JOptionPane.OK_OPTION)
994 String url = history.getSelectedItem().toString();
996 if (url.toLowerCase().endsWith(".jar"))
998 if (viewport != null)
1000 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1005 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1010 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1012 if (format.equals("URL NOT FOUND"))
1014 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1015 "Couldn't locate " + url, "URL not found",
1016 JOptionPane.WARNING_MESSAGE);
1021 if (viewport != null)
1023 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1027 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1038 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1040 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1041 cap.setForInput(viewport);
1042 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1050 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1052 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1053 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1055 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1056 getBounds().y, getWidth(), getHeight()));
1058 if (jconsole != null)
1060 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1061 jconsole.stopConsole();
1065 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1068 if (dialogExecutor != null)
1070 dialogExecutor.shutdownNow();
1076 private void storeLastKnownDimensions(String string, Rectangle jc)
1078 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1079 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1080 + " height:" + jc.height);
1082 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1083 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1084 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1085 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1094 public void aboutMenuItem_actionPerformed(ActionEvent e)
1096 // StringBuffer message = getAboutMessage(false);
1097 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1099 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1100 new Thread(new Runnable()
1104 new SplashScreen(true);
1109 public StringBuffer getAboutMessage(boolean shortv)
1111 StringBuffer message = new StringBuffer();
1112 message.append("<html>");
1115 message.append("<h1><strong>Version: "
1116 + jalview.bin.Cache.getProperty("VERSION")
1117 + "</strong></h1>");
1118 message.append("<strong>Last Updated: <em>"
1119 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1120 + "</em></strong>");
1126 message.append("<strong>Version "
1127 + jalview.bin.Cache.getProperty("VERSION")
1128 + "; last updated: "
1129 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1132 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1135 message.append("<br>...Checking latest version...</br>");
1137 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1138 .equals(jalview.bin.Cache.getProperty("VERSION")))
1140 boolean red = false;
1141 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1142 .indexOf("automated build") == -1)
1145 // Displayed when code version and jnlp version do not match and code
1146 // version is not a development build
1147 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1150 message.append("<br>!! Version "
1151 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1153 + " is available for download from "
1154 + jalview.bin.Cache.getDefault("www.jalview.org",
1155 "http://www.jalview.org") + " !!");
1158 message.append("</div>");
1161 message.append("<br>Authors: "
1165 "The Jalview Authors (See AUTHORS file for current list)")
1166 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1167 + "<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"
1168 + "<br><br>If you use Jalview, please cite:"
1169 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1170 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1171 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1182 public void documentationMenuItem_actionPerformed(ActionEvent e)
1186 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1187 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1188 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1190 javax.help.HelpBroker hb = hs.createHelpBroker();
1191 hb.setCurrentID("home");
1192 hb.setDisplayed(true);
1193 } catch (Exception ex)
1198 public void closeAll_actionPerformed(ActionEvent e)
1200 JInternalFrame[] frames = desktop.getAllFrames();
1201 for (int i = 0; i < frames.length; i++)
1205 frames[i].setClosed(true);
1206 } catch (java.beans.PropertyVetoException ex)
1210 System.out.println("ALL CLOSED");
1211 if (v_client != null)
1213 // TODO clear binding to vamsas document objects on close_all
1218 public void raiseRelated_actionPerformed(ActionEvent e)
1220 reorderAssociatedWindows(false, false);
1223 public void minimizeAssociated_actionPerformed(ActionEvent e)
1225 reorderAssociatedWindows(true, false);
1228 void closeAssociatedWindows()
1230 reorderAssociatedWindows(false, true);
1236 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1239 protected void garbageCollect_actionPerformed(ActionEvent e)
1241 // We simply collect the garbage
1242 jalview.bin.Cache.log.debug("Collecting garbage...");
1244 jalview.bin.Cache.log.debug("Finished garbage collection.");
1251 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1254 protected void showMemusage_actionPerformed(ActionEvent e)
1256 desktop.showMemoryUsage(showMemusage.isSelected());
1263 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1266 protected void showConsole_actionPerformed(ActionEvent e)
1268 showConsole(showConsole.isSelected());
1271 Console jconsole = null;
1274 * control whether the java console is visible or not
1278 void showConsole(boolean selected)
1280 showConsole.setSelected(selected);
1281 // TODO: decide if we should update properties file
1282 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1284 jconsole.setVisible(selected);
1287 void reorderAssociatedWindows(boolean minimize, boolean close)
1289 JInternalFrame[] frames = desktop.getAllFrames();
1290 if (frames == null || frames.length < 1)
1295 AlignViewport source = null, target = null;
1296 if (frames[0] instanceof AlignFrame)
1298 source = ((AlignFrame) frames[0]).getCurrentView();
1300 else if (frames[0] instanceof TreePanel)
1302 source = ((TreePanel) frames[0]).getViewPort();
1304 else if (frames[0] instanceof PCAPanel)
1306 source = ((PCAPanel) frames[0]).av;
1308 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1310 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1315 for (int i = 0; i < frames.length; i++)
1318 if (frames[i] == null)
1322 if (frames[i] instanceof AlignFrame)
1324 target = ((AlignFrame) frames[i]).getCurrentView();
1326 else if (frames[i] instanceof TreePanel)
1328 target = ((TreePanel) frames[i]).getViewPort();
1330 else if (frames[i] instanceof PCAPanel)
1332 target = ((PCAPanel) frames[i]).av;
1334 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1336 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1339 if (source == target)
1345 frames[i].setClosed(true);
1349 frames[i].setIcon(minimize);
1352 frames[i].toFront();
1356 } catch (java.beans.PropertyVetoException ex)
1370 protected void preferences_actionPerformed(ActionEvent e)
1381 public void saveState_actionPerformed(ActionEvent e)
1383 JalviewFileChooser chooser = new JalviewFileChooser(
1384 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1385 { "jvp" }, new String[]
1386 { "Jalview Project" }, "Jalview Project");
1388 chooser.setFileView(new JalviewFileView());
1389 chooser.setDialogTitle("Save State");
1391 int value = chooser.showSaveDialog(this);
1393 if (value == JalviewFileChooser.APPROVE_OPTION)
1395 final Desktop me = this;
1396 final java.io.File choice = chooser.getSelectedFile();
1397 new Thread(new Runnable()
1402 setProgressBar("Saving jalview project " + choice.getName(),
1404 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1405 choice.getParent());
1406 // TODO catch and handle errors for savestate
1407 // TODO prevent user from messing with the Desktop whilst we're saving
1410 new Jalview2XML().SaveState(choice);
1411 } catch (OutOfMemoryError oom)
1413 new OOMWarning("Whilst saving current state to "
1414 + choice.getName(), oom);
1415 } catch (Exception ex)
1418 "Problems whilst trying to save to " + choice.getName(),
1420 JOptionPane.showMessageDialog(
1422 "Error whilst saving current state to "
1423 + choice.getName(), "Couldn't save project",
1424 JOptionPane.WARNING_MESSAGE);
1426 setProgressBar(null, choice.hashCode());
1438 public void loadState_actionPerformed(ActionEvent e)
1440 JalviewFileChooser chooser = new JalviewFileChooser(
1441 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1442 { "jvp", "jar" }, new String[]
1443 { "Jalview Project", "Jalview Project (old)" },
1445 chooser.setFileView(new JalviewFileView());
1446 chooser.setDialogTitle("Restore state");
1448 int value = chooser.showOpenDialog(this);
1450 if (value == JalviewFileChooser.APPROVE_OPTION)
1452 final String choice = chooser.getSelectedFile().getAbsolutePath();
1453 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1454 .getSelectedFile().getParent());
1455 new Thread(new Runnable()
1459 setProgressBar("loading jalview project " + choice,
1463 new Jalview2XML().LoadJalviewAlign(choice);
1464 } catch (OutOfMemoryError oom)
1466 new OOMWarning("Whilst loading project from " + choice, oom);
1467 } catch (Exception ex)
1469 Cache.log.error("Problems whilst loading project from "
1471 JOptionPane.showMessageDialog(Desktop.desktop,
1472 "Error whilst loading project from " + choice,
1473 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1475 setProgressBar(null, choice.hashCode());
1481 public void inputSequence_actionPerformed(ActionEvent e)
1483 new SequenceFetcher(this);
1486 JPanel progressPanel;
1488 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1490 public void startLoading(final String fileName)
1492 if (fileLoadingCount == 0)
1494 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName
1500 private JPanel addProgressPanel(String string)
1502 if (progressPanel == null)
1504 progressPanel = new JPanel(new GridLayout(1, 1));
1505 totalProgressCount = 0;
1506 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1508 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1509 JProgressBar progressBar = new JProgressBar();
1510 progressBar.setIndeterminate(true);
1512 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1514 thisprogress.add(progressBar, BorderLayout.CENTER);
1515 progressPanel.add(thisprogress);
1516 ((GridLayout) progressPanel.getLayout())
1517 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1518 ++totalProgressCount;
1519 instance.validate();
1520 return thisprogress;
1523 int totalProgressCount = 0;
1525 private void removeProgressPanel(JPanel progbar)
1527 if (progressPanel != null)
1529 synchronized (progressPanel)
1531 progressPanel.remove(progbar);
1532 GridLayout gl = (GridLayout) progressPanel.getLayout();
1533 gl.setRows(gl.getRows() - 1);
1534 if (--totalProgressCount < 1)
1536 this.getContentPane().remove(progressPanel);
1537 progressPanel = null;
1544 public void stopLoading()
1547 if (fileLoadingCount < 1)
1549 while (fileLoadingPanels.size() > 0)
1551 removeProgressPanel(fileLoadingPanels.remove(0));
1553 fileLoadingPanels.clear();
1554 fileLoadingCount = 0;
1559 public static int getViewCount(String alignmentId)
1561 AlignViewport[] aps = getViewports(alignmentId);
1562 return (aps == null) ? 0 : aps.length;
1567 * @param alignmentId
1568 * @return all AlignmentPanels concerning the alignmentId sequence set
1570 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1573 if (Desktop.desktop == null)
1575 // no frames created and in headless mode
1576 // TODO: verify that frames are recoverable when in headless mode
1579 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1580 ArrayList aps = new ArrayList();
1581 for (int t = 0; t < frames.length; t++)
1583 if (frames[t] instanceof AlignFrame)
1585 AlignFrame af = (AlignFrame) frames[t];
1586 for (int a = 0; a < af.alignPanels.size(); a++)
1588 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1589 .elementAt(a)).av.getSequenceSetId()))
1591 aps.add(af.alignPanels.elementAt(a));
1596 if (aps.size() == 0)
1600 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1601 for (int t = 0; t < vap.length; t++)
1603 vap[t] = (AlignmentPanel) aps.get(t);
1609 * get all the viewports on an alignment.
1611 * @param sequenceSetId
1612 * unique alignment id
1613 * @return all viewports on the alignment bound to sequenceSetId
1615 public static AlignViewport[] getViewports(String sequenceSetId)
1617 Vector viewp = new Vector();
1618 if (desktop != null)
1620 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1622 for (int t = 0; t < frames.length; t++)
1624 if (frames[t] instanceof AlignFrame)
1626 AlignFrame afr = ((AlignFrame) frames[t]);
1627 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1629 if (afr.alignPanels != null)
1631 for (int a = 0; a < afr.alignPanels.size(); a++)
1633 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1634 .elementAt(a)).av.getSequenceSetId()))
1636 viewp.addElement(((AlignmentPanel) afr.alignPanels
1643 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1648 if (viewp.size() > 0)
1650 AlignViewport[] vp = new AlignViewport[viewp.size()];
1658 public void explodeViews(AlignFrame af)
1660 int size = af.alignPanels.size();
1666 for (int i = 0; i < size; i++)
1668 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1669 AlignFrame newaf = new AlignFrame(ap);
1670 if (ap.av.explodedPosition != null
1671 && !ap.av.explodedPosition.equals(af.getBounds()))
1673 newaf.setBounds(ap.av.explodedPosition);
1676 ap.av.gatherViewsHere = false;
1678 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1679 AlignFrame.DEFAULT_HEIGHT);
1682 af.alignPanels.clear();
1683 af.closeMenuItem_actionPerformed(true);
1687 public void gatherViews(AlignFrame source)
1689 source.viewport.gatherViewsHere = true;
1690 source.viewport.explodedPosition = source.getBounds();
1691 JInternalFrame[] frames = desktop.getAllFrames();
1692 String viewId = source.viewport.getSequenceSetId();
1694 for (int t = 0; t < frames.length; t++)
1696 if (frames[t] instanceof AlignFrame && frames[t] != source)
1698 AlignFrame af = (AlignFrame) frames[t];
1699 boolean gatherThis = false;
1700 for (int a = 0; a < af.alignPanels.size(); a++)
1702 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1703 if (viewId.equals(ap.av.getSequenceSetId()))
1706 ap.av.gatherViewsHere = false;
1707 ap.av.explodedPosition = af.getBounds();
1708 source.addAlignmentPanel(ap, false);
1714 af.alignPanels.clear();
1715 af.closeMenuItem_actionPerformed(true);
1722 jalview.gui.VamsasApplication v_client = null;
1724 public void vamsasImport_actionPerformed(ActionEvent e)
1726 if (v_client == null)
1728 // Load and try to start a session.
1729 JalviewFileChooser chooser = new JalviewFileChooser(
1730 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1732 chooser.setFileView(new JalviewFileView());
1733 chooser.setDialogTitle("Open a saved VAMSAS session");
1734 chooser.setToolTipText(MessageManager
1735 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1737 int value = chooser.showOpenDialog(this);
1739 if (value == JalviewFileChooser.APPROVE_OPTION)
1741 String fle = chooser.getSelectedFile().toString();
1742 if (!vamsasImport(chooser.getSelectedFile()))
1745 .showInternalMessageDialog(
1747 MessageManager.formatMessage(
1748 "label.couldnt_import_as_vamsas_session",
1752 .getString("label.vamsas_document_import_failed"),
1753 JOptionPane.ERROR_MESSAGE);
1759 jalview.bin.Cache.log
1760 .error("Implementation error - load session from a running session is not supported.");
1765 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1768 * @return true if import was a success and a session was started.
1770 public boolean vamsasImport(URL url)
1772 // TODO: create progress bar
1773 if (v_client != null)
1776 jalview.bin.Cache.log
1777 .error("Implementation error - load session from a running session is not supported.");
1783 // copy the URL content to a temporary local file
1784 // TODO: be a bit cleverer here with nio (?!)
1785 File file = File.createTempFile("vdocfromurl", ".vdj");
1786 FileOutputStream fos = new FileOutputStream(file);
1787 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1788 byte[] buffer = new byte[2048];
1790 while ((ln = bis.read(buffer)) > -1)
1792 fos.write(buffer, 0, ln);
1796 v_client = new jalview.gui.VamsasApplication(this, file,
1797 url.toExternalForm());
1798 } catch (Exception ex)
1800 jalview.bin.Cache.log.error(
1801 "Failed to create new vamsas session from contents of URL "
1805 setupVamsasConnectedGui();
1806 v_client.initial_update(); // TODO: thread ?
1807 return v_client.inSession();
1811 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1814 * @return true if import was a success and a session was started.
1816 public boolean vamsasImport(File file)
1818 if (v_client != null)
1821 jalview.bin.Cache.log
1822 .error("Implementation error - load session from a running session is not supported.");
1826 setProgressBar("Importing VAMSAS session from " + file.getName(),
1830 v_client = new jalview.gui.VamsasApplication(this, file, null);
1831 } catch (Exception ex)
1833 setProgressBar("Importing VAMSAS session from " + file.getName(),
1835 jalview.bin.Cache.log.error(
1836 "New vamsas session from existing session file failed:", ex);
1839 setupVamsasConnectedGui();
1840 v_client.initial_update(); // TODO: thread ?
1841 setProgressBar("Importing VAMSAS session from " + file.getName(),
1843 return v_client.inSession();
1846 public boolean joinVamsasSession(String mysesid)
1848 if (v_client != null)
1851 "Trying to join a vamsas session when another is already connected.");
1853 if (mysesid == null)
1855 throw new Error("Invalid vamsas session id.");
1857 v_client = new VamsasApplication(this, mysesid);
1858 setupVamsasConnectedGui();
1859 v_client.initial_update();
1860 return (v_client.inSession());
1863 public void vamsasStart_actionPerformed(ActionEvent e)
1865 if (v_client == null)
1868 // we just start a default session for moment.
1870 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1871 * getProperty("LAST_DIRECTORY"));
1873 * chooser.setFileView(new JalviewFileView());
1874 * chooser.setDialogTitle("Load Vamsas file");
1875 * chooser.setToolTipText("Import");
1877 * int value = chooser.showOpenDialog(this);
1879 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1880 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1882 v_client = new VamsasApplication(this);
1883 setupVamsasConnectedGui();
1884 v_client.initial_update(); // TODO: thread ?
1888 // store current data in session.
1889 v_client.push_update(); // TODO: thread
1893 protected void setupVamsasConnectedGui()
1895 vamsasStart.setText(MessageManager.getString("label.session_update"));
1896 vamsasSave.setVisible(true);
1897 vamsasStop.setVisible(true);
1898 vamsasImport.setVisible(false); // Document import to existing session is
1899 // not possible for vamsas-client-1.0.
1902 protected void setupVamsasDisconnectedGui()
1904 vamsasSave.setVisible(false);
1905 vamsasStop.setVisible(false);
1906 vamsasImport.setVisible(true);
1907 vamsasStart.setText(MessageManager
1908 .getString("label.new_vamsas_session"));
1911 public void vamsasStop_actionPerformed(ActionEvent e)
1913 if (v_client != null)
1915 v_client.end_session();
1917 setupVamsasDisconnectedGui();
1921 protected void buildVamsasStMenu()
1923 if (v_client == null)
1925 String[] sess = null;
1928 sess = VamsasApplication.getSessionList();
1929 } catch (Exception e)
1931 jalview.bin.Cache.log.warn(
1932 "Problem getting current sessions list.", e);
1937 jalview.bin.Cache.log.debug("Got current sessions list: "
1938 + sess.length + " entries.");
1939 VamsasStMenu.removeAll();
1940 for (int i = 0; i < sess.length; i++)
1942 JMenuItem sessit = new JMenuItem();
1943 sessit.setText(sess[i]);
1944 sessit.setToolTipText(MessageManager.formatMessage(
1945 "label.connect_to_session", new String[]
1947 final Desktop dsktp = this;
1948 final String mysesid = sess[i];
1949 sessit.addActionListener(new ActionListener()
1952 public void actionPerformed(ActionEvent e)
1954 if (dsktp.v_client == null)
1956 Thread rthr = new Thread(new Runnable()
1961 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1962 dsktp.setupVamsasConnectedGui();
1963 dsktp.v_client.initial_update();
1971 VamsasStMenu.add(sessit);
1973 // don't show an empty menu.
1974 VamsasStMenu.setVisible(sess.length > 0);
1979 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1980 VamsasStMenu.removeAll();
1981 VamsasStMenu.setVisible(false);
1986 // Not interested in the content. Just hide ourselves.
1987 VamsasStMenu.setVisible(false);
1991 public void vamsasSave_actionPerformed(ActionEvent e)
1993 if (v_client != null)
1995 JalviewFileChooser chooser = new JalviewFileChooser(
1996 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1997 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1999 { "Vamsas Document" }, "Vamsas Document");
2001 chooser.setFileView(new JalviewFileView());
2002 chooser.setDialogTitle("Save Vamsas Document Archive");
2004 int value = chooser.showSaveDialog(this);
2006 if (value == JalviewFileChooser.APPROVE_OPTION)
2008 java.io.File choice = chooser.getSelectedFile();
2009 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
2010 + choice.getName());
2011 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2012 String warnmsg = null;
2013 String warnttl = null;
2016 v_client.vclient.storeDocument(choice);
2019 warnttl = "Serious Problem saving Vamsas Document";
2020 warnmsg = ex.toString();
2021 jalview.bin.Cache.log.error("Error Whilst saving document to "
2024 } catch (Exception ex)
2026 warnttl = "Problem saving Vamsas Document.";
2027 warnmsg = ex.toString();
2028 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2032 removeProgressPanel(progpanel);
2033 if (warnmsg != null)
2035 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2037 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2043 JPanel vamUpdate = null;
2046 * hide vamsas user gui bits when a vamsas document event is being handled.
2049 * true to hide gui, false to reveal gui
2051 public void setVamsasUpdate(boolean b)
2053 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2054 + (b ? "in progress" : "finished"));
2056 if (vamUpdate != null)
2058 this.removeProgressPanel(vamUpdate);
2062 vamUpdate = this.addProgressPanel("Updating vamsas session");
2064 vamsasStart.setVisible(!b);
2065 vamsasStop.setVisible(!b);
2066 vamsasSave.setVisible(!b);
2069 public JInternalFrame[] getAllFrames()
2071 return desktop.getAllFrames();
2075 * Checks the given url to see if it gives a response indicating that the user
2076 * should be informed of a new questionnaire.
2080 public void checkForQuestionnaire(String url)
2082 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2083 // javax.swing.SwingUtilities.invokeLater(jvq);
2084 new Thread(jvq).start();
2088 * Proxy class for JDesktopPane which optionally displays the current memory
2089 * usage and highlights the desktop area with a red bar if free memory runs
2094 public class MyDesktopPane extends JDesktopPane implements Runnable
2097 boolean showMemoryUsage = false;
2101 java.text.NumberFormat df;
2103 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2106 public MyDesktopPane(boolean showMemoryUsage)
2108 showMemoryUsage(showMemoryUsage);
2111 public void showMemoryUsage(boolean showMemoryUsage)
2113 this.showMemoryUsage = showMemoryUsage;
2114 if (showMemoryUsage)
2116 Thread worker = new Thread(this);
2121 public boolean isShowMemoryUsage()
2123 return showMemoryUsage;
2128 df = java.text.NumberFormat.getNumberInstance();
2129 df.setMaximumFractionDigits(2);
2130 runtime = Runtime.getRuntime();
2132 while (showMemoryUsage)
2136 maxMemory = runtime.maxMemory() / 1048576f;
2137 allocatedMemory = runtime.totalMemory() / 1048576f;
2138 freeMemory = runtime.freeMemory() / 1048576f;
2139 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2141 percentUsage = (totalFreeMemory / maxMemory) * 100;
2143 // if (percentUsage < 20)
2145 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2147 // instance.set.setBorder(border1);
2150 // sleep after showing usage
2152 } catch (Exception ex)
2154 ex.printStackTrace();
2159 public void paintComponent(Graphics g)
2161 if (showMemoryUsage && g != null && df != null)
2163 if (percentUsage < 20)
2164 g.setColor(Color.red);
2165 FontMetrics fm = g.getFontMetrics();
2168 g.drawString(MessageManager.formatMessage(
2169 "label.memory_stats",
2171 { df.format(totalFreeMemory), df.format(maxMemory),
2172 df.format(percentUsage) }), 10,
2173 getHeight() - fm.getHeight());
2180 * fixes stacking order after a modal dialog to ensure windows that should be
2181 * on top actually are
2183 public void relayerWindows()
2188 protected JMenuItem groovyShell;
2190 public void doGroovyCheck()
2192 if (jalview.bin.Cache.groovyJarsPresent())
2194 groovyShell = new JMenuItem();
2195 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2196 groovyShell.addActionListener(new ActionListener()
2198 public void actionPerformed(ActionEvent e)
2200 groovyShell_actionPerformed(e);
2203 toolsMenu.add(groovyShell);
2204 groovyShell.setVisible(true);
2209 * Accessor method to quickly get all the AlignmentFrames loaded.
2211 public static AlignFrame[] getAlignframes()
2213 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2219 Vector avp = new Vector();
2223 for (int i = frames.length - 1; i > -1; i--)
2225 if (frames[i] instanceof AlignFrame)
2227 AlignFrame af = (AlignFrame) frames[i];
2231 } catch (Exception ex)
2233 ex.printStackTrace();
2235 if (avp.size() == 0)
2239 AlignFrame afs[] = new AlignFrame[avp.size()];
2240 for (int i = 0, j = avp.size(); i < j; i++)
2242 afs[i] = (AlignFrame) avp.elementAt(i);
2248 public AppJmol[] getJmols()
2250 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2256 Vector avp = new Vector();
2260 for (int i = frames.length - 1; i > -1; i--)
2262 if (frames[i] instanceof AppJmol)
2264 AppJmol af = (AppJmol) frames[i];
2268 } catch (Exception ex)
2270 ex.printStackTrace();
2272 if (avp.size() == 0)
2276 AppJmol afs[] = new AppJmol[avp.size()];
2277 for (int i = 0, j = avp.size(); i < j; i++)
2279 afs[i] = (AppJmol) avp.elementAt(i);
2286 * Add Groovy Support to Jalview
2288 public void groovyShell_actionPerformed(ActionEvent e)
2290 // use reflection to avoid creating compilation dependency.
2291 if (!jalview.bin.Cache.groovyJarsPresent())
2294 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2298 Class gcClass = Desktop.class.getClassLoader().loadClass(
2299 "groovy.ui.Console");
2300 Constructor gccons = gcClass.getConstructor(null);
2301 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2303 { String.class, Object.class });
2304 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2305 Object gc = gccons.newInstance(null);
2306 setvar.invoke(gc, new Object[]
2307 { "Jalview", this });
2308 run.invoke(gc, null);
2309 } catch (Exception ex)
2311 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2313 .showInternalMessageDialog(
2316 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2317 "Jalview Groovy Support Failed",
2318 JOptionPane.ERROR_MESSAGE);
2323 * Progress bars managed by the IProgressIndicator method.
2325 private Hashtable<Long, JPanel> progressBars;
2327 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2332 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2334 public void setProgressBar(String message, long id)
2336 if (progressBars == null)
2338 progressBars = new Hashtable<Long, JPanel>();
2339 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2342 if (progressBars.get(new Long(id)) != null)
2344 JPanel progressPanel = progressBars.remove(new Long(id));
2345 if (progressBarHandlers.contains(new Long(id)))
2347 progressBarHandlers.remove(new Long(id));
2349 removeProgressPanel(progressPanel);
2353 progressBars.put(new Long(id), addProgressPanel(message));
2360 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2361 * jalview.gui.IProgressIndicatorHandler)
2363 public void registerHandler(final long id,
2364 final IProgressIndicatorHandler handler)
2366 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2369 "call setProgressBar before registering the progress bar's handler.");
2371 progressBarHandlers.put(new Long(id), handler);
2372 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2373 if (handler.canCancel())
2375 JButton cancel = new JButton(
2376 MessageManager.getString("action.cancel"));
2377 final IProgressIndicator us = this;
2378 cancel.addActionListener(new ActionListener()
2381 public void actionPerformed(ActionEvent e)
2383 handler.cancelActivity(id);
2386 + ((JLabel) progressPanel.getComponent(0))
2390 progressPanel.add(cancel, BorderLayout.EAST);
2396 * @return true if any progress bars are still active
2399 public boolean operationInProgress()
2401 if (progressBars != null && progressBars.size() > 0)
2409 * This will return the first AlignFrame viewing AlignViewport av. It will
2410 * break if there are more than one AlignFrames viewing a particular av. This
2413 * @return alignFrame for av
2415 public static AlignFrame getAlignFrameFor(AlignViewport av)
2417 if (desktop != null)
2419 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2420 for (int panel = 0; aps != null && panel < aps.length; panel++)
2422 if (aps[panel] != null && aps[panel].av == av)
2424 return aps[panel].alignFrame;
2431 public VamsasApplication getVamsasApplication()
2438 * flag set if jalview GUI is being operated programmatically
2440 private boolean inBatchMode = false;
2443 * check if jalview GUI is being operated programmatically
2445 * @return inBatchMode
2447 public boolean isInBatchMode()
2453 * set flag if jalview GUI is being operated programmatically
2455 * @param inBatchMode
2457 public void setInBatchMode(boolean inBatchMode)
2459 this.inBatchMode = inBatchMode;
2462 public void startServiceDiscovery()
2464 startServiceDiscovery(false);
2467 public void startServiceDiscovery(boolean blocking)
2469 boolean alive = true;
2470 Thread t0 = null, t1 = null, t2 = null;
2471 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2474 // todo: changesupport handlers need to be transferred
2475 if (discoverer == null)
2477 discoverer = new jalview.ws.jws1.Discoverer();
2478 // register PCS handler for desktop.
2479 discoverer.addPropertyChangeListener(changeSupport);
2481 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2482 // until we phase out completely
2483 (t0 = new Thread(discoverer)).start();
2486 // ENFIN services are EOLed as of Jalview 2.8.1 release
2491 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2493 // EnfinEnvision web service menu entries are rebuild every time the
2494 // menu is shown, so no changeSupport events are needed.
2495 jalview.ws.EnfinEnvision2OneWay.getInstance();
2496 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2499 } catch (Exception e)
2502 .info("Exception when trying to launch Envision2 workflow discovery.",
2504 Cache.log.info(e.getStackTrace());
2508 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2510 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2512 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2514 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2520 // TODO: do rest service discovery
2529 } catch (Exception e)
2532 alive = (t1 != null && t1.isAlive())
2533 || (t2 != null && t2.isAlive())
2534 || (t3 != null && t3.isAlive())
2535 || (t0 != null && t0.isAlive());
2541 * called to check if the service discovery process completed successfully.
2545 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2547 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2549 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2550 .getErrorMessages();
2553 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2555 if (serviceChangedDialog == null)
2557 // only run if we aren't already displaying one of these.
2558 addDialogThread(serviceChangedDialog = new Runnable()
2564 * JalviewDialog jd =new JalviewDialog() {
2566 * @Override protected void cancelPressed() { // TODO
2567 * Auto-generated method stub
2569 * }@Override protected void okPressed() { // TODO
2570 * Auto-generated method stub
2572 * }@Override protected void raiseClosed() { // TODO
2573 * Auto-generated method stub
2575 * } }; jd.initDialogFrame(new
2576 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2577 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2578 * + " or mis-configured HTTP proxy settings.<br/>" +
2579 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2581 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2582 * ), true, true, "Web Service Configuration Problem", 450,
2585 * jd.waitForInput();
2591 "<html><table width=\"450\"><tr><td>"
2593 + "</td></tr></table>"
2594 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2595 + " or mis-configured HTTP proxy settings.</p>"
2596 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2597 + " Tools->Preferences dialog box to change them.</p></html>"),
2598 "Web Service Configuration Problem",
2599 JOptionPane.DEFAULT_OPTION,
2600 JOptionPane.ERROR_MESSAGE);
2601 serviceChangedDialog = null;
2610 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2617 private Runnable serviceChangedDialog = null;
2620 * start a thread to open a URL in the configured browser. Pops up a warning
2621 * dialog to the user if there is an exception when calling out to the browser
2626 public static void showUrl(final String url)
2628 showUrl(url, Desktop.instance);
2632 * Like showUrl but allows progress handler to be specified
2636 * (null) or object implementing IProgressIndicator
2638 public static void showUrl(final String url,
2639 final IProgressIndicator progress)
2641 new Thread(new Runnable()
2647 if (progress != null)
2649 progress.setProgressBar("Opening " + url, this.hashCode());
2651 jalview.util.BrowserLauncher.openURL(url);
2652 } catch (Exception ex)
2655 .showInternalMessageDialog(
2657 "Unixers: Couldn't find default web browser."
2658 + "\nAdd the full path to your browser in Preferences.",
2659 "Web browser not found",
2660 JOptionPane.WARNING_MESSAGE);
2662 ex.printStackTrace();
2664 if (progress != null)
2666 progress.setProgressBar(null, this.hashCode());
2672 public static WsParamSetManager wsparamManager = null;
2674 public static ParamManager getUserParameterStore()
2676 if (wsparamManager == null)
2678 wsparamManager = new WsParamSetManager();
2680 return wsparamManager;
2684 * static hyperlink handler proxy method for use by Jalview's internal windows
2688 public static void hyperlinkUpdate(HyperlinkEvent e)
2690 if (e.getEventType() == EventType.ACTIVATED)
2695 url = e.getURL().toString();
2696 Desktop.showUrl(url);
2697 } catch (Exception x)
2701 if (Cache.log != null)
2703 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2707 System.err.println("Couldn't handle string " + url
2711 // ignore any exceptions due to dud links.
2718 * single thread that handles display of dialogs to user.
2720 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2723 * flag indicating if dialogExecutor should try to acquire a permit
2725 private volatile boolean dialogPause = true;
2730 private java.util.concurrent.Semaphore block = new Semaphore(0);
2733 * add another dialog thread to the queue
2737 public void addDialogThread(final Runnable prompter)
2739 dialogExecutor.submit(new Runnable()
2748 } catch (InterruptedException x)
2753 if (instance == null)
2759 SwingUtilities.invokeAndWait(prompter);
2760 } catch (Exception q)
2762 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2768 public void startDialogQueue()
2770 // set the flag so we don't pause waiting for another permit and semaphore
2771 // the current task to begin
2772 dialogPause = false;
2776 protected void snapShotWindow_actionPerformed(ActionEvent e)
2780 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.EPS, "View of Desktop", getWidth(), getHeight(), of=new File("Jalview_snapshot"+System.currentTimeMillis()+".eps"), "View of desktop");
2782 paintAll(im.getGraphics());
2784 } catch (Exception q)
2786 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2789 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());