2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import jalview.bin.Cache;
21 import jalview.io.FileLoader;
22 import jalview.io.FormatAdapter;
23 import jalview.io.IdentifyFile;
24 import jalview.io.JalviewFileChooser;
25 import jalview.io.JalviewFileView;
26 import jalview.ws.params.ParamManager;
28 import java.awt.BorderLayout;
29 import java.awt.Color;
30 import java.awt.Dimension;
31 import java.awt.FontMetrics;
32 import java.awt.Graphics;
33 import java.awt.GridLayout;
34 import java.awt.Point;
35 import java.awt.Rectangle;
36 import java.awt.Toolkit;
37 import java.awt.datatransfer.Clipboard;
38 import java.awt.datatransfer.ClipboardOwner;
39 import java.awt.datatransfer.DataFlavor;
40 import java.awt.datatransfer.Transferable;
41 import java.awt.dnd.DnDConstants;
42 import java.awt.dnd.DropTargetDragEvent;
43 import java.awt.dnd.DropTargetDropEvent;
44 import java.awt.dnd.DropTargetEvent;
45 import java.awt.dnd.DropTargetListener;
46 import java.awt.event.ActionEvent;
47 import java.awt.event.ActionListener;
48 import java.awt.event.FocusEvent;
49 import java.awt.event.FocusListener;
50 import java.awt.event.MouseAdapter;
51 import java.awt.event.MouseEvent;
52 import java.awt.event.MouseListener;
53 import java.awt.event.WindowAdapter;
54 import java.awt.event.WindowEvent;
55 import java.beans.PropertyChangeEvent;
56 import java.beans.PropertyChangeListener;
57 import java.beans.PropertyVetoException;
58 import java.io.BufferedInputStream;
60 import java.io.FileOutputStream;
61 import java.lang.reflect.Constructor;
63 import java.util.ArrayList;
64 import java.util.Hashtable;
65 import java.util.StringTokenizer;
66 import java.util.Vector;
68 import javax.swing.DefaultDesktopManager;
69 import javax.swing.DesktopManager;
70 import javax.swing.JButton;
71 import javax.swing.JComboBox;
72 import javax.swing.JComponent;
73 import javax.swing.JDesktopPane;
74 import javax.swing.JFrame;
75 import javax.swing.JInternalFrame;
76 import javax.swing.JLabel;
77 import javax.swing.JMenuItem;
78 import javax.swing.JOptionPane;
79 import javax.swing.JPanel;
80 import javax.swing.JPopupMenu;
81 import javax.swing.JProgressBar;
82 import javax.swing.SwingUtilities;
83 import javax.swing.event.HyperlinkEvent;
84 import javax.swing.event.MenuEvent;
85 import javax.swing.event.MenuListener;
86 import javax.swing.event.HyperlinkEvent.EventType;
93 * @version $Revision: 1.155 $
95 public class Desktop extends jalview.jbgui.GDesktop implements
96 DropTargetListener, ClipboardOwner, IProgressIndicator, jalview.api.StructureSelectionManagerProvider
99 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
102 * news reader - null if it was never started.
104 private BlogReader jvnews=null;
108 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
110 public void addJalviewPropertyChangeListener(
111 PropertyChangeListener listener)
113 changeSupport.addJalviewPropertyChangeListener(listener);
117 * @param propertyName
119 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
120 * java.beans.PropertyChangeListener)
122 public void addJalviewPropertyChangeListener(String propertyName,
123 PropertyChangeListener listener)
125 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
129 * @param propertyName
131 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
132 * java.beans.PropertyChangeListener)
134 public void removeJalviewPropertyChangeListener(String propertyName,
135 PropertyChangeListener listener)
137 changeSupport.removeJalviewPropertyChangeListener(propertyName,
141 /** Singleton Desktop instance */
142 public static Desktop instance;
144 public static MyDesktopPane desktop;
146 static int openFrameCount = 0;
148 static final int xOffset = 30;
150 static final int yOffset = 30;
152 public static jalview.ws.jws1.Discoverer discoverer;
154 public static Object[] jalviewClipboard;
156 public static boolean internalCopy = false;
158 static int fileLoadingCount = 0;
160 class MyDesktopManager implements DesktopManager
163 private DesktopManager delegate;
165 public MyDesktopManager(DesktopManager delegate)
167 this.delegate = delegate;
170 public void activateFrame(JInternalFrame f)
174 delegate.activateFrame(f);
175 } catch (NullPointerException npe)
177 Point p = getMousePosition();
178 instance.showPasteMenu(p.x, p.y);
182 public void beginDraggingFrame(JComponent f)
184 delegate.beginDraggingFrame(f);
187 public void beginResizingFrame(JComponent f, int direction)
189 delegate.beginResizingFrame(f, direction);
192 public void closeFrame(JInternalFrame f)
194 delegate.closeFrame(f);
197 public void deactivateFrame(JInternalFrame f)
199 delegate.deactivateFrame(f);
202 public void deiconifyFrame(JInternalFrame f)
204 delegate.deiconifyFrame(f);
207 public void dragFrame(JComponent f, int newX, int newY)
213 delegate.dragFrame(f, newX, newY);
216 public void endDraggingFrame(JComponent f)
218 delegate.endDraggingFrame(f);
221 public void endResizingFrame(JComponent f)
223 delegate.endResizingFrame(f);
226 public void iconifyFrame(JInternalFrame f)
228 delegate.iconifyFrame(f);
231 public void maximizeFrame(JInternalFrame f)
233 delegate.maximizeFrame(f);
236 public void minimizeFrame(JInternalFrame f)
238 delegate.minimizeFrame(f);
241 public void openFrame(JInternalFrame f)
243 delegate.openFrame(f);
246 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
249 Rectangle b=desktop.getBounds();
254 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
257 public void setBoundsForFrame(JComponent f, int newX, int newY,
258 int newWidth, int newHeight)
260 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
263 // All other methods, simply delegate
268 * Creates a new Desktop object.
273 * A note to implementors. It is ESSENTIAL that any activities that might
274 * block are spawned off as threads rather than waited for during this
278 doVamsasClientCheck();
281 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
282 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
283 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
285 boolean showjconsole = jalview.bin.Cache.getDefault(
286 "SHOW_JAVA_CONSOLE", false);
287 desktop = new MyDesktopPane(selmemusage);
288 showMemusage.setSelected(selmemusage);
289 desktop.setBackground(Color.white);
290 getContentPane().setLayout(new BorderLayout());
291 // alternate config - have scrollbars - see notes in JAL-153
292 //JScrollPane sp = new JScrollPane();
293 //sp.getViewport().setView(desktop);
294 //getContentPane().add(sp, BorderLayout.CENTER);
295 getContentPane().add(desktop, BorderLayout.CENTER);
296 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
299 // This line prevents Windows Look&Feel resizing all new windows to maximum
300 // if previous window was maximised
301 desktop.setDesktopManager(new MyDesktopManager(
302 new DefaultDesktopManager()));
304 Rectangle dims = getLastKnownDimensions("");
311 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
312 setBounds((int) (screenSize.width - 900) / 2,
313 (int) (screenSize.height - 650) / 2, 900, 650);
315 jconsole = new Console(this, showjconsole);
316 // add essential build information
317 jconsole.setHeader("Jalview Desktop "
318 + jalview.bin.Cache.getProperty("VERSION") + "\n"
320 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
321 + "Java version: " + System.getProperty("java.version") + "\n"
322 + System.getProperty("os.arch") + " "
323 + System.getProperty("os.name") + " "
324 + System.getProperty("os.version"));
326 showConsole(showjconsole);
328 showNews.setVisible(false);
329 final Desktop me = this;
330 // Thread off the news reader, in case there are connection problems.
331 new Thread( new Runnable() {
335 Cache.log.debug("Starting news thread.");
337 jvnews = new BlogReader(me);
338 showNews.setVisible(true);
339 Cache.log.debug("Completed news thread.");
343 this.addWindowListener(new WindowAdapter()
345 public void windowClosing(WindowEvent evt)
352 this.addMouseListener(ma=new MouseAdapter()
354 public void mousePressed(MouseEvent evt)
356 if (SwingUtilities.isRightMouseButton(evt))
358 showPasteMenu(evt.getX(), evt.getY());
362 desktop.addMouseListener(ma);
364 this.addFocusListener(new FocusListener()
368 public void focusLost(FocusEvent e)
370 // TODO Auto-generated method stub
375 public void focusGained(FocusEvent e)
377 Cache.log.debug("Relaying windows after focus gain");
378 // make sure that we sort windows properly after we gain focus
379 instance.relayerWindows();
382 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
383 // Spawn a thread that shows the splashscreen
384 SwingUtilities.invokeLater(new Runnable()
393 // Thread off a new instance of the file chooser - this reduces the time it
394 // takes to open it later on.
395 new Thread(new Runnable()
399 Cache.log.debug("Filechooser init thread started.");
400 JalviewFileChooser chooser = new JalviewFileChooser(
401 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
402 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
403 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
404 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
405 Cache.log.debug("Filechooser init thread finished.");
408 // Add the service change listener
409 changeSupport.addJalviewPropertyChangeListener("services",
410 new PropertyChangeListener()
414 public void propertyChange(PropertyChangeEvent evt)
416 Cache.log.debug("Firing service changed event for "
417 + evt.getNewValue());
418 JalviewServicesChanged(evt);
424 protected void showNews_actionPerformed(ActionEvent e)
426 showNews(showNews.isSelected());
428 void showNews(boolean visible)
431 Cache.log.debug((visible?"Showing":"Hiding")+" news.");
432 showNews.setSelected(visible);
433 if (visible && !jvnews.isVisible())
435 new Thread(new Runnable() {
439 long instance=System.currentTimeMillis();
440 Desktop.instance.setProgressBar("Refreshing news", instance);
441 jvnews.refreshNews();
442 Desktop.instance.setProgressBar(null, instance);
451 * recover the last known dimensions for a jalview window
454 * - empty string is desktop, all other windows have unique prefix
455 * @return null or last known dimensions scaled to current geometry (if last
456 * window geom was known)
458 Rectangle getLastKnownDimensions(String windowName)
460 // TODO: lock aspect ratio for scaling desktop Bug #0058199
461 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
462 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
463 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
464 String width = jalview.bin.Cache.getProperty(windowName
466 String height = jalview.bin.Cache.getProperty(windowName
468 if ((x != null) && (y != null) && (width != null) && (height != null))
470 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
471 .parseInt(width), ih = Integer.parseInt(height);
472 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
474 // attempt #1 - try to cope with change in screen geometry - this
475 // version doesn't preserve original jv aspect ratio.
476 // take ratio of current screen size vs original screen size.
477 double sw = ((1f * screenSize.width) / (1f * Integer
478 .parseInt(jalview.bin.Cache
479 .getProperty("SCREENGEOMETRY_WIDTH"))));
480 double sh = ((1f * screenSize.height) / (1f * Integer
481 .parseInt(jalview.bin.Cache
482 .getProperty("SCREENGEOMETRY_HEIGHT"))));
483 // rescale the bounds depending upon the current screen geometry.
484 ix = (int) (ix * sw);
485 iw = (int) (iw * sw);
486 iy = (int) (iy * sh);
487 ih = (int) (ih * sh);
488 while (ix >= screenSize.width)
490 jalview.bin.Cache.log
491 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
492 ix -= screenSize.width;
494 while (iy >= screenSize.height)
496 jalview.bin.Cache.log
497 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
498 iy -= screenSize.height;
500 jalview.bin.Cache.log.debug("Got last known dimensions for "
501 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
504 // return dimensions for new instance
505 return new Rectangle(ix, iy, iw, ih);
510 private void doVamsasClientCheck()
512 if (jalview.bin.Cache.vamsasJarsPresent())
514 setupVamsasDisconnectedGui();
515 VamsasMenu.setVisible(true);
516 final Desktop us = this;
517 VamsasMenu.addMenuListener(new MenuListener()
519 // this listener remembers when the menu was first selected, and
520 // doesn't rebuild the session list until it has been cleared and
522 boolean refresh = true;
524 public void menuCanceled(MenuEvent e)
529 public void menuDeselected(MenuEvent e)
534 public void menuSelected(MenuEvent e)
538 us.buildVamsasStMenu();
543 vamsasStart.setVisible(true);
547 void showPasteMenu(int x, int y)
549 JPopupMenu popup = new JPopupMenu();
550 JMenuItem item = new JMenuItem("Paste To New Window");
551 item.addActionListener(new ActionListener()
553 public void actionPerformed(ActionEvent evt)
560 popup.show(this, x, y);
567 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
568 Transferable contents = c.getContents(this);
570 if (contents != null)
572 String file = (String) contents
573 .getTransferData(DataFlavor.stringFlavor);
575 String format = new IdentifyFile().Identify(file,
576 FormatAdapter.PASTE);
578 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
581 } catch (Exception ex)
584 .println("Unable to paste alignment from system clipboard:\n"
590 * Adds and opens the given frame to the desktop
601 public static synchronized void addInternalFrame(
602 final JInternalFrame frame, String title, int w, int h)
604 addInternalFrame(frame, title, w, h, true);
621 public static synchronized void addInternalFrame(
622 final JInternalFrame frame, String title, int w, int h,
626 // TODO: allow callers to determine X and Y position of frame (eg. via
628 // TODO: consider fixing method to update entries in the window submenu with
629 // the current window title
631 frame.setTitle(title);
632 if (frame.getWidth() < 1 || frame.getHeight() < 1)
636 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
637 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
638 // IF JALVIEW IS RUNNING HEADLESS
639 // ///////////////////////////////////////////////
640 if (System.getProperty("java.awt.headless") != null
641 && System.getProperty("java.awt.headless").equals("true"))
648 frame.setVisible(true);
649 frame.setClosable(true);
650 frame.setResizable(resizable);
651 frame.setMaximizable(resizable);
652 frame.setIconifiable(resizable);
653 frame.setFrameIcon(null);
655 if (frame.getX() < 1 && frame.getY() < 1)
657 frame.setLocation(xOffset * openFrameCount, yOffset
658 * ((openFrameCount - 1) % 10) + yOffset);
661 final JMenuItem menuItem = new JMenuItem(title);
662 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
664 public void internalFrameActivated(
665 javax.swing.event.InternalFrameEvent evt)
667 JInternalFrame itf = desktop.getSelectedFrame();
675 public void internalFrameClosed(
676 javax.swing.event.InternalFrameEvent evt)
678 PaintRefresher.RemoveComponent(frame);
680 windowMenu.remove(menuItem);
681 JInternalFrame itf = desktop.getSelectedFrame();
690 menuItem.addActionListener(new ActionListener()
692 public void actionPerformed(ActionEvent e)
696 frame.setSelected(true);
697 frame.setIcon(false);
698 } catch (java.beans.PropertyVetoException ex)
704 menuItem.addMouseListener(new MouseListener()
708 public void mouseReleased(MouseEvent e)
713 public void mousePressed(MouseEvent e)
718 public void mouseExited(MouseEvent e)
722 frame.setSelected(false);
723 } catch (PropertyVetoException e1)
729 public void mouseEntered(MouseEvent e)
733 frame.setSelected(true);
734 } catch (PropertyVetoException e1)
740 public void mouseClicked(MouseEvent e)
746 windowMenu.add(menuItem);
752 frame.setSelected(true);
753 frame.requestFocus();
754 } catch (java.beans.PropertyVetoException ve)
757 catch (java.lang.ClassCastException cex)
759 Cache.log.warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",cex);
763 public void lostOwnership(Clipboard clipboard, Transferable contents)
767 Desktop.jalviewClipboard = null;
770 internalCopy = false;
773 public void dragEnter(DropTargetDragEvent evt)
777 public void dragExit(DropTargetEvent evt)
781 public void dragOver(DropTargetDragEvent evt)
785 public void dropActionChanged(DropTargetDragEvent evt)
795 public void drop(DropTargetDropEvent evt)
797 Transferable t = evt.getTransferable();
798 java.util.List files = null;
799 java.util.List protocols = null;
803 DataFlavor uriListFlavor = new DataFlavor(
804 "text/uri-list;class=java.lang.String");
805 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
807 // Works on Windows and MacOSX
808 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
809 files = (java.util.List) t
810 .getTransferData(DataFlavor.javaFileListFlavor);
812 else if (t.isDataFlavorSupported(uriListFlavor))
814 // This is used by Unix drag system
815 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
816 String data = (String) t.getTransferData(uriListFlavor);
817 files = new java.util.ArrayList(1);
818 protocols = new java.util.ArrayList(1);
819 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
820 data, "\r\n"); st.hasMoreTokens();)
822 String s = st.nextToken();
823 if (s.startsWith("#"))
825 // the line is a comment (as per the RFC 2483)
828 java.net.URI uri = new java.net.URI(s);
829 if (uri.getScheme().toLowerCase().startsWith("http"))
831 protocols.add(FormatAdapter.URL);
832 files.add(uri.toString());
836 // otherwise preserve old behaviour: catch all for file objects
837 java.io.File file = new java.io.File(uri);
838 protocols.add(FormatAdapter.FILE);
839 files.add(file.toString());
843 } catch (Exception e)
851 for (int i = 0; i < files.size(); i++)
853 String file = files.get(i).toString();
854 String protocol = (protocols == null) ? FormatAdapter.FILE
855 : (String) protocols.get(i);
856 String format = null;
858 if (file.endsWith(".jar"))
865 format = new IdentifyFile().Identify(file, protocol);
868 new FileLoader().LoadFile(file, protocol, format);
871 } catch (Exception ex)
883 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
885 JalviewFileChooser chooser = new JalviewFileChooser(
886 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
887 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
888 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
889 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
891 chooser.setFileView(new JalviewFileView());
892 chooser.setDialogTitle("Open local file");
893 chooser.setToolTipText("Open");
895 int value = chooser.showOpenDialog(this);
897 if (value == JalviewFileChooser.APPROVE_OPTION)
899 String choice = chooser.getSelectedFile().getPath();
900 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
901 .getSelectedFile().getParent());
903 String format = null;
904 if (chooser.getSelectedFormat().equals("Jalview"))
910 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
913 if (viewport != null)
915 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
920 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
931 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
933 // This construct allows us to have a wider textfield
935 JLabel label = new JLabel("Enter URL of Input File");
936 final JComboBox history = new JComboBox();
938 JPanel panel = new JPanel(new GridLayout(2, 1));
941 history.setPreferredSize(new Dimension(400, 20));
942 history.setEditable(true);
943 history.addItem("http://www.");
945 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
949 if (historyItems != null)
951 st = new StringTokenizer(historyItems, "\t");
953 while (st.hasMoreTokens())
955 history.addItem(st.nextElement());
959 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
960 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
962 if (reply != JOptionPane.OK_OPTION)
967 String url = history.getSelectedItem().toString();
969 if (url.toLowerCase().endsWith(".jar"))
971 if (viewport != null)
973 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
978 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
983 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
985 if (format.equals("URL NOT FOUND"))
987 JOptionPane.showInternalMessageDialog(Desktop.desktop,
988 "Couldn't locate " + url, "URL not found",
989 JOptionPane.WARNING_MESSAGE);
994 if (viewport != null)
996 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1000 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1011 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1013 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1014 cap.setForInput(viewport);
1015 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1023 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1025 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1026 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1028 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1029 getBounds().y, getWidth(), getHeight()));
1031 if (jconsole != null)
1033 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1034 jconsole.stopConsole();
1038 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1045 private void storeLastKnownDimensions(String string, Rectangle jc)
1047 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1048 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1049 + " height:" + jc.height);
1051 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1052 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1053 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1054 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1063 public void aboutMenuItem_actionPerformed(ActionEvent e)
1065 // StringBuffer message = getAboutMessage(false);
1066 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1068 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1069 new Thread(new Runnable() { public void run() {new SplashScreen(true);}}).start();
1072 public StringBuffer getAboutMessage(boolean shortv)
1074 StringBuffer message = new StringBuffer();
1075 message.append("<html>");
1078 message.append("<h1><strong>Version: "
1079 + jalview.bin.Cache.getProperty("VERSION")
1080 + "</strong></h1><br>");
1081 message.append("<strong>Last Updated: <em>"
1082 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1083 + "</em></strong>");
1089 message.append("<strong>Version "
1090 + jalview.bin.Cache.getProperty("VERSION")
1091 + "; last updated: "
1092 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1095 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1098 message.append("<br>...Checking latest version...</br>");
1100 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1101 .equals(jalview.bin.Cache.getProperty("VERSION")))
1103 boolean red = false;
1104 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1105 .indexOf("automated build") == -1)
1108 // Displayed when code version and jnlp version do not match and code
1109 // version is not a development build
1110 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1113 message.append("<br>!! Version "
1114 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1116 + " is available for download from "
1117 + jalview.bin.Cache.getDefault("www.jalview.org",
1118 "http://www.jalview.org") + " !!");
1121 message.append("</div>");
1124 message.append("<br>Authors: "
1128 "Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton")
1129 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1130 + "<br>For help, see the FAQ at <a href=\"http://www.jalview.org\">www.jalview.org</a> and/or join the jalview-discuss@jalview.org mailing list"
1131 + "<br>If you use Jalview, please cite:"
1132 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1133 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1134 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1145 public void documentationMenuItem_actionPerformed(ActionEvent e)
1149 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1150 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1151 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1153 javax.help.HelpBroker hb = hs.createHelpBroker();
1154 hb.setCurrentID("home");
1155 hb.setDisplayed(true);
1156 } catch (Exception ex)
1161 public void closeAll_actionPerformed(ActionEvent e)
1163 JInternalFrame[] frames = desktop.getAllFrames();
1164 for (int i = 0; i < frames.length; i++)
1168 frames[i].setClosed(true);
1169 } catch (java.beans.PropertyVetoException ex)
1173 System.out.println("ALL CLOSED");
1174 if (v_client != null)
1176 // TODO clear binding to vamsas document objects on close_all
1181 public void raiseRelated_actionPerformed(ActionEvent e)
1183 reorderAssociatedWindows(false, false);
1186 public void minimizeAssociated_actionPerformed(ActionEvent e)
1188 reorderAssociatedWindows(true, false);
1191 void closeAssociatedWindows()
1193 reorderAssociatedWindows(false, true);
1199 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1202 protected void garbageCollect_actionPerformed(ActionEvent e)
1204 // We simply collect the garbage
1205 jalview.bin.Cache.log.debug("Collecting garbage...");
1207 jalview.bin.Cache.log.debug("Finished garbage collection.");
1214 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1217 protected void showMemusage_actionPerformed(ActionEvent e)
1219 desktop.showMemoryUsage(showMemusage.isSelected());
1226 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1229 protected void showConsole_actionPerformed(ActionEvent e)
1231 showConsole(showConsole.isSelected());
1234 Console jconsole = null;
1237 * control whether the java console is visible or not
1241 void showConsole(boolean selected)
1243 showConsole.setSelected(selected);
1244 // TODO: decide if we should update properties file
1245 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1247 jconsole.setVisible(selected);
1250 void reorderAssociatedWindows(boolean minimize, boolean close)
1252 JInternalFrame[] frames = desktop.getAllFrames();
1253 if (frames == null || frames.length < 1)
1258 AlignViewport source = null, target = null;
1259 if (frames[0] instanceof AlignFrame)
1261 source = ((AlignFrame) frames[0]).getCurrentView();
1263 else if (frames[0] instanceof TreePanel)
1265 source = ((TreePanel) frames[0]).getViewPort();
1267 else if (frames[0] instanceof PCAPanel)
1269 source = ((PCAPanel) frames[0]).av;
1271 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1273 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1278 for (int i = 0; i < frames.length; i++)
1281 if (frames[i] == null)
1285 if (frames[i] instanceof AlignFrame)
1287 target = ((AlignFrame) frames[i]).getCurrentView();
1289 else if (frames[i] instanceof TreePanel)
1291 target = ((TreePanel) frames[i]).getViewPort();
1293 else if (frames[i] instanceof PCAPanel)
1295 target = ((PCAPanel) frames[i]).av;
1297 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1299 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1302 if (source == target)
1308 frames[i].setClosed(true);
1312 frames[i].setIcon(minimize);
1315 frames[i].toFront();
1319 } catch (java.beans.PropertyVetoException ex)
1333 protected void preferences_actionPerformed(ActionEvent e)
1344 public void saveState_actionPerformed(ActionEvent e)
1346 JalviewFileChooser chooser = new JalviewFileChooser(
1347 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1348 { "jar" }, new String[]
1349 { "Jalview Project" }, "Jalview Project");
1351 chooser.setFileView(new JalviewFileView());
1352 chooser.setDialogTitle("Save State");
1354 int value = chooser.showSaveDialog(this);
1356 if (value == JalviewFileChooser.APPROVE_OPTION)
1358 final Desktop me = this;
1359 final java.io.File choice = chooser.getSelectedFile();
1360 new Thread(new Runnable()
1365 setProgressBar("Saving jalview project " + choice.getName(),
1367 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1368 // TODO catch and handle errors for savestate
1369 // TODO prevent user from messing with the Desktop whilst we're saving
1372 new Jalview2XML().SaveState(choice);
1373 } catch (OutOfMemoryError oom)
1376 "Whilst saving current state to " + choice.getName(), oom);
1377 } catch (Exception ex)
1380 .error("Problems whilst trying to save to "
1381 + choice.getName(), ex);
1382 JOptionPane.showMessageDialog(me,
1383 "Error whilst saving current state to " + choice.getName(),
1384 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1386 setProgressBar(null, choice.hashCode());
1398 public void loadState_actionPerformed(ActionEvent e)
1400 JalviewFileChooser chooser = new JalviewFileChooser(
1401 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1402 { "jar" }, new String[]
1403 { "Jalview Project" }, "Jalview Project");
1404 chooser.setFileView(new JalviewFileView());
1405 chooser.setDialogTitle("Restore state");
1407 int value = chooser.showOpenDialog(this);
1409 if (value == JalviewFileChooser.APPROVE_OPTION)
1411 final String choice = chooser.getSelectedFile().getAbsolutePath();
1412 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1413 .getSelectedFile().getParent());
1414 new Thread(new Runnable()
1418 setProgressBar("loading jalview project " + choice,
1422 new Jalview2XML().LoadJalviewAlign(choice);
1423 } catch (OutOfMemoryError oom)
1425 new OOMWarning("Whilst loading project from " + choice, oom);
1426 } catch (Exception ex)
1428 Cache.log.error("Problems whilst loading project from "
1430 JOptionPane.showMessageDialog(Desktop.desktop,
1431 "Error whilst loading project from " + choice,
1432 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1434 setProgressBar(null, choice.hashCode());
1440 public void inputSequence_actionPerformed(ActionEvent e)
1442 new SequenceFetcher(this);
1445 JPanel progressPanel;
1446 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1447 public void startLoading(final String fileName)
1449 if (fileLoadingCount == 0)
1451 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1456 private JPanel addProgressPanel(String string)
1458 if (progressPanel == null)
1460 progressPanel = new JPanel(new GridLayout(1,1));
1461 totalProgressCount = 0;
1462 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1464 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1465 JProgressBar progressBar = new JProgressBar();
1466 progressBar.setIndeterminate(true);
1468 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1470 thisprogress.add(progressBar, BorderLayout.CENTER);
1471 progressPanel.add(thisprogress);
1472 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1473 ++totalProgressCount;
1474 instance.validate();
1475 return thisprogress;
1478 int totalProgressCount = 0;
1480 private void removeProgressPanel(JPanel progbar)
1482 if (progressPanel != null)
1484 progressPanel.remove(progbar);
1485 GridLayout gl = (GridLayout) progressPanel.getLayout();
1486 gl.setRows(gl.getRows()-1);
1487 if (--totalProgressCount < 1)
1489 this.getContentPane().remove(progressPanel);
1490 progressPanel = null;
1496 public void stopLoading()
1499 if (fileLoadingCount < 1)
1501 for (JPanel flp : fileLoadingPanels)
1503 removeProgressPanel(flp);
1505 fileLoadingPanels.clear();
1506 fileLoadingCount = 0;
1511 public static int getViewCount(String alignmentId)
1513 AlignViewport[] aps = getViewports(alignmentId);
1514 return (aps == null) ? 0 : aps.length;
1519 * @param alignmentId
1520 * @return all AlignmentPanels concerning the alignmentId sequence set
1522 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1525 if (Desktop.desktop == null)
1527 // no frames created and in headless mode
1528 // TODO: verify that frames are recoverable when in headless mode
1531 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1532 ArrayList aps = new ArrayList();
1533 for (int t = 0; t < frames.length; t++)
1535 if (frames[t] instanceof AlignFrame)
1537 AlignFrame af = (AlignFrame) frames[t];
1538 for (int a = 0; a < af.alignPanels.size(); a++)
1541 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1542 .getSequenceSetId()))
1544 aps.add(af.alignPanels.elementAt(a));
1549 if (aps.size() == 0)
1553 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1554 for (int t = 0; t < vap.length; t++)
1556 vap[t] = (AlignmentPanel) aps.get(t);
1562 * get all the viewports on an alignment.
1564 * @param sequenceSetId
1565 * unique alignment id
1566 * @return all viewports on the alignment bound to sequenceSetId
1568 public static AlignViewport[] getViewports(String sequenceSetId)
1570 Vector viewp = new Vector();
1571 if (desktop != null)
1573 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1575 for (int t = 0; t < frames.length; t++)
1577 if (frames[t] instanceof AlignFrame)
1579 AlignFrame afr = ((AlignFrame) frames[t]);
1580 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1582 if (afr.alignPanels != null)
1584 for (int a = 0; a < afr.alignPanels.size(); a++)
1586 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1587 .elementAt(a)).av.getSequenceSetId()))
1589 viewp.addElement(((AlignmentPanel) afr.alignPanels
1596 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1601 if (viewp.size() > 0)
1603 AlignViewport[] vp = new AlignViewport[viewp.size()];
1611 public void explodeViews(AlignFrame af)
1613 int size = af.alignPanels.size();
1619 for (int i = 0; i < size; i++)
1621 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1622 AlignFrame newaf = new AlignFrame(ap);
1623 if (ap.av.explodedPosition != null
1624 && !ap.av.explodedPosition.equals(af.getBounds()))
1626 newaf.setBounds(ap.av.explodedPosition);
1629 ap.av.gatherViewsHere = false;
1631 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1632 AlignFrame.DEFAULT_HEIGHT);
1635 af.alignPanels.clear();
1636 af.closeMenuItem_actionPerformed(true);
1640 public void gatherViews(AlignFrame source)
1642 source.viewport.gatherViewsHere = true;
1643 source.viewport.explodedPosition = source.getBounds();
1644 JInternalFrame[] frames = desktop.getAllFrames();
1645 String viewId = source.viewport.getSequenceSetId();
1647 for (int t = 0; t < frames.length; t++)
1649 if (frames[t] instanceof AlignFrame && frames[t] != source)
1651 AlignFrame af = (AlignFrame) frames[t];
1652 boolean gatherThis = false;
1653 for (int a = 0; a < af.alignPanels.size(); a++)
1655 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1656 if (viewId.equals(ap.av.getSequenceSetId()))
1659 ap.av.gatherViewsHere = false;
1660 ap.av.explodedPosition = af.getBounds();
1661 source.addAlignmentPanel(ap, false);
1667 af.alignPanels.clear();
1668 af.closeMenuItem_actionPerformed(true);
1675 jalview.gui.VamsasApplication v_client = null;
1677 public void vamsasImport_actionPerformed(ActionEvent e)
1679 if (v_client == null)
1681 // Load and try to start a session.
1682 JalviewFileChooser chooser = new JalviewFileChooser(
1683 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1685 chooser.setFileView(new JalviewFileView());
1686 chooser.setDialogTitle("Open a saved VAMSAS session");
1687 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1689 int value = chooser.showOpenDialog(this);
1691 if (value == JalviewFileChooser.APPROVE_OPTION)
1693 String fle = chooser.getSelectedFile().toString();
1694 if (!vamsasImport(chooser.getSelectedFile()))
1696 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1697 "Couldn't import '" + fle + "' as a new vamsas session.",
1698 "Vamsas Document Import Failed",
1699 JOptionPane.ERROR_MESSAGE);
1705 jalview.bin.Cache.log
1706 .error("Implementation error - load session from a running session is not supported.");
1711 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1714 * @return true if import was a success and a session was started.
1716 public boolean vamsasImport(URL url)
1718 // TODO: create progress bar
1719 if (v_client != null)
1722 jalview.bin.Cache.log
1723 .error("Implementation error - load session from a running session is not supported.");
1729 // copy the URL content to a temporary local file
1730 // TODO: be a bit cleverer here with nio (?!)
1731 File file = File.createTempFile("vdocfromurl", ".vdj");
1732 FileOutputStream fos = new FileOutputStream(file);
1733 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1734 byte[] buffer = new byte[2048];
1736 while ((ln = bis.read(buffer)) > -1)
1738 fos.write(buffer, 0, ln);
1742 v_client = new jalview.gui.VamsasApplication(this, file,
1743 url.toExternalForm());
1744 } catch (Exception ex)
1746 jalview.bin.Cache.log.error(
1747 "Failed to create new vamsas session from contents of URL "
1751 setupVamsasConnectedGui();
1752 v_client.initial_update(); // TODO: thread ?
1753 return v_client.inSession();
1757 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1760 * @return true if import was a success and a session was started.
1762 public boolean vamsasImport(File file)
1764 if (v_client != null)
1767 jalview.bin.Cache.log
1768 .error("Implementation error - load session from a running session is not supported.");
1772 setProgressBar("Importing VAMSAS session from " + file.getName(),
1776 v_client = new jalview.gui.VamsasApplication(this, file, null);
1777 } catch (Exception ex)
1779 setProgressBar("Importing VAMSAS session from " + file.getName(),
1781 jalview.bin.Cache.log.error(
1782 "New vamsas session from existing session file failed:", ex);
1785 setupVamsasConnectedGui();
1786 v_client.initial_update(); // TODO: thread ?
1787 setProgressBar("Importing VAMSAS session from " + file.getName(),
1789 return v_client.inSession();
1792 public boolean joinVamsasSession(String mysesid)
1794 if (v_client != null)
1797 "Trying to join a vamsas session when another is already connected.");
1799 if (mysesid == null)
1801 throw new Error("Invalid vamsas session id.");
1803 v_client = new VamsasApplication(this, mysesid);
1804 setupVamsasConnectedGui();
1805 v_client.initial_update();
1806 return (v_client.inSession());
1809 public void vamsasStart_actionPerformed(ActionEvent e)
1811 if (v_client == null)
1814 // we just start a default session for moment.
1816 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1817 * getProperty("LAST_DIRECTORY"));
1819 * chooser.setFileView(new JalviewFileView());
1820 * chooser.setDialogTitle("Load Vamsas file");
1821 * chooser.setToolTipText("Import");
1823 * int value = chooser.showOpenDialog(this);
1825 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1826 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1828 v_client = new VamsasApplication(this);
1829 setupVamsasConnectedGui();
1830 v_client.initial_update(); // TODO: thread ?
1834 // store current data in session.
1835 v_client.push_update(); // TODO: thread
1839 protected void setupVamsasConnectedGui()
1841 vamsasStart.setText("Session Update");
1842 vamsasSave.setVisible(true);
1843 vamsasStop.setVisible(true);
1844 vamsasImport.setVisible(false); // Document import to existing session is
1845 // not possible for vamsas-client-1.0.
1848 protected void setupVamsasDisconnectedGui()
1850 vamsasSave.setVisible(false);
1851 vamsasStop.setVisible(false);
1852 vamsasImport.setVisible(true);
1853 vamsasStart.setText("New Vamsas Session");
1856 public void vamsasStop_actionPerformed(ActionEvent e)
1858 if (v_client != null)
1860 v_client.end_session();
1862 setupVamsasDisconnectedGui();
1866 protected void buildVamsasStMenu()
1868 if (v_client == null)
1870 String[] sess = null;
1873 sess = VamsasApplication.getSessionList();
1874 } catch (Exception e)
1876 jalview.bin.Cache.log.warn(
1877 "Problem getting current sessions list.", e);
1882 jalview.bin.Cache.log.debug("Got current sessions list: "
1883 + sess.length + " entries.");
1884 VamsasStMenu.removeAll();
1885 for (int i = 0; i < sess.length; i++)
1887 JMenuItem sessit = new JMenuItem();
1888 sessit.setText(sess[i]);
1889 sessit.setToolTipText("Connect to session " + sess[i]);
1890 final Desktop dsktp = this;
1891 final String mysesid = sess[i];
1892 sessit.addActionListener(new ActionListener()
1895 public void actionPerformed(ActionEvent e)
1897 if (dsktp.v_client == null)
1899 Thread rthr = new Thread(new Runnable()
1904 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1905 dsktp.setupVamsasConnectedGui();
1906 dsktp.v_client.initial_update();
1914 VamsasStMenu.add(sessit);
1916 // don't show an empty menu.
1917 VamsasStMenu.setVisible(sess.length > 0);
1922 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1923 VamsasStMenu.removeAll();
1924 VamsasStMenu.setVisible(false);
1929 // Not interested in the content. Just hide ourselves.
1930 VamsasStMenu.setVisible(false);
1934 public void vamsasSave_actionPerformed(ActionEvent e)
1936 if (v_client != null)
1938 JalviewFileChooser chooser = new JalviewFileChooser(
1939 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1940 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1942 { "Vamsas Document" }, "Vamsas Document");
1944 chooser.setFileView(new JalviewFileView());
1945 chooser.setDialogTitle("Save Vamsas Document Archive");
1947 int value = chooser.showSaveDialog(this);
1949 if (value == JalviewFileChooser.APPROVE_OPTION)
1951 java.io.File choice = chooser.getSelectedFile();
1952 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1953 + choice.getName());
1954 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1955 String warnmsg = null;
1956 String warnttl = null;
1959 v_client.vclient.storeDocument(choice);
1962 warnttl = "Serious Problem saving Vamsas Document";
1963 warnmsg = ex.toString();
1964 jalview.bin.Cache.log.error("Error Whilst saving document to "
1967 } catch (Exception ex)
1969 warnttl = "Problem saving Vamsas Document.";
1970 warnmsg = ex.toString();
1971 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1975 removeProgressPanel(progpanel);
1976 if (warnmsg != null)
1978 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1980 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1986 JPanel vamUpdate = null;
1989 * hide vamsas user gui bits when a vamsas document event is being handled.
1992 * true to hide gui, false to reveal gui
1994 public void setVamsasUpdate(boolean b)
1996 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1997 + (b ? "in progress" : "finished"));
1999 if (vamUpdate != null)
2001 this.removeProgressPanel(vamUpdate);
2005 vamUpdate = this.addProgressPanel("Updating vamsas session");
2007 vamsasStart.setVisible(!b);
2008 vamsasStop.setVisible(!b);
2009 vamsasSave.setVisible(!b);
2012 public JInternalFrame[] getAllFrames()
2014 return desktop.getAllFrames();
2018 * Checks the given url to see if it gives a response indicating that the user
2019 * should be informed of a new questionnaire.
2023 public void checkForQuestionnaire(String url)
2025 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2026 // javax.swing.SwingUtilities.invokeLater(jvq);
2027 new Thread(jvq).start();
2031 * Proxy class for JDesktopPane which optionally displays the current memory
2032 * usage and highlights the desktop area with a red bar if free memory runs
2037 public class MyDesktopPane extends JDesktopPane implements Runnable
2040 boolean showMemoryUsage = false;
2044 java.text.NumberFormat df;
2046 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2049 public MyDesktopPane(boolean showMemoryUsage)
2051 showMemoryUsage(showMemoryUsage);
2054 public void showMemoryUsage(boolean showMemoryUsage)
2056 this.showMemoryUsage = showMemoryUsage;
2057 if (showMemoryUsage)
2059 Thread worker = new Thread(this);
2064 public boolean isShowMemoryUsage()
2066 return showMemoryUsage;
2071 df = java.text.NumberFormat.getNumberInstance();
2072 df.setMaximumFractionDigits(2);
2073 runtime = Runtime.getRuntime();
2075 while (showMemoryUsage)
2079 maxMemory = runtime.maxMemory() / 1048576f;
2080 allocatedMemory = runtime.totalMemory() / 1048576f;
2081 freeMemory = runtime.freeMemory() / 1048576f;
2082 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2084 percentUsage = (totalFreeMemory / maxMemory) * 100;
2086 // if (percentUsage < 20)
2088 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2090 // instance.set.setBorder(border1);
2093 // sleep after showing usage
2095 } catch (Exception ex)
2097 ex.printStackTrace();
2102 public void paintComponent(Graphics g)
2104 if (showMemoryUsage && g != null && df != null)
2106 if (percentUsage < 20)
2107 g.setColor(Color.red);
2108 FontMetrics fm = g.getFontMetrics();
2112 "Total Free Memory: " + df.format(totalFreeMemory)
2113 + "MB; Max Memory: " + df.format(maxMemory)
2114 + "MB; " + df.format(percentUsage) + "%", 10,
2115 getHeight() - fm.getHeight());
2122 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2124 public void relayerWindows()
2129 protected JMenuItem groovyShell;
2131 public void doGroovyCheck()
2133 if (jalview.bin.Cache.groovyJarsPresent())
2135 groovyShell = new JMenuItem();
2136 groovyShell.setText("Groovy Console...");
2137 groovyShell.addActionListener(new ActionListener()
2139 public void actionPerformed(ActionEvent e)
2141 groovyShell_actionPerformed(e);
2144 toolsMenu.add(groovyShell);
2145 groovyShell.setVisible(true);
2150 * Accessor method to quickly get all the AlignmentFrames loaded.
2152 public static AlignFrame[] getAlignframes()
2154 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2160 Vector avp = new Vector();
2164 for (int i = frames.length - 1; i > -1; i--)
2166 if (frames[i] instanceof AlignFrame)
2168 AlignFrame af = (AlignFrame) frames[i];
2172 } catch (Exception ex)
2174 ex.printStackTrace();
2176 if (avp.size() == 0)
2180 AlignFrame afs[] = new AlignFrame[avp.size()];
2181 for (int i = 0, j = avp.size(); i < j; i++)
2183 afs[i] = (AlignFrame) avp.elementAt(i);
2188 public AppJmol[] getJmols()
2190 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2196 Vector avp = new Vector();
2200 for (int i = frames.length - 1; i > -1; i--)
2202 if (frames[i] instanceof AppJmol)
2204 AppJmol af = (AppJmol) frames[i];
2208 } catch (Exception ex)
2210 ex.printStackTrace();
2212 if (avp.size() == 0)
2216 AppJmol afs[] = new AppJmol[avp.size()];
2217 for (int i = 0, j = avp.size(); i < j; i++)
2219 afs[i] = (AppJmol) avp.elementAt(i);
2226 * Add Groovy Support to Jalview
2228 public void groovyShell_actionPerformed(ActionEvent e)
2230 // use reflection to avoid creating compilation dependency.
2231 if (!jalview.bin.Cache.groovyJarsPresent())
2234 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2238 Class gcClass = Desktop.class.getClassLoader().loadClass(
2239 "groovy.ui.Console");
2240 Constructor gccons = gcClass.getConstructor(null);
2241 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2243 { String.class, Object.class });
2244 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2245 Object gc = gccons.newInstance(null);
2246 setvar.invoke(gc, new Object[]
2247 { "Jalview", this });
2248 run.invoke(gc, null);
2249 } catch (Exception ex)
2251 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2253 .showInternalMessageDialog(
2256 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2257 "Jalview Groovy Support Failed",
2258 JOptionPane.ERROR_MESSAGE);
2263 * Progress bars managed by the IProgressIndicator method.
2265 private Hashtable<Long,JPanel> progressBars;
2266 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2271 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2273 public void setProgressBar(String message, long id)
2275 if (progressBars == null)
2277 progressBars = new Hashtable<Long,JPanel>();
2278 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2281 if (progressBars.get(new Long(id)) != null)
2283 JPanel progressPanel = progressBars
2284 .remove(new Long(id));
2285 if (progressBarHandlers.contains(new Long(id)))
2287 progressBarHandlers.remove(new Long(id));
2289 removeProgressPanel(progressPanel);
2293 progressBars.put(new Long(id), addProgressPanel(message));
2300 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2301 * jalview.gui.IProgressIndicatorHandler)
2303 public void registerHandler(final long id,
2304 final IProgressIndicatorHandler handler)
2306 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2309 "call setProgressBar before registering the progress bar's handler.");
2311 progressBarHandlers.put(new Long(id), handler);
2312 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2313 if (handler.canCancel())
2315 JButton cancel = new JButton("Cancel");
2316 final IProgressIndicator us = this;
2317 cancel.addActionListener(new ActionListener()
2320 public void actionPerformed(ActionEvent e)
2322 handler.cancelActivity(id);
2325 + ((JLabel) progressPanel.getComponent(0))
2329 progressPanel.add(cancel, BorderLayout.EAST);
2335 * @return true if any progress bars are still active
2338 public boolean operationInProgress()
2340 if (progressBars != null && progressBars.size() > 0)
2348 * This will return the first AlignFrame viewing AlignViewport av. It will
2349 * break if there are more than one AlignFrames viewing a particular av. This
2352 * @return alignFrame for av
2354 public static AlignFrame getAlignFrameFor(AlignViewport av)
2356 if (desktop != null)
2358 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2359 for (int panel = 0; aps != null && panel < aps.length; panel++)
2361 if (aps[panel] != null && aps[panel].av == av)
2363 return aps[panel].alignFrame;
2370 public VamsasApplication getVamsasApplication()
2377 * flag set if jalview GUI is being operated programmatically
2379 private boolean inBatchMode = false;
2382 * check if jalview GUI is being operated programmatically
2384 * @return inBatchMode
2386 public boolean isInBatchMode()
2392 * set flag if jalview GUI is being operated programmatically
2394 * @param inBatchMode
2396 public void setInBatchMode(boolean inBatchMode)
2398 this.inBatchMode = inBatchMode;
2401 public void startServiceDiscovery()
2403 startServiceDiscovery(false);
2406 public void startServiceDiscovery(boolean blocking)
2408 boolean alive = true;
2409 Thread t0 = null, t1 = null, t2 = null;
2411 // todo: changesupport handlers need to be transferred
2412 if (discoverer == null)
2414 discoverer = new jalview.ws.jws1.Discoverer();
2415 // register PCS handler for desktop.
2416 discoverer.addPropertyChangeListener(changeSupport);
2418 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2421 (t0 = new Thread(discoverer)).start();
2426 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2428 // EnfinEnvision web service menu entries are rebuild every time the
2429 // menu is shown, so no changeSupport events are needed.
2430 jalview.ws.EnfinEnvision2OneWay.getInstance();
2431 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2434 } catch (Exception e)
2437 .info("Exception when trying to launch Envision2 workflow discovery.",
2439 Cache.log.info(e.getStackTrace());
2441 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2443 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2445 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2447 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2453 // TODO: do rest service discovery
2462 } catch (Exception e)
2465 alive = (t1 != null && t1.isAlive())
2466 || (t2 != null && t2.isAlive())
2467 || (t3 != null && t3.isAlive())
2468 || (t0 != null && t0.isAlive());
2474 * called to check if the service discovery process completed successfully.
2478 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2480 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2482 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2483 .getErrorMessages();
2486 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2488 if (serviceChangedDialog == null)
2490 // only run if we aren't already displaying one of these.
2491 javax.swing.SwingUtilities
2492 .invokeLater(serviceChangedDialog = new Runnable()
2498 .showInternalMessageDialog(
2501 + "It may be that you have invalid JABA URLs\nin your web service preferences.\n\nGo to the Web services tab of the\nTools->Preferences dialog box to change them.\n",
2502 "Preferences Problem",
2503 JOptionPane.WARNING_MESSAGE);
2504 serviceChangedDialog = null;
2513 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2520 private Runnable serviceChangedDialog = null;
2523 * start a thread to open a URL in the configured browser. Pops up a warning
2524 * dialog to the user if there is an exception when calling out to the browser
2529 public static void showUrl(final String url)
2531 showUrl(url, Desktop.instance);
2534 * Like showUrl but allows progress handler to be specified
2536 * @param progress (null) or object implementing IProgressIndicator
2538 public static void showUrl(final String url, final IProgressIndicator progress)
2540 new Thread(new Runnable()
2546 if (progress!=null) {
2547 progress.setProgressBar("Opening "+url, this.hashCode());
2549 jalview.util.BrowserLauncher.openURL(url);
2550 } catch (Exception ex)
2553 .showInternalMessageDialog(
2555 "Unixers: Couldn't find default web browser."
2556 + "\nAdd the full path to your browser in Preferences.",
2557 "Web browser not found",
2558 JOptionPane.WARNING_MESSAGE);
2560 ex.printStackTrace();
2562 if (progress!=null) {
2563 progress.setProgressBar(null, this.hashCode());
2569 public static WsParamSetManager wsparamManager = null;
2571 public static ParamManager getUserParameterStore()
2573 if (wsparamManager == null)
2575 wsparamManager = new WsParamSetManager();
2577 return wsparamManager;
2581 * static hyperlink handler proxy method for use by Jalview's internal windows
2584 public static void hyperlinkUpdate(HyperlinkEvent e)
2586 if (e.getEventType() == EventType.ACTIVATED)
2591 url = e.getURL().toString();
2592 Desktop.showUrl(url);
2593 } catch (Exception x)
2596 if (Cache.log!=null) {
2597 Cache.log.error("Couldn't handle string "+url+" as a URL.");
2599 System.err.println("Couldn't handle string "+url+" as a URL.");
2602 // ignore any exceptions due to dud links.