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.viewmodel.AlignmentViewport;
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 AlignmentViewport 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 AlignmentViewport[] 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)
1643 if (Desktop.desktop == null)
1645 // no frames created and in headless mode
1646 // TODO: verify that frames are recoverable when in headless mode
1649 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1650 AlignFrame[] frames = getAlignFrames();
1655 for (AlignFrame af : frames)
1657 for (AlignmentPanel ap : af.alignPanels)
1659 if (alignmentId.equals(ap.av.getSequenceSetId()))
1664 // for (int a = 0; a < af.alignPanels.size(); a++)
1666 // if (alignmentId.equals(af.alignPanels
1667 // .get(a).av.getSequenceSetId()))
1669 // aps.add(af.alignPanels.get(a));
1673 if (aps.size() == 0)
1677 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1682 * get all the viewports on an alignment.
1684 * @param sequenceSetId
1685 * unique alignment id
1686 * @return all viewports on the alignment bound to sequenceSetId
1688 public static AlignmentViewport[] getViewports(String sequenceSetId)
1690 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1691 if (desktop != null)
1693 AlignFrame[] frames = Desktop.getAlignFrames();
1695 for (AlignFrame afr : frames)
1697 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1699 if (afr.alignPanels != null)
1701 for (AlignmentPanel ap : afr.alignPanels)
1703 if (sequenceSetId.equals(ap.av.getSequenceSetId()))
1711 viewp.add(afr.getViewport());
1715 if (viewp.size() > 0)
1717 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1723 public void explodeViews(AlignFrame af)
1725 int size = af.alignPanels.size();
1731 for (int i = 0; i < size; i++)
1733 AlignmentPanel ap = af.alignPanels.get(i);
1734 AlignFrame newaf = new AlignFrame(ap);
1735 if (ap.av.explodedPosition != null
1736 && !ap.av.explodedPosition.equals(af.getBounds()))
1738 newaf.setBounds(ap.av.explodedPosition);
1741 ap.av.gatherViewsHere = false;
1743 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1744 AlignFrame.DEFAULT_HEIGHT);
1747 af.alignPanels.clear();
1748 af.closeMenuItem_actionPerformed(true);
1752 public void gatherViews(AlignFrame source)
1754 source.viewport.gatherViewsHere = true;
1755 source.viewport.explodedPosition = source.getBounds();
1756 JInternalFrame[] frames = desktop.getAllFrames();
1757 String viewId = source.viewport.getSequenceSetId();
1759 for (int t = 0; t < frames.length; t++)
1761 if (frames[t] instanceof AlignFrame && frames[t] != source)
1763 AlignFrame af = (AlignFrame) frames[t];
1764 boolean gatherThis = false;
1765 for (int a = 0; a < af.alignPanels.size(); a++)
1767 AlignmentPanel ap = af.alignPanels.get(a);
1768 if (viewId.equals(ap.av.getSequenceSetId()))
1771 ap.av.gatherViewsHere = false;
1772 ap.av.explodedPosition = af.getBounds();
1773 source.addAlignmentPanel(ap, false);
1779 af.alignPanels.clear();
1780 af.closeMenuItem_actionPerformed(true);
1787 jalview.gui.VamsasApplication v_client = null;
1789 public void vamsasImport_actionPerformed(ActionEvent e)
1791 if (v_client == null)
1793 // Load and try to start a session.
1794 JalviewFileChooser chooser = new JalviewFileChooser(
1795 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1797 chooser.setFileView(new JalviewFileView());
1798 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1799 chooser.setToolTipText(MessageManager
1800 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1802 int value = chooser.showOpenDialog(this);
1804 if (value == JalviewFileChooser.APPROVE_OPTION)
1806 String fle = chooser.getSelectedFile().toString();
1807 if (!vamsasImport(chooser.getSelectedFile()))
1810 .showInternalMessageDialog(
1812 MessageManager.formatMessage(
1813 "label.couldnt_import_as_vamsas_session",
1817 .getString("label.vamsas_document_import_failed"),
1818 JOptionPane.ERROR_MESSAGE);
1824 jalview.bin.Cache.log
1825 .error("Implementation error - load session from a running session is not supported.");
1830 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1833 * @return true if import was a success and a session was started.
1835 public boolean vamsasImport(URL url)
1837 // TODO: create progress bar
1838 if (v_client != null)
1841 jalview.bin.Cache.log
1842 .error("Implementation error - load session from a running session is not supported.");
1848 // copy the URL content to a temporary local file
1849 // TODO: be a bit cleverer here with nio (?!)
1850 File file = File.createTempFile("vdocfromurl", ".vdj");
1851 FileOutputStream fos = new FileOutputStream(file);
1852 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1853 byte[] buffer = new byte[2048];
1855 while ((ln = bis.read(buffer)) > -1)
1857 fos.write(buffer, 0, ln);
1861 v_client = new jalview.gui.VamsasApplication(this, file,
1862 url.toExternalForm());
1863 } catch (Exception ex)
1865 jalview.bin.Cache.log.error(
1866 "Failed to create new vamsas session from contents of URL "
1870 setupVamsasConnectedGui();
1871 v_client.initial_update(); // TODO: thread ?
1872 return v_client.inSession();
1876 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1879 * @return true if import was a success and a session was started.
1881 public boolean vamsasImport(File file)
1883 if (v_client != null)
1886 jalview.bin.Cache.log
1887 .error("Implementation error - load session from a running session is not supported.");
1891 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1895 v_client = new jalview.gui.VamsasApplication(this, file, null);
1896 } catch (Exception ex)
1898 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1900 jalview.bin.Cache.log.error(
1901 "New vamsas session from existing session file failed:", ex);
1904 setupVamsasConnectedGui();
1905 v_client.initial_update(); // TODO: thread ?
1906 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1908 return v_client.inSession();
1911 public boolean joinVamsasSession(String mysesid)
1913 if (v_client != null)
1915 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1917 if (mysesid == null)
1919 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1921 v_client = new VamsasApplication(this, mysesid);
1922 setupVamsasConnectedGui();
1923 v_client.initial_update();
1924 return (v_client.inSession());
1927 public void vamsasStart_actionPerformed(ActionEvent e)
1929 if (v_client == null)
1932 // we just start a default session for moment.
1934 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1935 * getProperty("LAST_DIRECTORY"));
1937 * chooser.setFileView(new JalviewFileView());
1938 * chooser.setDialogTitle("Load Vamsas file");
1939 * chooser.setToolTipText("Import");
1941 * int value = chooser.showOpenDialog(this);
1943 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1944 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1946 v_client = new VamsasApplication(this);
1947 setupVamsasConnectedGui();
1948 v_client.initial_update(); // TODO: thread ?
1952 // store current data in session.
1953 v_client.push_update(); // TODO: thread
1957 protected void setupVamsasConnectedGui()
1959 vamsasStart.setText(MessageManager.getString("label.session_update"));
1960 vamsasSave.setVisible(true);
1961 vamsasStop.setVisible(true);
1962 vamsasImport.setVisible(false); // Document import to existing session is
1963 // not possible for vamsas-client-1.0.
1966 protected void setupVamsasDisconnectedGui()
1968 vamsasSave.setVisible(false);
1969 vamsasStop.setVisible(false);
1970 vamsasImport.setVisible(true);
1971 vamsasStart.setText(MessageManager
1972 .getString("label.new_vamsas_session"));
1975 public void vamsasStop_actionPerformed(ActionEvent e)
1977 if (v_client != null)
1979 v_client.end_session();
1981 setupVamsasDisconnectedGui();
1985 protected void buildVamsasStMenu()
1987 if (v_client == null)
1989 String[] sess = null;
1992 sess = VamsasApplication.getSessionList();
1993 } catch (Exception e)
1995 jalview.bin.Cache.log.warn(
1996 "Problem getting current sessions list.", e);
2001 jalview.bin.Cache.log.debug("Got current sessions list: "
2002 + sess.length + " entries.");
2003 VamsasStMenu.removeAll();
2004 for (int i = 0; i < sess.length; i++)
2006 JMenuItem sessit = new JMenuItem();
2007 sessit.setText(sess[i]);
2008 sessit.setToolTipText(MessageManager.formatMessage(
2009 "label.connect_to_session", new String[]
2011 final Desktop dsktp = this;
2012 final String mysesid = sess[i];
2013 sessit.addActionListener(new ActionListener()
2016 public void actionPerformed(ActionEvent e)
2018 if (dsktp.v_client == null)
2020 Thread rthr = new Thread(new Runnable()
2025 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2026 dsktp.setupVamsasConnectedGui();
2027 dsktp.v_client.initial_update();
2035 VamsasStMenu.add(sessit);
2037 // don't show an empty menu.
2038 VamsasStMenu.setVisible(sess.length > 0);
2043 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2044 VamsasStMenu.removeAll();
2045 VamsasStMenu.setVisible(false);
2050 // Not interested in the content. Just hide ourselves.
2051 VamsasStMenu.setVisible(false);
2055 public void vamsasSave_actionPerformed(ActionEvent e)
2057 if (v_client != null)
2059 JalviewFileChooser chooser = new JalviewFileChooser(
2060 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2061 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2063 { "Vamsas Document" }, "Vamsas Document");
2065 chooser.setFileView(new JalviewFileView());
2066 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2068 int value = chooser.showSaveDialog(this);
2070 if (value == JalviewFileChooser.APPROVE_OPTION)
2072 java.io.File choice = chooser.getSelectedFile();
2073 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2074 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2075 String warnmsg = null;
2076 String warnttl = null;
2079 v_client.vclient.storeDocument(choice);
2082 warnttl = "Serious Problem saving Vamsas Document";
2083 warnmsg = ex.toString();
2084 jalview.bin.Cache.log.error("Error Whilst saving document to "
2087 } catch (Exception ex)
2089 warnttl = "Problem saving Vamsas Document.";
2090 warnmsg = ex.toString();
2091 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2095 removeProgressPanel(progpanel);
2096 if (warnmsg != null)
2098 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2100 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2106 JPanel vamUpdate = null;
2109 * hide vamsas user gui bits when a vamsas document event is being handled.
2112 * true to hide gui, false to reveal gui
2114 public void setVamsasUpdate(boolean b)
2116 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2117 + (b ? "in progress" : "finished"));
2119 if (vamUpdate != null)
2121 this.removeProgressPanel(vamUpdate);
2125 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2127 vamsasStart.setVisible(!b);
2128 vamsasStop.setVisible(!b);
2129 vamsasSave.setVisible(!b);
2132 public JInternalFrame[] getAllFrames()
2134 return desktop.getAllFrames();
2138 * Checks the given url to see if it gives a response indicating that the user
2139 * should be informed of a new questionnaire.
2143 public void checkForQuestionnaire(String url)
2145 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2146 // javax.swing.SwingUtilities.invokeLater(jvq);
2147 new Thread(jvq).start();
2151 * Proxy class for JDesktopPane which optionally displays the current memory
2152 * usage and highlights the desktop area with a red bar if free memory runs
2157 public class MyDesktopPane extends JDesktopPane implements Runnable
2160 boolean showMemoryUsage = false;
2164 java.text.NumberFormat df;
2166 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2169 public MyDesktopPane(boolean showMemoryUsage)
2171 showMemoryUsage(showMemoryUsage);
2174 public void showMemoryUsage(boolean showMemoryUsage)
2176 this.showMemoryUsage = showMemoryUsage;
2177 if (showMemoryUsage)
2179 Thread worker = new Thread(this);
2184 public boolean isShowMemoryUsage()
2186 return showMemoryUsage;
2191 df = java.text.NumberFormat.getNumberInstance();
2192 df.setMaximumFractionDigits(2);
2193 runtime = Runtime.getRuntime();
2195 while (showMemoryUsage)
2199 maxMemory = runtime.maxMemory() / 1048576f;
2200 allocatedMemory = runtime.totalMemory() / 1048576f;
2201 freeMemory = runtime.freeMemory() / 1048576f;
2202 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2204 percentUsage = (totalFreeMemory / maxMemory) * 100;
2206 // if (percentUsage < 20)
2208 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2210 // instance.set.setBorder(border1);
2213 // sleep after showing usage
2215 } catch (Exception ex)
2217 ex.printStackTrace();
2222 public void paintComponent(Graphics g)
2224 if (showMemoryUsage && g != null && df != null)
2226 if (percentUsage < 20)
2228 g.setColor(Color.red);
2230 FontMetrics fm = g.getFontMetrics();
2233 g.drawString(MessageManager.formatMessage(
2234 "label.memory_stats",
2236 { df.format(totalFreeMemory), df.format(maxMemory),
2237 df.format(percentUsage) }), 10,
2238 getHeight() - fm.getHeight());
2245 * fixes stacking order after a modal dialog to ensure windows that should be
2246 * on top actually are
2248 public void relayerWindows()
2253 protected JMenuItem groovyShell;
2255 public void doGroovyCheck()
2257 if (jalview.bin.Cache.groovyJarsPresent())
2259 groovyShell = new JMenuItem();
2260 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2261 groovyShell.addActionListener(new ActionListener()
2263 public void actionPerformed(ActionEvent e)
2265 groovyShell_actionPerformed(e);
2268 toolsMenu.add(groovyShell);
2269 groovyShell.setVisible(true);
2274 * Accessor method to quickly get all the AlignmentFrames loaded.
2276 * @return an array of AlignFrame, or null if none found
2278 public static AlignFrame[] getAlignFrames()
2280 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2286 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2288 for (int i = frames.length - 1; i > -1; i--)
2290 if (frames[i] instanceof AlignFrame)
2292 avp.add((AlignFrame) frames[i]);
2294 else if (frames[i] instanceof SplitFrame)
2297 * Also check for a split frame containing an AlignFrame
2299 SplitFrame sf = (SplitFrame) frames[i];
2300 if (sf.getTopComponent() instanceof AlignFrame)
2302 avp.add((AlignFrame) sf.getTopComponent());
2304 if (sf.getBottomComponent() instanceof AlignFrame)
2306 avp.add((AlignFrame) sf.getBottomComponent());
2310 if (avp.size() == 0)
2314 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2319 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2323 public AppJmol[] getJmols()
2325 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2331 List<AppJmol> avp = new ArrayList<AppJmol>();
2333 for (int i = frames.length - 1; i > -1; i--)
2335 if (frames[i] instanceof AppJmol)
2337 AppJmol af = (AppJmol) frames[i];
2341 if (avp.size() == 0)
2345 AppJmol afs[] = avp.toArray(new AppJmol[avp.size()]);
2350 * Add Groovy Support to Jalview
2352 public void groovyShell_actionPerformed(ActionEvent e)
2354 // use reflection to avoid creating compilation dependency.
2355 if (!jalview.bin.Cache.groovyJarsPresent())
2357 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2361 Class gcClass = Desktop.class.getClassLoader().loadClass(
2362 "groovy.ui.Console");
2363 Constructor gccons = gcClass.getConstructor(null);
2364 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2366 { String.class, Object.class });
2367 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2368 Object gc = gccons.newInstance(null);
2369 setvar.invoke(gc, new Object[]
2370 { "Jalview", this });
2371 run.invoke(gc, null);
2372 } catch (Exception ex)
2374 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2376 .showInternalMessageDialog(
2379 MessageManager.getString("label.couldnt_create_groovy_shell"),
2380 MessageManager.getString("label.groovy_support_failed"),
2381 JOptionPane.ERROR_MESSAGE);
2386 * Progress bars managed by the IProgressIndicator method.
2388 private Hashtable<Long, JPanel> progressBars;
2390 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2395 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2397 public void setProgressBar(String message, long id)
2399 if (progressBars == null)
2401 progressBars = new Hashtable<Long, JPanel>();
2402 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2405 if (progressBars.get(new Long(id)) != null)
2407 JPanel progressPanel = progressBars.remove(new Long(id));
2408 if (progressBarHandlers.contains(new Long(id)))
2410 progressBarHandlers.remove(new Long(id));
2412 removeProgressPanel(progressPanel);
2416 progressBars.put(new Long(id), addProgressPanel(message));
2423 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2424 * jalview.gui.IProgressIndicatorHandler)
2426 public void registerHandler(final long id,
2427 final IProgressIndicatorHandler handler)
2429 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2431 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2433 progressBarHandlers.put(new Long(id), handler);
2434 final JPanel progressPanel = progressBars.get(new Long(id));
2435 if (handler.canCancel())
2437 JButton cancel = new JButton(
2438 MessageManager.getString("action.cancel"));
2439 final IProgressIndicator us = this;
2440 cancel.addActionListener(new ActionListener()
2443 public void actionPerformed(ActionEvent e)
2445 handler.cancelActivity(id);
2446 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2449 progressPanel.add(cancel, BorderLayout.EAST);
2455 * @return true if any progress bars are still active
2458 public boolean operationInProgress()
2460 if (progressBars != null && progressBars.size() > 0)
2468 * This will return the first AlignFrame viewing AlignViewport av. It will
2469 * break if there are more than one AlignFrames viewing a particular av.
2472 * @return alignFrame for av
2474 public static AlignFrame getAlignFrameFor(AlignmentViewport av)
2476 if (desktop != null)
2478 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2479 for (int panel = 0; aps != null && panel < aps.length; panel++)
2481 if (aps[panel] != null && aps[panel].av == av)
2483 return aps[panel].alignFrame;
2490 public VamsasApplication getVamsasApplication()
2497 * flag set if jalview GUI is being operated programmatically
2499 private boolean inBatchMode = false;
2502 * check if jalview GUI is being operated programmatically
2504 * @return inBatchMode
2506 public boolean isInBatchMode()
2512 * set flag if jalview GUI is being operated programmatically
2514 * @param inBatchMode
2516 public void setInBatchMode(boolean inBatchMode)
2518 this.inBatchMode = inBatchMode;
2521 public void startServiceDiscovery()
2523 startServiceDiscovery(false);
2526 public void startServiceDiscovery(boolean blocking)
2528 boolean alive = true;
2529 Thread t0 = null, t1 = null, t2 = null;
2530 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2533 // todo: changesupport handlers need to be transferred
2534 if (discoverer == null)
2536 discoverer = new jalview.ws.jws1.Discoverer();
2537 // register PCS handler for desktop.
2538 discoverer.addPropertyChangeListener(changeSupport);
2540 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2541 // until we phase out completely
2542 (t0 = new Thread(discoverer)).start();
2545 // ENFIN services are EOLed as of Jalview 2.8.1 release
2550 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2552 // EnfinEnvision web service menu entries are rebuild every time the
2553 // menu is shown, so no changeSupport events are needed.
2554 jalview.ws.EnfinEnvision2OneWay.getInstance();
2555 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2558 } catch (Exception e)
2561 .info("Exception when trying to launch Envision2 workflow discovery.",
2563 Cache.log.info(e.getStackTrace());
2567 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2569 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2571 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2573 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2579 // TODO: do rest service discovery
2588 } catch (Exception e)
2591 alive = (t1 != null && t1.isAlive())
2592 || (t2 != null && t2.isAlive())
2593 || (t3 != null && t3.isAlive())
2594 || (t0 != null && t0.isAlive());
2600 * called to check if the service discovery process completed successfully.
2604 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2606 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2608 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2609 .getErrorMessages();
2612 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2614 if (serviceChangedDialog == null)
2616 // only run if we aren't already displaying one of these.
2617 addDialogThread(serviceChangedDialog = new Runnable()
2623 * JalviewDialog jd =new JalviewDialog() {
2625 * @Override protected void cancelPressed() { // TODO
2626 * Auto-generated method stub
2628 * }@Override protected void okPressed() { // TODO
2629 * Auto-generated method stub
2631 * }@Override protected void raiseClosed() { // TODO
2632 * Auto-generated method stub
2634 * } }; jd.initDialogFrame(new
2635 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2636 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2637 * + " or mis-configured HTTP proxy settings.<br/>" +
2638 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2640 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2641 * ), true, true, "Web Service Configuration Problem", 450,
2644 * jd.waitForInput();
2650 "<html><table width=\"450\"><tr><td>"
2652 + "</td></tr></table>"
2653 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2654 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2655 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2656 + " Tools->Preferences dialog box to change them.</p></html>"),
2657 "Web Service Configuration Problem",
2658 JOptionPane.DEFAULT_OPTION,
2659 JOptionPane.ERROR_MESSAGE);
2660 serviceChangedDialog = null;
2669 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2676 private Runnable serviceChangedDialog = null;
2679 * start a thread to open a URL in the configured browser. Pops up a warning
2680 * dialog to the user if there is an exception when calling out to the browser
2685 public static void showUrl(final String url)
2687 showUrl(url, Desktop.instance);
2691 * Like showUrl but allows progress handler to be specified
2695 * (null) or object implementing IProgressIndicator
2697 public static void showUrl(final String url,
2698 final IProgressIndicator progress)
2700 new Thread(new Runnable()
2706 if (progress != null)
2708 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2710 jalview.util.BrowserLauncher.openURL(url);
2711 } catch (Exception ex)
2714 .showInternalMessageDialog(
2716 MessageManager.getString("label.web_browser_not_found_unix"),
2717 MessageManager.getString("label.web_browser_not_found"),
2718 JOptionPane.WARNING_MESSAGE);
2720 ex.printStackTrace();
2722 if (progress != null)
2724 progress.setProgressBar(null, this.hashCode());
2730 public static WsParamSetManager wsparamManager = null;
2732 public static ParamManager getUserParameterStore()
2734 if (wsparamManager == null)
2736 wsparamManager = new WsParamSetManager();
2738 return wsparamManager;
2742 * static hyperlink handler proxy method for use by Jalview's internal windows
2746 public static void hyperlinkUpdate(HyperlinkEvent e)
2748 if (e.getEventType() == EventType.ACTIVATED)
2753 url = e.getURL().toString();
2754 Desktop.showUrl(url);
2755 } catch (Exception x)
2759 if (Cache.log != null)
2761 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2765 System.err.println("Couldn't handle string " + url
2769 // ignore any exceptions due to dud links.
2776 * single thread that handles display of dialogs to user.
2778 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2781 * flag indicating if dialogExecutor should try to acquire a permit
2783 private volatile boolean dialogPause = true;
2788 private java.util.concurrent.Semaphore block = new Semaphore(0);
2791 * add another dialog thread to the queue
2795 public void addDialogThread(final Runnable prompter)
2797 dialogExecutor.submit(new Runnable()
2806 } catch (InterruptedException x)
2811 if (instance == null)
2817 SwingUtilities.invokeAndWait(prompter);
2818 } catch (Exception q)
2820 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2826 public void startDialogQueue()
2828 // set the flag so we don't pause waiting for another permit and semaphore
2829 // the current task to begin
2830 dialogPause = false;
2834 protected void snapShotWindow_actionPerformed(ActionEvent e)
2838 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2839 "View of Desktop", getWidth(), getHeight(), of = new File(
2840 "Jalview_snapshot" + System.currentTimeMillis()
2841 + ".eps"), "View of desktop");
2843 paintAll(im.getGraphics());
2845 } catch (Exception q)
2847 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2850 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());