2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ 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.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.bin.Cache;
26 import jalview.bin.Jalview;
27 import jalview.io.FileLoader;
28 import jalview.io.FormatAdapter;
29 import jalview.io.IdentifyFile;
30 import jalview.io.JalviewFileChooser;
31 import jalview.io.JalviewFileView;
32 import jalview.jbgui.GSplitFrame;
33 import jalview.jbgui.GStructureViewer;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.util.ImageMaker;
36 import jalview.util.MessageManager;
37 import jalview.util.Platform;
38 import jalview.viewmodel.AlignmentViewport;
39 import jalview.ws.params.ParamManager;
41 import java.awt.BorderLayout;
42 import java.awt.Color;
43 import java.awt.Dimension;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.GridLayout;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.Toolkit;
50 import java.awt.Window;
51 import java.awt.datatransfer.Clipboard;
52 import java.awt.datatransfer.ClipboardOwner;
53 import java.awt.datatransfer.DataFlavor;
54 import java.awt.datatransfer.Transferable;
55 import java.awt.dnd.DnDConstants;
56 import java.awt.dnd.DropTargetDragEvent;
57 import java.awt.dnd.DropTargetDropEvent;
58 import java.awt.dnd.DropTargetEvent;
59 import java.awt.dnd.DropTargetListener;
60 import java.awt.event.ActionEvent;
61 import java.awt.event.ActionListener;
62 import java.awt.event.FocusEvent;
63 import java.awt.event.FocusListener;
64 import java.awt.event.KeyEvent;
65 import java.awt.event.MouseAdapter;
66 import java.awt.event.MouseEvent;
67 import java.awt.event.MouseListener;
68 import java.awt.event.WindowAdapter;
69 import java.awt.event.WindowEvent;
70 import java.beans.PropertyChangeEvent;
71 import java.beans.PropertyChangeListener;
72 import java.beans.PropertyVetoException;
73 import java.io.BufferedInputStream;
75 import java.io.FileOutputStream;
77 import java.util.ArrayList;
78 import java.util.Hashtable;
79 import java.util.List;
80 import java.util.StringTokenizer;
81 import java.util.Vector;
82 import java.util.concurrent.ExecutorService;
83 import java.util.concurrent.Executors;
84 import java.util.concurrent.Semaphore;
86 import javax.swing.AbstractAction;
87 import javax.swing.DefaultDesktopManager;
88 import javax.swing.DesktopManager;
89 import javax.swing.JButton;
90 import javax.swing.JComboBox;
91 import javax.swing.JComponent;
92 import javax.swing.JDesktopPane;
93 import javax.swing.JFrame;
94 import javax.swing.JInternalFrame;
95 import javax.swing.JLabel;
96 import javax.swing.JMenuItem;
97 import javax.swing.JOptionPane;
98 import javax.swing.JPanel;
99 import javax.swing.JPopupMenu;
100 import javax.swing.JProgressBar;
101 import javax.swing.KeyStroke;
102 import javax.swing.SwingUtilities;
103 import javax.swing.event.HyperlinkEvent;
104 import javax.swing.event.HyperlinkEvent.EventType;
105 import javax.swing.event.MenuEvent;
106 import javax.swing.event.MenuListener;
113 * @version $Revision: 1.155 $
115 public class Desktop extends jalview.jbgui.GDesktop implements
116 DropTargetListener, ClipboardOwner, IProgressIndicator,
117 jalview.api.StructureSelectionManagerProvider
120 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
123 * news reader - null if it was never started.
125 private BlogReader jvnews = null;
127 private File projectFile;
131 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
133 public void addJalviewPropertyChangeListener(
134 PropertyChangeListener listener)
136 changeSupport.addJalviewPropertyChangeListener(listener);
140 * @param propertyName
142 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
143 * java.beans.PropertyChangeListener)
145 public void addJalviewPropertyChangeListener(String propertyName,
146 PropertyChangeListener listener)
148 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
152 * @param propertyName
154 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
155 * java.beans.PropertyChangeListener)
157 public void removeJalviewPropertyChangeListener(String propertyName,
158 PropertyChangeListener listener)
160 changeSupport.removeJalviewPropertyChangeListener(propertyName,
164 /** Singleton Desktop instance */
165 public static Desktop instance;
167 public static MyDesktopPane desktop;
169 static int openFrameCount = 0;
171 static final int xOffset = 30;
173 static final int yOffset = 30;
175 public static jalview.ws.jws1.Discoverer discoverer;
177 public static Object[] jalviewClipboard;
179 public static boolean internalCopy = false;
181 static int fileLoadingCount = 0;
183 class MyDesktopManager implements DesktopManager
186 private DesktopManager delegate;
188 public MyDesktopManager(DesktopManager delegate)
190 this.delegate = delegate;
194 public void activateFrame(JInternalFrame f)
198 delegate.activateFrame(f);
199 } catch (NullPointerException npe)
201 Point p = getMousePosition();
202 instance.showPasteMenu(p.x, p.y);
207 public void beginDraggingFrame(JComponent f)
209 delegate.beginDraggingFrame(f);
213 public void beginResizingFrame(JComponent f, int direction)
215 delegate.beginResizingFrame(f, direction);
219 public void closeFrame(JInternalFrame f)
221 delegate.closeFrame(f);
225 public void deactivateFrame(JInternalFrame f)
227 delegate.deactivateFrame(f);
231 public void deiconifyFrame(JInternalFrame f)
233 delegate.deiconifyFrame(f);
237 public void dragFrame(JComponent f, int newX, int newY)
243 delegate.dragFrame(f, newX, newY);
247 public void endDraggingFrame(JComponent f)
249 delegate.endDraggingFrame(f);
253 public void endResizingFrame(JComponent f)
255 delegate.endResizingFrame(f);
259 public void iconifyFrame(JInternalFrame f)
261 delegate.iconifyFrame(f);
265 public void maximizeFrame(JInternalFrame f)
267 delegate.maximizeFrame(f);
271 public void minimizeFrame(JInternalFrame f)
273 delegate.minimizeFrame(f);
277 public void openFrame(JInternalFrame f)
279 delegate.openFrame(f);
283 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
290 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
294 public void setBoundsForFrame(JComponent f, int newX, int newY,
295 int newWidth, int newHeight)
297 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
300 // All other methods, simply delegate
305 * Creates a new Desktop object.
310 * A note to implementors. It is ESSENTIAL that any activities that might
311 * block are spawned off as threads rather than waited for during this
315 doVamsasClientCheck();
317 groovyShell = new JMenuItem();
318 groovyShell.setText(MessageManager.getString("label.groovy_console"));
319 groovyShell.addActionListener(new ActionListener()
322 public void actionPerformed(ActionEvent e)
324 groovyShell_actionPerformed();
327 toolsMenu.add(groovyShell);
328 groovyShell.setVisible(true);
330 doConfigureStructurePrefs();
331 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
332 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
333 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
335 boolean showjconsole = jalview.bin.Cache.getDefault(
336 "SHOW_JAVA_CONSOLE", false);
337 desktop = new MyDesktopPane(selmemusage);
338 if (Platform.isAMac())
340 desktop.setDoubleBuffered(false);
342 showMemusage.setSelected(selmemusage);
343 desktop.setBackground(Color.white);
344 getContentPane().setLayout(new BorderLayout());
345 // alternate config - have scrollbars - see notes in JAL-153
346 // JScrollPane sp = new JScrollPane();
347 // sp.getViewport().setView(desktop);
348 // getContentPane().add(sp, BorderLayout.CENTER);
349 getContentPane().add(desktop, BorderLayout.CENTER);
350 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
352 // This line prevents Windows Look&Feel resizing all new windows to maximum
353 // if previous window was maximised
354 desktop.setDesktopManager(new MyDesktopManager(
355 new DefaultDesktopManager()));
357 Rectangle dims = getLastKnownDimensions("");
364 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
365 setBounds((screenSize.width - 900) / 2,
366 (screenSize.height - 650) / 2, 900, 650);
368 jconsole = new Console(this, showjconsole);
369 // add essential build information
370 jconsole.setHeader("Jalview Version: "
371 + jalview.bin.Cache.getProperty("VERSION") + "\n"
372 + "Jalview Installation: "
373 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
374 + "\n" + "Build Date: "
375 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
376 + "Java version: " + System.getProperty("java.version") + "\n"
377 + System.getProperty("os.arch") + " "
378 + System.getProperty("os.name") + " "
379 + System.getProperty("os.version"));
381 showConsole(showjconsole);
383 showNews.setVisible(false);
385 this.addWindowListener(new WindowAdapter()
388 public void windowClosing(WindowEvent evt)
395 this.addMouseListener(ma = new MouseAdapter()
398 public void mousePressed(MouseEvent evt)
400 if (evt.isPopupTrigger())
402 showPasteMenu(evt.getX(), evt.getY());
406 desktop.addMouseListener(ma);
408 this.addFocusListener(new FocusListener()
412 public void focusLost(FocusEvent e)
414 // TODO Auto-generated method stub
419 public void focusGained(FocusEvent e)
421 Cache.log.debug("Relaying windows after focus gain");
422 // make sure that we sort windows properly after we gain focus
423 instance.relayerWindows();
426 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
427 // Spawn a thread that shows the splashscreen
428 SwingUtilities.invokeLater(new Runnable()
438 // Thread off a new instance of the file chooser - this reduces the time it
439 // takes to open it later on.
440 new Thread(new Runnable()
445 Cache.log.debug("Filechooser init thread started.");
446 new JalviewFileChooser(
447 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
448 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
449 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
450 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
451 Cache.log.debug("Filechooser init thread finished.");
454 // Add the service change listener
455 changeSupport.addJalviewPropertyChangeListener("services",
456 new PropertyChangeListener()
460 public void propertyChange(PropertyChangeEvent evt)
462 Cache.log.debug("Firing service changed event for "
463 + evt.getNewValue());
464 JalviewServicesChanged(evt);
470 public void doConfigureStructurePrefs()
472 // configure services
473 StructureSelectionManager ssm = StructureSelectionManager
474 .getStructureSelectionManager(this);
475 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
477 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
478 Preferences.ADD_TEMPFACT_ANN, true));
479 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
480 Preferences.STRUCT_FROM_PDB, true));
481 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
482 Preferences.USE_RNAVIEW, true));
486 ssm.setAddTempFacAnnot(false);
487 ssm.setProcessSecondaryStructure(false);
488 ssm.setSecStructServices(false);
492 public void checkForNews()
494 final Desktop me = this;
495 // Thread off the news reader, in case there are connection problems.
496 addDialogThread(new Runnable()
501 Cache.log.debug("Starting news thread.");
503 jvnews = new BlogReader(me);
504 showNews.setVisible(true);
505 Cache.log.debug("Completed news thread.");
511 protected void showNews_actionPerformed(ActionEvent e)
513 showNews(showNews.isSelected());
516 void showNews(boolean visible)
519 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
520 showNews.setSelected(visible);
521 if (visible && !jvnews.isVisible())
523 new Thread(new Runnable()
528 long now = System.currentTimeMillis();
529 Desktop.instance.setProgressBar(
530 MessageManager.getString("status.refreshing_news"), now);
531 jvnews.refreshNews();
532 Desktop.instance.setProgressBar(null, now);
541 * recover the last known dimensions for a jalview window
544 * - empty string is desktop, all other windows have unique prefix
545 * @return null or last known dimensions scaled to current geometry (if last
546 * window geom was known)
548 Rectangle getLastKnownDimensions(String windowName)
550 // TODO: lock aspect ratio for scaling desktop Bug #0058199
551 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
552 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
553 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
554 String width = jalview.bin.Cache.getProperty(windowName
556 String height = jalview.bin.Cache.getProperty(windowName
558 if ((x != null) && (y != null) && (width != null) && (height != null))
560 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
561 .parseInt(width), ih = Integer.parseInt(height);
562 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
564 // attempt #1 - try to cope with change in screen geometry - this
565 // version doesn't preserve original jv aspect ratio.
566 // take ratio of current screen size vs original screen size.
567 double sw = ((1f * screenSize.width) / (1f * Integer
568 .parseInt(jalview.bin.Cache
569 .getProperty("SCREENGEOMETRY_WIDTH"))));
570 double sh = ((1f * screenSize.height) / (1f * Integer
571 .parseInt(jalview.bin.Cache
572 .getProperty("SCREENGEOMETRY_HEIGHT"))));
573 // rescale the bounds depending upon the current screen geometry.
574 ix = (int) (ix * sw);
575 iw = (int) (iw * sw);
576 iy = (int) (iy * sh);
577 ih = (int) (ih * sh);
578 while (ix >= screenSize.width)
580 jalview.bin.Cache.log
581 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
582 ix -= screenSize.width;
584 while (iy >= screenSize.height)
586 jalview.bin.Cache.log
587 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
588 iy -= screenSize.height;
590 jalview.bin.Cache.log.debug("Got last known dimensions for "
591 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
594 // return dimensions for new instance
595 return new Rectangle(ix, iy, iw, ih);
600 private void doVamsasClientCheck()
602 if (jalview.bin.Cache.vamsasJarsPresent())
604 setupVamsasDisconnectedGui();
605 VamsasMenu.setVisible(true);
606 final Desktop us = this;
607 VamsasMenu.addMenuListener(new MenuListener()
609 // this listener remembers when the menu was first selected, and
610 // doesn't rebuild the session list until it has been cleared and
612 boolean refresh = true;
615 public void menuCanceled(MenuEvent e)
621 public void menuDeselected(MenuEvent e)
627 public void menuSelected(MenuEvent e)
631 us.buildVamsasStMenu();
636 vamsasStart.setVisible(true);
640 void showPasteMenu(int x, int y)
642 JPopupMenu popup = new JPopupMenu();
643 JMenuItem item = new JMenuItem(
644 MessageManager.getString("label.paste_new_window"));
645 item.addActionListener(new ActionListener()
648 public void actionPerformed(ActionEvent evt)
655 popup.show(this, x, y);
662 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
663 Transferable contents = c.getContents(this);
665 if (contents != null)
667 String file = (String) contents
668 .getTransferData(DataFlavor.stringFlavor);
670 String format = new IdentifyFile().identify(file,
671 FormatAdapter.PASTE);
673 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
676 } catch (Exception ex)
679 .println("Unable to paste alignment from system clipboard:\n"
685 * Adds and opens the given frame to the desktop
696 public static synchronized void addInternalFrame(
697 final JInternalFrame frame, String title, int w, int h)
699 addInternalFrame(frame, title, true, w, h, true);
703 * Add an internal frame to the Jalview desktop
710 * When true, display frame immediately, otherwise, caller must call
711 * setVisible themselves.
717 public static synchronized void addInternalFrame(
718 final JInternalFrame frame, String title, boolean makeVisible,
721 addInternalFrame(frame, title, makeVisible, w, h, true);
725 * Add an internal frame to the Jalview desktop and make it visible
738 public static synchronized void addInternalFrame(
739 final JInternalFrame frame, String title, int w, int h,
742 addInternalFrame(frame, title, true, w, h, resizable);
746 * Add an internal frame to the Jalview desktop
753 * When true, display frame immediately, otherwise, caller must call
754 * setVisible themselves.
762 public static synchronized void addInternalFrame(
763 final JInternalFrame frame, String title, boolean makeVisible,
764 int w, int h, boolean resizable)
767 // TODO: allow callers to determine X and Y position of frame (eg. via
769 // TODO: consider fixing method to update entries in the window submenu with
770 // the current window title
772 frame.setTitle(title);
773 if (frame.getWidth() < 1 || frame.getHeight() < 1)
777 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
778 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
779 // IF JALVIEW IS RUNNING HEADLESS
780 // ///////////////////////////////////////////////
782 || (System.getProperty("java.awt.headless") != null && System
783 .getProperty("java.awt.headless").equals("true")))
790 frame.setVisible(makeVisible);
791 frame.setClosable(true);
792 frame.setResizable(resizable);
793 frame.setMaximizable(resizable);
794 frame.setIconifiable(resizable);
795 if (Platform.isAMac())
797 frame.setIconifiable(false);
798 frame.setFrameIcon(null);
799 // frame.setDesktopIcon(null);
800 frame.setDoubleBuffered(false);
802 if (frame.getX() < 1 && frame.getY() < 1)
804 frame.setLocation(xOffset * openFrameCount, yOffset
805 * ((openFrameCount - 1) % 10) + yOffset);
808 final JMenuItem menuItem = new JMenuItem(title);
809 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
812 public void internalFrameActivated(
813 javax.swing.event.InternalFrameEvent evt)
815 JInternalFrame itf = desktop.getSelectedFrame();
824 public void internalFrameClosed(
825 javax.swing.event.InternalFrameEvent evt)
827 PaintRefresher.RemoveComponent(frame);
830 * defensive check to prevent frames being
831 * added half off the window
833 if (openFrameCount > 0)
837 windowMenu.remove(menuItem);
838 JInternalFrame itf = desktop.getSelectedFrame();
847 menuItem.addActionListener(new ActionListener()
850 public void actionPerformed(ActionEvent e)
854 frame.setSelected(true);
855 frame.setIcon(false);
856 } catch (java.beans.PropertyVetoException ex)
862 menuItem.addMouseListener(new MouseListener()
866 public void mouseReleased(MouseEvent e)
871 public void mousePressed(MouseEvent e)
876 public void mouseExited(MouseEvent e)
880 frame.setSelected(false);
881 } catch (PropertyVetoException e1)
887 public void mouseEntered(MouseEvent e)
891 frame.setSelected(true);
892 } catch (PropertyVetoException e1)
898 public void mouseClicked(MouseEvent e)
904 windowMenu.add(menuItem);
910 frame.setSelected(true);
911 frame.requestFocus();
912 } catch (java.beans.PropertyVetoException ve)
914 } catch (java.lang.ClassCastException cex)
917 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
923 public void lostOwnership(Clipboard clipboard, Transferable contents)
927 Desktop.jalviewClipboard = null;
930 internalCopy = false;
934 public void dragEnter(DropTargetDragEvent evt)
939 public void dragExit(DropTargetEvent evt)
944 public void dragOver(DropTargetDragEvent evt)
949 public void dropActionChanged(DropTargetDragEvent evt)
960 public void drop(DropTargetDropEvent evt)
962 boolean success = true;
963 Transferable t = evt.getTransferable();
964 java.util.List<String> files = new ArrayList<String>();
965 java.util.List<String> protocols = new ArrayList<String>();
969 Desktop.transferFromDropTarget(files, protocols, evt, t);
970 } catch (Exception e)
980 for (int i = 0; i < files.size(); i++)
982 String file = files.get(i).toString();
983 String protocol = (protocols == null) ? FormatAdapter.FILE
984 : (String) protocols.get(i);
985 String format = null;
987 if (file.endsWith(".jar"))
994 format = new IdentifyFile().identify(file, protocol);
997 new FileLoader().LoadFile(file, protocol, format);
1000 } catch (Exception ex)
1005 evt.dropComplete(success); // need this to ensure input focus is properly
1006 // transfered to any new windows created
1016 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1018 JalviewFileChooser chooser = new JalviewFileChooser(
1019 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1020 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1021 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1022 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1024 chooser.setFileView(new JalviewFileView());
1025 chooser.setDialogTitle(MessageManager
1026 .getString("label.open_local_file"));
1027 chooser.setToolTipText(MessageManager.getString("action.open"));
1029 int value = chooser.showOpenDialog(this);
1031 if (value == JalviewFileChooser.APPROVE_OPTION)
1033 String choice = chooser.getSelectedFile().getPath();
1034 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1035 .getSelectedFile().getParent());
1037 String format = null;
1038 if (chooser.getSelectedFormat() != null
1039 && chooser.getSelectedFormat().equals("Jalview"))
1045 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1048 if (viewport != null)
1050 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1055 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1067 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1069 // This construct allows us to have a wider textfield
1071 JLabel label = new JLabel(
1072 MessageManager.getString("label.input_file_url"));
1073 final JComboBox history = new JComboBox();
1075 JPanel panel = new JPanel(new GridLayout(2, 1));
1078 history.setPreferredSize(new Dimension(400, 20));
1079 history.setEditable(true);
1080 history.addItem("http://www.");
1082 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1086 if (historyItems != null)
1088 st = new StringTokenizer(historyItems, "\t");
1090 while (st.hasMoreTokens())
1092 history.addItem(st.nextElement());
1096 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1097 MessageManager.getString("label.input_alignment_from_url"),
1098 JOptionPane.OK_CANCEL_OPTION);
1100 if (reply != JOptionPane.OK_OPTION)
1105 String url = history.getSelectedItem().toString();
1107 if (url.toLowerCase().endsWith(".jar"))
1109 if (viewport != null)
1111 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1116 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1121 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1123 if (format.equals("URL NOT FOUND"))
1125 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1126 MessageManager.formatMessage("label.couldnt_locate",
1127 new Object[] { url }), MessageManager
1128 .getString("label.url_not_found"),
1129 JOptionPane.WARNING_MESSAGE);
1134 if (viewport != null)
1136 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1140 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1146 * Opens the CutAndPaste window for the user to paste an alignment in to
1149 * - if not null, the pasted alignment is added to the current
1150 * alignment; if null, to a new alignment window
1153 public void inputTextboxMenuItem_actionPerformed(
1154 AlignmentViewPanel viewPanel)
1156 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1157 cap.setForInput(viewPanel);
1158 Desktop.addInternalFrame(cap,
1159 MessageManager.getString("label.cut_paste_alignmen_file"),
1169 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1171 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1172 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1174 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1175 getBounds().y, getWidth(), getHeight()));
1177 if (jconsole != null)
1179 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1180 jconsole.stopConsole();
1184 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1187 if (dialogExecutor != null)
1189 dialogExecutor.shutdownNow();
1191 closeAll_actionPerformed(null);
1193 if (groovyConsole != null)
1195 // suppress a possible repeat prompt to save script
1196 groovyConsole.setDirty(false);
1197 groovyConsole.exit();
1202 private void storeLastKnownDimensions(String string, Rectangle jc)
1204 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1205 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1206 + " height:" + jc.height);
1208 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1209 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1210 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1211 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1221 public void aboutMenuItem_actionPerformed(ActionEvent e)
1223 // StringBuffer message = getAboutMessage(false);
1224 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1226 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1227 new Thread(new Runnable()
1232 new SplashScreen(true);
1237 public StringBuffer getAboutMessage(boolean shortv)
1239 StringBuffer message = new StringBuffer();
1240 message.append("<html>");
1243 message.append("<h1><strong>Version: "
1244 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1245 message.append("<strong>Last Updated: <em>"
1246 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1247 + "</em></strong>");
1253 message.append("<strong>Version "
1254 + jalview.bin.Cache.getProperty("VERSION")
1255 + "; last updated: "
1256 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1259 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1262 message.append("<br>...Checking latest version...</br>");
1264 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1265 .equals(jalview.bin.Cache.getProperty("VERSION")))
1267 boolean red = false;
1268 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1269 .indexOf("automated build") == -1)
1272 // Displayed when code version and jnlp version do not match and code
1273 // version is not a development build
1274 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1277 message.append("<br>!! Version "
1278 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1280 + " is available for download from "
1281 + jalview.bin.Cache.getDefault("www.jalview.org",
1282 "http://www.jalview.org") + " !!");
1285 message.append("</div>");
1288 message.append("<br>Authors: "
1290 .getDefault("AUTHORFNAMES",
1291 "The Jalview Authors (See AUTHORS file for current list)")
1292 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1293 + "<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"
1294 + "<br><br>If you use Jalview, please cite:"
1295 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1296 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1297 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1309 public void documentationMenuItem_actionPerformed(ActionEvent e)
1313 Help.showHelpWindow();
1314 } catch (Exception ex)
1320 public void closeAll_actionPerformed(ActionEvent e)
1322 JInternalFrame[] frames = desktop.getAllFrames();
1323 for (int i = 0; i < frames.length; i++)
1327 frames[i].setClosed(true);
1328 } catch (java.beans.PropertyVetoException ex)
1332 System.out.println("ALL CLOSED");
1333 if (v_client != null)
1335 // TODO clear binding to vamsas document objects on close_all
1339 * reset state of singleton objects as appropriate (clear down session state
1340 * when all windows are closed)
1342 StructureSelectionManager ssm = StructureSelectionManager
1343 .getStructureSelectionManager(this);
1351 public void raiseRelated_actionPerformed(ActionEvent e)
1353 reorderAssociatedWindows(false, false);
1357 public void minimizeAssociated_actionPerformed(ActionEvent e)
1359 reorderAssociatedWindows(true, false);
1362 void closeAssociatedWindows()
1364 reorderAssociatedWindows(false, true);
1370 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1374 protected void garbageCollect_actionPerformed(ActionEvent e)
1376 // We simply collect the garbage
1377 jalview.bin.Cache.log.debug("Collecting garbage...");
1379 jalview.bin.Cache.log.debug("Finished garbage collection.");
1386 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1390 protected void showMemusage_actionPerformed(ActionEvent e)
1392 desktop.showMemoryUsage(showMemusage.isSelected());
1399 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1403 protected void showConsole_actionPerformed(ActionEvent e)
1405 showConsole(showConsole.isSelected());
1408 Console jconsole = null;
1411 * control whether the java console is visible or not
1415 void showConsole(boolean selected)
1417 showConsole.setSelected(selected);
1418 // TODO: decide if we should update properties file
1419 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1421 jconsole.setVisible(selected);
1424 void reorderAssociatedWindows(boolean minimize, boolean close)
1426 JInternalFrame[] frames = desktop.getAllFrames();
1427 if (frames == null || frames.length < 1)
1432 AlignmentViewport source = null, target = null;
1433 if (frames[0] instanceof AlignFrame)
1435 source = ((AlignFrame) frames[0]).getCurrentView();
1437 else if (frames[0] instanceof TreePanel)
1439 source = ((TreePanel) frames[0]).getViewPort();
1441 else if (frames[0] instanceof PCAPanel)
1443 source = ((PCAPanel) frames[0]).av;
1445 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1447 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1452 for (int i = 0; i < frames.length; i++)
1455 if (frames[i] == null)
1459 if (frames[i] instanceof AlignFrame)
1461 target = ((AlignFrame) frames[i]).getCurrentView();
1463 else if (frames[i] instanceof TreePanel)
1465 target = ((TreePanel) frames[i]).getViewPort();
1467 else if (frames[i] instanceof PCAPanel)
1469 target = ((PCAPanel) frames[i]).av;
1471 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1473 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1476 if (source == target)
1482 frames[i].setClosed(true);
1486 frames[i].setIcon(minimize);
1489 frames[i].toFront();
1493 } catch (java.beans.PropertyVetoException ex)
1508 protected void preferences_actionPerformed(ActionEvent e)
1520 public void saveState_actionPerformed(ActionEvent e)
1522 JalviewFileChooser chooser = new JalviewFileChooser(
1523 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1524 new String[] { "jvp" }, new String[] { "Jalview Project" },
1527 chooser.setFileView(new JalviewFileView());
1528 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1530 int value = chooser.showSaveDialog(this);
1532 if (value == JalviewFileChooser.APPROVE_OPTION)
1534 final Desktop me = this;
1535 final java.io.File choice = chooser.getSelectedFile();
1536 setProjectFile(choice);
1538 new Thread(new Runnable()
1543 // TODO: refactor to Jalview desktop session controller action.
1544 setProgressBar(MessageManager.formatMessage(
1545 "label.saving_jalview_project",
1546 new Object[] { choice.getName() }), choice.hashCode());
1547 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1548 choice.getParent());
1549 // TODO catch and handle errors for savestate
1550 // TODO prevent user from messing with the Desktop whilst we're saving
1553 new Jalview2XML().saveState(choice);
1554 } catch (OutOfMemoryError oom)
1556 new OOMWarning("Whilst saving current state to "
1557 + choice.getName(), oom);
1558 } catch (Exception ex)
1561 "Problems whilst trying to save to " + choice.getName(),
1563 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1564 "label.error_whilst_saving_current_state_to",
1565 new Object[] { choice.getName() }), MessageManager
1566 .getString("label.couldnt_save_project"),
1567 JOptionPane.WARNING_MESSAGE);
1569 setProgressBar(null, choice.hashCode());
1575 private void setProjectFile(File choice)
1577 this.projectFile = choice;
1580 public File getProjectFile()
1582 return this.projectFile;
1592 public void loadState_actionPerformed(ActionEvent e)
1594 JalviewFileChooser chooser = new JalviewFileChooser(
1595 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1596 "jvp", "jar" }, new String[] { "Jalview Project",
1597 "Jalview Project (old)" }, "Jalview Project");
1598 chooser.setFileView(new JalviewFileView());
1599 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1601 int value = chooser.showOpenDialog(this);
1603 if (value == JalviewFileChooser.APPROVE_OPTION)
1605 final File selectedFile = chooser.getSelectedFile();
1606 setProjectFile(selectedFile);
1607 final String choice = selectedFile.getAbsolutePath();
1608 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1609 selectedFile.getParent());
1610 new Thread(new Runnable()
1616 MessageManager.formatMessage(
1617 "label.loading_jalview_project",
1618 new Object[] { choice }), choice.hashCode());
1621 new Jalview2XML().loadJalviewAlign(choice);
1622 } catch (OutOfMemoryError oom)
1624 new OOMWarning("Whilst loading project from " + choice, oom);
1625 } catch (Exception ex)
1627 Cache.log.error("Problems whilst loading project from "
1629 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1631 "label.error_whilst_loading_project_from",
1632 new Object[] { choice }), MessageManager
1633 .getString("label.couldnt_load_project"),
1634 JOptionPane.WARNING_MESSAGE);
1636 setProgressBar(null, choice.hashCode());
1643 public void inputSequence_actionPerformed(ActionEvent e)
1645 new SequenceFetcher(this);
1648 JPanel progressPanel;
1650 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1652 public void startLoading(final String fileName)
1654 if (fileLoadingCount == 0)
1656 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1657 "label.loading_file", new Object[] { fileName })));
1662 private JPanel addProgressPanel(String string)
1664 if (progressPanel == null)
1666 progressPanel = new JPanel(new GridLayout(1, 1));
1667 totalProgressCount = 0;
1668 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1670 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1671 JProgressBar progressBar = new JProgressBar();
1672 progressBar.setIndeterminate(true);
1674 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1676 thisprogress.add(progressBar, BorderLayout.CENTER);
1677 progressPanel.add(thisprogress);
1678 ((GridLayout) progressPanel.getLayout())
1679 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1680 ++totalProgressCount;
1681 instance.validate();
1682 return thisprogress;
1685 int totalProgressCount = 0;
1687 private void removeProgressPanel(JPanel progbar)
1689 if (progressPanel != null)
1691 synchronized (progressPanel)
1693 progressPanel.remove(progbar);
1694 GridLayout gl = (GridLayout) progressPanel.getLayout();
1695 gl.setRows(gl.getRows() - 1);
1696 if (--totalProgressCount < 1)
1698 this.getContentPane().remove(progressPanel);
1699 progressPanel = null;
1706 public void stopLoading()
1709 if (fileLoadingCount < 1)
1711 while (fileLoadingPanels.size() > 0)
1713 removeProgressPanel(fileLoadingPanels.remove(0));
1715 fileLoadingPanels.clear();
1716 fileLoadingCount = 0;
1721 public static int getViewCount(String alignmentId)
1723 AlignmentViewport[] aps = getViewports(alignmentId);
1724 return (aps == null) ? 0 : aps.length;
1729 * @param alignmentId
1730 * - if null, all sets are returned
1731 * @return all AlignmentPanels concerning the alignmentId sequence set
1733 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1735 if (Desktop.desktop == null)
1737 // no frames created and in headless mode
1738 // TODO: verify that frames are recoverable when in headless mode
1741 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1742 AlignFrame[] frames = getAlignFrames();
1747 for (AlignFrame af : frames)
1749 for (AlignmentPanel ap : af.alignPanels)
1751 if (alignmentId == null
1752 || alignmentId.equals(ap.av.getSequenceSetId()))
1758 if (aps.size() == 0)
1762 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1767 * get all the viewports on an alignment.
1769 * @param sequenceSetId
1770 * unique alignment id (may be null - all viewports returned in that
1772 * @return all viewports on the alignment bound to sequenceSetId
1774 public static AlignmentViewport[] getViewports(String sequenceSetId)
1776 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1777 if (desktop != null)
1779 AlignFrame[] frames = Desktop.getAlignFrames();
1781 for (AlignFrame afr : frames)
1783 if (sequenceSetId == null
1784 || afr.getViewport().getSequenceSetId()
1785 .equals(sequenceSetId))
1787 if (afr.alignPanels != null)
1789 for (AlignmentPanel ap : afr.alignPanels)
1791 if (sequenceSetId == null
1792 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1800 viewp.add(afr.getViewport());
1804 if (viewp.size() > 0)
1806 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1813 * Explode the views in the given frame into separate AlignFrame
1817 public static void explodeViews(AlignFrame af)
1819 int size = af.alignPanels.size();
1825 for (int i = 0; i < size; i++)
1827 AlignmentPanel ap = af.alignPanels.get(i);
1828 AlignFrame newaf = new AlignFrame(ap);
1831 * Restore the view's last exploded frame geometry if known. Multiple
1832 * views from one exploded frame share and restore the same (frame)
1833 * position and size.
1835 Rectangle geometry = ap.av.getExplodedGeometry();
1836 if (geometry != null)
1838 newaf.setBounds(geometry);
1841 ap.av.setGatherViewsHere(false);
1843 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1844 AlignFrame.DEFAULT_HEIGHT);
1847 af.alignPanels.clear();
1848 af.closeMenuItem_actionPerformed(true);
1853 * Gather expanded views (separate AlignFrame's) with the same sequence set
1854 * identifier back in to this frame as additional views, and close the
1855 * expanded views. Note the expanded frames may themselves have multiple
1856 * views. We take the lot.
1860 public void gatherViews(AlignFrame source)
1862 source.viewport.setGatherViewsHere(true);
1863 source.viewport.setExplodedGeometry(source.getBounds());
1864 JInternalFrame[] frames = desktop.getAllFrames();
1865 String viewId = source.viewport.getSequenceSetId();
1867 for (int t = 0; t < frames.length; t++)
1869 if (frames[t] instanceof AlignFrame && frames[t] != source)
1871 AlignFrame af = (AlignFrame) frames[t];
1872 boolean gatherThis = false;
1873 for (int a = 0; a < af.alignPanels.size(); a++)
1875 AlignmentPanel ap = af.alignPanels.get(a);
1876 if (viewId.equals(ap.av.getSequenceSetId()))
1879 ap.av.setGatherViewsHere(false);
1880 ap.av.setExplodedGeometry(af.getBounds());
1881 source.addAlignmentPanel(ap, false);
1887 af.alignPanels.clear();
1888 af.closeMenuItem_actionPerformed(true);
1895 jalview.gui.VamsasApplication v_client = null;
1898 public void vamsasImport_actionPerformed(ActionEvent e)
1900 if (v_client == null)
1902 // Load and try to start a session.
1903 JalviewFileChooser chooser = new JalviewFileChooser(
1904 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1906 chooser.setFileView(new JalviewFileView());
1907 chooser.setDialogTitle(MessageManager
1908 .getString("label.open_saved_vamsas_session"));
1909 chooser.setToolTipText(MessageManager
1910 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1912 int value = chooser.showOpenDialog(this);
1914 if (value == JalviewFileChooser.APPROVE_OPTION)
1916 String fle = chooser.getSelectedFile().toString();
1917 if (!vamsasImport(chooser.getSelectedFile()))
1920 .showInternalMessageDialog(
1922 MessageManager.formatMessage(
1923 "label.couldnt_import_as_vamsas_session",
1924 new Object[] { fle }),
1926 .getString("label.vamsas_document_import_failed"),
1927 JOptionPane.ERROR_MESSAGE);
1933 jalview.bin.Cache.log
1934 .error("Implementation error - load session from a running session is not supported.");
1939 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1942 * @return true if import was a success and a session was started.
1944 public boolean vamsasImport(URL url)
1946 // TODO: create progress bar
1947 if (v_client != null)
1950 jalview.bin.Cache.log
1951 .error("Implementation error - load session from a running session is not supported.");
1957 // copy the URL content to a temporary local file
1958 // TODO: be a bit cleverer here with nio (?!)
1959 File file = File.createTempFile("vdocfromurl", ".vdj");
1960 FileOutputStream fos = new FileOutputStream(file);
1961 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1962 byte[] buffer = new byte[2048];
1964 while ((ln = bis.read(buffer)) > -1)
1966 fos.write(buffer, 0, ln);
1970 v_client = new jalview.gui.VamsasApplication(this, file,
1971 url.toExternalForm());
1972 } catch (Exception ex)
1974 jalview.bin.Cache.log.error(
1975 "Failed to create new vamsas session from contents of URL "
1979 setupVamsasConnectedGui();
1980 v_client.initial_update(); // TODO: thread ?
1981 return v_client.inSession();
1985 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1988 * @return true if import was a success and a session was started.
1990 public boolean vamsasImport(File file)
1992 if (v_client != null)
1995 jalview.bin.Cache.log
1996 .error("Implementation error - load session from a running session is not supported.");
2000 setProgressBar(MessageManager.formatMessage(
2001 "status.importing_vamsas_session_from",
2002 new Object[] { file.getName() }), file.hashCode());
2005 v_client = new jalview.gui.VamsasApplication(this, file, null);
2006 } catch (Exception ex)
2008 setProgressBar(MessageManager.formatMessage(
2009 "status.importing_vamsas_session_from",
2010 new Object[] { file.getName() }), file.hashCode());
2011 jalview.bin.Cache.log.error(
2012 "New vamsas session from existing session file failed:", ex);
2015 setupVamsasConnectedGui();
2016 v_client.initial_update(); // TODO: thread ?
2017 setProgressBar(MessageManager.formatMessage(
2018 "status.importing_vamsas_session_from",
2019 new Object[] { file.getName() }), file.hashCode());
2020 return v_client.inSession();
2023 public boolean joinVamsasSession(String mysesid)
2025 if (v_client != null)
2029 .getString("error.try_join_vamsas_session_another"));
2031 if (mysesid == null)
2034 MessageManager.getString("error.invalid_vamsas_session_id"));
2036 v_client = new VamsasApplication(this, mysesid);
2037 setupVamsasConnectedGui();
2038 v_client.initial_update();
2039 return (v_client.inSession());
2043 public void vamsasStart_actionPerformed(ActionEvent e)
2045 if (v_client == null)
2048 // we just start a default session for moment.
2050 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2051 * getProperty("LAST_DIRECTORY"));
2053 * chooser.setFileView(new JalviewFileView());
2054 * chooser.setDialogTitle("Load Vamsas file");
2055 * chooser.setToolTipText("Import");
2057 * int value = chooser.showOpenDialog(this);
2059 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2060 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2062 v_client = new VamsasApplication(this);
2063 setupVamsasConnectedGui();
2064 v_client.initial_update(); // TODO: thread ?
2068 // store current data in session.
2069 v_client.push_update(); // TODO: thread
2073 protected void setupVamsasConnectedGui()
2075 vamsasStart.setText(MessageManager.getString("label.session_update"));
2076 vamsasSave.setVisible(true);
2077 vamsasStop.setVisible(true);
2078 vamsasImport.setVisible(false); // Document import to existing session is
2079 // not possible for vamsas-client-1.0.
2082 protected void setupVamsasDisconnectedGui()
2084 vamsasSave.setVisible(false);
2085 vamsasStop.setVisible(false);
2086 vamsasImport.setVisible(true);
2087 vamsasStart.setText(MessageManager
2088 .getString("label.new_vamsas_session"));
2092 public void vamsasStop_actionPerformed(ActionEvent e)
2094 if (v_client != null)
2096 v_client.end_session();
2098 setupVamsasDisconnectedGui();
2102 protected void buildVamsasStMenu()
2104 if (v_client == null)
2106 String[] sess = null;
2109 sess = VamsasApplication.getSessionList();
2110 } catch (Exception e)
2112 jalview.bin.Cache.log.warn(
2113 "Problem getting current sessions list.", e);
2118 jalview.bin.Cache.log.debug("Got current sessions list: "
2119 + sess.length + " entries.");
2120 VamsasStMenu.removeAll();
2121 for (int i = 0; i < sess.length; i++)
2123 JMenuItem sessit = new JMenuItem();
2124 sessit.setText(sess[i]);
2125 sessit.setToolTipText(MessageManager.formatMessage(
2126 "label.connect_to_session", new Object[] { sess[i] }));
2127 final Desktop dsktp = this;
2128 final String mysesid = sess[i];
2129 sessit.addActionListener(new ActionListener()
2133 public void actionPerformed(ActionEvent e)
2135 if (dsktp.v_client == null)
2137 Thread rthr = new Thread(new Runnable()
2143 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2144 dsktp.setupVamsasConnectedGui();
2145 dsktp.v_client.initial_update();
2153 VamsasStMenu.add(sessit);
2155 // don't show an empty menu.
2156 VamsasStMenu.setVisible(sess.length > 0);
2161 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2162 VamsasStMenu.removeAll();
2163 VamsasStMenu.setVisible(false);
2168 // Not interested in the content. Just hide ourselves.
2169 VamsasStMenu.setVisible(false);
2174 public void vamsasSave_actionPerformed(ActionEvent e)
2176 if (v_client != null)
2178 JalviewFileChooser chooser = new JalviewFileChooser(
2179 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2180 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2181 new String[] { "Vamsas Document" }, "Vamsas Document");
2183 chooser.setFileView(new JalviewFileView());
2184 chooser.setDialogTitle(MessageManager
2185 .getString("label.save_vamsas_document_archive"));
2187 int value = chooser.showSaveDialog(this);
2189 if (value == JalviewFileChooser.APPROVE_OPTION)
2191 java.io.File choice = chooser.getSelectedFile();
2192 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2193 "label.saving_vamsas_doc",
2194 new Object[] { choice.getName() }));
2195 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2196 String warnmsg = null;
2197 String warnttl = null;
2200 v_client.vclient.storeDocument(choice);
2203 warnttl = "Serious Problem saving Vamsas Document";
2204 warnmsg = ex.toString();
2205 jalview.bin.Cache.log.error("Error Whilst saving document to "
2208 } catch (Exception ex)
2210 warnttl = "Problem saving Vamsas Document.";
2211 warnmsg = ex.toString();
2212 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2216 removeProgressPanel(progpanel);
2217 if (warnmsg != null)
2219 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2221 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2227 JPanel vamUpdate = null;
2230 * hide vamsas user gui bits when a vamsas document event is being handled.
2233 * true to hide gui, false to reveal gui
2235 public void setVamsasUpdate(boolean b)
2237 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2238 + (b ? "in progress" : "finished"));
2240 if (vamUpdate != null)
2242 this.removeProgressPanel(vamUpdate);
2246 vamUpdate = this.addProgressPanel(MessageManager
2247 .getString("label.updating_vamsas_session"));
2249 vamsasStart.setVisible(!b);
2250 vamsasStop.setVisible(!b);
2251 vamsasSave.setVisible(!b);
2254 public JInternalFrame[] getAllFrames()
2256 return desktop.getAllFrames();
2260 * Checks the given url to see if it gives a response indicating that the user
2261 * should be informed of a new questionnaire.
2265 public void checkForQuestionnaire(String url)
2267 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2268 // javax.swing.SwingUtilities.invokeLater(jvq);
2269 new Thread(jvq).start();
2273 * Proxy class for JDesktopPane which optionally displays the current memory
2274 * usage and highlights the desktop area with a red bar if free memory runs
2279 public class MyDesktopPane extends JDesktopPane implements Runnable
2282 private static final float ONE_MB = 1048576f;
2284 boolean showMemoryUsage = false;
2288 java.text.NumberFormat df;
2290 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2293 public MyDesktopPane(boolean showMemoryUsage)
2295 showMemoryUsage(showMemoryUsage);
2298 public void showMemoryUsage(boolean showMemory)
2300 this.showMemoryUsage = showMemory;
2303 Thread worker = new Thread(this);
2308 public boolean isShowMemoryUsage()
2310 return showMemoryUsage;
2316 df = java.text.NumberFormat.getNumberInstance();
2317 df.setMaximumFractionDigits(2);
2318 runtime = Runtime.getRuntime();
2320 while (showMemoryUsage)
2324 maxMemory = runtime.maxMemory() / ONE_MB;
2325 allocatedMemory = runtime.totalMemory() / ONE_MB;
2326 freeMemory = runtime.freeMemory() / ONE_MB;
2327 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2329 percentUsage = (totalFreeMemory / maxMemory) * 100;
2331 // if (percentUsage < 20)
2333 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2335 // instance.set.setBorder(border1);
2338 // sleep after showing usage
2340 } catch (Exception ex)
2342 ex.printStackTrace();
2348 public void paintComponent(Graphics g)
2350 if (showMemoryUsage && g != null && df != null)
2352 if (percentUsage < 20)
2354 g.setColor(Color.red);
2356 FontMetrics fm = g.getFontMetrics();
2359 g.drawString(MessageManager.formatMessage(
2360 "label.memory_stats",
2361 new Object[] { df.format(totalFreeMemory),
2362 df.format(maxMemory), df.format(percentUsage) }), 10,
2363 getHeight() - fm.getHeight());
2370 * fixes stacking order after a modal dialog to ensure windows that should be
2371 * on top actually are
2373 public void relayerWindows()
2378 protected JMenuItem groovyShell;
2381 * Accessor method to quickly get all the AlignmentFrames loaded.
2383 * @return an array of AlignFrame, or null if none found
2385 public static AlignFrame[] getAlignFrames()
2387 if (Jalview.isHeadlessMode())
2389 // Desktop.desktop is null in headless mode
2390 return new AlignFrame[] { Jalview.currentAlignFrame };
2393 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2399 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2401 for (int i = frames.length - 1; i > -1; i--)
2403 if (frames[i] instanceof AlignFrame)
2405 avp.add((AlignFrame) frames[i]);
2407 else if (frames[i] instanceof SplitFrame)
2410 * Also check for a split frame containing an AlignFrame
2412 GSplitFrame sf = (GSplitFrame) frames[i];
2413 if (sf.getTopFrame() instanceof AlignFrame)
2415 avp.add((AlignFrame) sf.getTopFrame());
2417 if (sf.getBottomFrame() instanceof AlignFrame)
2419 avp.add((AlignFrame) sf.getBottomFrame());
2423 if (avp.size() == 0)
2427 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2432 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2436 public GStructureViewer[] getJmols()
2438 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2444 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2446 for (int i = frames.length - 1; i > -1; i--)
2448 if (frames[i] instanceof AppJmol)
2450 GStructureViewer af = (GStructureViewer) frames[i];
2454 if (avp.size() == 0)
2458 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2463 * Add Groovy Support to Jalview
2465 public void groovyShell_actionPerformed()
2469 openGroovyConsole();
2470 } catch (Exception ex)
2472 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2473 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2475 MessageManager.getString("label.couldnt_create_groovy_shell"),
2476 MessageManager.getString("label.groovy_support_failed"),
2477 JOptionPane.ERROR_MESSAGE);
2482 * Open the Groovy console
2484 void openGroovyConsole()
2486 if (groovyConsole == null)
2488 groovyConsole = new groovy.ui.Console();
2489 groovyConsole.setVariable("Jalview", this);
2490 groovyConsole.run();
2493 * We allow only one console at a time, so that AlignFrame menu option
2494 * 'Calculate | Run Groovy script' is unambiguous.
2495 * Disable 'Groovy Console', and enable 'Run script', when the console is
2496 * opened, and the reverse when it is closed
2498 Window window = (Window) groovyConsole.getFrame();
2499 window.addWindowListener(new WindowAdapter()
2502 public void windowClosed(WindowEvent e)
2505 * rebind CMD-Q from Groovy Console to Jalview Quit
2508 enableExecuteGroovy(false);
2514 * show Groovy console window (after close and reopen)
2516 ((Window) groovyConsole.getFrame()).setVisible(true);
2519 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2520 * and disable opening a second console
2522 enableExecuteGroovy(true);
2526 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2527 * binding when opened
2529 protected void addQuitHandler()
2531 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2532 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2533 .getDefaultToolkit().getMenuShortcutKeyMask()),
2535 getRootPane().getActionMap().put("Quit", new AbstractAction()
2538 public void actionPerformed(ActionEvent e)
2546 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2549 * true if Groovy console is open
2551 public void enableExecuteGroovy(boolean enabled)
2554 * disable opening a second Groovy console
2555 * (or re-enable when the console is closed)
2557 groovyShell.setEnabled(!enabled);
2559 AlignFrame[] alignFrames = getAlignFrames();
2560 if (alignFrames != null)
2562 for (AlignFrame af : alignFrames)
2564 af.setGroovyEnabled(enabled);
2570 * Progress bars managed by the IProgressIndicator method.
2572 private Hashtable<Long, JPanel> progressBars;
2574 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2579 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2582 public void setProgressBar(String message, long id)
2584 if (progressBars == null)
2586 progressBars = new Hashtable<Long, JPanel>();
2587 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2590 if (progressBars.get(new Long(id)) != null)
2592 JPanel panel = progressBars.remove(new Long(id));
2593 if (progressBarHandlers.contains(new Long(id)))
2595 progressBarHandlers.remove(new Long(id));
2597 removeProgressPanel(panel);
2601 progressBars.put(new Long(id), addProgressPanel(message));
2608 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2609 * jalview.gui.IProgressIndicatorHandler)
2612 public void registerHandler(final long id,
2613 final IProgressIndicatorHandler handler)
2615 if (progressBarHandlers == null
2616 || !progressBars.containsKey(new Long(id)))
2620 .getString("error.call_setprogressbar_before_registering_handler"));
2622 progressBarHandlers.put(new Long(id), handler);
2623 final JPanel progressPanel = progressBars.get(new Long(id));
2624 if (handler.canCancel())
2626 JButton cancel = new JButton(
2627 MessageManager.getString("action.cancel"));
2628 final IProgressIndicator us = this;
2629 cancel.addActionListener(new ActionListener()
2633 public void actionPerformed(ActionEvent e)
2635 handler.cancelActivity(id);
2636 us.setProgressBar(MessageManager.formatMessage(
2637 "label.cancelled_params",
2638 new Object[] { ((JLabel) progressPanel.getComponent(0))
2642 progressPanel.add(cancel, BorderLayout.EAST);
2648 * @return true if any progress bars are still active
2651 public boolean operationInProgress()
2653 if (progressBars != null && progressBars.size() > 0)
2661 * This will return the first AlignFrame holding the given viewport instance.
2662 * It will break if there are more than one AlignFrames viewing a particular
2666 * @return alignFrame for viewport
2668 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2670 if (desktop != null)
2672 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2673 for (int panel = 0; aps != null && panel < aps.length; panel++)
2675 if (aps[panel] != null && aps[panel].av == viewport)
2677 return aps[panel].alignFrame;
2684 public VamsasApplication getVamsasApplication()
2691 * flag set if jalview GUI is being operated programmatically
2693 private boolean inBatchMode = false;
2696 * check if jalview GUI is being operated programmatically
2698 * @return inBatchMode
2700 public boolean isInBatchMode()
2706 * set flag if jalview GUI is being operated programmatically
2708 * @param inBatchMode
2710 public void setInBatchMode(boolean inBatchMode)
2712 this.inBatchMode = inBatchMode;
2715 public void startServiceDiscovery()
2717 startServiceDiscovery(false);
2720 public void startServiceDiscovery(boolean blocking)
2722 boolean alive = true;
2723 Thread t0 = null, t1 = null, t2 = null;
2724 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2727 // todo: changesupport handlers need to be transferred
2728 if (discoverer == null)
2730 discoverer = new jalview.ws.jws1.Discoverer();
2731 // register PCS handler for desktop.
2732 discoverer.addPropertyChangeListener(changeSupport);
2734 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2735 // until we phase out completely
2736 (t0 = new Thread(discoverer)).start();
2739 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2741 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2743 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2745 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2751 // TODO: do rest service discovery
2760 } catch (Exception e)
2763 alive = (t1 != null && t1.isAlive())
2764 || (t2 != null && t2.isAlive())
2765 || (t3 != null && t3.isAlive())
2766 || (t0 != null && t0.isAlive());
2772 * called to check if the service discovery process completed successfully.
2776 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2778 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2780 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2781 .getErrorMessages();
2784 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2786 if (serviceChangedDialog == null)
2788 // only run if we aren't already displaying one of these.
2789 addDialogThread(serviceChangedDialog = new Runnable()
2796 * JalviewDialog jd =new JalviewDialog() {
2798 * @Override protected void cancelPressed() { // TODO
2799 * Auto-generated method stub
2801 * }@Override protected void okPressed() { // TODO
2802 * Auto-generated method stub
2804 * }@Override protected void raiseClosed() { // TODO
2805 * Auto-generated method stub
2807 * } }; jd.initDialogFrame(new
2808 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2809 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2810 * + " or mis-configured HTTP proxy settings.<br/>" +
2811 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2813 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2814 * ), true, true, "Web Service Configuration Problem", 450,
2817 * jd.waitForInput();
2823 "<html><table width=\"450\"><tr><td>"
2825 + "</td></tr></table>"
2826 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2827 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2828 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2829 + " Tools->Preferences dialog box to change them.</p></html>"),
2830 "Web Service Configuration Problem",
2831 JOptionPane.DEFAULT_OPTION,
2832 JOptionPane.ERROR_MESSAGE);
2833 serviceChangedDialog = null;
2842 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2849 private Runnable serviceChangedDialog = null;
2852 * start a thread to open a URL in the configured browser. Pops up a warning
2853 * dialog to the user if there is an exception when calling out to the browser
2858 public static void showUrl(final String url)
2860 showUrl(url, Desktop.instance);
2864 * Like showUrl but allows progress handler to be specified
2868 * (null) or object implementing IProgressIndicator
2870 public static void showUrl(final String url,
2871 final IProgressIndicator progress)
2873 new Thread(new Runnable()
2880 if (progress != null)
2882 progress.setProgressBar(MessageManager.formatMessage(
2883 "status.opening_params", new Object[] { url }), this
2886 jalview.util.BrowserLauncher.openURL(url);
2887 } catch (Exception ex)
2889 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2891 .getString("label.web_browser_not_found_unix"),
2892 MessageManager.getString("label.web_browser_not_found"),
2893 JOptionPane.WARNING_MESSAGE);
2895 ex.printStackTrace();
2897 if (progress != null)
2899 progress.setProgressBar(null, this.hashCode());
2905 public static WsParamSetManager wsparamManager = null;
2907 public static ParamManager getUserParameterStore()
2909 if (wsparamManager == null)
2911 wsparamManager = new WsParamSetManager();
2913 return wsparamManager;
2917 * static hyperlink handler proxy method for use by Jalview's internal windows
2921 public static void hyperlinkUpdate(HyperlinkEvent e)
2923 if (e.getEventType() == EventType.ACTIVATED)
2928 url = e.getURL().toString();
2929 Desktop.showUrl(url);
2930 } catch (Exception x)
2934 if (Cache.log != null)
2936 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2940 System.err.println("Couldn't handle string " + url
2944 // ignore any exceptions due to dud links.
2951 * single thread that handles display of dialogs to user.
2953 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2956 * flag indicating if dialogExecutor should try to acquire a permit
2958 private volatile boolean dialogPause = true;
2963 private java.util.concurrent.Semaphore block = new Semaphore(0);
2965 private static groovy.ui.Console groovyConsole;
2968 * add another dialog thread to the queue
2972 public void addDialogThread(final Runnable prompter)
2974 dialogExecutor.submit(new Runnable()
2984 } catch (InterruptedException x)
2989 if (instance == null)
2995 SwingUtilities.invokeAndWait(prompter);
2996 } catch (Exception q)
2998 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3004 public void startDialogQueue()
3006 // set the flag so we don't pause waiting for another permit and semaphore
3007 // the current task to begin
3008 dialogPause = false;
3013 protected void snapShotWindow_actionPerformed(ActionEvent e)
3017 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3018 "View of Desktop", getWidth(), getHeight(), of = new File(
3019 "Jalview_snapshot" + System.currentTimeMillis()
3020 + ".eps"), "View of desktop", null, 0, false);
3023 paintAll(im.getGraphics());
3025 } catch (Exception q)
3027 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3031 Cache.log.info("Successfully written snapshot to file "
3032 + of.getAbsolutePath());
3036 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3037 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3038 * and location last time the view was expanded (if any). However it does not
3039 * remember the split pane divider location - this is set to match the
3040 * 'exploding' frame.
3044 public void explodeViews(SplitFrame sf)
3046 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3047 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3048 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3050 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3052 int viewCount = topPanels.size();
3059 * Processing in reverse order works, forwards order leaves the first panels
3060 * not visible. I don't know why!
3062 for (int i = viewCount - 1; i >= 0; i--)
3065 * Make new top and bottom frames. These take over the respective
3066 * AlignmentPanel objects, including their AlignmentViewports, so the
3067 * cdna/protein relationships between the viewports is carried over to the
3070 * explodedGeometry holds the (x, y) position of the previously exploded
3071 * SplitFrame, and the (width, height) of the AlignFrame component
3073 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3074 AlignFrame newTopFrame = new AlignFrame(topPanel);
3075 newTopFrame.setSize(oldTopFrame.getSize());
3076 newTopFrame.setVisible(true);
3077 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3078 .getExplodedGeometry();
3079 if (geometry != null)
3081 newTopFrame.setSize(geometry.getSize());
3084 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3085 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3086 newBottomFrame.setSize(oldBottomFrame.getSize());
3087 newBottomFrame.setVisible(true);
3088 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3089 .getExplodedGeometry();
3090 if (geometry != null)
3092 newBottomFrame.setSize(geometry.getSize());
3095 topPanel.av.setGatherViewsHere(false);
3096 bottomPanel.av.setGatherViewsHere(false);
3097 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3099 if (geometry != null)
3101 splitFrame.setLocation(geometry.getLocation());
3103 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3107 * Clear references to the panels (now relocated in the new SplitFrames)
3108 * before closing the old SplitFrame.
3111 bottomPanels.clear();
3116 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3117 * back into the given SplitFrame as additional views. Note that the gathered
3118 * frames may themselves have multiple views.
3122 public void gatherViews(GSplitFrame source)
3125 * special handling of explodedGeometry for a view within a SplitFrame: - it
3126 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3127 * height) of the AlignFrame component
3129 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3130 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3131 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3132 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3133 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3134 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3136 myTopFrame.viewport.setGatherViewsHere(true);
3137 myBottomFrame.viewport.setGatherViewsHere(true);
3138 String topViewId = myTopFrame.viewport.getSequenceSetId();
3139 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3141 JInternalFrame[] frames = desktop.getAllFrames();
3142 for (JInternalFrame frame : frames)
3144 if (frame instanceof SplitFrame && frame != source)
3146 SplitFrame sf = (SplitFrame) frame;
3147 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3148 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3149 boolean gatherThis = false;
3150 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3152 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3153 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3154 if (topViewId.equals(topPanel.av.getSequenceSetId())
3155 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3158 topPanel.av.setGatherViewsHere(false);
3159 bottomPanel.av.setGatherViewsHere(false);
3160 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3161 topFrame.getSize()));
3162 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3163 .getLocation(), bottomFrame.getSize()));
3164 myTopFrame.addAlignmentPanel(topPanel, false);
3165 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3171 topFrame.getAlignPanels().clear();
3172 bottomFrame.getAlignPanels().clear();
3179 * The dust settles...give focus to the tab we did this from.
3181 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3184 public static groovy.ui.Console getGroovyConsole()
3186 return groovyConsole;
3189 public static void transferFromDropTarget(List<String> files,
3190 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3194 DataFlavor uriListFlavor = new DataFlavor(
3195 "text/uri-list;class=java.lang.String");
3196 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3198 // Works on Windows and MacOSX
3199 Cache.log.debug("Drop handled as javaFileListFlavor");
3200 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3201 for (Object file : (List) t
3202 .getTransferData(DataFlavor.javaFileListFlavor))
3204 files.add(((File)file).toString());
3205 protocols.add(FormatAdapter.FILE);
3210 // Unix like behaviour
3211 boolean added = false;
3213 if (t.isDataFlavorSupported(uriListFlavor))
3215 Cache.log.debug("Drop handled as uriListFlavor");
3216 // This is used by Unix drag system
3217 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3218 data = (String) t.getTransferData(uriListFlavor);
3222 // fallback to text: workaround - on OSX where there's a JVM bug
3223 Cache.log.debug("standard URIListFlavor failed. Trying text");
3224 // try text fallback
3225 data = (String) t.getTransferData(new DataFlavor(
3226 "text/plain;class=java.lang.String"));
3227 if (Cache.log.isDebugEnabled())
3229 Cache.log.debug("fallback returned " + data);
3232 while (protocols.size() < files.size())
3234 Cache.log.debug("Adding missing FILE protocol for "
3235 + files.get(protocols.size()));
3236 protocols.add(FormatAdapter.FILE);
3238 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3239 data, "\r\n"); st.hasMoreTokens();)
3242 String s = st.nextToken();
3243 if (s.startsWith("#"))
3245 // the line is a comment (as per the RFC 2483)
3248 java.net.URI uri = new java.net.URI(s);
3249 if (uri.getScheme().toLowerCase().startsWith("http"))
3251 protocols.add(FormatAdapter.URL);
3252 files.add(uri.toString());
3256 // otherwise preserve old behaviour: catch all for file objects
3257 java.io.File file = new java.io.File(uri);
3258 protocols.add(FormatAdapter.FILE);
3259 files.add(file.toString());
3262 if (Cache.log.isDebugEnabled())
3264 if (data == null || !added)
3267 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3268 for (DataFlavor fl : t.getTransferDataFlavors())
3270 Cache.log.debug("Supported transfer dataflavor: "
3272 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3273 Object df = t.getTransferData(fl);
3276 Cache.log.debug("Retrieves: " + df);
3280 Cache.log.debug("Retrieved nothing");