2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, 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.MenuEvent;
84 import javax.swing.event.MenuListener;
91 * @version $Revision: 1.155 $
93 public class Desktop extends jalview.jbgui.GDesktop implements
94 DropTargetListener, ClipboardOwner, IProgressIndicator, jalview.api.StructureSelectionManagerProvider
97 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
100 * news reader - null if it was never started.
102 private BlogReader jvnews=null;
106 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
108 public void addJalviewPropertyChangeListener(
109 PropertyChangeListener listener)
111 changeSupport.addJalviewPropertyChangeListener(listener);
115 * @param propertyName
117 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
118 * java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(String propertyName,
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void removeJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.removeJalviewPropertyChangeListener(propertyName,
139 /** Singleton Desktop instance */
140 public static Desktop instance;
142 public static MyDesktopPane desktop;
144 static int openFrameCount = 0;
146 static final int xOffset = 30;
148 static final int yOffset = 30;
150 public static jalview.ws.jws1.Discoverer discoverer;
152 public static Object[] jalviewClipboard;
154 public static boolean internalCopy = false;
156 static int fileLoadingCount = 0;
158 class MyDesktopManager implements DesktopManager
161 private DesktopManager delegate;
163 public MyDesktopManager(DesktopManager delegate)
165 this.delegate = delegate;
168 public void activateFrame(JInternalFrame f)
172 delegate.activateFrame(f);
173 } catch (NullPointerException npe)
175 Point p = getMousePosition();
176 instance.showPasteMenu(p.x, p.y);
180 public void beginDraggingFrame(JComponent f)
182 delegate.beginDraggingFrame(f);
185 public void beginResizingFrame(JComponent f, int direction)
187 delegate.beginResizingFrame(f, direction);
190 public void closeFrame(JInternalFrame f)
192 delegate.closeFrame(f);
195 public void deactivateFrame(JInternalFrame f)
197 delegate.deactivateFrame(f);
200 public void deiconifyFrame(JInternalFrame f)
202 delegate.deiconifyFrame(f);
205 public void dragFrame(JComponent f, int newX, int newY)
207 delegate.dragFrame(f, newX, newY);
210 public void endDraggingFrame(JComponent f)
212 delegate.endDraggingFrame(f);
215 public void endResizingFrame(JComponent f)
217 delegate.endResizingFrame(f);
220 public void iconifyFrame(JInternalFrame f)
222 delegate.iconifyFrame(f);
225 public void maximizeFrame(JInternalFrame f)
227 delegate.maximizeFrame(f);
230 public void minimizeFrame(JInternalFrame f)
232 delegate.minimizeFrame(f);
235 public void openFrame(JInternalFrame f)
237 delegate.openFrame(f);
240 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
243 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
246 public void setBoundsForFrame(JComponent f, int newX, int newY,
247 int newWidth, int newHeight)
249 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
252 // All other methods, simply delegate
257 * Creates a new Desktop object.
262 * A note to implementors. It is ESSENTIAL that any activities that might
263 * block are spawned off as threads rather than waited for during this
267 doVamsasClientCheck();
270 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
271 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
272 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
274 boolean showjconsole = jalview.bin.Cache.getDefault(
275 "SHOW_JAVA_CONSOLE", false);
276 desktop = new MyDesktopPane(selmemusage);
277 showMemusage.setSelected(selmemusage);
278 desktop.setBackground(Color.white);
279 getContentPane().setLayout(new BorderLayout());
280 // alternate config - have scrollbars - see notes in JAL-153
281 //JScrollPane sp = new JScrollPane();
282 //sp.getViewport().setView(desktop);
283 //getContentPane().add(sp, BorderLayout.CENTER);
284 getContentPane().add(desktop, BorderLayout.CENTER);
285 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
287 // This line prevents Windows Look&Feel resizing all new windows to maximum
288 // if previous window was maximised
289 desktop.setDesktopManager(new MyDesktopManager(
290 new DefaultDesktopManager()));
291 Rectangle dims = getLastKnownDimensions("");
298 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
299 setBounds((int) (screenSize.width - 900) / 2,
300 (int) (screenSize.height - 650) / 2, 900, 650);
302 jconsole = new Console(this, showjconsole);
303 // add essential build information
304 jconsole.setHeader("Jalview Desktop "
305 + jalview.bin.Cache.getProperty("VERSION") + "\n"
307 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
308 + "Java version: " + System.getProperty("java.version") + "\n"
309 + System.getProperty("os.arch") + " "
310 + System.getProperty("os.name") + " "
311 + System.getProperty("os.version"));
313 showConsole(showjconsole);
315 showNews.setVisible(false);
316 final Desktop me = this;
317 // Thread off the news reader, in case there are connection problems.
318 new Thread( new Runnable() {
322 Cache.log.debug("Starting news thread.");
324 jvnews = new BlogReader(me);
325 showNews.setVisible(true);
326 Cache.log.debug("Completed news thread.");
330 this.addWindowListener(new WindowAdapter()
332 public void windowClosing(WindowEvent evt)
338 this.addMouseListener(new MouseAdapter()
340 public void mousePressed(MouseEvent evt)
342 if (SwingUtilities.isRightMouseButton(evt))
344 showPasteMenu(evt.getX(), evt.getY());
348 this.addFocusListener(new FocusListener()
352 public void focusLost(FocusEvent e)
354 // TODO Auto-generated method stub
359 public void focusGained(FocusEvent e)
361 Cache.log.debug("Relaying windows after focus gain");
362 // make sure that we sort windows properly after we gain focus
363 instance.relayerWindows();
366 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
367 // Spawn a thread that shows the splashscreen
368 SwingUtilities.invokeLater(new Runnable()
377 // Thread off a new instance of the file chooser - this reduces the time it
378 // takes to open it later on.
379 new Thread(new Runnable()
383 Cache.log.debug("Filechooser init thread started.");
384 JalviewFileChooser chooser = new JalviewFileChooser(
385 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
386 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
387 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
388 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
389 Cache.log.debug("Filechooser init thread finished.");
392 // Add the service change listener
393 changeSupport.addJalviewPropertyChangeListener("services",
394 new PropertyChangeListener()
398 public void propertyChange(PropertyChangeEvent evt)
400 Cache.log.debug("Firing service changed event for "
401 + evt.getNewValue());
402 JalviewServicesChanged(evt);
408 protected void showNews_actionPerformed(ActionEvent e)
410 showNews(showNews.isSelected());
412 void showNews(boolean visible)
415 Cache.log.debug((visible?"Showing":"Hiding")+" news.");
416 showNews.setSelected(visible);
417 if (visible && !jvnews.isVisible())
419 new Thread(new Runnable() {
423 long instance=System.currentTimeMillis();
424 Desktop.instance.setProgressBar("Refreshing news", instance);
425 jvnews.refreshNews();
426 Desktop.instance.setProgressBar(null, instance);
435 * recover the last known dimensions for a jalview window
438 * - empty string is desktop, all other windows have unique prefix
439 * @return null or last known dimensions scaled to current geometry (if last
440 * window geom was known)
442 Rectangle getLastKnownDimensions(String windowName)
444 // TODO: lock aspect ratio for scaling desktop Bug #0058199
445 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
446 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
447 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
448 String width = jalview.bin.Cache.getProperty(windowName
450 String height = jalview.bin.Cache.getProperty(windowName
452 if ((x != null) && (y != null) && (width != null) && (height != null))
454 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
455 .parseInt(width), ih = Integer.parseInt(height);
456 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
458 // attempt #1 - try to cope with change in screen geometry - this
459 // version doesn't preserve original jv aspect ratio.
460 // take ratio of current screen size vs original screen size.
461 double sw = ((1f * screenSize.width) / (1f * Integer
462 .parseInt(jalview.bin.Cache
463 .getProperty("SCREENGEOMETRY_WIDTH"))));
464 double sh = ((1f * screenSize.height) / (1f * Integer
465 .parseInt(jalview.bin.Cache
466 .getProperty("SCREENGEOMETRY_HEIGHT"))));
467 // rescale the bounds depending upon the current screen geometry.
468 ix = (int) (ix * sw);
469 iw = (int) (iw * sw);
470 iy = (int) (iy * sh);
471 ih = (int) (ih * sh);
472 while (ix >= screenSize.width)
474 jalview.bin.Cache.log
475 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
476 ix -= screenSize.width;
478 while (iy >= screenSize.height)
480 jalview.bin.Cache.log
481 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
482 iy -= screenSize.height;
484 jalview.bin.Cache.log.debug("Got last known dimensions for "
485 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
488 // return dimensions for new instance
489 return new Rectangle(ix, iy, iw, ih);
494 private void doVamsasClientCheck()
496 if (jalview.bin.Cache.vamsasJarsPresent())
498 setupVamsasDisconnectedGui();
499 VamsasMenu.setVisible(true);
500 final Desktop us = this;
501 VamsasMenu.addMenuListener(new MenuListener()
503 // this listener remembers when the menu was first selected, and
504 // doesn't rebuild the session list until it has been cleared and
506 boolean refresh = true;
508 public void menuCanceled(MenuEvent e)
513 public void menuDeselected(MenuEvent e)
518 public void menuSelected(MenuEvent e)
522 us.buildVamsasStMenu();
527 vamsasStart.setVisible(true);
531 void showPasteMenu(int x, int y)
533 JPopupMenu popup = new JPopupMenu();
534 JMenuItem item = new JMenuItem("Paste To New Window");
535 item.addActionListener(new ActionListener()
537 public void actionPerformed(ActionEvent evt)
544 popup.show(this, x, y);
551 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
552 Transferable contents = c.getContents(this);
554 if (contents != null)
556 String file = (String) contents
557 .getTransferData(DataFlavor.stringFlavor);
559 String format = new IdentifyFile().Identify(file,
560 FormatAdapter.PASTE);
562 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
565 } catch (Exception ex)
568 .println("Unable to paste alignment from system clipboard:\n"
574 * Adds and opens the given frame to the desktop
585 public static synchronized void addInternalFrame(
586 final JInternalFrame frame, String title, int w, int h)
588 addInternalFrame(frame, title, w, h, true);
605 public static synchronized void addInternalFrame(
606 final JInternalFrame frame, String title, int w, int h,
610 // TODO: allow callers to determine X and Y position of frame (eg. via
612 // TODO: consider fixing method to update entries in the window submenu with
613 // the current window title
615 frame.setTitle(title);
616 if (frame.getWidth() < 1 || frame.getHeight() < 1)
620 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
621 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
622 // IF JALVIEW IS RUNNING HEADLESS
623 // ///////////////////////////////////////////////
624 if (System.getProperty("java.awt.headless") != null
625 && System.getProperty("java.awt.headless").equals("true"))
632 frame.setVisible(true);
633 frame.setClosable(true);
634 frame.setResizable(resizable);
635 frame.setMaximizable(resizable);
636 frame.setIconifiable(resizable);
637 frame.setFrameIcon(null);
639 if (frame.getX() < 1 && frame.getY() < 1)
641 frame.setLocation(xOffset * openFrameCount, yOffset
642 * ((openFrameCount - 1) % 10) + yOffset);
645 final JMenuItem menuItem = new JMenuItem(title);
646 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
648 public void internalFrameActivated(
649 javax.swing.event.InternalFrameEvent evt)
651 JInternalFrame itf = desktop.getSelectedFrame();
659 public void internalFrameClosed(
660 javax.swing.event.InternalFrameEvent evt)
662 PaintRefresher.RemoveComponent(frame);
664 windowMenu.remove(menuItem);
665 JInternalFrame itf = desktop.getSelectedFrame();
674 menuItem.addActionListener(new ActionListener()
676 public void actionPerformed(ActionEvent e)
680 frame.setSelected(true);
681 frame.setIcon(false);
682 } catch (java.beans.PropertyVetoException ex)
688 menuItem.addMouseListener(new MouseListener()
692 public void mouseReleased(MouseEvent e)
697 public void mousePressed(MouseEvent e)
702 public void mouseExited(MouseEvent e)
706 frame.setSelected(false);
707 } catch (PropertyVetoException e1)
713 public void mouseEntered(MouseEvent e)
717 frame.setSelected(true);
718 } catch (PropertyVetoException e1)
724 public void mouseClicked(MouseEvent e)
730 windowMenu.add(menuItem);
736 frame.setSelected(true);
737 frame.requestFocus();
738 } catch (java.beans.PropertyVetoException ve)
741 catch (java.lang.ClassCastException cex)
743 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);
747 public void lostOwnership(Clipboard clipboard, Transferable contents)
751 Desktop.jalviewClipboard = null;
754 internalCopy = false;
757 public void dragEnter(DropTargetDragEvent evt)
761 public void dragExit(DropTargetEvent evt)
765 public void dragOver(DropTargetDragEvent evt)
769 public void dropActionChanged(DropTargetDragEvent evt)
779 public void drop(DropTargetDropEvent evt)
781 Transferable t = evt.getTransferable();
782 java.util.List files = null;
783 java.util.List protocols = null;
787 DataFlavor uriListFlavor = new DataFlavor(
788 "text/uri-list;class=java.lang.String");
789 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
791 // Works on Windows and MacOSX
792 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
793 files = (java.util.List) t
794 .getTransferData(DataFlavor.javaFileListFlavor);
796 else if (t.isDataFlavorSupported(uriListFlavor))
798 // This is used by Unix drag system
799 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
800 String data = (String) t.getTransferData(uriListFlavor);
801 files = new java.util.ArrayList(1);
802 protocols = new java.util.ArrayList(1);
803 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
804 data, "\r\n"); st.hasMoreTokens();)
806 String s = st.nextToken();
807 if (s.startsWith("#"))
809 // the line is a comment (as per the RFC 2483)
812 java.net.URI uri = new java.net.URI(s);
813 if (uri.getScheme().toLowerCase().startsWith("http"))
815 protocols.add(FormatAdapter.URL);
816 files.add(uri.toString());
820 // otherwise preserve old behaviour: catch all for file objects
821 java.io.File file = new java.io.File(uri);
822 protocols.add(FormatAdapter.FILE);
823 files.add(file.toString());
827 } catch (Exception e)
835 for (int i = 0; i < files.size(); i++)
837 String file = files.get(i).toString();
838 String protocol = (protocols == null) ? FormatAdapter.FILE
839 : (String) protocols.get(i);
840 String format = null;
842 if (file.endsWith(".jar"))
849 format = new IdentifyFile().Identify(file, protocol);
852 new FileLoader().LoadFile(file, protocol, format);
855 } catch (Exception ex)
867 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
869 JalviewFileChooser chooser = new JalviewFileChooser(
870 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
871 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
872 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
873 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
875 chooser.setFileView(new JalviewFileView());
876 chooser.setDialogTitle("Open local file");
877 chooser.setToolTipText("Open");
879 int value = chooser.showOpenDialog(this);
881 if (value == JalviewFileChooser.APPROVE_OPTION)
883 String choice = chooser.getSelectedFile().getPath();
884 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
885 .getSelectedFile().getParent());
887 String format = null;
888 if (chooser.getSelectedFormat().equals("Jalview"))
894 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
897 if (viewport != null)
899 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
904 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
915 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
917 // This construct allows us to have a wider textfield
919 JLabel label = new JLabel("Enter URL of Input File");
920 final JComboBox history = new JComboBox();
922 JPanel panel = new JPanel(new GridLayout(2, 1));
925 history.setPreferredSize(new Dimension(400, 20));
926 history.setEditable(true);
927 history.addItem("http://www.");
929 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
933 if (historyItems != null)
935 st = new StringTokenizer(historyItems, "\t");
937 while (st.hasMoreTokens())
939 history.addItem(st.nextElement());
943 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
944 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
946 if (reply != JOptionPane.OK_OPTION)
951 String url = history.getSelectedItem().toString();
953 if (url.toLowerCase().endsWith(".jar"))
955 if (viewport != null)
957 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
962 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
967 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
969 if (format.equals("URL NOT FOUND"))
971 JOptionPane.showInternalMessageDialog(Desktop.desktop,
972 "Couldn't locate " + url, "URL not found",
973 JOptionPane.WARNING_MESSAGE);
978 if (viewport != null)
980 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
984 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
995 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
997 CutAndPasteTransfer cap = new CutAndPasteTransfer();
998 cap.setForInput(viewport);
999 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1007 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1009 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1010 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1012 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1013 getBounds().y, getWidth(), getHeight()));
1015 if (jconsole != null)
1017 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1018 jconsole.stopConsole();
1022 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1029 private void storeLastKnownDimensions(String string, Rectangle jc)
1031 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1032 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1033 + " height:" + jc.height);
1035 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1036 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1037 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1038 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1047 public void aboutMenuItem_actionPerformed(ActionEvent e)
1049 StringBuffer message = new StringBuffer("Jalview version "
1050 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
1051 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1053 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
1054 jalview.bin.Cache.getProperty("VERSION")))
1056 message.append("\n\n!! Jalview version "
1057 + jalview.bin.Cache.getProperty("LATEST_VERSION")
1058 + " is available for download from "+jalview.bin.Cache.getDefault("www.jalview.org","http://www.jalview.org")+" !!\n");
1061 // TODO: update this text for each release or centrally store it for lite
1063 message.append("\nAuthors: Jim Procter, Andrew Waterhouse, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
1064 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
1065 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
1066 + "\nIf you use Jalview, please cite:"
1067 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1068 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1069 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
1070 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1072 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1081 public void documentationMenuItem_actionPerformed(ActionEvent e)
1085 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1086 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1087 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1089 javax.help.HelpBroker hb = hs.createHelpBroker();
1090 hb.setCurrentID("home");
1091 hb.setDisplayed(true);
1092 } catch (Exception ex)
1097 public void closeAll_actionPerformed(ActionEvent e)
1099 JInternalFrame[] frames = desktop.getAllFrames();
1100 for (int i = 0; i < frames.length; i++)
1104 frames[i].setClosed(true);
1105 } catch (java.beans.PropertyVetoException ex)
1109 System.out.println("ALL CLOSED");
1110 if (v_client != null)
1112 // TODO clear binding to vamsas document objects on close_all
1117 public void raiseRelated_actionPerformed(ActionEvent e)
1119 reorderAssociatedWindows(false, false);
1122 public void minimizeAssociated_actionPerformed(ActionEvent e)
1124 reorderAssociatedWindows(true, false);
1127 void closeAssociatedWindows()
1129 reorderAssociatedWindows(false, true);
1135 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1138 protected void garbageCollect_actionPerformed(ActionEvent e)
1140 // We simply collect the garbage
1141 jalview.bin.Cache.log.debug("Collecting garbage...");
1143 jalview.bin.Cache.log.debug("Finished garbage collection.");
1150 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1153 protected void showMemusage_actionPerformed(ActionEvent e)
1155 desktop.showMemoryUsage(showMemusage.isSelected());
1162 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1165 protected void showConsole_actionPerformed(ActionEvent e)
1167 showConsole(showConsole.isSelected());
1170 Console jconsole = null;
1173 * control whether the java console is visible or not
1177 void showConsole(boolean selected)
1179 showConsole.setSelected(selected);
1180 // TODO: decide if we should update properties file
1181 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1183 jconsole.setVisible(selected);
1186 void reorderAssociatedWindows(boolean minimize, boolean close)
1188 JInternalFrame[] frames = desktop.getAllFrames();
1189 if (frames == null || frames.length < 1)
1194 AlignViewport source = null, target = null;
1195 if (frames[0] instanceof AlignFrame)
1197 source = ((AlignFrame) frames[0]).getCurrentView();
1199 else if (frames[0] instanceof TreePanel)
1201 source = ((TreePanel) frames[0]).getViewPort();
1203 else if (frames[0] instanceof PCAPanel)
1205 source = ((PCAPanel) frames[0]).av;
1207 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1209 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1214 for (int i = 0; i < frames.length; i++)
1217 if (frames[i] == null)
1221 if (frames[i] instanceof AlignFrame)
1223 target = ((AlignFrame) frames[i]).getCurrentView();
1225 else if (frames[i] instanceof TreePanel)
1227 target = ((TreePanel) frames[i]).getViewPort();
1229 else if (frames[i] instanceof PCAPanel)
1231 target = ((PCAPanel) frames[i]).av;
1233 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1235 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1238 if (source == target)
1244 frames[i].setClosed(true);
1248 frames[i].setIcon(minimize);
1251 frames[i].toFront();
1255 } catch (java.beans.PropertyVetoException ex)
1269 protected void preferences_actionPerformed(ActionEvent e)
1280 public void saveState_actionPerformed(ActionEvent e)
1282 JalviewFileChooser chooser = new JalviewFileChooser(
1283 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1284 { "jar" }, new String[]
1285 { "Jalview Project" }, "Jalview Project");
1287 chooser.setFileView(new JalviewFileView());
1288 chooser.setDialogTitle("Save State");
1290 int value = chooser.showSaveDialog(this);
1292 if (value == JalviewFileChooser.APPROVE_OPTION)
1294 final Desktop me = this;
1295 final java.io.File choice = chooser.getSelectedFile();
1296 new Thread(new Runnable()
1301 setProgressBar("Saving jalview project " + choice.getName(),
1303 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1304 // TODO catch and handle errors for savestate
1305 // TODO prevent user from messing with the Desktop whilst we're saving
1308 new Jalview2XML().SaveState(choice);
1309 } catch (OutOfMemoryError oom)
1312 "Whilst saving current state to " + choice.getName(), oom);
1313 } catch (Exception ex)
1316 .error("Problems whilst trying to save to "
1317 + choice.getName(), ex);
1318 JOptionPane.showMessageDialog(me,
1319 "Error whilst saving current state to " + choice.getName(),
1320 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1322 setProgressBar(null, choice.hashCode());
1334 public void loadState_actionPerformed(ActionEvent e)
1336 JalviewFileChooser chooser = new JalviewFileChooser(
1337 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1338 { "jar" }, new String[]
1339 { "Jalview Project" }, "Jalview Project");
1340 chooser.setFileView(new JalviewFileView());
1341 chooser.setDialogTitle("Restore state");
1343 int value = chooser.showOpenDialog(this);
1345 if (value == JalviewFileChooser.APPROVE_OPTION)
1347 final String choice = chooser.getSelectedFile().getAbsolutePath();
1348 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1349 .getSelectedFile().getParent());
1350 new Thread(new Runnable()
1354 setProgressBar("loading jalview project " + choice,
1358 new Jalview2XML().LoadJalviewAlign(choice);
1359 } catch (OutOfMemoryError oom)
1361 new OOMWarning("Whilst loading project from " + choice, oom);
1362 } catch (Exception ex)
1364 Cache.log.error("Problems whilst loading project from "
1366 JOptionPane.showMessageDialog(Desktop.desktop,
1367 "Error whilst loading project from " + choice,
1368 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1370 setProgressBar(null, choice.hashCode());
1376 public void inputSequence_actionPerformed(ActionEvent e)
1378 new SequenceFetcher(this);
1381 JPanel progressPanel;
1382 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1383 public void startLoading(final String fileName)
1385 if (fileLoadingCount == 0)
1387 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1392 private JPanel addProgressPanel(String string)
1394 if (progressPanel == null)
1396 progressPanel = new JPanel(new GridLayout(1,1));
1397 totalProgressCount = 0;
1398 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1400 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1401 JProgressBar progressBar = new JProgressBar();
1402 progressBar.setIndeterminate(true);
1404 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1406 thisprogress.add(progressBar, BorderLayout.CENTER);
1407 progressPanel.add(thisprogress);
1408 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1409 ++totalProgressCount;
1410 instance.validate();
1411 return thisprogress;
1414 int totalProgressCount = 0;
1416 private void removeProgressPanel(JPanel progbar)
1418 if (progressPanel != null)
1420 progressPanel.remove(progbar);
1421 GridLayout gl = (GridLayout) progressPanel.getLayout();
1422 gl.setRows(gl.getRows()-1);
1423 if (--totalProgressCount < 1)
1425 this.getContentPane().remove(progressPanel);
1426 progressPanel = null;
1432 public void stopLoading()
1435 if (fileLoadingCount < 1)
1437 for (JPanel flp : fileLoadingPanels)
1439 removeProgressPanel(flp);
1441 fileLoadingPanels.clear();
1442 fileLoadingCount = 0;
1447 public static int getViewCount(String alignmentId)
1449 AlignViewport[] aps = getViewports(alignmentId);
1450 return (aps == null) ? 0 : aps.length;
1455 * @param alignmentId
1456 * @return all AlignmentPanels concerning the alignmentId sequence set
1458 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1461 if (Desktop.desktop == null)
1463 // no frames created and in headless mode
1464 // TODO: verify that frames are recoverable when in headless mode
1467 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1468 ArrayList aps = new ArrayList();
1469 for (int t = 0; t < frames.length; t++)
1471 if (frames[t] instanceof AlignFrame)
1473 AlignFrame af = (AlignFrame) frames[t];
1474 for (int a = 0; a < af.alignPanels.size(); a++)
1477 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1478 .getSequenceSetId()))
1480 aps.add(af.alignPanels.elementAt(a));
1485 if (aps.size() == 0)
1489 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1490 for (int t = 0; t < vap.length; t++)
1492 vap[t] = (AlignmentPanel) aps.get(t);
1498 * get all the viewports on an alignment.
1500 * @param sequenceSetId
1501 * unique alignment id
1502 * @return all viewports on the alignment bound to sequenceSetId
1504 public static AlignViewport[] getViewports(String sequenceSetId)
1506 Vector viewp = new Vector();
1507 if (desktop != null)
1509 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1511 for (int t = 0; t < frames.length; t++)
1513 if (frames[t] instanceof AlignFrame)
1515 AlignFrame afr = ((AlignFrame) frames[t]);
1516 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1518 if (afr.alignPanels != null)
1520 for (int a = 0; a < afr.alignPanels.size(); a++)
1522 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1523 .elementAt(a)).av.getSequenceSetId()))
1525 viewp.addElement(((AlignmentPanel) afr.alignPanels
1532 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1537 if (viewp.size() > 0)
1539 AlignViewport[] vp = new AlignViewport[viewp.size()];
1547 public void explodeViews(AlignFrame af)
1549 int size = af.alignPanels.size();
1555 for (int i = 0; i < size; i++)
1557 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1558 AlignFrame newaf = new AlignFrame(ap);
1559 if (ap.av.explodedPosition != null
1560 && !ap.av.explodedPosition.equals(af.getBounds()))
1562 newaf.setBounds(ap.av.explodedPosition);
1565 ap.av.gatherViewsHere = false;
1567 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1568 AlignFrame.DEFAULT_HEIGHT);
1571 af.alignPanels.clear();
1572 af.closeMenuItem_actionPerformed(true);
1576 public void gatherViews(AlignFrame source)
1578 source.viewport.gatherViewsHere = true;
1579 source.viewport.explodedPosition = source.getBounds();
1580 JInternalFrame[] frames = desktop.getAllFrames();
1581 String viewId = source.viewport.sequenceSetID;
1583 for (int t = 0; t < frames.length; t++)
1585 if (frames[t] instanceof AlignFrame && frames[t] != source)
1587 AlignFrame af = (AlignFrame) frames[t];
1588 boolean gatherThis = false;
1589 for (int a = 0; a < af.alignPanels.size(); a++)
1591 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1592 if (viewId.equals(ap.av.getSequenceSetId()))
1595 ap.av.gatherViewsHere = false;
1596 ap.av.explodedPosition = af.getBounds();
1597 source.addAlignmentPanel(ap, false);
1603 af.alignPanels.clear();
1604 af.closeMenuItem_actionPerformed(true);
1611 jalview.gui.VamsasApplication v_client = null;
1613 public void vamsasImport_actionPerformed(ActionEvent e)
1615 if (v_client == null)
1617 // Load and try to start a session.
1618 JalviewFileChooser chooser = new JalviewFileChooser(
1619 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1621 chooser.setFileView(new JalviewFileView());
1622 chooser.setDialogTitle("Open a saved VAMSAS session");
1623 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1625 int value = chooser.showOpenDialog(this);
1627 if (value == JalviewFileChooser.APPROVE_OPTION)
1629 String fle = chooser.getSelectedFile().toString();
1630 if (!vamsasImport(chooser.getSelectedFile()))
1632 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1633 "Couldn't import '" + fle + "' as a new vamsas session.",
1634 "Vamsas Document Import Failed",
1635 JOptionPane.ERROR_MESSAGE);
1641 jalview.bin.Cache.log
1642 .error("Implementation error - load session from a running session is not supported.");
1647 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1650 * @return true if import was a success and a session was started.
1652 public boolean vamsasImport(URL url)
1654 // TODO: create progress bar
1655 if (v_client != null)
1658 jalview.bin.Cache.log
1659 .error("Implementation error - load session from a running session is not supported.");
1665 // copy the URL content to a temporary local file
1666 // TODO: be a bit cleverer here with nio (?!)
1667 File file = File.createTempFile("vdocfromurl", ".vdj");
1668 FileOutputStream fos = new FileOutputStream(file);
1669 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1670 byte[] buffer = new byte[2048];
1672 while ((ln = bis.read(buffer)) > -1)
1674 fos.write(buffer, 0, ln);
1678 v_client = new jalview.gui.VamsasApplication(this, file,
1679 url.toExternalForm());
1680 } catch (Exception ex)
1682 jalview.bin.Cache.log.error(
1683 "Failed to create new vamsas session from contents of URL "
1687 setupVamsasConnectedGui();
1688 v_client.initial_update(); // TODO: thread ?
1689 return v_client.inSession();
1693 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1696 * @return true if import was a success and a session was started.
1698 public boolean vamsasImport(File file)
1700 if (v_client != null)
1703 jalview.bin.Cache.log
1704 .error("Implementation error - load session from a running session is not supported.");
1708 setProgressBar("Importing VAMSAS session from " + file.getName(),
1712 v_client = new jalview.gui.VamsasApplication(this, file, null);
1713 } catch (Exception ex)
1715 setProgressBar("Importing VAMSAS session from " + file.getName(),
1717 jalview.bin.Cache.log.error(
1718 "New vamsas session from existing session file failed:", ex);
1721 setupVamsasConnectedGui();
1722 v_client.initial_update(); // TODO: thread ?
1723 setProgressBar("Importing VAMSAS session from " + file.getName(),
1725 return v_client.inSession();
1728 public boolean joinVamsasSession(String mysesid)
1730 if (v_client != null)
1733 "Trying to join a vamsas session when another is already connected.");
1735 if (mysesid == null)
1737 throw new Error("Invalid vamsas session id.");
1739 v_client = new VamsasApplication(this, mysesid);
1740 setupVamsasConnectedGui();
1741 v_client.initial_update();
1742 return (v_client.inSession());
1745 public void vamsasStart_actionPerformed(ActionEvent e)
1747 if (v_client == null)
1750 // we just start a default session for moment.
1752 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1753 * getProperty("LAST_DIRECTORY"));
1755 * chooser.setFileView(new JalviewFileView());
1756 * chooser.setDialogTitle("Load Vamsas file");
1757 * chooser.setToolTipText("Import");
1759 * int value = chooser.showOpenDialog(this);
1761 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1762 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1764 v_client = new VamsasApplication(this);
1765 setupVamsasConnectedGui();
1766 v_client.initial_update(); // TODO: thread ?
1770 // store current data in session.
1771 v_client.push_update(); // TODO: thread
1775 protected void setupVamsasConnectedGui()
1777 vamsasStart.setText("Session Update");
1778 vamsasSave.setVisible(true);
1779 vamsasStop.setVisible(true);
1780 vamsasImport.setVisible(false); // Document import to existing session is
1781 // not possible for vamsas-client-1.0.
1784 protected void setupVamsasDisconnectedGui()
1786 vamsasSave.setVisible(false);
1787 vamsasStop.setVisible(false);
1788 vamsasImport.setVisible(true);
1789 vamsasStart.setText("New Vamsas Session");
1792 public void vamsasStop_actionPerformed(ActionEvent e)
1794 if (v_client != null)
1796 v_client.end_session();
1798 setupVamsasDisconnectedGui();
1802 protected void buildVamsasStMenu()
1804 if (v_client == null)
1806 String[] sess = null;
1809 sess = VamsasApplication.getSessionList();
1810 } catch (Exception e)
1812 jalview.bin.Cache.log.warn(
1813 "Problem getting current sessions list.", e);
1818 jalview.bin.Cache.log.debug("Got current sessions list: "
1819 + sess.length + " entries.");
1820 VamsasStMenu.removeAll();
1821 for (int i = 0; i < sess.length; i++)
1823 JMenuItem sessit = new JMenuItem();
1824 sessit.setText(sess[i]);
1825 sessit.setToolTipText("Connect to session " + sess[i]);
1826 final Desktop dsktp = this;
1827 final String mysesid = sess[i];
1828 sessit.addActionListener(new ActionListener()
1831 public void actionPerformed(ActionEvent e)
1833 if (dsktp.v_client == null)
1835 Thread rthr = new Thread(new Runnable()
1840 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1841 dsktp.setupVamsasConnectedGui();
1842 dsktp.v_client.initial_update();
1850 VamsasStMenu.add(sessit);
1852 // don't show an empty menu.
1853 VamsasStMenu.setVisible(sess.length > 0);
1858 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1859 VamsasStMenu.removeAll();
1860 VamsasStMenu.setVisible(false);
1865 // Not interested in the content. Just hide ourselves.
1866 VamsasStMenu.setVisible(false);
1870 public void vamsasSave_actionPerformed(ActionEvent e)
1872 if (v_client != null)
1874 JalviewFileChooser chooser = new JalviewFileChooser(
1875 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1876 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1878 { "Vamsas Document" }, "Vamsas Document");
1880 chooser.setFileView(new JalviewFileView());
1881 chooser.setDialogTitle("Save Vamsas Document Archive");
1883 int value = chooser.showSaveDialog(this);
1885 if (value == JalviewFileChooser.APPROVE_OPTION)
1887 java.io.File choice = chooser.getSelectedFile();
1888 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1889 + choice.getName());
1890 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1891 String warnmsg = null;
1892 String warnttl = null;
1895 v_client.vclient.storeDocument(choice);
1898 warnttl = "Serious Problem saving Vamsas Document";
1899 warnmsg = ex.toString();
1900 jalview.bin.Cache.log.error("Error Whilst saving document to "
1903 } catch (Exception ex)
1905 warnttl = "Problem saving Vamsas Document.";
1906 warnmsg = ex.toString();
1907 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1911 removeProgressPanel(progpanel);
1912 if (warnmsg != null)
1914 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1916 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1922 JPanel vamUpdate = null;
1925 * hide vamsas user gui bits when a vamsas document event is being handled.
1928 * true to hide gui, false to reveal gui
1930 public void setVamsasUpdate(boolean b)
1932 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1933 + (b ? "in progress" : "finished"));
1935 if (vamUpdate != null)
1937 this.removeProgressPanel(vamUpdate);
1941 vamUpdate = this.addProgressPanel("Updating vamsas session");
1943 vamsasStart.setVisible(!b);
1944 vamsasStop.setVisible(!b);
1945 vamsasSave.setVisible(!b);
1948 public JInternalFrame[] getAllFrames()
1950 return desktop.getAllFrames();
1954 * Checks the given url to see if it gives a response indicating that the user
1955 * should be informed of a new questionnaire.
1959 public void checkForQuestionnaire(String url)
1961 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1962 // javax.swing.SwingUtilities.invokeLater(jvq);
1963 new Thread(jvq).start();
1967 * Proxy class for JDesktopPane which optionally displays the current memory
1968 * usage and highlights the desktop area with a red bar if free memory runs
1973 public class MyDesktopPane extends JDesktopPane implements Runnable
1976 boolean showMemoryUsage = false;
1980 java.text.NumberFormat df;
1982 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1985 public MyDesktopPane(boolean showMemoryUsage)
1987 showMemoryUsage(showMemoryUsage);
1990 public void showMemoryUsage(boolean showMemoryUsage)
1992 this.showMemoryUsage = showMemoryUsage;
1993 if (showMemoryUsage)
1995 Thread worker = new Thread(this);
2000 public boolean isShowMemoryUsage()
2002 return showMemoryUsage;
2007 df = java.text.NumberFormat.getNumberInstance();
2008 df.setMaximumFractionDigits(2);
2009 runtime = Runtime.getRuntime();
2011 while (showMemoryUsage)
2015 maxMemory = runtime.maxMemory() / 1048576f;
2016 allocatedMemory = runtime.totalMemory() / 1048576f;
2017 freeMemory = runtime.freeMemory() / 1048576f;
2018 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2020 percentUsage = (totalFreeMemory / maxMemory) * 100;
2022 // if (percentUsage < 20)
2024 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2026 // instance.set.setBorder(border1);
2029 // sleep after showing usage
2031 } catch (Exception ex)
2033 ex.printStackTrace();
2038 public void paintComponent(Graphics g)
2040 if (showMemoryUsage && g != null && df != null)
2042 if (percentUsage < 20)
2043 g.setColor(Color.red);
2044 FontMetrics fm = g.getFontMetrics();
2048 "Total Free Memory: " + df.format(totalFreeMemory)
2049 + "MB; Max Memory: " + df.format(maxMemory)
2050 + "MB; " + df.format(percentUsage) + "%", 10,
2051 getHeight() - fm.getHeight());
2059 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2061 public void relayerWindows()
2066 protected JMenuItem groovyShell;
2068 public void doGroovyCheck()
2070 if (jalview.bin.Cache.groovyJarsPresent())
2072 groovyShell = new JMenuItem();
2073 groovyShell.setText("Groovy Console...");
2074 groovyShell.addActionListener(new ActionListener()
2076 public void actionPerformed(ActionEvent e)
2078 groovyShell_actionPerformed(e);
2081 toolsMenu.add(groovyShell);
2082 groovyShell.setVisible(true);
2087 * Accessor method to quickly get all the AlignmentFrames loaded.
2089 public static AlignFrame[] getAlignframes()
2091 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2097 Vector avp = new Vector();
2101 for (int i = frames.length - 1; i > -1; i--)
2103 if (frames[i] instanceof AlignFrame)
2105 AlignFrame af = (AlignFrame) frames[i];
2109 } catch (Exception ex)
2111 ex.printStackTrace();
2113 if (avp.size() == 0)
2117 AlignFrame afs[] = new AlignFrame[avp.size()];
2118 for (int i = 0, j = avp.size(); i < j; i++)
2120 afs[i] = (AlignFrame) avp.elementAt(i);
2125 public AppJmol[] getJmols()
2127 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2133 Vector avp = new Vector();
2137 for (int i = frames.length - 1; i > -1; i--)
2139 if (frames[i] instanceof AppJmol)
2141 AppJmol af = (AppJmol) frames[i];
2145 } catch (Exception ex)
2147 ex.printStackTrace();
2149 if (avp.size() == 0)
2153 AppJmol afs[] = new AppJmol[avp.size()];
2154 for (int i = 0, j = avp.size(); i < j; i++)
2156 afs[i] = (AppJmol) avp.elementAt(i);
2163 * Add Groovy Support to Jalview
2165 public void groovyShell_actionPerformed(ActionEvent e)
2167 // use reflection to avoid creating compilation dependency.
2168 if (!jalview.bin.Cache.groovyJarsPresent())
2171 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2175 Class gcClass = Desktop.class.getClassLoader().loadClass(
2176 "groovy.ui.Console");
2177 Constructor gccons = gcClass.getConstructor(null);
2178 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2180 { String.class, Object.class });
2181 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2182 Object gc = gccons.newInstance(null);
2183 setvar.invoke(gc, new Object[]
2184 { "Jalview", this });
2185 run.invoke(gc, null);
2186 } catch (Exception ex)
2188 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2190 .showInternalMessageDialog(
2193 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2194 "Jalview Groovy Support Failed",
2195 JOptionPane.ERROR_MESSAGE);
2200 * Progress bars managed by the IProgressIndicator method.
2202 private Hashtable<Long,JPanel> progressBars;
2203 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2208 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2210 public void setProgressBar(String message, long id)
2212 if (progressBars == null)
2214 progressBars = new Hashtable<Long,JPanel>();
2215 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2218 if (progressBars.get(new Long(id)) != null)
2220 JPanel progressPanel = progressBars
2221 .remove(new Long(id));
2222 if (progressBarHandlers.contains(new Long(id)))
2224 progressBarHandlers.remove(new Long(id));
2226 removeProgressPanel(progressPanel);
2230 progressBars.put(new Long(id), addProgressPanel(message));
2237 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2238 * jalview.gui.IProgressIndicatorHandler)
2240 public void registerHandler(final long id,
2241 final IProgressIndicatorHandler handler)
2243 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2246 "call setProgressBar before registering the progress bar's handler.");
2248 progressBarHandlers.put(new Long(id), handler);
2249 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2250 if (handler.canCancel())
2252 JButton cancel = new JButton("Cancel");
2253 final IProgressIndicator us = this;
2254 cancel.addActionListener(new ActionListener()
2257 public void actionPerformed(ActionEvent e)
2259 handler.cancelActivity(id);
2262 + ((JLabel) progressPanel.getComponent(0))
2266 progressPanel.add(cancel, BorderLayout.EAST);
2271 * This will return the first AlignFrame viewing AlignViewport av. It will
2272 * break if there are more than one AlignFrames viewing a particular av. This
2275 * @return alignFrame for av
2277 public static AlignFrame getAlignFrameFor(AlignViewport av)
2279 if (desktop != null)
2281 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2282 for (int panel = 0; aps != null && panel < aps.length; panel++)
2284 if (aps[panel] != null && aps[panel].av == av)
2286 return aps[panel].alignFrame;
2293 public VamsasApplication getVamsasApplication()
2300 * flag set if jalview GUI is being operated programmatically
2302 private boolean inBatchMode = false;
2305 * check if jalview GUI is being operated programmatically
2307 * @return inBatchMode
2309 public boolean isInBatchMode()
2315 * set flag if jalview GUI is being operated programmatically
2317 * @param inBatchMode
2319 public void setInBatchMode(boolean inBatchMode)
2321 this.inBatchMode = inBatchMode;
2324 public void startServiceDiscovery()
2326 startServiceDiscovery(false);
2329 public void startServiceDiscovery(boolean blocking)
2331 boolean alive = true;
2332 Thread t0 = null, t1 = null, t2 = null;
2334 // todo: changesupport handlers need to be transferred
2335 if (discoverer == null)
2337 discoverer = new jalview.ws.jws1.Discoverer();
2338 // register PCS handler for desktop.
2339 discoverer.addPropertyChangeListener(changeSupport);
2341 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2344 (t0 = new Thread(discoverer)).start();
2349 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2351 // EnfinEnvision web service menu entries are rebuild every time the
2352 // menu is shown, so no changeSupport events are needed.
2353 jalview.ws.EnfinEnvision2OneWay.getInstance();
2354 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2357 } catch (Exception e)
2360 .info("Exception when trying to launch Envision2 workflow discovery.",
2362 Cache.log.info(e.getStackTrace());
2364 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2366 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2368 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2370 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2376 // TODO: do rest service discovery
2385 } catch (Exception e)
2388 alive = (t1 != null && t1.isAlive())
2389 || (t2 != null && t2.isAlive())
2390 || (t3 != null && t3.isAlive())
2391 || (t0 != null && t0.isAlive());
2397 * called to check if the service discovery process completed successfully.
2401 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2403 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2405 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2406 .getErrorMessages();
2409 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2411 if (serviceChangedDialog == null)
2413 // only run if we aren't already displaying one of these.
2414 javax.swing.SwingUtilities
2415 .invokeLater(serviceChangedDialog = new Runnable()
2421 .showInternalMessageDialog(
2424 + "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",
2425 "Preferences Problem",
2426 JOptionPane.WARNING_MESSAGE);
2427 serviceChangedDialog = null;
2436 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2443 private Runnable serviceChangedDialog = null;
2446 * start a thread to open a URL in the configured browser. Pops up a warning
2447 * dialog to the user if there is an exception when calling out to the browser
2452 public static void showUrl(final String url)
2454 showUrl(url, Desktop.instance);
2457 * Like showUrl but allows progress handler to be specified
2459 * @param progress (null) or object implementing IProgressIndicator
2461 public static void showUrl(final String url, final IProgressIndicator progress)
2463 new Thread(new Runnable()
2469 if (progress!=null) {
2470 progress.setProgressBar("Opening "+url, this.hashCode());
2472 jalview.util.BrowserLauncher.openURL(url);
2473 } catch (Exception ex)
2476 .showInternalMessageDialog(
2478 "Unixers: Couldn't find default web browser."
2479 + "\nAdd the full path to your browser in Preferences.",
2480 "Web browser not found",
2481 JOptionPane.WARNING_MESSAGE);
2483 ex.printStackTrace();
2485 if (progress!=null) {
2486 progress.setProgressBar(null, this.hashCode());
2492 public static WsParamSetManager wsparamManager = null;
2494 public static ParamManager getUserParameterStore()
2496 if (wsparamManager == null)
2498 wsparamManager = new WsParamSetManager();
2500 return wsparamManager;