2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.io.FileLoader;
25 import jalview.io.FormatAdapter;
26 import jalview.io.IdentifyFile;
27 import jalview.io.JalviewFileChooser;
28 import jalview.io.JalviewFileView;
29 import jalview.structure.StructureSelectionManager;
30 import jalview.util.ImageMaker;
31 import jalview.util.MessageManager;
32 import jalview.ws.params.ParamManager;
34 import java.awt.BorderLayout;
35 import java.awt.Color;
36 import java.awt.Dimension;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics;
39 import java.awt.GridLayout;
40 import java.awt.Point;
41 import java.awt.Rectangle;
42 import java.awt.Toolkit;
43 import java.awt.datatransfer.Clipboard;
44 import java.awt.datatransfer.ClipboardOwner;
45 import java.awt.datatransfer.DataFlavor;
46 import java.awt.datatransfer.Transferable;
47 import java.awt.dnd.DnDConstants;
48 import java.awt.dnd.DropTargetDragEvent;
49 import java.awt.dnd.DropTargetDropEvent;
50 import java.awt.dnd.DropTargetEvent;
51 import java.awt.dnd.DropTargetListener;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.ActionListener;
54 import java.awt.event.FocusEvent;
55 import java.awt.event.FocusListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.WindowAdapter;
60 import java.awt.event.WindowEvent;
61 import java.beans.PropertyChangeEvent;
62 import java.beans.PropertyChangeListener;
63 import java.beans.PropertyVetoException;
64 import java.io.BufferedInputStream;
66 import java.io.FileOutputStream;
67 import java.lang.reflect.Constructor;
69 import java.util.ArrayList;
70 import java.util.Hashtable;
71 import java.util.StringTokenizer;
72 import java.util.Vector;
73 import java.util.concurrent.ExecutorService;
74 import java.util.concurrent.Executors;
75 import java.util.concurrent.Semaphore;
77 import javax.swing.DefaultDesktopManager;
78 import javax.swing.DesktopManager;
79 import javax.swing.JButton;
80 import javax.swing.JComboBox;
81 import javax.swing.JComponent;
82 import javax.swing.JDesktopPane;
83 import javax.swing.JFrame;
84 import javax.swing.JInternalFrame;
85 import javax.swing.JLabel;
86 import javax.swing.JMenuItem;
87 import javax.swing.JOptionPane;
88 import javax.swing.JPanel;
89 import javax.swing.JPopupMenu;
90 import javax.swing.JProgressBar;
91 import javax.swing.SwingUtilities;
92 import javax.swing.event.HyperlinkEvent;
93 import javax.swing.event.HyperlinkEvent.EventType;
94 import javax.swing.event.MenuEvent;
95 import javax.swing.event.MenuListener;
102 * @version $Revision: 1.155 $
104 public class Desktop extends jalview.jbgui.GDesktop implements
105 DropTargetListener, ClipboardOwner, IProgressIndicator,
106 jalview.api.StructureSelectionManagerProvider
109 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
112 * news reader - null if it was never started.
114 private BlogReader jvnews = null;
118 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void addJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
139 * @param propertyName
141 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
142 * java.beans.PropertyChangeListener)
144 public void removeJalviewPropertyChangeListener(String propertyName,
145 PropertyChangeListener listener)
147 changeSupport.removeJalviewPropertyChangeListener(propertyName,
151 /** Singleton Desktop instance */
152 public static Desktop instance;
154 public static MyDesktopPane desktop;
156 static int openFrameCount = 0;
158 static final int xOffset = 30;
160 static final int yOffset = 30;
162 public static jalview.ws.jws1.Discoverer discoverer;
164 public static Object[] jalviewClipboard;
166 public static boolean internalCopy = false;
168 static int fileLoadingCount = 0;
170 class MyDesktopManager implements DesktopManager
173 private DesktopManager delegate;
175 public MyDesktopManager(DesktopManager delegate)
177 this.delegate = delegate;
180 public void activateFrame(JInternalFrame f)
184 delegate.activateFrame(f);
185 } catch (NullPointerException npe)
187 Point p = getMousePosition();
188 instance.showPasteMenu(p.x, p.y);
192 public void beginDraggingFrame(JComponent f)
194 delegate.beginDraggingFrame(f);
197 public void beginResizingFrame(JComponent f, int direction)
199 delegate.beginResizingFrame(f, direction);
202 public void closeFrame(JInternalFrame f)
204 delegate.closeFrame(f);
207 public void deactivateFrame(JInternalFrame f)
209 delegate.deactivateFrame(f);
212 public void deiconifyFrame(JInternalFrame f)
214 delegate.deiconifyFrame(f);
217 public void dragFrame(JComponent f, int newX, int newY)
223 delegate.dragFrame(f, newX, newY);
226 public void endDraggingFrame(JComponent f)
228 delegate.endDraggingFrame(f);
231 public void endResizingFrame(JComponent f)
233 delegate.endResizingFrame(f);
236 public void iconifyFrame(JInternalFrame f)
238 delegate.iconifyFrame(f);
241 public void maximizeFrame(JInternalFrame f)
243 delegate.maximizeFrame(f);
246 public void minimizeFrame(JInternalFrame f)
248 delegate.minimizeFrame(f);
251 public void openFrame(JInternalFrame f)
253 delegate.openFrame(f);
256 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
259 Rectangle b = desktop.getBounds();
264 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
267 public void setBoundsForFrame(JComponent f, int newX, int newY,
268 int newWidth, int newHeight)
270 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
273 // All other methods, simply delegate
278 * Creates a new Desktop object.
283 * A note to implementors. It is ESSENTIAL that any activities that might
284 * block are spawned off as threads rather than waited for during this
288 doVamsasClientCheck();
290 doConfigureStructurePrefs();
291 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
292 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
293 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
295 boolean showjconsole = jalview.bin.Cache.getDefault(
296 "SHOW_JAVA_CONSOLE", false);
297 desktop = new MyDesktopPane(selmemusage);
298 showMemusage.setSelected(selmemusage);
299 desktop.setBackground(Color.white);
300 getContentPane().setLayout(new BorderLayout());
301 // alternate config - have scrollbars - see notes in JAL-153
302 // JScrollPane sp = new JScrollPane();
303 // sp.getViewport().setView(desktop);
304 // getContentPane().add(sp, BorderLayout.CENTER);
305 getContentPane().add(desktop, BorderLayout.CENTER);
306 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
308 // This line prevents Windows Look&Feel resizing all new windows to maximum
309 // if previous window was maximised
310 desktop.setDesktopManager(new MyDesktopManager(
311 new DefaultDesktopManager()));
313 Rectangle dims = getLastKnownDimensions("");
320 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
321 setBounds((screenSize.width - 900) / 2,
322 (screenSize.height - 650) / 2, 900, 650);
324 jconsole = new Console(this, showjconsole);
325 // add essential build information
326 jconsole.setHeader("Jalview Desktop "
327 + jalview.bin.Cache.getProperty("VERSION") + "\n"
329 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
330 + "Java version: " + System.getProperty("java.version") + "\n"
331 + System.getProperty("os.arch") + " "
332 + System.getProperty("os.name") + " "
333 + System.getProperty("os.version"));
335 showConsole(showjconsole);
337 showNews.setVisible(false);
339 this.addWindowListener(new WindowAdapter()
341 public void windowClosing(WindowEvent evt)
348 this.addMouseListener(ma = new MouseAdapter()
350 public void mousePressed(MouseEvent evt)
352 if (SwingUtilities.isRightMouseButton(evt))
354 showPasteMenu(evt.getX(), evt.getY());
358 desktop.addMouseListener(ma);
360 this.addFocusListener(new FocusListener()
364 public void focusLost(FocusEvent e)
366 // TODO Auto-generated method stub
371 public void focusGained(FocusEvent e)
373 Cache.log.debug("Relaying windows after focus gain");
374 // make sure that we sort windows properly after we gain focus
375 instance.relayerWindows();
378 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
379 // Spawn a thread that shows the splashscreen
380 SwingUtilities.invokeLater(new Runnable()
389 // Thread off a new instance of the file chooser - this reduces the time it
390 // takes to open it later on.
391 new Thread(new Runnable()
395 Cache.log.debug("Filechooser init thread started.");
396 JalviewFileChooser chooser = new JalviewFileChooser(
397 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
398 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
399 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
400 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
401 Cache.log.debug("Filechooser init thread finished.");
404 // Add the service change listener
405 changeSupport.addJalviewPropertyChangeListener("services",
406 new PropertyChangeListener()
410 public void propertyChange(PropertyChangeEvent evt)
412 Cache.log.debug("Firing service changed event for "
413 + evt.getNewValue());
414 JalviewServicesChanged(evt);
420 public void doConfigureStructurePrefs()
422 // configure services
423 StructureSelectionManager ssm = StructureSelectionManager
424 .getStructureSelectionManager(this);
425 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
427 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
428 Preferences.ADD_TEMPFACT_ANN, true));
429 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
430 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
435 ssm.setAddTempFacAnnot(false);
436 ssm.setProcessSecondaryStructure(false);
437 ssm.setSecStructServices(false);
441 public void checkForNews()
443 final Desktop me = this;
444 // Thread off the news reader, in case there are connection problems.
445 addDialogThread(new Runnable()
450 Cache.log.debug("Starting news thread.");
452 jvnews = new BlogReader(me);
453 showNews.setVisible(true);
454 Cache.log.debug("Completed news thread.");
459 protected void showNews_actionPerformed(ActionEvent e)
461 showNews(showNews.isSelected());
464 void showNews(boolean visible)
467 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
468 showNews.setSelected(visible);
469 if (visible && !jvnews.isVisible())
471 new Thread(new Runnable()
476 long instance = System.currentTimeMillis();
477 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
478 jvnews.refreshNews();
479 Desktop.instance.setProgressBar(null, instance);
488 * recover the last known dimensions for a jalview window
491 * - empty string is desktop, all other windows have unique prefix
492 * @return null or last known dimensions scaled to current geometry (if last
493 * window geom was known)
495 Rectangle getLastKnownDimensions(String windowName)
497 // TODO: lock aspect ratio for scaling desktop Bug #0058199
498 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
499 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
500 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
501 String width = jalview.bin.Cache.getProperty(windowName
503 String height = jalview.bin.Cache.getProperty(windowName
505 if ((x != null) && (y != null) && (width != null) && (height != null))
507 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
508 .parseInt(width), ih = Integer.parseInt(height);
509 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
511 // attempt #1 - try to cope with change in screen geometry - this
512 // version doesn't preserve original jv aspect ratio.
513 // take ratio of current screen size vs original screen size.
514 double sw = ((1f * screenSize.width) / (1f * Integer
515 .parseInt(jalview.bin.Cache
516 .getProperty("SCREENGEOMETRY_WIDTH"))));
517 double sh = ((1f * screenSize.height) / (1f * Integer
518 .parseInt(jalview.bin.Cache
519 .getProperty("SCREENGEOMETRY_HEIGHT"))));
520 // rescale the bounds depending upon the current screen geometry.
521 ix = (int) (ix * sw);
522 iw = (int) (iw * sw);
523 iy = (int) (iy * sh);
524 ih = (int) (ih * sh);
525 while (ix >= screenSize.width)
527 jalview.bin.Cache.log
528 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
529 ix -= screenSize.width;
531 while (iy >= screenSize.height)
533 jalview.bin.Cache.log
534 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
535 iy -= screenSize.height;
537 jalview.bin.Cache.log.debug("Got last known dimensions for "
538 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
541 // return dimensions for new instance
542 return new Rectangle(ix, iy, iw, ih);
547 private void doVamsasClientCheck()
549 if (jalview.bin.Cache.vamsasJarsPresent())
551 setupVamsasDisconnectedGui();
552 VamsasMenu.setVisible(true);
553 final Desktop us = this;
554 VamsasMenu.addMenuListener(new MenuListener()
556 // this listener remembers when the menu was first selected, and
557 // doesn't rebuild the session list until it has been cleared and
559 boolean refresh = true;
561 public void menuCanceled(MenuEvent e)
566 public void menuDeselected(MenuEvent e)
571 public void menuSelected(MenuEvent e)
575 us.buildVamsasStMenu();
580 vamsasStart.setVisible(true);
584 void showPasteMenu(int x, int y)
586 JPopupMenu popup = new JPopupMenu();
587 JMenuItem item = new JMenuItem(
588 MessageManager.getString("label.paste_new_window"));
589 item.addActionListener(new ActionListener()
591 public void actionPerformed(ActionEvent evt)
598 popup.show(this, x, y);
605 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
606 Transferable contents = c.getContents(this);
608 if (contents != null)
610 String file = (String) contents
611 .getTransferData(DataFlavor.stringFlavor);
613 String format = new IdentifyFile().Identify(file,
614 FormatAdapter.PASTE);
616 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
619 } catch (Exception ex)
622 .println("Unable to paste alignment from system clipboard:\n"
628 * Adds and opens the given frame to the desktop
639 public static synchronized void addInternalFrame(
640 final JInternalFrame frame, String title, int w, int h)
642 addInternalFrame(frame, title, w, h, true);
659 public static synchronized void addInternalFrame(
660 final JInternalFrame frame, String title, int w, int h,
664 // TODO: allow callers to determine X and Y position of frame (eg. via
666 // TODO: consider fixing method to update entries in the window submenu with
667 // the current window title
669 frame.setTitle(title);
670 if (frame.getWidth() < 1 || frame.getHeight() < 1)
674 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
675 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
676 // IF JALVIEW IS RUNNING HEADLESS
677 // ///////////////////////////////////////////////
679 || (System.getProperty("java.awt.headless") != null && System
680 .getProperty("java.awt.headless").equals("true")))
687 frame.setVisible(true);
688 frame.setClosable(true);
689 frame.setResizable(resizable);
690 frame.setMaximizable(resizable);
691 frame.setIconifiable(resizable);
692 frame.setFrameIcon(null);
694 if (frame.getX() < 1 && frame.getY() < 1)
696 frame.setLocation(xOffset * openFrameCount, yOffset
697 * ((openFrameCount - 1) % 10) + yOffset);
700 final JMenuItem menuItem = new JMenuItem(title);
701 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
703 public void internalFrameActivated(
704 javax.swing.event.InternalFrameEvent evt)
706 JInternalFrame itf = desktop.getSelectedFrame();
714 public void internalFrameClosed(
715 javax.swing.event.InternalFrameEvent evt)
717 PaintRefresher.RemoveComponent(frame);
719 windowMenu.remove(menuItem);
720 JInternalFrame itf = desktop.getSelectedFrame();
729 menuItem.addActionListener(new ActionListener()
731 public void actionPerformed(ActionEvent e)
735 frame.setSelected(true);
736 frame.setIcon(false);
737 } catch (java.beans.PropertyVetoException ex)
743 menuItem.addMouseListener(new MouseListener()
747 public void mouseReleased(MouseEvent e)
752 public void mousePressed(MouseEvent e)
757 public void mouseExited(MouseEvent e)
761 frame.setSelected(false);
762 } catch (PropertyVetoException e1)
768 public void mouseEntered(MouseEvent e)
772 frame.setSelected(true);
773 } catch (PropertyVetoException e1)
779 public void mouseClicked(MouseEvent e)
785 windowMenu.add(menuItem);
791 frame.setSelected(true);
792 frame.requestFocus();
793 } catch (java.beans.PropertyVetoException ve)
795 } catch (java.lang.ClassCastException cex)
798 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
803 public void lostOwnership(Clipboard clipboard, Transferable contents)
807 Desktop.jalviewClipboard = null;
810 internalCopy = false;
813 public void dragEnter(DropTargetDragEvent evt)
817 public void dragExit(DropTargetEvent evt)
821 public void dragOver(DropTargetDragEvent evt)
825 public void dropActionChanged(DropTargetDragEvent evt)
835 public void drop(DropTargetDropEvent evt)
837 boolean success = true;
838 Transferable t = evt.getTransferable();
839 java.util.List files = null;
840 java.util.List protocols = null;
844 DataFlavor uriListFlavor = new DataFlavor(
845 "text/uri-list;class=java.lang.String");
846 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
848 // Works on Windows and MacOSX
849 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
850 files = (java.util.List) t
851 .getTransferData(DataFlavor.javaFileListFlavor);
853 else if (t.isDataFlavorSupported(uriListFlavor))
855 // This is used by Unix drag system
856 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
857 String data = (String) t.getTransferData(uriListFlavor);
858 files = new java.util.ArrayList(1);
859 protocols = new java.util.ArrayList(1);
860 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
861 data, "\r\n"); st.hasMoreTokens();)
863 String s = st.nextToken();
864 if (s.startsWith("#"))
866 // the line is a comment (as per the RFC 2483)
869 java.net.URI uri = new java.net.URI(s);
870 if (uri.getScheme().toLowerCase().startsWith("http"))
872 protocols.add(FormatAdapter.URL);
873 files.add(uri.toString());
877 // otherwise preserve old behaviour: catch all for file objects
878 java.io.File file = new java.io.File(uri);
879 protocols.add(FormatAdapter.FILE);
880 files.add(file.toString());
884 } catch (Exception e)
893 for (int i = 0; i < files.size(); i++)
895 String file = files.get(i).toString();
896 String protocol = (protocols == null) ? FormatAdapter.FILE
897 : (String) protocols.get(i);
898 String format = null;
900 if (file.endsWith(".jar"))
907 format = new IdentifyFile().Identify(file, protocol);
910 new FileLoader().LoadFile(file, protocol, format);
913 } catch (Exception ex)
918 evt.dropComplete(success); // need this to ensure input focus is properly
919 // transfered to any new windows created
928 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
930 JalviewFileChooser chooser = new JalviewFileChooser(
931 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
932 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
933 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
934 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
936 chooser.setFileView(new JalviewFileView());
937 chooser.setDialogTitle(MessageManager
938 .getString("label.open_local_file"));
939 chooser.setToolTipText(MessageManager.getString("action.open"));
941 int value = chooser.showOpenDialog(this);
943 if (value == JalviewFileChooser.APPROVE_OPTION)
945 String choice = chooser.getSelectedFile().getPath();
946 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
947 .getSelectedFile().getParent());
949 String format = null;
950 if (chooser.getSelectedFormat() != null
951 && chooser.getSelectedFormat().equals("Jalview"))
957 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
960 if (viewport != null)
962 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
967 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
978 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
980 // This construct allows us to have a wider textfield
982 JLabel label = new JLabel(
983 MessageManager.getString("label.input_file_url"));
984 final JComboBox history = new JComboBox();
986 JPanel panel = new JPanel(new GridLayout(2, 1));
989 history.setPreferredSize(new Dimension(400, 20));
990 history.setEditable(true);
991 history.addItem("http://www.");
993 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
997 if (historyItems != null)
999 st = new StringTokenizer(historyItems, "\t");
1001 while (st.hasMoreTokens())
1003 history.addItem(st.nextElement());
1007 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1008 MessageManager.getString("label.input_alignment_from_url"),
1009 JOptionPane.OK_CANCEL_OPTION);
1011 if (reply != JOptionPane.OK_OPTION)
1016 String url = history.getSelectedItem().toString();
1018 if (url.toLowerCase().endsWith(".jar"))
1020 if (viewport != null)
1022 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1027 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1032 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1034 if (format.equals("URL NOT FOUND"))
1036 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1037 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1038 JOptionPane.WARNING_MESSAGE);
1043 if (viewport != null)
1045 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1049 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1060 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1062 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1063 cap.setForInput(viewport);
1064 Desktop.addInternalFrame(cap, MessageManager.getString("label.cut_paste_alignmen_file"), 600, 500);
1072 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1074 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1075 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1077 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1078 getBounds().y, getWidth(), getHeight()));
1080 if (jconsole != null)
1082 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1083 jconsole.stopConsole();
1087 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1090 if (dialogExecutor != null)
1092 dialogExecutor.shutdownNow();
1098 private void storeLastKnownDimensions(String string, Rectangle jc)
1100 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1101 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1102 + " height:" + jc.height);
1104 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1105 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1106 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1107 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1116 public void aboutMenuItem_actionPerformed(ActionEvent e)
1118 // StringBuffer message = getAboutMessage(false);
1119 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1121 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1122 new Thread(new Runnable()
1126 new SplashScreen(true);
1131 public StringBuffer getAboutMessage(boolean shortv)
1133 StringBuffer message = new StringBuffer();
1134 message.append("<html>");
1137 message.append("<h1><strong>Version: "
1138 + jalview.bin.Cache.getProperty("VERSION")
1139 + "</strong></h1>");
1140 message.append("<strong>Last Updated: <em>"
1141 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1142 + "</em></strong>");
1148 message.append("<strong>Version "
1149 + jalview.bin.Cache.getProperty("VERSION")
1150 + "; last updated: "
1151 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1154 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1157 message.append("<br>...Checking latest version...</br>");
1159 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1160 .equals(jalview.bin.Cache.getProperty("VERSION")))
1162 boolean red = false;
1163 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1164 .indexOf("automated build") == -1)
1167 // Displayed when code version and jnlp version do not match and code
1168 // version is not a development build
1169 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1172 message.append("<br>!! Version "
1173 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1175 + " is available for download from "
1176 + jalview.bin.Cache.getDefault("www.jalview.org",
1177 "http://www.jalview.org") + " !!");
1180 message.append("</div>");
1183 message.append("<br>Authors: "
1187 "The Jalview Authors (See AUTHORS file for current list)")
1188 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1189 + "<br><br>For help, see the FAQ at <a href=\"http://www.jalview.org/faq\">www.jalview.org/faq</a> and/or join the jalview-discuss@jalview.org mailing list"
1190 + "<br><br>If you use Jalview, please cite:"
1191 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1192 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1193 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1204 public void documentationMenuItem_actionPerformed(ActionEvent e)
1208 Help.showHelpWindow();
1209 } catch (Exception ex)
1214 public void closeAll_actionPerformed(ActionEvent e)
1216 JInternalFrame[] frames = desktop.getAllFrames();
1217 for (int i = 0; i < frames.length; i++)
1221 frames[i].setClosed(true);
1222 } catch (java.beans.PropertyVetoException ex)
1226 System.out.println("ALL CLOSED");
1227 if (v_client != null)
1229 // TODO clear binding to vamsas document objects on close_all
1234 public void raiseRelated_actionPerformed(ActionEvent e)
1236 reorderAssociatedWindows(false, false);
1239 public void minimizeAssociated_actionPerformed(ActionEvent e)
1241 reorderAssociatedWindows(true, false);
1244 void closeAssociatedWindows()
1246 reorderAssociatedWindows(false, true);
1252 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1255 protected void garbageCollect_actionPerformed(ActionEvent e)
1257 // We simply collect the garbage
1258 jalview.bin.Cache.log.debug("Collecting garbage...");
1260 jalview.bin.Cache.log.debug("Finished garbage collection.");
1267 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1270 protected void showMemusage_actionPerformed(ActionEvent e)
1272 desktop.showMemoryUsage(showMemusage.isSelected());
1279 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1282 protected void showConsole_actionPerformed(ActionEvent e)
1284 showConsole(showConsole.isSelected());
1287 Console jconsole = null;
1290 * control whether the java console is visible or not
1294 void showConsole(boolean selected)
1296 showConsole.setSelected(selected);
1297 // TODO: decide if we should update properties file
1298 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1300 jconsole.setVisible(selected);
1303 void reorderAssociatedWindows(boolean minimize, boolean close)
1305 JInternalFrame[] frames = desktop.getAllFrames();
1306 if (frames == null || frames.length < 1)
1311 AlignViewport source = null, target = null;
1312 if (frames[0] instanceof AlignFrame)
1314 source = ((AlignFrame) frames[0]).getCurrentView();
1316 else if (frames[0] instanceof TreePanel)
1318 source = ((TreePanel) frames[0]).getViewPort();
1320 else if (frames[0] instanceof PCAPanel)
1322 source = ((PCAPanel) frames[0]).av;
1324 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1326 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1331 for (int i = 0; i < frames.length; i++)
1334 if (frames[i] == null)
1338 if (frames[i] instanceof AlignFrame)
1340 target = ((AlignFrame) frames[i]).getCurrentView();
1342 else if (frames[i] instanceof TreePanel)
1344 target = ((TreePanel) frames[i]).getViewPort();
1346 else if (frames[i] instanceof PCAPanel)
1348 target = ((PCAPanel) frames[i]).av;
1350 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1352 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1355 if (source == target)
1361 frames[i].setClosed(true);
1365 frames[i].setIcon(minimize);
1368 frames[i].toFront();
1372 } catch (java.beans.PropertyVetoException ex)
1386 protected void preferences_actionPerformed(ActionEvent e)
1397 public void saveState_actionPerformed(ActionEvent e)
1399 JalviewFileChooser chooser = new JalviewFileChooser(
1400 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1401 { "jvp" }, new String[]
1402 { "Jalview Project" }, "Jalview Project");
1404 chooser.setFileView(new JalviewFileView());
1405 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1407 int value = chooser.showSaveDialog(this);
1409 if (value == JalviewFileChooser.APPROVE_OPTION)
1411 final Desktop me = this;
1412 final java.io.File choice = chooser.getSelectedFile();
1413 new Thread(new Runnable()
1418 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1420 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1421 choice.getParent());
1422 // TODO catch and handle errors for savestate
1423 // TODO prevent user from messing with the Desktop whilst we're saving
1426 new Jalview2XML().SaveState(choice);
1427 } catch (OutOfMemoryError oom)
1429 new OOMWarning("Whilst saving current state to "
1430 + choice.getName(), oom);
1431 } catch (Exception ex)
1434 "Problems whilst trying to save to " + choice.getName(),
1436 JOptionPane.showMessageDialog(
1438 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1439 MessageManager.getString("label.couldnt_save_project"),
1440 JOptionPane.WARNING_MESSAGE);
1442 setProgressBar(null, choice.hashCode());
1454 public void loadState_actionPerformed(ActionEvent e)
1456 JalviewFileChooser chooser = new JalviewFileChooser(
1457 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1458 { "jvp", "jar" }, new String[]
1459 { "Jalview Project", "Jalview Project (old)" },
1461 chooser.setFileView(new JalviewFileView());
1462 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1464 int value = chooser.showOpenDialog(this);
1466 if (value == JalviewFileChooser.APPROVE_OPTION)
1468 final String choice = chooser.getSelectedFile().getAbsolutePath();
1469 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1470 .getSelectedFile().getParent());
1471 new Thread(new Runnable()
1475 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1479 new Jalview2XML().LoadJalviewAlign(choice);
1480 } catch (OutOfMemoryError oom)
1482 new OOMWarning("Whilst loading project from " + choice, oom);
1483 } catch (Exception ex)
1485 Cache.log.error("Problems whilst loading project from "
1487 JOptionPane.showMessageDialog(Desktop.desktop,
1488 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1489 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1491 setProgressBar(null, choice.hashCode());
1497 public void inputSequence_actionPerformed(ActionEvent e)
1499 new SequenceFetcher(this);
1502 JPanel progressPanel;
1504 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1506 public void startLoading(final String fileName)
1508 if (fileLoadingCount == 0)
1510 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1515 private JPanel addProgressPanel(String string)
1517 if (progressPanel == null)
1519 progressPanel = new JPanel(new GridLayout(1, 1));
1520 totalProgressCount = 0;
1521 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1523 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1524 JProgressBar progressBar = new JProgressBar();
1525 progressBar.setIndeterminate(true);
1527 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1529 thisprogress.add(progressBar, BorderLayout.CENTER);
1530 progressPanel.add(thisprogress);
1531 ((GridLayout) progressPanel.getLayout())
1532 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1533 ++totalProgressCount;
1534 instance.validate();
1535 return thisprogress;
1538 int totalProgressCount = 0;
1540 private void removeProgressPanel(JPanel progbar)
1542 if (progressPanel != null)
1544 synchronized (progressPanel)
1546 progressPanel.remove(progbar);
1547 GridLayout gl = (GridLayout) progressPanel.getLayout();
1548 gl.setRows(gl.getRows() - 1);
1549 if (--totalProgressCount < 1)
1551 this.getContentPane().remove(progressPanel);
1552 progressPanel = null;
1559 public void stopLoading()
1562 if (fileLoadingCount < 1)
1564 while (fileLoadingPanels.size() > 0)
1566 removeProgressPanel(fileLoadingPanels.remove(0));
1568 fileLoadingPanels.clear();
1569 fileLoadingCount = 0;
1574 public static int getViewCount(String alignmentId)
1576 AlignViewport[] aps = getViewports(alignmentId);
1577 return (aps == null) ? 0 : aps.length;
1582 * @param alignmentId
1583 * @return all AlignmentPanels concerning the alignmentId sequence set
1585 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1588 if (Desktop.desktop == null)
1590 // no frames created and in headless mode
1591 // TODO: verify that frames are recoverable when in headless mode
1594 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1595 ArrayList aps = new ArrayList();
1596 for (int t = 0; t < frames.length; t++)
1598 if (frames[t] instanceof AlignFrame)
1600 AlignFrame af = (AlignFrame) frames[t];
1601 for (int a = 0; a < af.alignPanels.size(); a++)
1603 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1604 .elementAt(a)).av.getSequenceSetId()))
1606 aps.add(af.alignPanels.elementAt(a));
1611 if (aps.size() == 0)
1615 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1616 for (int t = 0; t < vap.length; t++)
1618 vap[t] = (AlignmentPanel) aps.get(t);
1624 * get all the viewports on an alignment.
1626 * @param sequenceSetId
1627 * unique alignment id
1628 * @return all viewports on the alignment bound to sequenceSetId
1630 public static AlignViewport[] getViewports(String sequenceSetId)
1632 Vector viewp = new Vector();
1633 if (desktop != null)
1635 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1637 for (int t = 0; t < frames.length; t++)
1639 if (frames[t] instanceof AlignFrame)
1641 AlignFrame afr = ((AlignFrame) frames[t]);
1642 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1644 if (afr.alignPanels != null)
1646 for (int a = 0; a < afr.alignPanels.size(); a++)
1648 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1649 .elementAt(a)).av.getSequenceSetId()))
1651 viewp.addElement(((AlignmentPanel) afr.alignPanels
1658 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1663 if (viewp.size() > 0)
1665 AlignViewport[] vp = new AlignViewport[viewp.size()];
1673 public void explodeViews(AlignFrame af)
1675 int size = af.alignPanels.size();
1681 for (int i = 0; i < size; i++)
1683 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1684 AlignFrame newaf = new AlignFrame(ap);
1685 if (ap.av.explodedPosition != null
1686 && !ap.av.explodedPosition.equals(af.getBounds()))
1688 newaf.setBounds(ap.av.explodedPosition);
1691 ap.av.gatherViewsHere = false;
1693 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1694 AlignFrame.DEFAULT_HEIGHT);
1697 af.alignPanels.clear();
1698 af.closeMenuItem_actionPerformed(true);
1702 public void gatherViews(AlignFrame source)
1704 source.viewport.gatherViewsHere = true;
1705 source.viewport.explodedPosition = source.getBounds();
1706 JInternalFrame[] frames = desktop.getAllFrames();
1707 String viewId = source.viewport.getSequenceSetId();
1709 for (int t = 0; t < frames.length; t++)
1711 if (frames[t] instanceof AlignFrame && frames[t] != source)
1713 AlignFrame af = (AlignFrame) frames[t];
1714 boolean gatherThis = false;
1715 for (int a = 0; a < af.alignPanels.size(); a++)
1717 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1718 if (viewId.equals(ap.av.getSequenceSetId()))
1721 ap.av.gatherViewsHere = false;
1722 ap.av.explodedPosition = af.getBounds();
1723 source.addAlignmentPanel(ap, false);
1729 af.alignPanels.clear();
1730 af.closeMenuItem_actionPerformed(true);
1737 jalview.gui.VamsasApplication v_client = null;
1739 public void vamsasImport_actionPerformed(ActionEvent e)
1741 if (v_client == null)
1743 // Load and try to start a session.
1744 JalviewFileChooser chooser = new JalviewFileChooser(
1745 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1747 chooser.setFileView(new JalviewFileView());
1748 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1749 chooser.setToolTipText(MessageManager
1750 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1752 int value = chooser.showOpenDialog(this);
1754 if (value == JalviewFileChooser.APPROVE_OPTION)
1756 String fle = chooser.getSelectedFile().toString();
1757 if (!vamsasImport(chooser.getSelectedFile()))
1760 .showInternalMessageDialog(
1762 MessageManager.formatMessage(
1763 "label.couldnt_import_as_vamsas_session",
1767 .getString("label.vamsas_document_import_failed"),
1768 JOptionPane.ERROR_MESSAGE);
1774 jalview.bin.Cache.log
1775 .error("Implementation error - load session from a running session is not supported.");
1780 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1783 * @return true if import was a success and a session was started.
1785 public boolean vamsasImport(URL url)
1787 // TODO: create progress bar
1788 if (v_client != null)
1791 jalview.bin.Cache.log
1792 .error("Implementation error - load session from a running session is not supported.");
1798 // copy the URL content to a temporary local file
1799 // TODO: be a bit cleverer here with nio (?!)
1800 File file = File.createTempFile("vdocfromurl", ".vdj");
1801 FileOutputStream fos = new FileOutputStream(file);
1802 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1803 byte[] buffer = new byte[2048];
1805 while ((ln = bis.read(buffer)) > -1)
1807 fos.write(buffer, 0, ln);
1811 v_client = new jalview.gui.VamsasApplication(this, file,
1812 url.toExternalForm());
1813 } catch (Exception ex)
1815 jalview.bin.Cache.log.error(
1816 "Failed to create new vamsas session from contents of URL "
1820 setupVamsasConnectedGui();
1821 v_client.initial_update(); // TODO: thread ?
1822 return v_client.inSession();
1826 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1829 * @return true if import was a success and a session was started.
1831 public boolean vamsasImport(File file)
1833 if (v_client != null)
1836 jalview.bin.Cache.log
1837 .error("Implementation error - load session from a running session is not supported.");
1841 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1845 v_client = new jalview.gui.VamsasApplication(this, file, null);
1846 } catch (Exception ex)
1848 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1850 jalview.bin.Cache.log.error(
1851 "New vamsas session from existing session file failed:", ex);
1854 setupVamsasConnectedGui();
1855 v_client.initial_update(); // TODO: thread ?
1856 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1858 return v_client.inSession();
1861 public boolean joinVamsasSession(String mysesid)
1863 if (v_client != null)
1865 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1867 if (mysesid == null)
1869 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1871 v_client = new VamsasApplication(this, mysesid);
1872 setupVamsasConnectedGui();
1873 v_client.initial_update();
1874 return (v_client.inSession());
1877 public void vamsasStart_actionPerformed(ActionEvent e)
1879 if (v_client == null)
1882 // we just start a default session for moment.
1884 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1885 * getProperty("LAST_DIRECTORY"));
1887 * chooser.setFileView(new JalviewFileView());
1888 * chooser.setDialogTitle("Load Vamsas file");
1889 * chooser.setToolTipText("Import");
1891 * int value = chooser.showOpenDialog(this);
1893 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1894 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1896 v_client = new VamsasApplication(this);
1897 setupVamsasConnectedGui();
1898 v_client.initial_update(); // TODO: thread ?
1902 // store current data in session.
1903 v_client.push_update(); // TODO: thread
1907 protected void setupVamsasConnectedGui()
1909 vamsasStart.setText(MessageManager.getString("label.session_update"));
1910 vamsasSave.setVisible(true);
1911 vamsasStop.setVisible(true);
1912 vamsasImport.setVisible(false); // Document import to existing session is
1913 // not possible for vamsas-client-1.0.
1916 protected void setupVamsasDisconnectedGui()
1918 vamsasSave.setVisible(false);
1919 vamsasStop.setVisible(false);
1920 vamsasImport.setVisible(true);
1921 vamsasStart.setText(MessageManager
1922 .getString("label.new_vamsas_session"));
1925 public void vamsasStop_actionPerformed(ActionEvent e)
1927 if (v_client != null)
1929 v_client.end_session();
1931 setupVamsasDisconnectedGui();
1935 protected void buildVamsasStMenu()
1937 if (v_client == null)
1939 String[] sess = null;
1942 sess = VamsasApplication.getSessionList();
1943 } catch (Exception e)
1945 jalview.bin.Cache.log.warn(
1946 "Problem getting current sessions list.", e);
1951 jalview.bin.Cache.log.debug("Got current sessions list: "
1952 + sess.length + " entries.");
1953 VamsasStMenu.removeAll();
1954 for (int i = 0; i < sess.length; i++)
1956 JMenuItem sessit = new JMenuItem();
1957 sessit.setText(sess[i]);
1958 sessit.setToolTipText(MessageManager.formatMessage(
1959 "label.connect_to_session", new String[]
1961 final Desktop dsktp = this;
1962 final String mysesid = sess[i];
1963 sessit.addActionListener(new ActionListener()
1966 public void actionPerformed(ActionEvent e)
1968 if (dsktp.v_client == null)
1970 Thread rthr = new Thread(new Runnable()
1975 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1976 dsktp.setupVamsasConnectedGui();
1977 dsktp.v_client.initial_update();
1985 VamsasStMenu.add(sessit);
1987 // don't show an empty menu.
1988 VamsasStMenu.setVisible(sess.length > 0);
1993 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1994 VamsasStMenu.removeAll();
1995 VamsasStMenu.setVisible(false);
2000 // Not interested in the content. Just hide ourselves.
2001 VamsasStMenu.setVisible(false);
2005 public void vamsasSave_actionPerformed(ActionEvent e)
2007 if (v_client != null)
2009 JalviewFileChooser chooser = new JalviewFileChooser(
2010 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2011 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2013 { "Vamsas Document" }, "Vamsas Document");
2015 chooser.setFileView(new JalviewFileView());
2016 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2018 int value = chooser.showSaveDialog(this);
2020 if (value == JalviewFileChooser.APPROVE_OPTION)
2022 java.io.File choice = chooser.getSelectedFile();
2023 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2024 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2025 String warnmsg = null;
2026 String warnttl = null;
2029 v_client.vclient.storeDocument(choice);
2032 warnttl = "Serious Problem saving Vamsas Document";
2033 warnmsg = ex.toString();
2034 jalview.bin.Cache.log.error("Error Whilst saving document to "
2037 } catch (Exception ex)
2039 warnttl = "Problem saving Vamsas Document.";
2040 warnmsg = ex.toString();
2041 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2045 removeProgressPanel(progpanel);
2046 if (warnmsg != null)
2048 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2050 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2056 JPanel vamUpdate = null;
2059 * hide vamsas user gui bits when a vamsas document event is being handled.
2062 * true to hide gui, false to reveal gui
2064 public void setVamsasUpdate(boolean b)
2066 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2067 + (b ? "in progress" : "finished"));
2069 if (vamUpdate != null)
2071 this.removeProgressPanel(vamUpdate);
2075 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2077 vamsasStart.setVisible(!b);
2078 vamsasStop.setVisible(!b);
2079 vamsasSave.setVisible(!b);
2082 public JInternalFrame[] getAllFrames()
2084 return desktop.getAllFrames();
2088 * Checks the given url to see if it gives a response indicating that the user
2089 * should be informed of a new questionnaire.
2093 public void checkForQuestionnaire(String url)
2095 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2096 // javax.swing.SwingUtilities.invokeLater(jvq);
2097 new Thread(jvq).start();
2101 * Proxy class for JDesktopPane which optionally displays the current memory
2102 * usage and highlights the desktop area with a red bar if free memory runs
2107 public class MyDesktopPane extends JDesktopPane implements Runnable
2110 boolean showMemoryUsage = false;
2114 java.text.NumberFormat df;
2116 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2119 public MyDesktopPane(boolean showMemoryUsage)
2121 showMemoryUsage(showMemoryUsage);
2124 public void showMemoryUsage(boolean showMemoryUsage)
2126 this.showMemoryUsage = showMemoryUsage;
2127 if (showMemoryUsage)
2129 Thread worker = new Thread(this);
2134 public boolean isShowMemoryUsage()
2136 return showMemoryUsage;
2141 df = java.text.NumberFormat.getNumberInstance();
2142 df.setMaximumFractionDigits(2);
2143 runtime = Runtime.getRuntime();
2145 while (showMemoryUsage)
2149 maxMemory = runtime.maxMemory() / 1048576f;
2150 allocatedMemory = runtime.totalMemory() / 1048576f;
2151 freeMemory = runtime.freeMemory() / 1048576f;
2152 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2154 percentUsage = (totalFreeMemory / maxMemory) * 100;
2156 // if (percentUsage < 20)
2158 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2160 // instance.set.setBorder(border1);
2163 // sleep after showing usage
2165 } catch (Exception ex)
2167 ex.printStackTrace();
2172 public void paintComponent(Graphics g)
2174 if (showMemoryUsage && g != null && df != null)
2176 if (percentUsage < 20)
2178 g.setColor(Color.red);
2180 FontMetrics fm = g.getFontMetrics();
2183 g.drawString(MessageManager.formatMessage(
2184 "label.memory_stats",
2186 { df.format(totalFreeMemory), df.format(maxMemory),
2187 df.format(percentUsage) }), 10,
2188 getHeight() - fm.getHeight());
2195 * fixes stacking order after a modal dialog to ensure windows that should be
2196 * on top actually are
2198 public void relayerWindows()
2203 protected JMenuItem groovyShell;
2205 public void doGroovyCheck()
2207 if (jalview.bin.Cache.groovyJarsPresent())
2209 groovyShell = new JMenuItem();
2210 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2211 groovyShell.addActionListener(new ActionListener()
2213 public void actionPerformed(ActionEvent e)
2215 groovyShell_actionPerformed(e);
2218 toolsMenu.add(groovyShell);
2219 groovyShell.setVisible(true);
2224 * Accessor method to quickly get all the AlignmentFrames loaded.
2226 public static AlignFrame[] getAlignframes()
2228 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2234 Vector avp = new Vector();
2238 for (int i = frames.length - 1; i > -1; i--)
2240 if (frames[i] instanceof AlignFrame)
2242 AlignFrame af = (AlignFrame) frames[i];
2246 } catch (Exception ex)
2248 ex.printStackTrace();
2250 if (avp.size() == 0)
2254 AlignFrame afs[] = new AlignFrame[avp.size()];
2255 for (int i = 0, j = avp.size(); i < j; i++)
2257 afs[i] = (AlignFrame) avp.elementAt(i);
2263 public AppJmol[] getJmols()
2265 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2271 Vector avp = new Vector();
2275 for (int i = frames.length - 1; i > -1; i--)
2277 if (frames[i] instanceof AppJmol)
2279 AppJmol af = (AppJmol) frames[i];
2283 } catch (Exception ex)
2285 ex.printStackTrace();
2287 if (avp.size() == 0)
2291 AppJmol afs[] = new AppJmol[avp.size()];
2292 for (int i = 0, j = avp.size(); i < j; i++)
2294 afs[i] = (AppJmol) avp.elementAt(i);
2301 * Add Groovy Support to Jalview
2303 public void groovyShell_actionPerformed(ActionEvent e)
2305 // use reflection to avoid creating compilation dependency.
2306 if (!jalview.bin.Cache.groovyJarsPresent())
2308 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2312 Class gcClass = Desktop.class.getClassLoader().loadClass(
2313 "groovy.ui.Console");
2314 Constructor gccons = gcClass.getConstructor(null);
2315 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2317 { String.class, Object.class });
2318 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2319 Object gc = gccons.newInstance(null);
2320 setvar.invoke(gc, new Object[]
2321 { "Jalview", this });
2322 run.invoke(gc, null);
2323 } catch (Exception ex)
2325 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2327 .showInternalMessageDialog(
2330 MessageManager.getString("label.couldnt_create_groovy_shell"),
2331 MessageManager.getString("label.groovy_support_failed"),
2332 JOptionPane.ERROR_MESSAGE);
2337 * Progress bars managed by the IProgressIndicator method.
2339 private Hashtable<Long, JPanel> progressBars;
2341 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2346 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2348 public void setProgressBar(String message, long id)
2350 if (progressBars == null)
2352 progressBars = new Hashtable<Long, JPanel>();
2353 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2356 if (progressBars.get(new Long(id)) != null)
2358 JPanel progressPanel = progressBars.remove(new Long(id));
2359 if (progressBarHandlers.contains(new Long(id)))
2361 progressBarHandlers.remove(new Long(id));
2363 removeProgressPanel(progressPanel);
2367 progressBars.put(new Long(id), addProgressPanel(message));
2374 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2375 * jalview.gui.IProgressIndicatorHandler)
2377 public void registerHandler(final long id,
2378 final IProgressIndicatorHandler handler)
2380 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2382 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2384 progressBarHandlers.put(new Long(id), handler);
2385 final JPanel progressPanel = progressBars.get(new Long(id));
2386 if (handler.canCancel())
2388 JButton cancel = new JButton(
2389 MessageManager.getString("action.cancel"));
2390 final IProgressIndicator us = this;
2391 cancel.addActionListener(new ActionListener()
2394 public void actionPerformed(ActionEvent e)
2396 handler.cancelActivity(id);
2397 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2400 progressPanel.add(cancel, BorderLayout.EAST);
2406 * @return true if any progress bars are still active
2409 public boolean operationInProgress()
2411 if (progressBars != null && progressBars.size() > 0)
2419 * This will return the first AlignFrame viewing AlignViewport av. It will
2420 * break if there are more than one AlignFrames viewing a particular av. This
2423 * @return alignFrame for av
2425 public static AlignFrame getAlignFrameFor(AlignViewport av)
2427 if (desktop != null)
2429 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2430 for (int panel = 0; aps != null && panel < aps.length; panel++)
2432 if (aps[panel] != null && aps[panel].av == av)
2434 return aps[panel].alignFrame;
2441 public VamsasApplication getVamsasApplication()
2448 * flag set if jalview GUI is being operated programmatically
2450 private boolean inBatchMode = false;
2453 * check if jalview GUI is being operated programmatically
2455 * @return inBatchMode
2457 public boolean isInBatchMode()
2463 * set flag if jalview GUI is being operated programmatically
2465 * @param inBatchMode
2467 public void setInBatchMode(boolean inBatchMode)
2469 this.inBatchMode = inBatchMode;
2472 public void startServiceDiscovery()
2474 startServiceDiscovery(false);
2477 public void startServiceDiscovery(boolean blocking)
2479 boolean alive = true;
2480 Thread t0 = null, t1 = null, t2 = null;
2481 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2484 // todo: changesupport handlers need to be transferred
2485 if (discoverer == null)
2487 discoverer = new jalview.ws.jws1.Discoverer();
2488 // register PCS handler for desktop.
2489 discoverer.addPropertyChangeListener(changeSupport);
2491 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2492 // until we phase out completely
2493 (t0 = new Thread(discoverer)).start();
2496 // ENFIN services are EOLed as of Jalview 2.8.1 release
2501 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2503 // EnfinEnvision web service menu entries are rebuild every time the
2504 // menu is shown, so no changeSupport events are needed.
2505 jalview.ws.EnfinEnvision2OneWay.getInstance();
2506 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2509 } catch (Exception e)
2512 .info("Exception when trying to launch Envision2 workflow discovery.",
2514 Cache.log.info(e.getStackTrace());
2518 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2520 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2522 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2524 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2530 // TODO: do rest service discovery
2539 } catch (Exception e)
2542 alive = (t1 != null && t1.isAlive())
2543 || (t2 != null && t2.isAlive())
2544 || (t3 != null && t3.isAlive())
2545 || (t0 != null && t0.isAlive());
2551 * called to check if the service discovery process completed successfully.
2555 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2557 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2559 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2560 .getErrorMessages();
2563 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2565 if (serviceChangedDialog == null)
2567 // only run if we aren't already displaying one of these.
2568 addDialogThread(serviceChangedDialog = new Runnable()
2574 * JalviewDialog jd =new JalviewDialog() {
2576 * @Override protected void cancelPressed() { // TODO
2577 * Auto-generated method stub
2579 * }@Override protected void okPressed() { // TODO
2580 * Auto-generated method stub
2582 * }@Override protected void raiseClosed() { // TODO
2583 * Auto-generated method stub
2585 * } }; jd.initDialogFrame(new
2586 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2587 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2588 * + " or mis-configured HTTP proxy settings.<br/>" +
2589 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2591 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2592 * ), true, true, "Web Service Configuration Problem", 450,
2595 * jd.waitForInput();
2601 "<html><table width=\"450\"><tr><td>"
2603 + "</td></tr></table>"
2604 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2605 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2606 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2607 + " Tools->Preferences dialog box to change them.</p></html>"),
2608 "Web Service Configuration Problem",
2609 JOptionPane.DEFAULT_OPTION,
2610 JOptionPane.ERROR_MESSAGE);
2611 serviceChangedDialog = null;
2620 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2627 private Runnable serviceChangedDialog = null;
2630 * start a thread to open a URL in the configured browser. Pops up a warning
2631 * dialog to the user if there is an exception when calling out to the browser
2636 public static void showUrl(final String url)
2638 showUrl(url, Desktop.instance);
2642 * Like showUrl but allows progress handler to be specified
2646 * (null) or object implementing IProgressIndicator
2648 public static void showUrl(final String url,
2649 final IProgressIndicator progress)
2651 new Thread(new Runnable()
2657 if (progress != null)
2659 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2661 jalview.util.BrowserLauncher.openURL(url);
2662 } catch (Exception ex)
2665 .showInternalMessageDialog(
2667 MessageManager.getString("label.web_browser_not_found_unix"),
2668 MessageManager.getString("label.web_browser_not_found"),
2669 JOptionPane.WARNING_MESSAGE);
2671 ex.printStackTrace();
2673 if (progress != null)
2675 progress.setProgressBar(null, this.hashCode());
2681 public static WsParamSetManager wsparamManager = null;
2683 public static ParamManager getUserParameterStore()
2685 if (wsparamManager == null)
2687 wsparamManager = new WsParamSetManager();
2689 return wsparamManager;
2693 * static hyperlink handler proxy method for use by Jalview's internal windows
2697 public static void hyperlinkUpdate(HyperlinkEvent e)
2699 if (e.getEventType() == EventType.ACTIVATED)
2704 url = e.getURL().toString();
2705 Desktop.showUrl(url);
2706 } catch (Exception x)
2710 if (Cache.log != null)
2712 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2716 System.err.println("Couldn't handle string " + url
2720 // ignore any exceptions due to dud links.
2727 * single thread that handles display of dialogs to user.
2729 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2732 * flag indicating if dialogExecutor should try to acquire a permit
2734 private volatile boolean dialogPause = true;
2739 private java.util.concurrent.Semaphore block = new Semaphore(0);
2742 * add another dialog thread to the queue
2746 public void addDialogThread(final Runnable prompter)
2748 dialogExecutor.submit(new Runnable()
2757 } catch (InterruptedException x)
2762 if (instance == null)
2768 SwingUtilities.invokeAndWait(prompter);
2769 } catch (Exception q)
2771 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2777 public void startDialogQueue()
2779 // set the flag so we don't pause waiting for another permit and semaphore
2780 // the current task to begin
2781 dialogPause = false;
2785 protected void snapShotWindow_actionPerformed(ActionEvent e)
2789 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2790 "View of Desktop", getWidth(), getHeight(), of = new File(
2791 "Jalview_snapshot" + System.currentTimeMillis()
2792 + ".eps"), "View of desktop");
2794 paintAll(im.getGraphics());
2796 } catch (Exception q)
2798 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2801 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());