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.HyperlinkEvent.EventType;
93 import javax.swing.event.MenuEvent;
94 import javax.swing.event.MenuListener;
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((screenSize.width - 900) / 2,
321 (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(MessageManager.getString("status.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 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.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, MessageManager.getString("label.cut_paste_alignmen_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 Help.showHelpWindow();
1187 } catch (Exception ex)
1192 public void closeAll_actionPerformed(ActionEvent e)
1194 JInternalFrame[] frames = desktop.getAllFrames();
1195 for (int i = 0; i < frames.length; i++)
1199 frames[i].setClosed(true);
1200 } catch (java.beans.PropertyVetoException ex)
1204 System.out.println("ALL CLOSED");
1205 if (v_client != null)
1207 // TODO clear binding to vamsas document objects on close_all
1212 public void raiseRelated_actionPerformed(ActionEvent e)
1214 reorderAssociatedWindows(false, false);
1217 public void minimizeAssociated_actionPerformed(ActionEvent e)
1219 reorderAssociatedWindows(true, false);
1222 void closeAssociatedWindows()
1224 reorderAssociatedWindows(false, true);
1230 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1233 protected void garbageCollect_actionPerformed(ActionEvent e)
1235 // We simply collect the garbage
1236 jalview.bin.Cache.log.debug("Collecting garbage...");
1238 jalview.bin.Cache.log.debug("Finished garbage collection.");
1245 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1248 protected void showMemusage_actionPerformed(ActionEvent e)
1250 desktop.showMemoryUsage(showMemusage.isSelected());
1257 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1260 protected void showConsole_actionPerformed(ActionEvent e)
1262 showConsole(showConsole.isSelected());
1265 Console jconsole = null;
1268 * control whether the java console is visible or not
1272 void showConsole(boolean selected)
1274 showConsole.setSelected(selected);
1275 // TODO: decide if we should update properties file
1276 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1278 jconsole.setVisible(selected);
1281 void reorderAssociatedWindows(boolean minimize, boolean close)
1283 JInternalFrame[] frames = desktop.getAllFrames();
1284 if (frames == null || frames.length < 1)
1289 AlignViewport source = null, target = null;
1290 if (frames[0] instanceof AlignFrame)
1292 source = ((AlignFrame) frames[0]).getCurrentView();
1294 else if (frames[0] instanceof TreePanel)
1296 source = ((TreePanel) frames[0]).getViewPort();
1298 else if (frames[0] instanceof PCAPanel)
1300 source = ((PCAPanel) frames[0]).av;
1302 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1304 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1309 for (int i = 0; i < frames.length; i++)
1312 if (frames[i] == null)
1316 if (frames[i] instanceof AlignFrame)
1318 target = ((AlignFrame) frames[i]).getCurrentView();
1320 else if (frames[i] instanceof TreePanel)
1322 target = ((TreePanel) frames[i]).getViewPort();
1324 else if (frames[i] instanceof PCAPanel)
1326 target = ((PCAPanel) frames[i]).av;
1328 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1330 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1333 if (source == target)
1339 frames[i].setClosed(true);
1343 frames[i].setIcon(minimize);
1346 frames[i].toFront();
1350 } catch (java.beans.PropertyVetoException ex)
1364 protected void preferences_actionPerformed(ActionEvent e)
1375 public void saveState_actionPerformed(ActionEvent e)
1377 JalviewFileChooser chooser = new JalviewFileChooser(
1378 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1379 { "jvp" }, new String[]
1380 { "Jalview Project" }, "Jalview Project");
1382 chooser.setFileView(new JalviewFileView());
1383 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1385 int value = chooser.showSaveDialog(this);
1387 if (value == JalviewFileChooser.APPROVE_OPTION)
1389 final Desktop me = this;
1390 final java.io.File choice = chooser.getSelectedFile();
1391 new Thread(new Runnable()
1396 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1398 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1399 choice.getParent());
1400 // TODO catch and handle errors for savestate
1401 // TODO prevent user from messing with the Desktop whilst we're saving
1404 new Jalview2XML().SaveState(choice);
1405 } catch (OutOfMemoryError oom)
1407 new OOMWarning("Whilst saving current state to "
1408 + choice.getName(), oom);
1409 } catch (Exception ex)
1412 "Problems whilst trying to save to " + choice.getName(),
1414 JOptionPane.showMessageDialog(
1416 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1417 MessageManager.getString("label.couldnt_save_project"),
1418 JOptionPane.WARNING_MESSAGE);
1420 setProgressBar(null, choice.hashCode());
1432 public void loadState_actionPerformed(ActionEvent e)
1434 JalviewFileChooser chooser = new JalviewFileChooser(
1435 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1436 { "jvp", "jar" }, new String[]
1437 { "Jalview Project", "Jalview Project (old)" },
1439 chooser.setFileView(new JalviewFileView());
1440 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1442 int value = chooser.showOpenDialog(this);
1444 if (value == JalviewFileChooser.APPROVE_OPTION)
1446 final String choice = chooser.getSelectedFile().getAbsolutePath();
1447 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1448 .getSelectedFile().getParent());
1449 new Thread(new Runnable()
1453 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1457 new Jalview2XML().LoadJalviewAlign(choice);
1458 } catch (OutOfMemoryError oom)
1460 new OOMWarning("Whilst loading project from " + choice, oom);
1461 } catch (Exception ex)
1463 Cache.log.error("Problems whilst loading project from "
1465 JOptionPane.showMessageDialog(Desktop.desktop,
1466 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1467 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1469 setProgressBar(null, choice.hashCode());
1475 public void inputSequence_actionPerformed(ActionEvent e)
1477 new SequenceFetcher(this);
1480 JPanel progressPanel;
1482 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1484 public void startLoading(final String fileName)
1486 if (fileLoadingCount == 0)
1488 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1493 private JPanel addProgressPanel(String string)
1495 if (progressPanel == null)
1497 progressPanel = new JPanel(new GridLayout(1, 1));
1498 totalProgressCount = 0;
1499 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1501 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1502 JProgressBar progressBar = new JProgressBar();
1503 progressBar.setIndeterminate(true);
1505 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1507 thisprogress.add(progressBar, BorderLayout.CENTER);
1508 progressPanel.add(thisprogress);
1509 ((GridLayout) progressPanel.getLayout())
1510 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1511 ++totalProgressCount;
1512 instance.validate();
1513 return thisprogress;
1516 int totalProgressCount = 0;
1518 private void removeProgressPanel(JPanel progbar)
1520 if (progressPanel != null)
1522 synchronized (progressPanel)
1524 progressPanel.remove(progbar);
1525 GridLayout gl = (GridLayout) progressPanel.getLayout();
1526 gl.setRows(gl.getRows() - 1);
1527 if (--totalProgressCount < 1)
1529 this.getContentPane().remove(progressPanel);
1530 progressPanel = null;
1537 public void stopLoading()
1540 if (fileLoadingCount < 1)
1542 while (fileLoadingPanels.size() > 0)
1544 removeProgressPanel(fileLoadingPanels.remove(0));
1546 fileLoadingPanels.clear();
1547 fileLoadingCount = 0;
1552 public static int getViewCount(String alignmentId)
1554 AlignViewport[] aps = getViewports(alignmentId);
1555 return (aps == null) ? 0 : aps.length;
1560 * @param alignmentId
1561 * @return all AlignmentPanels concerning the alignmentId sequence set
1563 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1566 if (Desktop.desktop == null)
1568 // no frames created and in headless mode
1569 // TODO: verify that frames are recoverable when in headless mode
1572 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1573 ArrayList aps = new ArrayList();
1574 for (int t = 0; t < frames.length; t++)
1576 if (frames[t] instanceof AlignFrame)
1578 AlignFrame af = (AlignFrame) frames[t];
1579 for (int a = 0; a < af.alignPanels.size(); a++)
1581 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1582 .elementAt(a)).av.getSequenceSetId()))
1584 aps.add(af.alignPanels.elementAt(a));
1589 if (aps.size() == 0)
1593 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1594 for (int t = 0; t < vap.length; t++)
1596 vap[t] = (AlignmentPanel) aps.get(t);
1602 * get all the viewports on an alignment.
1604 * @param sequenceSetId
1605 * unique alignment id
1606 * @return all viewports on the alignment bound to sequenceSetId
1608 public static AlignViewport[] getViewports(String sequenceSetId)
1610 Vector viewp = new Vector();
1611 if (desktop != null)
1613 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1615 for (int t = 0; t < frames.length; t++)
1617 if (frames[t] instanceof AlignFrame)
1619 AlignFrame afr = ((AlignFrame) frames[t]);
1620 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1622 if (afr.alignPanels != null)
1624 for (int a = 0; a < afr.alignPanels.size(); a++)
1626 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1627 .elementAt(a)).av.getSequenceSetId()))
1629 viewp.addElement(((AlignmentPanel) afr.alignPanels
1636 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1641 if (viewp.size() > 0)
1643 AlignViewport[] vp = new AlignViewport[viewp.size()];
1651 public void explodeViews(AlignFrame af)
1653 int size = af.alignPanels.size();
1659 for (int i = 0; i < size; i++)
1661 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1662 AlignFrame newaf = new AlignFrame(ap);
1663 if (ap.av.explodedPosition != null
1664 && !ap.av.explodedPosition.equals(af.getBounds()))
1666 newaf.setBounds(ap.av.explodedPosition);
1669 ap.av.gatherViewsHere = false;
1671 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1672 AlignFrame.DEFAULT_HEIGHT);
1675 af.alignPanels.clear();
1676 af.closeMenuItem_actionPerformed(true);
1680 public void gatherViews(AlignFrame source)
1682 source.viewport.gatherViewsHere = true;
1683 source.viewport.explodedPosition = source.getBounds();
1684 JInternalFrame[] frames = desktop.getAllFrames();
1685 String viewId = source.viewport.getSequenceSetId();
1687 for (int t = 0; t < frames.length; t++)
1689 if (frames[t] instanceof AlignFrame && frames[t] != source)
1691 AlignFrame af = (AlignFrame) frames[t];
1692 boolean gatherThis = false;
1693 for (int a = 0; a < af.alignPanels.size(); a++)
1695 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1696 if (viewId.equals(ap.av.getSequenceSetId()))
1699 ap.av.gatherViewsHere = false;
1700 ap.av.explodedPosition = af.getBounds();
1701 source.addAlignmentPanel(ap, false);
1707 af.alignPanels.clear();
1708 af.closeMenuItem_actionPerformed(true);
1715 jalview.gui.VamsasApplication v_client = null;
1717 public void vamsasImport_actionPerformed(ActionEvent e)
1719 if (v_client == null)
1721 // Load and try to start a session.
1722 JalviewFileChooser chooser = new JalviewFileChooser(
1723 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1725 chooser.setFileView(new JalviewFileView());
1726 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1727 chooser.setToolTipText(MessageManager
1728 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1730 int value = chooser.showOpenDialog(this);
1732 if (value == JalviewFileChooser.APPROVE_OPTION)
1734 String fle = chooser.getSelectedFile().toString();
1735 if (!vamsasImport(chooser.getSelectedFile()))
1738 .showInternalMessageDialog(
1740 MessageManager.formatMessage(
1741 "label.couldnt_import_as_vamsas_session",
1745 .getString("label.vamsas_document_import_failed"),
1746 JOptionPane.ERROR_MESSAGE);
1752 jalview.bin.Cache.log
1753 .error("Implementation error - load session from a running session is not supported.");
1758 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1761 * @return true if import was a success and a session was started.
1763 public boolean vamsasImport(URL url)
1765 // TODO: create progress bar
1766 if (v_client != null)
1769 jalview.bin.Cache.log
1770 .error("Implementation error - load session from a running session is not supported.");
1776 // copy the URL content to a temporary local file
1777 // TODO: be a bit cleverer here with nio (?!)
1778 File file = File.createTempFile("vdocfromurl", ".vdj");
1779 FileOutputStream fos = new FileOutputStream(file);
1780 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1781 byte[] buffer = new byte[2048];
1783 while ((ln = bis.read(buffer)) > -1)
1785 fos.write(buffer, 0, ln);
1789 v_client = new jalview.gui.VamsasApplication(this, file,
1790 url.toExternalForm());
1791 } catch (Exception ex)
1793 jalview.bin.Cache.log.error(
1794 "Failed to create new vamsas session from contents of URL "
1798 setupVamsasConnectedGui();
1799 v_client.initial_update(); // TODO: thread ?
1800 return v_client.inSession();
1804 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1807 * @return true if import was a success and a session was started.
1809 public boolean vamsasImport(File file)
1811 if (v_client != null)
1814 jalview.bin.Cache.log
1815 .error("Implementation error - load session from a running session is not supported.");
1819 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1823 v_client = new jalview.gui.VamsasApplication(this, file, null);
1824 } catch (Exception ex)
1826 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1828 jalview.bin.Cache.log.error(
1829 "New vamsas session from existing session file failed:", ex);
1832 setupVamsasConnectedGui();
1833 v_client.initial_update(); // TODO: thread ?
1834 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1836 return v_client.inSession();
1839 public boolean joinVamsasSession(String mysesid)
1841 if (v_client != null)
1843 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1845 if (mysesid == null)
1847 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1849 v_client = new VamsasApplication(this, mysesid);
1850 setupVamsasConnectedGui();
1851 v_client.initial_update();
1852 return (v_client.inSession());
1855 public void vamsasStart_actionPerformed(ActionEvent e)
1857 if (v_client == null)
1860 // we just start a default session for moment.
1862 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1863 * getProperty("LAST_DIRECTORY"));
1865 * chooser.setFileView(new JalviewFileView());
1866 * chooser.setDialogTitle("Load Vamsas file");
1867 * chooser.setToolTipText("Import");
1869 * int value = chooser.showOpenDialog(this);
1871 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1872 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1874 v_client = new VamsasApplication(this);
1875 setupVamsasConnectedGui();
1876 v_client.initial_update(); // TODO: thread ?
1880 // store current data in session.
1881 v_client.push_update(); // TODO: thread
1885 protected void setupVamsasConnectedGui()
1887 vamsasStart.setText(MessageManager.getString("label.session_update"));
1888 vamsasSave.setVisible(true);
1889 vamsasStop.setVisible(true);
1890 vamsasImport.setVisible(false); // Document import to existing session is
1891 // not possible for vamsas-client-1.0.
1894 protected void setupVamsasDisconnectedGui()
1896 vamsasSave.setVisible(false);
1897 vamsasStop.setVisible(false);
1898 vamsasImport.setVisible(true);
1899 vamsasStart.setText(MessageManager
1900 .getString("label.new_vamsas_session"));
1903 public void vamsasStop_actionPerformed(ActionEvent e)
1905 if (v_client != null)
1907 v_client.end_session();
1909 setupVamsasDisconnectedGui();
1913 protected void buildVamsasStMenu()
1915 if (v_client == null)
1917 String[] sess = null;
1920 sess = VamsasApplication.getSessionList();
1921 } catch (Exception e)
1923 jalview.bin.Cache.log.warn(
1924 "Problem getting current sessions list.", e);
1929 jalview.bin.Cache.log.debug("Got current sessions list: "
1930 + sess.length + " entries.");
1931 VamsasStMenu.removeAll();
1932 for (int i = 0; i < sess.length; i++)
1934 JMenuItem sessit = new JMenuItem();
1935 sessit.setText(sess[i]);
1936 sessit.setToolTipText(MessageManager.formatMessage(
1937 "label.connect_to_session", new String[]
1939 final Desktop dsktp = this;
1940 final String mysesid = sess[i];
1941 sessit.addActionListener(new ActionListener()
1944 public void actionPerformed(ActionEvent e)
1946 if (dsktp.v_client == null)
1948 Thread rthr = new Thread(new Runnable()
1953 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1954 dsktp.setupVamsasConnectedGui();
1955 dsktp.v_client.initial_update();
1963 VamsasStMenu.add(sessit);
1965 // don't show an empty menu.
1966 VamsasStMenu.setVisible(sess.length > 0);
1971 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1972 VamsasStMenu.removeAll();
1973 VamsasStMenu.setVisible(false);
1978 // Not interested in the content. Just hide ourselves.
1979 VamsasStMenu.setVisible(false);
1983 public void vamsasSave_actionPerformed(ActionEvent e)
1985 if (v_client != null)
1987 JalviewFileChooser chooser = new JalviewFileChooser(
1988 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1989 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1991 { "Vamsas Document" }, "Vamsas Document");
1993 chooser.setFileView(new JalviewFileView());
1994 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
1996 int value = chooser.showSaveDialog(this);
1998 if (value == JalviewFileChooser.APPROVE_OPTION)
2000 java.io.File choice = chooser.getSelectedFile();
2001 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2002 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2003 String warnmsg = null;
2004 String warnttl = null;
2007 v_client.vclient.storeDocument(choice);
2010 warnttl = "Serious Problem saving Vamsas Document";
2011 warnmsg = ex.toString();
2012 jalview.bin.Cache.log.error("Error Whilst saving document to "
2015 } catch (Exception ex)
2017 warnttl = "Problem saving Vamsas Document.";
2018 warnmsg = ex.toString();
2019 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2023 removeProgressPanel(progpanel);
2024 if (warnmsg != null)
2026 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2028 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2034 JPanel vamUpdate = null;
2037 * hide vamsas user gui bits when a vamsas document event is being handled.
2040 * true to hide gui, false to reveal gui
2042 public void setVamsasUpdate(boolean b)
2044 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2045 + (b ? "in progress" : "finished"));
2047 if (vamUpdate != null)
2049 this.removeProgressPanel(vamUpdate);
2053 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2055 vamsasStart.setVisible(!b);
2056 vamsasStop.setVisible(!b);
2057 vamsasSave.setVisible(!b);
2060 public JInternalFrame[] getAllFrames()
2062 return desktop.getAllFrames();
2066 * Checks the given url to see if it gives a response indicating that the user
2067 * should be informed of a new questionnaire.
2071 public void checkForQuestionnaire(String url)
2073 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2074 // javax.swing.SwingUtilities.invokeLater(jvq);
2075 new Thread(jvq).start();
2079 * Proxy class for JDesktopPane which optionally displays the current memory
2080 * usage and highlights the desktop area with a red bar if free memory runs
2085 public class MyDesktopPane extends JDesktopPane implements Runnable
2088 boolean showMemoryUsage = false;
2092 java.text.NumberFormat df;
2094 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2097 public MyDesktopPane(boolean showMemoryUsage)
2099 showMemoryUsage(showMemoryUsage);
2102 public void showMemoryUsage(boolean showMemoryUsage)
2104 this.showMemoryUsage = showMemoryUsage;
2105 if (showMemoryUsage)
2107 Thread worker = new Thread(this);
2112 public boolean isShowMemoryUsage()
2114 return showMemoryUsage;
2119 df = java.text.NumberFormat.getNumberInstance();
2120 df.setMaximumFractionDigits(2);
2121 runtime = Runtime.getRuntime();
2123 while (showMemoryUsage)
2127 maxMemory = runtime.maxMemory() / 1048576f;
2128 allocatedMemory = runtime.totalMemory() / 1048576f;
2129 freeMemory = runtime.freeMemory() / 1048576f;
2130 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2132 percentUsage = (totalFreeMemory / maxMemory) * 100;
2134 // if (percentUsage < 20)
2136 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2138 // instance.set.setBorder(border1);
2141 // sleep after showing usage
2143 } catch (Exception ex)
2145 ex.printStackTrace();
2150 public void paintComponent(Graphics g)
2152 if (showMemoryUsage && g != null && df != null)
2154 if (percentUsage < 20)
2156 g.setColor(Color.red);
2158 FontMetrics fm = g.getFontMetrics();
2161 g.drawString(MessageManager.formatMessage(
2162 "label.memory_stats",
2164 { df.format(totalFreeMemory), df.format(maxMemory),
2165 df.format(percentUsage) }), 10,
2166 getHeight() - fm.getHeight());
2173 * fixes stacking order after a modal dialog to ensure windows that should be
2174 * on top actually are
2176 public void relayerWindows()
2181 protected JMenuItem groovyShell;
2183 public void doGroovyCheck()
2185 if (jalview.bin.Cache.groovyJarsPresent())
2187 groovyShell = new JMenuItem();
2188 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2189 groovyShell.addActionListener(new ActionListener()
2191 public void actionPerformed(ActionEvent e)
2193 groovyShell_actionPerformed(e);
2196 toolsMenu.add(groovyShell);
2197 groovyShell.setVisible(true);
2202 * Accessor method to quickly get all the AlignmentFrames loaded.
2204 public static AlignFrame[] getAlignframes()
2206 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2212 Vector avp = new Vector();
2216 for (int i = frames.length - 1; i > -1; i--)
2218 if (frames[i] instanceof AlignFrame)
2220 AlignFrame af = (AlignFrame) frames[i];
2224 } catch (Exception ex)
2226 ex.printStackTrace();
2228 if (avp.size() == 0)
2232 AlignFrame afs[] = new AlignFrame[avp.size()];
2233 for (int i = 0, j = avp.size(); i < j; i++)
2235 afs[i] = (AlignFrame) avp.elementAt(i);
2241 public AppJmol[] getJmols()
2243 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2249 Vector avp = new Vector();
2253 for (int i = frames.length - 1; i > -1; i--)
2255 if (frames[i] instanceof AppJmol)
2257 AppJmol af = (AppJmol) frames[i];
2261 } catch (Exception ex)
2263 ex.printStackTrace();
2265 if (avp.size() == 0)
2269 AppJmol afs[] = new AppJmol[avp.size()];
2270 for (int i = 0, j = avp.size(); i < j; i++)
2272 afs[i] = (AppJmol) avp.elementAt(i);
2279 * Add Groovy Support to Jalview
2281 public void groovyShell_actionPerformed(ActionEvent e)
2283 // use reflection to avoid creating compilation dependency.
2284 if (!jalview.bin.Cache.groovyJarsPresent())
2286 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2290 Class gcClass = Desktop.class.getClassLoader().loadClass(
2291 "groovy.ui.Console");
2292 Constructor gccons = gcClass.getConstructor(null);
2293 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2295 { String.class, Object.class });
2296 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2297 Object gc = gccons.newInstance(null);
2298 setvar.invoke(gc, new Object[]
2299 { "Jalview", this });
2300 run.invoke(gc, null);
2301 } catch (Exception ex)
2303 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2305 .showInternalMessageDialog(
2308 MessageManager.getString("label.couldnt_create_groovy_shell"),
2309 MessageManager.getString("label.groovy_support_failed"),
2310 JOptionPane.ERROR_MESSAGE);
2315 * Progress bars managed by the IProgressIndicator method.
2317 private Hashtable<Long, JPanel> progressBars;
2319 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2324 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2326 public void setProgressBar(String message, long id)
2328 if (progressBars == null)
2330 progressBars = new Hashtable<Long, JPanel>();
2331 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2334 if (progressBars.get(new Long(id)) != null)
2336 JPanel progressPanel = progressBars.remove(new Long(id));
2337 if (progressBarHandlers.contains(new Long(id)))
2339 progressBarHandlers.remove(new Long(id));
2341 removeProgressPanel(progressPanel);
2345 progressBars.put(new Long(id), addProgressPanel(message));
2352 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2353 * jalview.gui.IProgressIndicatorHandler)
2355 public void registerHandler(final long id,
2356 final IProgressIndicatorHandler handler)
2358 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2360 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2362 progressBarHandlers.put(new Long(id), handler);
2363 final JPanel progressPanel = progressBars.get(new Long(id));
2364 if (handler.canCancel())
2366 JButton cancel = new JButton(
2367 MessageManager.getString("action.cancel"));
2368 final IProgressIndicator us = this;
2369 cancel.addActionListener(new ActionListener()
2372 public void actionPerformed(ActionEvent e)
2374 handler.cancelActivity(id);
2375 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2378 progressPanel.add(cancel, BorderLayout.EAST);
2384 * @return true if any progress bars are still active
2387 public boolean operationInProgress()
2389 if (progressBars != null && progressBars.size() > 0)
2397 * This will return the first AlignFrame viewing AlignViewport av. It will
2398 * break if there are more than one AlignFrames viewing a particular av. This
2401 * @return alignFrame for av
2403 public static AlignFrame getAlignFrameFor(AlignViewport av)
2405 if (desktop != null)
2407 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2408 for (int panel = 0; aps != null && panel < aps.length; panel++)
2410 if (aps[panel] != null && aps[panel].av == av)
2412 return aps[panel].alignFrame;
2419 public VamsasApplication getVamsasApplication()
2426 * flag set if jalview GUI is being operated programmatically
2428 private boolean inBatchMode = false;
2431 * check if jalview GUI is being operated programmatically
2433 * @return inBatchMode
2435 public boolean isInBatchMode()
2441 * set flag if jalview GUI is being operated programmatically
2443 * @param inBatchMode
2445 public void setInBatchMode(boolean inBatchMode)
2447 this.inBatchMode = inBatchMode;
2450 public void startServiceDiscovery()
2452 startServiceDiscovery(false);
2455 public void startServiceDiscovery(boolean blocking)
2457 boolean alive = true;
2458 Thread t0 = null, t1 = null, t2 = null;
2459 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2462 // todo: changesupport handlers need to be transferred
2463 if (discoverer == null)
2465 discoverer = new jalview.ws.jws1.Discoverer();
2466 // register PCS handler for desktop.
2467 discoverer.addPropertyChangeListener(changeSupport);
2469 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2470 // until we phase out completely
2471 (t0 = new Thread(discoverer)).start();
2474 // ENFIN services are EOLed as of Jalview 2.8.1 release
2479 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2481 // EnfinEnvision web service menu entries are rebuild every time the
2482 // menu is shown, so no changeSupport events are needed.
2483 jalview.ws.EnfinEnvision2OneWay.getInstance();
2484 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2487 } catch (Exception e)
2490 .info("Exception when trying to launch Envision2 workflow discovery.",
2492 Cache.log.info(e.getStackTrace());
2496 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2498 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2500 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2502 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2508 // TODO: do rest service discovery
2517 } catch (Exception e)
2520 alive = (t1 != null && t1.isAlive())
2521 || (t2 != null && t2.isAlive())
2522 || (t3 != null && t3.isAlive())
2523 || (t0 != null && t0.isAlive());
2529 * called to check if the service discovery process completed successfully.
2533 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2535 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2537 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2538 .getErrorMessages();
2541 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2543 if (serviceChangedDialog == null)
2545 // only run if we aren't already displaying one of these.
2546 addDialogThread(serviceChangedDialog = new Runnable()
2552 * JalviewDialog jd =new JalviewDialog() {
2554 * @Override protected void cancelPressed() { // TODO
2555 * Auto-generated method stub
2557 * }@Override protected void okPressed() { // TODO
2558 * Auto-generated method stub
2560 * }@Override protected void raiseClosed() { // TODO
2561 * Auto-generated method stub
2563 * } }; jd.initDialogFrame(new
2564 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2565 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2566 * + " or mis-configured HTTP proxy settings.<br/>" +
2567 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2569 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2570 * ), true, true, "Web Service Configuration Problem", 450,
2573 * jd.waitForInput();
2579 "<html><table width=\"450\"><tr><td>"
2581 + "</td></tr></table>"
2582 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2583 + " or mis-configured HTTP proxy settings.</p>"
2584 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2585 + " Tools->Preferences dialog box to change them.</p></html>"),
2586 "Web Service Configuration Problem",
2587 JOptionPane.DEFAULT_OPTION,
2588 JOptionPane.ERROR_MESSAGE);
2589 serviceChangedDialog = null;
2598 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2605 private Runnable serviceChangedDialog = null;
2608 * start a thread to open a URL in the configured browser. Pops up a warning
2609 * dialog to the user if there is an exception when calling out to the browser
2614 public static void showUrl(final String url)
2616 showUrl(url, Desktop.instance);
2620 * Like showUrl but allows progress handler to be specified
2624 * (null) or object implementing IProgressIndicator
2626 public static void showUrl(final String url,
2627 final IProgressIndicator progress)
2629 new Thread(new Runnable()
2635 if (progress != null)
2637 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2639 jalview.util.BrowserLauncher.openURL(url);
2640 } catch (Exception ex)
2643 .showInternalMessageDialog(
2645 MessageManager.getString("label.web_browser_not_found_unix"),
2646 MessageManager.getString("label.web_browser_not_found"),
2647 JOptionPane.WARNING_MESSAGE);
2649 ex.printStackTrace();
2651 if (progress != null)
2653 progress.setProgressBar(null, this.hashCode());
2659 public static WsParamSetManager wsparamManager = null;
2661 public static ParamManager getUserParameterStore()
2663 if (wsparamManager == null)
2665 wsparamManager = new WsParamSetManager();
2667 return wsparamManager;
2671 * static hyperlink handler proxy method for use by Jalview's internal windows
2675 public static void hyperlinkUpdate(HyperlinkEvent e)
2677 if (e.getEventType() == EventType.ACTIVATED)
2682 url = e.getURL().toString();
2683 Desktop.showUrl(url);
2684 } catch (Exception x)
2688 if (Cache.log != null)
2690 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2694 System.err.println("Couldn't handle string " + url
2698 // ignore any exceptions due to dud links.
2705 * single thread that handles display of dialogs to user.
2707 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2710 * flag indicating if dialogExecutor should try to acquire a permit
2712 private volatile boolean dialogPause = true;
2717 private java.util.concurrent.Semaphore block = new Semaphore(0);
2720 * add another dialog thread to the queue
2724 public void addDialogThread(final Runnable prompter)
2726 dialogExecutor.submit(new Runnable()
2735 } catch (InterruptedException x)
2740 if (instance == null)
2746 SwingUtilities.invokeAndWait(prompter);
2747 } catch (Exception q)
2749 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2755 public void startDialogQueue()
2757 // set the flag so we don't pause waiting for another permit and semaphore
2758 // the current task to begin
2759 dialogPause = false;
2763 protected void snapShotWindow_actionPerformed(ActionEvent e)
2767 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2768 "View of Desktop", getWidth(), getHeight(), of = new File(
2769 "Jalview_snapshot" + System.currentTimeMillis()
2770 + ".eps"), "View of desktop");
2772 paintAll(im.getGraphics());
2774 } catch (Exception q)
2776 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2779 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());