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.datamodel.AlignmentI;
25 import jalview.io.FileLoader;
26 import jalview.io.FormatAdapter;
27 import jalview.io.IdentifyFile;
28 import jalview.io.JalviewFileChooser;
29 import jalview.io.JalviewFileView;
30 import jalview.structure.StructureSelectionManager;
31 import jalview.util.ImageMaker;
32 import jalview.util.MessageManager;
33 import jalview.ws.params.ParamManager;
35 import java.awt.BorderLayout;
36 import java.awt.Color;
37 import java.awt.Dimension;
38 import java.awt.FontMetrics;
39 import java.awt.Graphics;
40 import java.awt.GridLayout;
41 import java.awt.Point;
42 import java.awt.Rectangle;
43 import java.awt.Toolkit;
44 import java.awt.datatransfer.Clipboard;
45 import java.awt.datatransfer.ClipboardOwner;
46 import java.awt.datatransfer.DataFlavor;
47 import java.awt.datatransfer.Transferable;
48 import java.awt.dnd.DnDConstants;
49 import java.awt.dnd.DropTargetDragEvent;
50 import java.awt.dnd.DropTargetDropEvent;
51 import java.awt.dnd.DropTargetEvent;
52 import java.awt.dnd.DropTargetListener;
53 import java.awt.event.ActionEvent;
54 import java.awt.event.ActionListener;
55 import java.awt.event.FocusEvent;
56 import java.awt.event.FocusListener;
57 import java.awt.event.MouseAdapter;
58 import java.awt.event.MouseEvent;
59 import java.awt.event.MouseListener;
60 import java.awt.event.WindowAdapter;
61 import java.awt.event.WindowEvent;
62 import java.beans.PropertyChangeEvent;
63 import java.beans.PropertyChangeListener;
64 import java.beans.PropertyVetoException;
65 import java.io.BufferedInputStream;
67 import java.io.FileOutputStream;
68 import java.lang.reflect.Constructor;
70 import java.util.ArrayList;
71 import java.util.Hashtable;
72 import java.util.List;
73 import java.util.StringTokenizer;
74 import java.util.Vector;
75 import java.util.concurrent.ExecutorService;
76 import java.util.concurrent.Executors;
77 import java.util.concurrent.Semaphore;
79 import javax.swing.DefaultDesktopManager;
80 import javax.swing.DesktopManager;
81 import javax.swing.JButton;
82 import javax.swing.JComboBox;
83 import javax.swing.JComponent;
84 import javax.swing.JDesktopPane;
85 import javax.swing.JFrame;
86 import javax.swing.JInternalFrame;
87 import javax.swing.JLabel;
88 import javax.swing.JMenuItem;
89 import javax.swing.JOptionPane;
90 import javax.swing.JPanel;
91 import javax.swing.JPopupMenu;
92 import javax.swing.JProgressBar;
93 import javax.swing.SwingUtilities;
94 import javax.swing.event.HyperlinkEvent;
95 import javax.swing.event.HyperlinkEvent.EventType;
96 import javax.swing.event.MenuEvent;
97 import javax.swing.event.MenuListener;
104 * @version $Revision: 1.155 $
106 public class Desktop extends jalview.jbgui.GDesktop implements
107 DropTargetListener, ClipboardOwner, IProgressIndicator,
108 jalview.api.StructureSelectionManagerProvider
111 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
114 * news reader - null if it was never started.
116 private BlogReader jvnews = null;
120 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
122 public void addJalviewPropertyChangeListener(
123 PropertyChangeListener listener)
125 changeSupport.addJalviewPropertyChangeListener(listener);
129 * @param propertyName
131 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
132 * java.beans.PropertyChangeListener)
134 public void addJalviewPropertyChangeListener(String propertyName,
135 PropertyChangeListener listener)
137 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
141 * @param propertyName
143 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
144 * java.beans.PropertyChangeListener)
146 public void removeJalviewPropertyChangeListener(String propertyName,
147 PropertyChangeListener listener)
149 changeSupport.removeJalviewPropertyChangeListener(propertyName,
153 /** Singleton Desktop instance */
154 public static Desktop instance;
156 public static MyDesktopPane desktop;
158 static int openFrameCount = 0;
160 static final int xOffset = 30;
162 static final int yOffset = 30;
164 private static final int THREE = 3;
166 public static jalview.ws.jws1.Discoverer discoverer;
168 public static Object[] jalviewClipboard;
170 public static boolean internalCopy = false;
172 static int fileLoadingCount = 0;
174 class MyDesktopManager implements DesktopManager
177 private DesktopManager delegate;
179 public MyDesktopManager(DesktopManager delegate)
181 this.delegate = delegate;
184 public void activateFrame(JInternalFrame f)
188 delegate.activateFrame(f);
189 } catch (NullPointerException npe)
191 Point p = getMousePosition();
192 instance.showPasteMenu(p.x, p.y);
196 public void beginDraggingFrame(JComponent f)
198 delegate.beginDraggingFrame(f);
201 public void beginResizingFrame(JComponent f, int direction)
203 delegate.beginResizingFrame(f, direction);
206 public void closeFrame(JInternalFrame f)
208 delegate.closeFrame(f);
211 public void deactivateFrame(JInternalFrame f)
213 delegate.deactivateFrame(f);
216 public void deiconifyFrame(JInternalFrame f)
218 delegate.deiconifyFrame(f);
221 public void dragFrame(JComponent f, int newX, int newY)
227 delegate.dragFrame(f, newX, newY);
230 public void endDraggingFrame(JComponent f)
232 delegate.endDraggingFrame(f);
235 public void endResizingFrame(JComponent f)
237 delegate.endResizingFrame(f);
240 public void iconifyFrame(JInternalFrame f)
242 delegate.iconifyFrame(f);
245 public void maximizeFrame(JInternalFrame f)
247 delegate.maximizeFrame(f);
250 public void minimizeFrame(JInternalFrame f)
252 delegate.minimizeFrame(f);
255 public void openFrame(JInternalFrame f)
257 delegate.openFrame(f);
260 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
263 Rectangle b = desktop.getBounds();
268 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
271 public void setBoundsForFrame(JComponent f, int newX, int newY,
272 int newWidth, int newHeight)
274 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
277 // All other methods, simply delegate
282 * Creates a new Desktop object.
287 * A note to implementors. It is ESSENTIAL that any activities that might
288 * block are spawned off as threads rather than waited for during this
292 doVamsasClientCheck();
294 doConfigureStructurePrefs();
295 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
296 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
297 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
299 boolean showjconsole = jalview.bin.Cache.getDefault(
300 "SHOW_JAVA_CONSOLE", false);
301 desktop = new MyDesktopPane(selmemusage);
302 showMemusage.setSelected(selmemusage);
303 desktop.setBackground(Color.white);
304 getContentPane().setLayout(new BorderLayout());
305 // alternate config - have scrollbars - see notes in JAL-153
306 // JScrollPane sp = new JScrollPane();
307 // sp.getViewport().setView(desktop);
308 // getContentPane().add(sp, BorderLayout.CENTER);
309 getContentPane().add(desktop, BorderLayout.CENTER);
310 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
312 // This line prevents Windows Look&Feel resizing all new windows to maximum
313 // if previous window was maximised
314 desktop.setDesktopManager(new MyDesktopManager(
315 new DefaultDesktopManager()));
317 Rectangle dims = getLastKnownDimensions("");
324 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
325 setBounds((screenSize.width - 900) / 2,
326 (screenSize.height - 650) / 2, 900, 650);
328 jconsole = new Console(this, showjconsole);
329 // add essential build information
330 jconsole.setHeader("Jalview Version: "
331 + jalview.bin.Cache.getProperty("VERSION") + "\n"
332 + "Jalview Installation: "
333 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
336 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
337 + "Java version: " + System.getProperty("java.version") + "\n"
338 + System.getProperty("os.arch") + " "
339 + System.getProperty("os.name") + " "
340 + System.getProperty("os.version"));
342 showConsole(showjconsole);
344 showNews.setVisible(false);
346 this.addWindowListener(new WindowAdapter()
348 public void windowClosing(WindowEvent evt)
355 this.addMouseListener(ma = new MouseAdapter()
357 public void mousePressed(MouseEvent evt)
359 if (SwingUtilities.isRightMouseButton(evt))
361 showPasteMenu(evt.getX(), evt.getY());
365 desktop.addMouseListener(ma);
367 this.addFocusListener(new FocusListener()
371 public void focusLost(FocusEvent e)
373 // TODO Auto-generated method stub
378 public void focusGained(FocusEvent e)
380 Cache.log.debug("Relaying windows after focus gain");
381 // make sure that we sort windows properly after we gain focus
382 instance.relayerWindows();
385 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
386 // Spawn a thread that shows the splashscreen
387 SwingUtilities.invokeLater(new Runnable()
396 // Thread off a new instance of the file chooser - this reduces the time it
397 // takes to open it later on.
398 new Thread(new Runnable()
402 Cache.log.debug("Filechooser init thread started.");
403 JalviewFileChooser chooser = new JalviewFileChooser(
404 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
405 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
406 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
407 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
408 Cache.log.debug("Filechooser init thread finished.");
411 // Add the service change listener
412 changeSupport.addJalviewPropertyChangeListener("services",
413 new PropertyChangeListener()
417 public void propertyChange(PropertyChangeEvent evt)
419 Cache.log.debug("Firing service changed event for "
420 + evt.getNewValue());
421 JalviewServicesChanged(evt);
427 public void doConfigureStructurePrefs()
429 // configure services
430 StructureSelectionManager ssm = StructureSelectionManager
431 .getStructureSelectionManager(this);
432 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
434 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
435 Preferences.ADD_TEMPFACT_ANN, true));
436 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
437 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
442 ssm.setAddTempFacAnnot(false);
443 ssm.setProcessSecondaryStructure(false);
444 ssm.setSecStructServices(false);
448 public void checkForNews()
450 final Desktop me = this;
451 // Thread off the news reader, in case there are connection problems.
452 addDialogThread(new Runnable()
457 Cache.log.debug("Starting news thread.");
459 jvnews = new BlogReader(me);
460 showNews.setVisible(true);
461 Cache.log.debug("Completed news thread.");
466 protected void showNews_actionPerformed(ActionEvent e)
468 showNews(showNews.isSelected());
471 void showNews(boolean visible)
474 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
475 showNews.setSelected(visible);
476 if (visible && !jvnews.isVisible())
478 new Thread(new Runnable()
483 long instance = System.currentTimeMillis();
484 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
485 jvnews.refreshNews();
486 Desktop.instance.setProgressBar(null, instance);
495 * recover the last known dimensions for a jalview window
498 * - empty string is desktop, all other windows have unique prefix
499 * @return null or last known dimensions scaled to current geometry (if last
500 * window geom was known)
502 Rectangle getLastKnownDimensions(String windowName)
504 // TODO: lock aspect ratio for scaling desktop Bug #0058199
505 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
506 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
507 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
508 String width = jalview.bin.Cache.getProperty(windowName
510 String height = jalview.bin.Cache.getProperty(windowName
512 if ((x != null) && (y != null) && (width != null) && (height != null))
514 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
515 .parseInt(width), ih = Integer.parseInt(height);
516 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
518 // attempt #1 - try to cope with change in screen geometry - this
519 // version doesn't preserve original jv aspect ratio.
520 // take ratio of current screen size vs original screen size.
521 double sw = ((1f * screenSize.width) / (1f * Integer
522 .parseInt(jalview.bin.Cache
523 .getProperty("SCREENGEOMETRY_WIDTH"))));
524 double sh = ((1f * screenSize.height) / (1f * Integer
525 .parseInt(jalview.bin.Cache
526 .getProperty("SCREENGEOMETRY_HEIGHT"))));
527 // rescale the bounds depending upon the current screen geometry.
528 ix = (int) (ix * sw);
529 iw = (int) (iw * sw);
530 iy = (int) (iy * sh);
531 ih = (int) (ih * sh);
532 while (ix >= screenSize.width)
534 jalview.bin.Cache.log
535 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
536 ix -= screenSize.width;
538 while (iy >= screenSize.height)
540 jalview.bin.Cache.log
541 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
542 iy -= screenSize.height;
544 jalview.bin.Cache.log.debug("Got last known dimensions for "
545 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
548 // return dimensions for new instance
549 return new Rectangle(ix, iy, iw, ih);
554 private void doVamsasClientCheck()
556 if (jalview.bin.Cache.vamsasJarsPresent())
558 setupVamsasDisconnectedGui();
559 VamsasMenu.setVisible(true);
560 final Desktop us = this;
561 VamsasMenu.addMenuListener(new MenuListener()
563 // this listener remembers when the menu was first selected, and
564 // doesn't rebuild the session list until it has been cleared and
566 boolean refresh = true;
568 public void menuCanceled(MenuEvent e)
573 public void menuDeselected(MenuEvent e)
578 public void menuSelected(MenuEvent e)
582 us.buildVamsasStMenu();
587 vamsasStart.setVisible(true);
591 void showPasteMenu(int x, int y)
593 JPopupMenu popup = new JPopupMenu();
594 JMenuItem item = new JMenuItem(
595 MessageManager.getString("label.paste_new_window"));
596 item.addActionListener(new ActionListener()
598 public void actionPerformed(ActionEvent evt)
605 popup.show(this, x, y);
612 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
613 Transferable contents = c.getContents(this);
615 if (contents != null)
617 String file = (String) contents
618 .getTransferData(DataFlavor.stringFlavor);
620 String format = new IdentifyFile().Identify(file,
621 FormatAdapter.PASTE);
623 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
626 } catch (Exception ex)
629 .println("Unable to paste alignment from system clipboard:\n"
635 * Adds and opens the given frame to the desktop
646 public static synchronized void addInternalFrame(
647 final JInternalFrame frame, String title, int w, int h)
649 addInternalFrame(frame, title, true, w, h, true);
654 * Add an internal frame to the Jalview desktop
661 * When true, display frame immediately, otherwise, caller must call
662 * setVisible themselves.
668 public static synchronized void addInternalFrame(
669 final JInternalFrame frame, String title, boolean makeVisible,
672 addInternalFrame(frame, title, makeVisible, w, h, true);
676 * Add an internal frame to the Jalview desktop and make it visible
689 public static synchronized void addInternalFrame(
690 final JInternalFrame frame, String title, int w, int h,
693 addInternalFrame(frame, title, true, w, h, resizable);
697 * Add an internal frame to the Jalview desktop
704 * When true, display frame immediately, otherwise, caller must call
705 * setVisible themselves.
713 public static synchronized void addInternalFrame(
714 final JInternalFrame frame, String title, boolean makeVisible,
715 int w, int h, boolean resizable)
718 // TODO: allow callers to determine X and Y position of frame (eg. via
720 // TODO: consider fixing method to update entries in the window submenu with
721 // the current window title
723 frame.setTitle(title);
724 if (frame.getWidth() < 1 || frame.getHeight() < 1)
728 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
729 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
730 // IF JALVIEW IS RUNNING HEADLESS
731 // ///////////////////////////////////////////////
733 || (System.getProperty("java.awt.headless") != null && System
734 .getProperty("java.awt.headless").equals("true")))
741 frame.setVisible(makeVisible);
742 frame.setClosable(true);
743 frame.setResizable(resizable);
744 frame.setMaximizable(resizable);
745 frame.setIconifiable(resizable);
746 frame.setFrameIcon(null);
748 if (frame.getX() < 1 && frame.getY() < 1)
750 frame.setLocation(xOffset * openFrameCount, yOffset
751 * ((openFrameCount - 1) % 10) + yOffset);
754 final JMenuItem menuItem = new JMenuItem(title);
755 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
757 public void internalFrameActivated(
758 javax.swing.event.InternalFrameEvent evt)
760 JInternalFrame itf = desktop.getSelectedFrame();
768 public void internalFrameClosed(
769 javax.swing.event.InternalFrameEvent evt)
771 PaintRefresher.RemoveComponent(frame);
773 windowMenu.remove(menuItem);
774 JInternalFrame itf = desktop.getSelectedFrame();
783 menuItem.addActionListener(new ActionListener()
785 public void actionPerformed(ActionEvent e)
789 frame.setSelected(true);
790 frame.setIcon(false);
791 } catch (java.beans.PropertyVetoException ex)
797 menuItem.addMouseListener(new MouseListener()
801 public void mouseReleased(MouseEvent e)
806 public void mousePressed(MouseEvent e)
811 public void mouseExited(MouseEvent e)
815 frame.setSelected(false);
816 } catch (PropertyVetoException e1)
822 public void mouseEntered(MouseEvent e)
826 frame.setSelected(true);
827 } catch (PropertyVetoException e1)
833 public void mouseClicked(MouseEvent e)
839 windowMenu.add(menuItem);
845 frame.setSelected(true);
846 frame.requestFocus();
847 } catch (java.beans.PropertyVetoException ve)
849 } catch (java.lang.ClassCastException cex)
852 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
857 public void lostOwnership(Clipboard clipboard, Transferable contents)
861 Desktop.jalviewClipboard = null;
864 internalCopy = false;
867 public void dragEnter(DropTargetDragEvent evt)
871 public void dragExit(DropTargetEvent evt)
875 public void dragOver(DropTargetDragEvent evt)
879 public void dropActionChanged(DropTargetDragEvent evt)
889 public void drop(DropTargetDropEvent evt)
891 boolean success = true;
892 Transferable t = evt.getTransferable();
893 java.util.List files = null;
894 java.util.List protocols = null;
898 DataFlavor uriListFlavor = new DataFlavor(
899 "text/uri-list;class=java.lang.String");
900 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
902 // Works on Windows and MacOSX
903 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
904 files = (java.util.List) t
905 .getTransferData(DataFlavor.javaFileListFlavor);
907 else if (t.isDataFlavorSupported(uriListFlavor))
909 // This is used by Unix drag system
910 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
911 String data = (String) t.getTransferData(uriListFlavor);
912 files = new java.util.ArrayList(1);
913 protocols = new java.util.ArrayList(1);
914 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
915 data, "\r\n"); st.hasMoreTokens();)
917 String s = st.nextToken();
918 if (s.startsWith("#"))
920 // the line is a comment (as per the RFC 2483)
923 java.net.URI uri = new java.net.URI(s);
924 if (uri.getScheme().toLowerCase().startsWith("http"))
926 protocols.add(FormatAdapter.URL);
927 files.add(uri.toString());
931 // otherwise preserve old behaviour: catch all for file objects
932 java.io.File file = new java.io.File(uri);
933 protocols.add(FormatAdapter.FILE);
934 files.add(file.toString());
938 } catch (Exception e)
947 for (int i = 0; i < files.size(); i++)
949 String file = files.get(i).toString();
950 String protocol = (protocols == null) ? FormatAdapter.FILE
951 : (String) protocols.get(i);
952 String format = null;
954 if (file.endsWith(".jar"))
961 format = new IdentifyFile().Identify(file, protocol);
964 new FileLoader().LoadFile(file, protocol, format);
967 } catch (Exception ex)
972 evt.dropComplete(success); // need this to ensure input focus is properly
973 // transfered to any new windows created
982 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
984 JalviewFileChooser chooser = new JalviewFileChooser(
985 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
986 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
987 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
988 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
990 chooser.setFileView(new JalviewFileView());
991 chooser.setDialogTitle(MessageManager
992 .getString("label.open_local_file"));
993 chooser.setToolTipText(MessageManager.getString("action.open"));
995 int value = chooser.showOpenDialog(this);
997 if (value == JalviewFileChooser.APPROVE_OPTION)
999 String choice = chooser.getSelectedFile().getPath();
1000 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1001 .getSelectedFile().getParent());
1003 String format = null;
1004 if (chooser.getSelectedFormat() != null
1005 && chooser.getSelectedFormat().equals("Jalview"))
1011 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1014 if (viewport != null)
1016 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1021 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1032 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1034 // This construct allows us to have a wider textfield
1036 JLabel label = new JLabel(
1037 MessageManager.getString("label.input_file_url"));
1038 final JComboBox history = new JComboBox();
1040 JPanel panel = new JPanel(new GridLayout(2, 1));
1043 history.setPreferredSize(new Dimension(400, 20));
1044 history.setEditable(true);
1045 history.addItem("http://www.");
1047 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1051 if (historyItems != null)
1053 st = new StringTokenizer(historyItems, "\t");
1055 while (st.hasMoreTokens())
1057 history.addItem(st.nextElement());
1061 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1062 MessageManager.getString("label.input_alignment_from_url"),
1063 JOptionPane.OK_CANCEL_OPTION);
1065 if (reply != JOptionPane.OK_OPTION)
1070 String url = history.getSelectedItem().toString();
1072 if (url.toLowerCase().endsWith(".jar"))
1074 if (viewport != null)
1076 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1081 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1086 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1088 if (format.equals("URL NOT FOUND"))
1090 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1091 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1092 JOptionPane.WARNING_MESSAGE);
1097 if (viewport != null)
1099 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1103 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1114 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1116 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1117 cap.setForInput(viewport);
1118 Desktop.addInternalFrame(cap,
1119 MessageManager.getString("label.cut_paste_alignmen_file"),
1128 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1130 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1131 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1133 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1134 getBounds().y, getWidth(), getHeight()));
1136 if (jconsole != null)
1138 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1139 jconsole.stopConsole();
1143 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1146 if (dialogExecutor != null)
1148 dialogExecutor.shutdownNow();
1154 private void storeLastKnownDimensions(String string, Rectangle jc)
1156 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1157 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1158 + " height:" + jc.height);
1160 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1161 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1162 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1163 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1172 public void aboutMenuItem_actionPerformed(ActionEvent e)
1174 // StringBuffer message = getAboutMessage(false);
1175 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1177 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1178 new Thread(new Runnable()
1182 new SplashScreen(true);
1187 public StringBuffer getAboutMessage(boolean shortv)
1189 StringBuffer message = new StringBuffer();
1190 message.append("<html>");
1193 message.append("<h1><strong>Version: "
1194 + jalview.bin.Cache.getProperty("VERSION")
1195 + "</strong></h1>");
1196 message.append("<strong>Last Updated: <em>"
1197 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1198 + "</em></strong>");
1204 message.append("<strong>Version "
1205 + jalview.bin.Cache.getProperty("VERSION")
1206 + "; last updated: "
1207 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1210 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1213 message.append("<br>...Checking latest version...</br>");
1215 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1216 .equals(jalview.bin.Cache.getProperty("VERSION")))
1218 boolean red = false;
1219 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1220 .indexOf("automated build") == -1)
1223 // Displayed when code version and jnlp version do not match and code
1224 // version is not a development build
1225 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1228 message.append("<br>!! Version "
1229 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1231 + " is available for download from "
1232 + jalview.bin.Cache.getDefault("www.jalview.org",
1233 "http://www.jalview.org") + " !!");
1236 message.append("</div>");
1239 message.append("<br>Authors: "
1243 "The Jalview Authors (See AUTHORS file for current list)")
1244 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1245 + "<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"
1246 + "<br><br>If you use Jalview, please cite:"
1247 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1248 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1249 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1260 public void documentationMenuItem_actionPerformed(ActionEvent e)
1264 Help.showHelpWindow();
1265 } catch (Exception ex)
1270 public void closeAll_actionPerformed(ActionEvent e)
1272 JInternalFrame[] frames = desktop.getAllFrames();
1273 for (int i = 0; i < frames.length; i++)
1277 frames[i].setClosed(true);
1278 } catch (java.beans.PropertyVetoException ex)
1282 System.out.println("ALL CLOSED");
1283 if (v_client != null)
1285 // TODO clear binding to vamsas document objects on close_all
1290 public void raiseRelated_actionPerformed(ActionEvent e)
1292 reorderAssociatedWindows(false, false);
1295 public void minimizeAssociated_actionPerformed(ActionEvent e)
1297 reorderAssociatedWindows(true, false);
1300 void closeAssociatedWindows()
1302 reorderAssociatedWindows(false, true);
1308 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1311 protected void garbageCollect_actionPerformed(ActionEvent e)
1313 // We simply collect the garbage
1314 jalview.bin.Cache.log.debug("Collecting garbage...");
1316 jalview.bin.Cache.log.debug("Finished garbage collection.");
1323 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1326 protected void showMemusage_actionPerformed(ActionEvent e)
1328 desktop.showMemoryUsage(showMemusage.isSelected());
1335 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1338 protected void showConsole_actionPerformed(ActionEvent e)
1340 showConsole(showConsole.isSelected());
1343 Console jconsole = null;
1346 * control whether the java console is visible or not
1350 void showConsole(boolean selected)
1352 showConsole.setSelected(selected);
1353 // TODO: decide if we should update properties file
1354 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1356 jconsole.setVisible(selected);
1359 void reorderAssociatedWindows(boolean minimize, boolean close)
1361 JInternalFrame[] frames = desktop.getAllFrames();
1362 if (frames == null || frames.length < 1)
1367 AlignViewport source = null, target = null;
1368 if (frames[0] instanceof AlignFrame)
1370 source = ((AlignFrame) frames[0]).getCurrentView();
1372 else if (frames[0] instanceof TreePanel)
1374 source = ((TreePanel) frames[0]).getViewPort();
1376 else if (frames[0] instanceof PCAPanel)
1378 source = ((PCAPanel) frames[0]).av;
1380 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1382 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1387 for (int i = 0; i < frames.length; i++)
1390 if (frames[i] == null)
1394 if (frames[i] instanceof AlignFrame)
1396 target = ((AlignFrame) frames[i]).getCurrentView();
1398 else if (frames[i] instanceof TreePanel)
1400 target = ((TreePanel) frames[i]).getViewPort();
1402 else if (frames[i] instanceof PCAPanel)
1404 target = ((PCAPanel) frames[i]).av;
1406 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1408 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1411 if (source == target)
1417 frames[i].setClosed(true);
1421 frames[i].setIcon(minimize);
1424 frames[i].toFront();
1428 } catch (java.beans.PropertyVetoException ex)
1442 protected void preferences_actionPerformed(ActionEvent e)
1453 public void saveState_actionPerformed(ActionEvent e)
1455 JalviewFileChooser chooser = new JalviewFileChooser(
1456 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1457 { "jvp" }, new String[]
1458 { "Jalview Project" }, "Jalview Project");
1460 chooser.setFileView(new JalviewFileView());
1461 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1463 int value = chooser.showSaveDialog(this);
1465 if (value == JalviewFileChooser.APPROVE_OPTION)
1467 final Desktop me = this;
1468 final java.io.File choice = chooser.getSelectedFile();
1469 new Thread(new Runnable()
1474 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1476 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1477 choice.getParent());
1478 // TODO catch and handle errors for savestate
1479 // TODO prevent user from messing with the Desktop whilst we're saving
1482 new Jalview2XML().SaveState(choice);
1483 } catch (OutOfMemoryError oom)
1485 new OOMWarning("Whilst saving current state to "
1486 + choice.getName(), oom);
1487 } catch (Exception ex)
1490 "Problems whilst trying to save to " + choice.getName(),
1492 JOptionPane.showMessageDialog(
1494 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1495 MessageManager.getString("label.couldnt_save_project"),
1496 JOptionPane.WARNING_MESSAGE);
1498 setProgressBar(null, choice.hashCode());
1510 public void loadState_actionPerformed(ActionEvent e)
1512 JalviewFileChooser chooser = new JalviewFileChooser(
1513 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1514 { "jvp", "jar" }, new String[]
1515 { "Jalview Project", "Jalview Project (old)" },
1517 chooser.setFileView(new JalviewFileView());
1518 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1520 int value = chooser.showOpenDialog(this);
1522 if (value == JalviewFileChooser.APPROVE_OPTION)
1524 final String choice = chooser.getSelectedFile().getAbsolutePath();
1525 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1526 .getSelectedFile().getParent());
1527 new Thread(new Runnable()
1531 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1535 new Jalview2XML().LoadJalviewAlign(choice);
1536 } catch (OutOfMemoryError oom)
1538 new OOMWarning("Whilst loading project from " + choice, oom);
1539 } catch (Exception ex)
1541 Cache.log.error("Problems whilst loading project from "
1543 JOptionPane.showMessageDialog(Desktop.desktop,
1544 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1545 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1547 setProgressBar(null, choice.hashCode());
1553 public void inputSequence_actionPerformed(ActionEvent e)
1555 new SequenceFetcher(this);
1558 JPanel progressPanel;
1560 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1562 public void startLoading(final String fileName)
1564 if (fileLoadingCount == 0)
1566 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1571 private JPanel addProgressPanel(String string)
1573 if (progressPanel == null)
1575 progressPanel = new JPanel(new GridLayout(1, 1));
1576 totalProgressCount = 0;
1577 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1579 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1580 JProgressBar progressBar = new JProgressBar();
1581 progressBar.setIndeterminate(true);
1583 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1585 thisprogress.add(progressBar, BorderLayout.CENTER);
1586 progressPanel.add(thisprogress);
1587 ((GridLayout) progressPanel.getLayout())
1588 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1589 ++totalProgressCount;
1590 instance.validate();
1591 return thisprogress;
1594 int totalProgressCount = 0;
1596 private void removeProgressPanel(JPanel progbar)
1598 if (progressPanel != null)
1600 synchronized (progressPanel)
1602 progressPanel.remove(progbar);
1603 GridLayout gl = (GridLayout) progressPanel.getLayout();
1604 gl.setRows(gl.getRows() - 1);
1605 if (--totalProgressCount < 1)
1607 this.getContentPane().remove(progressPanel);
1608 progressPanel = null;
1615 public void stopLoading()
1618 if (fileLoadingCount < 1)
1620 while (fileLoadingPanels.size() > 0)
1622 removeProgressPanel(fileLoadingPanels.remove(0));
1624 fileLoadingPanels.clear();
1625 fileLoadingCount = 0;
1630 public static int getViewCount(String alignmentId)
1632 AlignViewport[] aps = getViewports(alignmentId);
1633 return (aps == null) ? 0 : aps.length;
1638 * @param alignmentId
1639 * @return all AlignmentPanels concerning the alignmentId sequence set
1641 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1644 if (Desktop.desktop == null)
1646 // no frames created and in headless mode
1647 // TODO: verify that frames are recoverable when in headless mode
1650 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1651 ArrayList aps = new ArrayList();
1652 for (int t = 0; t < frames.length; t++)
1654 if (frames[t] instanceof AlignFrame)
1656 AlignFrame af = (AlignFrame) frames[t];
1657 for (int a = 0; a < af.alignPanels.size(); a++)
1659 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1660 .elementAt(a)).av.getSequenceSetId()))
1662 aps.add(af.alignPanels.elementAt(a));
1667 if (aps.size() == 0)
1671 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1672 for (int t = 0; t < vap.length; t++)
1674 vap[t] = (AlignmentPanel) aps.get(t);
1680 * get all the viewports on an alignment.
1682 * @param sequenceSetId
1683 * unique alignment id
1684 * @return all viewports on the alignment bound to sequenceSetId
1686 public static AlignViewport[] getViewports(String sequenceSetId)
1688 Vector viewp = new Vector();
1689 if (desktop != null)
1691 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1693 for (int t = 0; t < frames.length; t++)
1695 if (frames[t] instanceof AlignFrame)
1697 AlignFrame afr = ((AlignFrame) frames[t]);
1698 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1700 if (afr.alignPanels != null)
1702 for (int a = 0; a < afr.alignPanels.size(); a++)
1704 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1705 .elementAt(a)).av.getSequenceSetId()))
1707 viewp.addElement(((AlignmentPanel) afr.alignPanels
1714 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1719 if (viewp.size() > 0)
1721 AlignViewport[] vp = new AlignViewport[viewp.size()];
1729 public void explodeViews(AlignFrame af)
1731 int size = af.alignPanels.size();
1737 for (int i = 0; i < size; i++)
1739 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1740 AlignFrame newaf = new AlignFrame(ap);
1741 if (ap.av.explodedPosition != null
1742 && !ap.av.explodedPosition.equals(af.getBounds()))
1744 newaf.setBounds(ap.av.explodedPosition);
1747 ap.av.gatherViewsHere = false;
1749 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1750 AlignFrame.DEFAULT_HEIGHT);
1753 af.alignPanels.clear();
1754 af.closeMenuItem_actionPerformed(true);
1758 public void gatherViews(AlignFrame source)
1760 source.viewport.gatherViewsHere = true;
1761 source.viewport.explodedPosition = source.getBounds();
1762 JInternalFrame[] frames = desktop.getAllFrames();
1763 String viewId = source.viewport.getSequenceSetId();
1765 for (int t = 0; t < frames.length; t++)
1767 if (frames[t] instanceof AlignFrame && frames[t] != source)
1769 AlignFrame af = (AlignFrame) frames[t];
1770 boolean gatherThis = false;
1771 for (int a = 0; a < af.alignPanels.size(); a++)
1773 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1774 if (viewId.equals(ap.av.getSequenceSetId()))
1777 ap.av.gatherViewsHere = false;
1778 ap.av.explodedPosition = af.getBounds();
1779 source.addAlignmentPanel(ap, false);
1785 af.alignPanels.clear();
1786 af.closeMenuItem_actionPerformed(true);
1793 jalview.gui.VamsasApplication v_client = null;
1795 public void vamsasImport_actionPerformed(ActionEvent e)
1797 if (v_client == null)
1799 // Load and try to start a session.
1800 JalviewFileChooser chooser = new JalviewFileChooser(
1801 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1803 chooser.setFileView(new JalviewFileView());
1804 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1805 chooser.setToolTipText(MessageManager
1806 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1808 int value = chooser.showOpenDialog(this);
1810 if (value == JalviewFileChooser.APPROVE_OPTION)
1812 String fle = chooser.getSelectedFile().toString();
1813 if (!vamsasImport(chooser.getSelectedFile()))
1816 .showInternalMessageDialog(
1818 MessageManager.formatMessage(
1819 "label.couldnt_import_as_vamsas_session",
1823 .getString("label.vamsas_document_import_failed"),
1824 JOptionPane.ERROR_MESSAGE);
1830 jalview.bin.Cache.log
1831 .error("Implementation error - load session from a running session is not supported.");
1836 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1839 * @return true if import was a success and a session was started.
1841 public boolean vamsasImport(URL url)
1843 // TODO: create progress bar
1844 if (v_client != null)
1847 jalview.bin.Cache.log
1848 .error("Implementation error - load session from a running session is not supported.");
1854 // copy the URL content to a temporary local file
1855 // TODO: be a bit cleverer here with nio (?!)
1856 File file = File.createTempFile("vdocfromurl", ".vdj");
1857 FileOutputStream fos = new FileOutputStream(file);
1858 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1859 byte[] buffer = new byte[2048];
1861 while ((ln = bis.read(buffer)) > -1)
1863 fos.write(buffer, 0, ln);
1867 v_client = new jalview.gui.VamsasApplication(this, file,
1868 url.toExternalForm());
1869 } catch (Exception ex)
1871 jalview.bin.Cache.log.error(
1872 "Failed to create new vamsas session from contents of URL "
1876 setupVamsasConnectedGui();
1877 v_client.initial_update(); // TODO: thread ?
1878 return v_client.inSession();
1882 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1885 * @return true if import was a success and a session was started.
1887 public boolean vamsasImport(File file)
1889 if (v_client != null)
1892 jalview.bin.Cache.log
1893 .error("Implementation error - load session from a running session is not supported.");
1897 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1901 v_client = new jalview.gui.VamsasApplication(this, file, null);
1902 } catch (Exception ex)
1904 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1906 jalview.bin.Cache.log.error(
1907 "New vamsas session from existing session file failed:", ex);
1910 setupVamsasConnectedGui();
1911 v_client.initial_update(); // TODO: thread ?
1912 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1914 return v_client.inSession();
1917 public boolean joinVamsasSession(String mysesid)
1919 if (v_client != null)
1921 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1923 if (mysesid == null)
1925 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1927 v_client = new VamsasApplication(this, mysesid);
1928 setupVamsasConnectedGui();
1929 v_client.initial_update();
1930 return (v_client.inSession());
1933 public void vamsasStart_actionPerformed(ActionEvent e)
1935 if (v_client == null)
1938 // we just start a default session for moment.
1940 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1941 * getProperty("LAST_DIRECTORY"));
1943 * chooser.setFileView(new JalviewFileView());
1944 * chooser.setDialogTitle("Load Vamsas file");
1945 * chooser.setToolTipText("Import");
1947 * int value = chooser.showOpenDialog(this);
1949 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1950 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1952 v_client = new VamsasApplication(this);
1953 setupVamsasConnectedGui();
1954 v_client.initial_update(); // TODO: thread ?
1958 // store current data in session.
1959 v_client.push_update(); // TODO: thread
1963 protected void setupVamsasConnectedGui()
1965 vamsasStart.setText(MessageManager.getString("label.session_update"));
1966 vamsasSave.setVisible(true);
1967 vamsasStop.setVisible(true);
1968 vamsasImport.setVisible(false); // Document import to existing session is
1969 // not possible for vamsas-client-1.0.
1972 protected void setupVamsasDisconnectedGui()
1974 vamsasSave.setVisible(false);
1975 vamsasStop.setVisible(false);
1976 vamsasImport.setVisible(true);
1977 vamsasStart.setText(MessageManager
1978 .getString("label.new_vamsas_session"));
1981 public void vamsasStop_actionPerformed(ActionEvent e)
1983 if (v_client != null)
1985 v_client.end_session();
1987 setupVamsasDisconnectedGui();
1991 protected void buildVamsasStMenu()
1993 if (v_client == null)
1995 String[] sess = null;
1998 sess = VamsasApplication.getSessionList();
1999 } catch (Exception e)
2001 jalview.bin.Cache.log.warn(
2002 "Problem getting current sessions list.", e);
2007 jalview.bin.Cache.log.debug("Got current sessions list: "
2008 + sess.length + " entries.");
2009 VamsasStMenu.removeAll();
2010 for (int i = 0; i < sess.length; i++)
2012 JMenuItem sessit = new JMenuItem();
2013 sessit.setText(sess[i]);
2014 sessit.setToolTipText(MessageManager.formatMessage(
2015 "label.connect_to_session", new String[]
2017 final Desktop dsktp = this;
2018 final String mysesid = sess[i];
2019 sessit.addActionListener(new ActionListener()
2022 public void actionPerformed(ActionEvent e)
2024 if (dsktp.v_client == null)
2026 Thread rthr = new Thread(new Runnable()
2031 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2032 dsktp.setupVamsasConnectedGui();
2033 dsktp.v_client.initial_update();
2041 VamsasStMenu.add(sessit);
2043 // don't show an empty menu.
2044 VamsasStMenu.setVisible(sess.length > 0);
2049 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2050 VamsasStMenu.removeAll();
2051 VamsasStMenu.setVisible(false);
2056 // Not interested in the content. Just hide ourselves.
2057 VamsasStMenu.setVisible(false);
2061 public void vamsasSave_actionPerformed(ActionEvent e)
2063 if (v_client != null)
2065 JalviewFileChooser chooser = new JalviewFileChooser(
2066 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2067 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2069 { "Vamsas Document" }, "Vamsas Document");
2071 chooser.setFileView(new JalviewFileView());
2072 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2074 int value = chooser.showSaveDialog(this);
2076 if (value == JalviewFileChooser.APPROVE_OPTION)
2078 java.io.File choice = chooser.getSelectedFile();
2079 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2080 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2081 String warnmsg = null;
2082 String warnttl = null;
2085 v_client.vclient.storeDocument(choice);
2088 warnttl = "Serious Problem saving Vamsas Document";
2089 warnmsg = ex.toString();
2090 jalview.bin.Cache.log.error("Error Whilst saving document to "
2093 } catch (Exception ex)
2095 warnttl = "Problem saving Vamsas Document.";
2096 warnmsg = ex.toString();
2097 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2101 removeProgressPanel(progpanel);
2102 if (warnmsg != null)
2104 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2106 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2112 JPanel vamUpdate = null;
2115 * hide vamsas user gui bits when a vamsas document event is being handled.
2118 * true to hide gui, false to reveal gui
2120 public void setVamsasUpdate(boolean b)
2122 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2123 + (b ? "in progress" : "finished"));
2125 if (vamUpdate != null)
2127 this.removeProgressPanel(vamUpdate);
2131 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2133 vamsasStart.setVisible(!b);
2134 vamsasStop.setVisible(!b);
2135 vamsasSave.setVisible(!b);
2138 public JInternalFrame[] getAllFrames()
2140 return desktop.getAllFrames();
2144 * Checks the given url to see if it gives a response indicating that the user
2145 * should be informed of a new questionnaire.
2149 public void checkForQuestionnaire(String url)
2151 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2152 // javax.swing.SwingUtilities.invokeLater(jvq);
2153 new Thread(jvq).start();
2157 * Proxy class for JDesktopPane which optionally displays the current memory
2158 * usage and highlights the desktop area with a red bar if free memory runs
2163 public class MyDesktopPane extends JDesktopPane implements Runnable
2166 boolean showMemoryUsage = false;
2170 java.text.NumberFormat df;
2172 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2175 public MyDesktopPane(boolean showMemoryUsage)
2177 showMemoryUsage(showMemoryUsage);
2180 public void showMemoryUsage(boolean showMemoryUsage)
2182 this.showMemoryUsage = showMemoryUsage;
2183 if (showMemoryUsage)
2185 Thread worker = new Thread(this);
2190 public boolean isShowMemoryUsage()
2192 return showMemoryUsage;
2197 df = java.text.NumberFormat.getNumberInstance();
2198 df.setMaximumFractionDigits(2);
2199 runtime = Runtime.getRuntime();
2201 while (showMemoryUsage)
2205 maxMemory = runtime.maxMemory() / 1048576f;
2206 allocatedMemory = runtime.totalMemory() / 1048576f;
2207 freeMemory = runtime.freeMemory() / 1048576f;
2208 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2210 percentUsage = (totalFreeMemory / maxMemory) * 100;
2212 // if (percentUsage < 20)
2214 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2216 // instance.set.setBorder(border1);
2219 // sleep after showing usage
2221 } catch (Exception ex)
2223 ex.printStackTrace();
2228 public void paintComponent(Graphics g)
2230 if (showMemoryUsage && g != null && df != null)
2232 if (percentUsage < 20)
2234 g.setColor(Color.red);
2236 FontMetrics fm = g.getFontMetrics();
2239 g.drawString(MessageManager.formatMessage(
2240 "label.memory_stats",
2242 { df.format(totalFreeMemory), df.format(maxMemory),
2243 df.format(percentUsage) }), 10,
2244 getHeight() - fm.getHeight());
2251 * fixes stacking order after a modal dialog to ensure windows that should be
2252 * on top actually are
2254 public void relayerWindows()
2259 protected JMenuItem groovyShell;
2261 public void doGroovyCheck()
2263 if (jalview.bin.Cache.groovyJarsPresent())
2265 groovyShell = new JMenuItem();
2266 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2267 groovyShell.addActionListener(new ActionListener()
2269 public void actionPerformed(ActionEvent e)
2271 groovyShell_actionPerformed(e);
2274 toolsMenu.add(groovyShell);
2275 groovyShell.setVisible(true);
2280 * Accessor method to quickly get all the AlignmentFrames loaded.
2282 public static AlignFrame[] getAlignframes()
2284 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2290 Vector avp = new Vector();
2294 for (int i = frames.length - 1; i > -1; i--)
2296 if (frames[i] instanceof AlignFrame)
2298 AlignFrame af = (AlignFrame) frames[i];
2302 } catch (Exception ex)
2304 ex.printStackTrace();
2306 if (avp.size() == 0)
2310 AlignFrame afs[] = new AlignFrame[avp.size()];
2311 for (int i = 0, j = avp.size(); i < j; i++)
2313 afs[i] = (AlignFrame) avp.elementAt(i);
2319 public AppJmol[] getJmols()
2321 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2327 Vector avp = new Vector();
2331 for (int i = frames.length - 1; i > -1; i--)
2333 if (frames[i] instanceof AppJmol)
2335 AppJmol af = (AppJmol) frames[i];
2339 } catch (Exception ex)
2341 ex.printStackTrace();
2343 if (avp.size() == 0)
2347 AppJmol afs[] = new AppJmol[avp.size()];
2348 for (int i = 0, j = avp.size(); i < j; i++)
2350 afs[i] = (AppJmol) avp.elementAt(i);
2357 * Add Groovy Support to Jalview
2359 public void groovyShell_actionPerformed(ActionEvent e)
2361 // use reflection to avoid creating compilation dependency.
2362 if (!jalview.bin.Cache.groovyJarsPresent())
2364 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2368 Class gcClass = Desktop.class.getClassLoader().loadClass(
2369 "groovy.ui.Console");
2370 Constructor gccons = gcClass.getConstructor(null);
2371 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2373 { String.class, Object.class });
2374 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2375 Object gc = gccons.newInstance(null);
2376 setvar.invoke(gc, new Object[]
2377 { "Jalview", this });
2378 run.invoke(gc, null);
2379 } catch (Exception ex)
2381 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2383 .showInternalMessageDialog(
2386 MessageManager.getString("label.couldnt_create_groovy_shell"),
2387 MessageManager.getString("label.groovy_support_failed"),
2388 JOptionPane.ERROR_MESSAGE);
2393 * Progress bars managed by the IProgressIndicator method.
2395 private Hashtable<Long, JPanel> progressBars;
2397 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2402 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2404 public void setProgressBar(String message, long id)
2406 if (progressBars == null)
2408 progressBars = new Hashtable<Long, JPanel>();
2409 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2412 if (progressBars.get(new Long(id)) != null)
2414 JPanel progressPanel = progressBars.remove(new Long(id));
2415 if (progressBarHandlers.contains(new Long(id)))
2417 progressBarHandlers.remove(new Long(id));
2419 removeProgressPanel(progressPanel);
2423 progressBars.put(new Long(id), addProgressPanel(message));
2430 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2431 * jalview.gui.IProgressIndicatorHandler)
2433 public void registerHandler(final long id,
2434 final IProgressIndicatorHandler handler)
2436 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2438 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2440 progressBarHandlers.put(new Long(id), handler);
2441 final JPanel progressPanel = progressBars.get(new Long(id));
2442 if (handler.canCancel())
2444 JButton cancel = new JButton(
2445 MessageManager.getString("action.cancel"));
2446 final IProgressIndicator us = this;
2447 cancel.addActionListener(new ActionListener()
2450 public void actionPerformed(ActionEvent e)
2452 handler.cancelActivity(id);
2453 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2456 progressPanel.add(cancel, BorderLayout.EAST);
2462 * @return true if any progress bars are still active
2465 public boolean operationInProgress()
2467 if (progressBars != null && progressBars.size() > 0)
2475 * This will return the first AlignFrame viewing AlignViewport av. It will
2476 * break if there are more than one AlignFrames viewing a particular av. This
2479 * @return alignFrame for av
2481 public static AlignFrame getAlignFrameFor(AlignViewport av)
2483 if (desktop != null)
2485 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2486 for (int panel = 0; aps != null && panel < aps.length; panel++)
2488 if (aps[panel] != null && aps[panel].av == av)
2490 return aps[panel].alignFrame;
2497 public VamsasApplication getVamsasApplication()
2504 * flag set if jalview GUI is being operated programmatically
2506 private boolean inBatchMode = false;
2509 * check if jalview GUI is being operated programmatically
2511 * @return inBatchMode
2513 public boolean isInBatchMode()
2519 * set flag if jalview GUI is being operated programmatically
2521 * @param inBatchMode
2523 public void setInBatchMode(boolean inBatchMode)
2525 this.inBatchMode = inBatchMode;
2528 public void startServiceDiscovery()
2530 startServiceDiscovery(false);
2533 public void startServiceDiscovery(boolean blocking)
2535 boolean alive = true;
2536 Thread t0 = null, t1 = null, t2 = null;
2537 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2540 // todo: changesupport handlers need to be transferred
2541 if (discoverer == null)
2543 discoverer = new jalview.ws.jws1.Discoverer();
2544 // register PCS handler for desktop.
2545 discoverer.addPropertyChangeListener(changeSupport);
2547 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2548 // until we phase out completely
2549 (t0 = new Thread(discoverer)).start();
2552 // ENFIN services are EOLed as of Jalview 2.8.1 release
2557 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2559 // EnfinEnvision web service menu entries are rebuild every time the
2560 // menu is shown, so no changeSupport events are needed.
2561 jalview.ws.EnfinEnvision2OneWay.getInstance();
2562 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2565 } catch (Exception e)
2568 .info("Exception when trying to launch Envision2 workflow discovery.",
2570 Cache.log.info(e.getStackTrace());
2574 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2576 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2578 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2580 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2586 // TODO: do rest service discovery
2595 } catch (Exception e)
2598 alive = (t1 != null && t1.isAlive())
2599 || (t2 != null && t2.isAlive())
2600 || (t3 != null && t3.isAlive())
2601 || (t0 != null && t0.isAlive());
2607 * called to check if the service discovery process completed successfully.
2611 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2613 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2615 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2616 .getErrorMessages();
2619 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2621 if (serviceChangedDialog == null)
2623 // only run if we aren't already displaying one of these.
2624 addDialogThread(serviceChangedDialog = new Runnable()
2630 * JalviewDialog jd =new JalviewDialog() {
2632 * @Override protected void cancelPressed() { // TODO
2633 * Auto-generated method stub
2635 * }@Override protected void okPressed() { // TODO
2636 * Auto-generated method stub
2638 * }@Override protected void raiseClosed() { // TODO
2639 * Auto-generated method stub
2641 * } }; jd.initDialogFrame(new
2642 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2643 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2644 * + " or mis-configured HTTP proxy settings.<br/>" +
2645 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2647 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2648 * ), true, true, "Web Service Configuration Problem", 450,
2651 * jd.waitForInput();
2657 "<html><table width=\"450\"><tr><td>"
2659 + "</td></tr></table>"
2660 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2661 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2662 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2663 + " Tools->Preferences dialog box to change them.</p></html>"),
2664 "Web Service Configuration Problem",
2665 JOptionPane.DEFAULT_OPTION,
2666 JOptionPane.ERROR_MESSAGE);
2667 serviceChangedDialog = null;
2676 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2683 private Runnable serviceChangedDialog = null;
2686 * start a thread to open a URL in the configured browser. Pops up a warning
2687 * dialog to the user if there is an exception when calling out to the browser
2692 public static void showUrl(final String url)
2694 showUrl(url, Desktop.instance);
2698 * Like showUrl but allows progress handler to be specified
2702 * (null) or object implementing IProgressIndicator
2704 public static void showUrl(final String url,
2705 final IProgressIndicator progress)
2707 new Thread(new Runnable()
2713 if (progress != null)
2715 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2717 jalview.util.BrowserLauncher.openURL(url);
2718 } catch (Exception ex)
2721 .showInternalMessageDialog(
2723 MessageManager.getString("label.web_browser_not_found_unix"),
2724 MessageManager.getString("label.web_browser_not_found"),
2725 JOptionPane.WARNING_MESSAGE);
2727 ex.printStackTrace();
2729 if (progress != null)
2731 progress.setProgressBar(null, this.hashCode());
2737 public static WsParamSetManager wsparamManager = null;
2739 public static ParamManager getUserParameterStore()
2741 if (wsparamManager == null)
2743 wsparamManager = new WsParamSetManager();
2745 return wsparamManager;
2749 * static hyperlink handler proxy method for use by Jalview's internal windows
2753 public static void hyperlinkUpdate(HyperlinkEvent e)
2755 if (e.getEventType() == EventType.ACTIVATED)
2760 url = e.getURL().toString();
2761 Desktop.showUrl(url);
2762 } catch (Exception x)
2766 if (Cache.log != null)
2768 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2772 System.err.println("Couldn't handle string " + url
2776 // ignore any exceptions due to dud links.
2783 * single thread that handles display of dialogs to user.
2785 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2788 * flag indicating if dialogExecutor should try to acquire a permit
2790 private volatile boolean dialogPause = true;
2795 private java.util.concurrent.Semaphore block = new Semaphore(0);
2798 * add another dialog thread to the queue
2802 public void addDialogThread(final Runnable prompter)
2804 dialogExecutor.submit(new Runnable()
2813 } catch (InterruptedException x)
2818 if (instance == null)
2824 SwingUtilities.invokeAndWait(prompter);
2825 } catch (Exception q)
2827 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2833 public void startDialogQueue()
2835 // set the flag so we don't pause waiting for another permit and semaphore
2836 // the current task to begin
2837 dialogPause = false;
2841 protected void snapShotWindow_actionPerformed(ActionEvent e)
2845 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2846 "View of Desktop", getWidth(), getHeight(), of = new File(
2847 "Jalview_snapshot" + System.currentTimeMillis()
2848 + ".eps"), "View of desktop");
2850 paintAll(im.getGraphics());
2852 } catch (Exception q)
2854 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2857 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());