/* * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ package jalview.gui; import java.util.*; import java.awt.*; import javax.swing.*; import javax.swing.event.*; import java.awt.event.*; import java.io.*; import jalview.jbgui.GStructureViewer; import jalview.api.AlignmentViewPanel; import jalview.api.SequenceStructureBinding; import jalview.bin.Cache; import jalview.datamodel.*; import jalview.gui.ViewSelectionMenu.ViewSetProvider; import jalview.structure.*; import jalview.datamodel.PDBEntry; import jalview.io.*; import jalview.schemes.*; public class AppJmol extends GStructureViewer implements Runnable, SequenceStructureBinding, ViewSetProvider { AppJmolBinding jmb; JPanel scriptWindow; JSplitPane splitPane; RenderPanel renderPanel; AlignmentPanel ap; Vector atomsPicked = new Vector(); private boolean addingStructures = false; /** * * @param file * @param id * @param seq * @param ap * @param loadStatus * @param bounds * @deprecated defaults to AppJmol(String[] files, ... , viewid); */ public AppJmol(String file, String id, SequenceI[] seq, AlignmentPanel ap, String loadStatus, Rectangle bounds) { this(file, id, seq, ap, loadStatus, bounds, null); } /** * @deprecated */ public AppJmol(String file, String id, SequenceI[] seq, AlignmentPanel ap, String loadStatus, Rectangle bounds, String viewid) { this(new String[] { file }, new String[] { id }, new SequenceI[][] { seq }, ap, true, true, false, loadStatus, bounds, viewid); } ViewSelectionMenu seqColourBy; /** * * @param files * @param ids * @param seqs * @param ap * @param usetoColour * - add the alignment panel to the list used for colouring these * structures * @param useToAlign * - add the alignment panel to the list used for aligning these * structures * @param leaveColouringToJmol * - do not update the colours from any other source. Jmol is handling them * @param loadStatus * @param bounds * @param viewid */ public AppJmol(String[] files, String[] ids, SequenceI[][] seqs, AlignmentPanel ap, boolean usetoColour, boolean useToAlign, boolean leaveColouringToJmol, String loadStatus, Rectangle bounds, String viewid) { PDBEntry[] pdbentrys = new PDBEntry[files.length]; for (int i = 0; i < pdbentrys.length; i++) { PDBEntry pdbentry = new PDBEntry(); pdbentry.setFile(files[i]); pdbentry.setId(ids[i]); pdbentrys[i] = pdbentry; } // / TODO: check if protocol is needed to be set, and if chains are // autodiscovered. jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(), pdbentrys, seqs, null, null); jmb.setLoadingFromArchive(true); addAlignmentPanel(ap); if (useToAlign) { useAlignmentPanelForSuperposition(ap); } if (leaveColouringToJmol || !usetoColour) { jmb.setColourBySequence(false); seqColour.setSelected(false); jmolColour.setSelected(true); } if (usetoColour) { useAlignmentPanelForColourbyseq(ap); jmb.setColourBySequence(true); seqColour.setSelected(true); jmolColour.setSelected(false); } this.setBounds(bounds); initMenus(); viewId = viewid; // jalview.gui.Desktop.addInternalFrame(this, "Loading File", // bounds.width,bounds.height); this.addInternalFrameListener(new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent internalFrameEvent) { closeViewer(); } }); initJmol(loadStatus); // pdbentry, seq, JBPCHECK! } private void initMenus() { seqColour.setSelected(jmb.isColourBySequence()); jmolColour.setSelected(!jmb.isColourBySequence()); if (_colourwith==null) { _colourwith=new Vector(); } if (_alignwith==null) { _alignwith=new Vector(); } seqColourBy = new ViewSelectionMenu("Colour by ..", this, _colourwith, new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (!seqColour.isSelected()) { seqColour.doClick(); } else { // update the jmol display now. seqColour_actionPerformed(null); } } }); viewMenu.add(seqColourBy); final ItemListener handler; JMenu alpanels = new ViewSelectionMenu("Superpose with ..", this, _alignwith, handler = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { alignStructs.setEnabled(_alignwith.size() > 0); alignStructs.setToolTipText("Align structures using " + _alignwith.size() + " linked alignment views"); } }); handler.itemStateChanged(null); jmolActionMenu.add(alpanels); jmolActionMenu.addMenuListener(new MenuListener() { @Override public void menuSelected(MenuEvent e) { handler.itemStateChanged(null); } @Override public void menuDeselected(MenuEvent e) { // TODO Auto-generated method stub } @Override public void menuCanceled(MenuEvent e) { // TODO Auto-generated method stub } }); } IProgressIndicator progressBar = null; /** * add a single PDB structure to a new or existing Jmol view * @param pdbentry * @param seq * @param chains * @param ap */ public AppJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains, final AlignmentPanel ap) { progressBar = ap.alignFrame; // //////////////////////////////// // Is the pdb file already loaded? String alreadyMapped = ap.getStructureSelectionManager().alreadyMappedToFile( pdbentry.getId()); if (alreadyMapped != null) { int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop, pdbentry.getId() + " is already displayed." + "\nDo you want to re-use this viewer ?", "Map Sequences to Visible Window: " + pdbentry.getId(), JOptionPane.YES_NO_OPTION); if (option == JOptionPane.YES_OPTION) { // TODO : Fix multiple seq to one chain issue here. ap.getStructureSelectionManager().setMapping(seq, chains, alreadyMapped, AppletFormatAdapter.FILE); if (ap.seqPanel.seqCanvas.fr != null) { ap.seqPanel.seqCanvas.fr.featuresAdded(); ap.paintAlignment(true); } // Now this AppJmol is mapped to new sequences. We must add them to // the exisiting array JInternalFrame[] frames = Desktop.instance.getAllFrames(); for (int i = 0; i < frames.length; i++) { if (frames[i] instanceof AppJmol) { final AppJmol topJmol = ((AppJmol) frames[i]); // JBPNOTE: this looks like a binding routine, rather than a gui // routine for (int pe = 0; pe < topJmol.jmb.pdbentry.length; pe++) { if (topJmol.jmb.pdbentry[pe].getFile().equals(alreadyMapped)) { topJmol.jmb.addSequence(pe, seq); topJmol.addAlignmentPanel(ap); // add it to the set used for colouring topJmol.useAlignmentPanelForColourbyseq(ap); topJmol.buildJmolActionMenu(); ap.getStructureSelectionManager().sequenceColoursChanged(ap); break; } } } } return; } } // ///////////////////////////////// // Check if there are other Jmol views involving this alignment // and prompt user about adding this molecule to one of them Vector existingViews = getJmolsFor(ap); if (existingViews.size() > 0) { Enumeration jm = existingViews.elements(); while (jm.hasMoreElements()) { AppJmol topJmol = (AppJmol) jm.nextElement(); // TODO: highlight topJmol in view somehow int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Do you want to add " + pdbentry.getId() + " to the view called\n'" + topJmol.getTitle() + "'\n", "Align to existing structure view", JOptionPane.YES_NO_OPTION); if (option == JOptionPane.YES_OPTION) { topJmol.useAlignmentPanelForSuperposition(ap); topJmol.addStructure(pdbentry, seq, chains, true, ap.alignFrame); return; } } } // ///////////////////////////////// openNewJmol(ap, new PDBEntry[] { pdbentry }, new SequenceI[][] { seq }); } private void openNewJmol(AlignmentPanel ap, PDBEntry[] pdbentrys, SequenceI[][] seqs) { boolean promptUser=pdbentrys.length==1; progressBar = ap.alignFrame; jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(), pdbentrys, seqs, null, null); addAlignmentPanel(ap); useAlignmentPanelForColourbyseq(ap); if (pdbentrys.length>1) { alignAddedStructures=true; useAlignmentPanelForSuperposition(ap); } jmb.setColourBySequence(true); setSize(400, 400); // probably should be a configurable/dynamic default here initMenus(); worker=null; String filelist=""; // for (PDBEntry pe: pdbentrys) // { // if (pe.getFile()==null) { addingStructures = false; worker = new Thread(this); worker.start(); // break; } // filelist+=" \""+pe.getFile()+"\""; /* } if (worker==null) { initJmol("load"+(pdbentrys.length>1 ? " APPEND" : "") + filelist); } */ this.addInternalFrameListener(new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent internalFrameEvent) { closeViewer(); } }); } /** * create a new Jmol containing several structures superimposed using the given alignPanel. * @param ap * @param pe * @param seqs */ public AppJmol(AlignmentPanel ap, PDBEntry[] pe, SequenceI[][] seqs) { openNewJmol(ap, pe, seqs); } /** * list of sequenceSet ids associated with the view */ ArrayList _aps = new ArrayList(); public AlignmentPanel[] getAllAlignmentPanels() { AlignmentPanel[] t, list = new AlignmentPanel[0]; for (String setid : _aps) { AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(setid); if (panels != null) { t = new AlignmentPanel[list.length + panels.length]; System.arraycopy(list, 0, t, 0, list.length); System.arraycopy(panels, 0, t, list.length, panels.length); list = t; } } return list; } /** * list of alignment panels to use for superposition */ Vector _alignwith = new Vector(); /** * list of alignment panels that are used for colouring structures by aligned * sequences */ Vector _colourwith = new Vector(); /** * set the primary alignmentPanel reference and add another alignPanel to the * list of ones to use for colouring and aligning * * @param nap */ public void addAlignmentPanel(AlignmentPanel nap) { if (ap == null) { ap = nap; } if (!_aps.contains(nap.av.getSequenceSetId())) { _aps.add(nap.av.getSequenceSetId()); } } /** * remove any references held to the given alignment panel * * @param nap */ public void removeAlignmentPanel(AlignmentPanel nap) { try { _alignwith.remove(nap); _colourwith.remove(nap); if (ap == nap) { ap = null; for (AlignmentPanel aps : getAllAlignmentPanels()) { if (aps != nap) { ap = aps; break; } } } } catch (Exception ex) { } if (ap != null) { buildJmolActionMenu(); } } public void useAlignmentPanelForSuperposition(AlignmentPanel nap) { addAlignmentPanel(nap); if (!_alignwith.contains(nap)) { _alignwith.add(nap); } } public void excludeAlignmentPanelForSuperposition(AlignmentPanel nap) { if (_alignwith.contains(nap)) { _alignwith.remove(nap); } } public void useAlignmentPanelForColourbyseq(AlignmentPanel nap, boolean enableColourBySeq) { useAlignmentPanelForColourbyseq(nap); jmb.setColourBySequence(enableColourBySeq); seqColour.setSelected(enableColourBySeq); jmolColour.setSelected(!enableColourBySeq); } public void useAlignmentPanelForColourbyseq(AlignmentPanel nap) { addAlignmentPanel(nap); if (!_colourwith.contains(nap)) { _colourwith.add(nap); } } public void excludeAlignmentPanelForColourbyseq(AlignmentPanel nap) { if (_colourwith.contains(nap)) { _colourwith.remove(nap); } } /** * pdb retrieval thread. */ private Thread worker = null; /** * add a new structure (with associated sequences and chains) to this viewer, * retrieving it if necessary first. * * @param pdbentry * @param seq * @param chains * @param alignFrame * @param align * if true, new structure(s) will be align using associated alignment */ private void addStructure(final PDBEntry pdbentry, final SequenceI[] seq, final String[] chains, final boolean b, final IProgressIndicator alignFrame) { if (pdbentry.getFile() == null) { if (worker != null && worker.isAlive()) { // a retrieval is in progress, wait around and add ourselves to the // queue. new Thread(new Runnable() { public void run() { while (worker != null && worker.isAlive() && _started) { try { Thread.sleep(100 + ((int) Math.random() * 100)); } catch (Exception e) { } } // and call ourselves again. addStructure(pdbentry, seq, chains, b, alignFrame); } }).start(); return; } } // otherwise, start adding the structure. jmb.addSequenceAndChain(new PDBEntry[] { pdbentry }, new SequenceI[][] { seq }, new String[][] { chains }); addingStructures = true; _started = false; alignAddedStructures = b; progressBar = alignFrame; // visual indication happens on caller frame. (worker = new Thread(this)).start(); return; } private Vector getJmolsFor(AlignmentPanel ap2) { Vector otherJmols = new Vector(); // Now this AppJmol is mapped to new sequences. We must add them to // the exisiting array JInternalFrame[] frames = Desktop.instance.getAllFrames(); for (int i = 0; i < frames.length; i++) { if (frames[i] instanceof AppJmol) { AppJmol topJmol = ((AppJmol) frames[i]); if (topJmol.isLinkedWith(ap2)) { otherJmols.addElement(topJmol); } } } return otherJmols; } void initJmol(String command) { jmb.setFinishedInit(false); renderPanel = new RenderPanel(); // TODO: consider waiting until the structure/view is fully loaded before // displaying this.getContentPane().add(renderPanel, java.awt.BorderLayout.CENTER); jalview.gui.Desktop.addInternalFrame(this, jmb.getViewerTitle(), getBounds().width, getBounds().height); if (scriptWindow == null) { BorderLayout bl = new BorderLayout(); bl.setHgap(0); bl.setVgap(0); scriptWindow = new JPanel(bl); scriptWindow.setVisible(false); } ; jmb.allocateViewer(renderPanel, true, "", null, null, "", scriptWindow, null); jmb.newJmolPopup(true, "Jmol", true); if (command==null) { command=""; } jmb.evalStateCommand(command); jmb.setFinishedInit(true); } void setChainMenuItems(Vector chains) { chainMenu.removeAll(); if (chains == null) { return; } JMenuItem menuItem = new JMenuItem("All"); menuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { allChainsSelected = true; for (int i = 0; i < chainMenu.getItemCount(); i++) { if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem) ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true); } centerViewer(); allChainsSelected = false; } }); chainMenu.add(menuItem); for (int c = 0; c < chains.size(); c++) { menuItem = new JCheckBoxMenuItem(chains.elementAt(c).toString(), true); menuItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent evt) { if (!allChainsSelected) centerViewer(); } }); chainMenu.add(menuItem); } } boolean allChainsSelected = false; private boolean alignAddedStructures = false; void centerViewer() { Vector toshow = new Vector(); String lbl; int mlength, p, mnum; for (int i = 0; i < chainMenu.getItemCount(); i++) { if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem) { JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i); if (item.isSelected()) { toshow.addElement(item.getText()); } } } jmb.centerViewer(toshow); } void closeViewer() { jmb.closeViewer(); ap = null; _aps.clear(); _alignwith.clear(); _colourwith.clear(); // TODO: check for memory leaks where instance isn't finalised because jmb // holds a reference to the window jmb = null; } /** * state flag for PDB retrieval thread */ private boolean _started = false; public void run() { _started = true; String pdbid = ""; // todo - record which pdbids were successfuly imported. StringBuffer errormsgs = new StringBuffer(), files = new StringBuffer(); try { String[] curfiles = jmb.getPdbFile(); // files currently in viewer // TODO: replace with reference fetching/transfer code (validate PDBentry // as a DBRef?) jalview.ws.dbsources.Pdb pdbclient = new jalview.ws.dbsources.Pdb(); for (int pi = 0; pi < jmb.pdbentry.length; pi++) { String file = jmb.pdbentry[pi].getFile(); if (file == null) { // retrieve the pdb and store it locally AlignmentI pdbseq = null; pdbid = jmb.pdbentry[pi].getId(); long hdl = pdbid.hashCode() - System.currentTimeMillis(); if (progressBar != null) { progressBar.setProgressBar("Fetching PDB " + pdbid, hdl); } try { pdbseq = pdbclient.getSequenceRecords(pdbid = jmb.pdbentry[pi] .getId()); } catch (OutOfMemoryError oomerror) { new OOMWarning("Retrieving PDB id " + pdbid, oomerror); } catch (Exception ex) { ex.printStackTrace(); errormsgs.append("'" + pdbid + "'"); } if (progressBar != null) { progressBar.setProgressBar("Finished.", hdl); } if (pdbseq != null) { // just transfer the file name from the first sequence's first // PDBEntry jmb.pdbentry[pi].setFile(file = ((PDBEntry) pdbseq .getSequenceAt(0).getPDBId().elementAt(0)).getFile()); files.append(" \"" + file + "\""); } else { errormsgs.append("'" + pdbid + "' "); } } else { if (curfiles != null && curfiles.length > 0) { addingStructures = true; // already files loaded. for (int c = 0; c < curfiles.length; c++) { if (curfiles[c].equals(file)) { file = null; break; } } } if (file != null) { files.append(" \"" + file + "\""); } } } } catch (OutOfMemoryError oomerror) { new OOMWarning("Retrieving PDB files: " + pdbid, oomerror); } catch (Exception ex) { ex.printStackTrace(); errormsgs.append("When retrieving pdbfiles : current was: '" + pdbid + "'"); } if (errormsgs.length() > 0) { JOptionPane.showInternalMessageDialog(Desktop.desktop, "The following pdb entries could not be retrieved from the PDB:\n" + errormsgs.toString() + "\nPlease try downloading them manually.", "Couldn't load file", JOptionPane.ERROR_MESSAGE); } long lastnotify = jmb.getLoadNotifiesHandled(); if (files.length() > 0) { if (!addingStructures) { try { initJmol("load FILES " + files.toString()); } catch (OutOfMemoryError oomerror) { new OOMWarning("When trying to open the Jmol viewer!", oomerror); Cache.log.debug("File locations are " + files); } catch (Exception ex) { Cache.log.error("Couldn't open Jmol viewer!", ex); } } else { StringBuffer cmd = new StringBuffer(); cmd.append("loadingJalviewdata=true\nload APPEND "); cmd.append(files.toString()); cmd.append("\nloadingJalviewdata=null"); final String command = cmd.toString(); cmd = null; lastnotify = jmb.getLoadNotifiesHandled(); try { jmb.evalStateCommand(command); } catch (OutOfMemoryError oomerror) { new OOMWarning( "When trying to add structures to the Jmol viewer!", oomerror); Cache.log.debug("File locations are " + files); } catch (Exception ex) { Cache.log.error("Couldn't add files to Jmol viewer!", ex); } } // need to wait around until script has finished while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled() : (jmb.isFinishedInit() && jmb.getPdbFile().length!=jmb.pdbentry.length)) { try { Cache.log.debug("Waiting around for jmb notify."); Thread.sleep(35); } catch (Exception e) { } } // refresh the sequence colours for the new structure(s) for (AlignmentPanel ap : _colourwith) { jmb.updateColours(ap); } // do superposition if asked to if (alignAddedStructures) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { alignStructs_withAllAlignPanels(); // jmb.superposeStructures(ap.av.getAlignment(), -1, null); } }); alignAddedStructures = false; } addingStructures = false; } _started = false; worker = null; } public void pdbFile_actionPerformed(ActionEvent actionEvent) { JalviewFileChooser chooser = new JalviewFileChooser( jalview.bin.Cache.getProperty("LAST_DIRECTORY")); chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle("Save PDB File"); chooser.setToolTipText("Save"); int value = chooser.showSaveDialog(this); if (value == JalviewFileChooser.APPROVE_OPTION) { try { // TODO: cope with multiple PDB files in view BufferedReader in = new BufferedReader(new FileReader( jmb.getPdbFile()[0])); File outFile = chooser.getSelectedFile(); PrintWriter out = new PrintWriter(new FileOutputStream(outFile)); String data; while ((data = in.readLine()) != null) { if (!(data.indexOf("
") > -1 || data.indexOf("
") > -1)) { out.println(data); } } out.close(); } catch (Exception ex) { ex.printStackTrace(); } } } public void viewMapping_actionPerformed(ActionEvent actionEvent) { jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer(); try { for (int pdbe = 0; pdbe < jmb.pdbentry.length; pdbe++) { cap.appendText(jmb.printMapping( jmb.pdbentry[pdbe].getFile())); cap.appendText("\n"); } } catch (OutOfMemoryError e) { new OOMWarning( "composing sequence-structure alignments for display in text box.", e); cap.dispose(); return; } jalview.gui.Desktop.addInternalFrame(cap, "PDB - Sequence Mapping", 550, 600); } /** * DOCUMENT ME! * * @param e * DOCUMENT ME! */ public void eps_actionPerformed(ActionEvent e) { makePDBImage(jalview.util.ImageMaker.EPS); } /** * DOCUMENT ME! * * @param e * DOCUMENT ME! */ public void png_actionPerformed(ActionEvent e) { makePDBImage(jalview.util.ImageMaker.PNG); } void makePDBImage(int type) { int width = getWidth(); int height = getHeight(); jalview.util.ImageMaker im; if (type == jalview.util.ImageMaker.PNG) { im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.PNG, "Make PNG image from view", width, height, null, null); } else { im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.EPS, "Make EPS file from view", width, height, null, this.getTitle()); } if (im.getGraphics() != null) { Rectangle rect = new Rectangle(width, height); jmb.viewer.renderScreenImage(im.getGraphics(), rect.getSize(), rect); im.writeImage(); } } public void jmolColour_actionPerformed(ActionEvent actionEvent) { if (jmolColour.isSelected()) { // disable automatic sequence colouring. jmb.setColourBySequence(false); } } public void seqColour_actionPerformed(ActionEvent actionEvent) { jmb.setColourBySequence(seqColour.isSelected()); if (_colourwith == null) { _colourwith = new Vector(); } if (jmb.isColourBySequence()) { if (!jmb.isLoadingFromArchive()) { if (_colourwith.size()==0 && ap!=null) { // Make the currently displayed alignment panel the associated view _colourwith.add(ap.alignFrame.alignPanel); } } // Set the colour using the current view for the associated alignframe for (AlignmentPanel ap : _colourwith) { jmb.colourBySequence(ap.av.showSequenceFeatures, ap); } } } public void chainColour_actionPerformed(ActionEvent actionEvent) { chainColour.setSelected(true); jmb.colourByChain(); } public void chargeColour_actionPerformed(ActionEvent actionEvent) { chargeColour.setSelected(true); jmb.colourByCharge(); } public void zappoColour_actionPerformed(ActionEvent actionEvent) { zappoColour.setSelected(true); jmb.setJalviewColourScheme(new ZappoColourScheme()); } public void taylorColour_actionPerformed(ActionEvent actionEvent) { taylorColour.setSelected(true); jmb.setJalviewColourScheme(new TaylorColourScheme()); } public void hydroColour_actionPerformed(ActionEvent actionEvent) { hydroColour.setSelected(true); jmb.setJalviewColourScheme(new HydrophobicColourScheme()); } public void helixColour_actionPerformed(ActionEvent actionEvent) { helixColour.setSelected(true); jmb.setJalviewColourScheme(new HelixColourScheme()); } public void strandColour_actionPerformed(ActionEvent actionEvent) { strandColour.setSelected(true); jmb.setJalviewColourScheme(new StrandColourScheme()); } public void turnColour_actionPerformed(ActionEvent actionEvent) { turnColour.setSelected(true); jmb.setJalviewColourScheme(new TurnColourScheme()); } public void buriedColour_actionPerformed(ActionEvent actionEvent) { buriedColour.setSelected(true); jmb.setJalviewColourScheme(new BuriedColourScheme()); } public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent) { setJalviewColourScheme(new PurinePyrimidineColourScheme()); } public void userColour_actionPerformed(ActionEvent actionEvent) { userColour.setSelected(true); new UserDefinedColours(this, null); } public void backGround_actionPerformed(ActionEvent actionEvent) { java.awt.Color col = JColorChooser.showDialog(this, "Select Background Colour", null); if (col != null) { jmb.setBackgroundColour(col); } } public void jmolHelp_actionPerformed(ActionEvent actionEvent) { try { jalview.util.BrowserLauncher .openURL("http://jmol.sourceforge.net/docs/JmolUserGuide/"); } catch (Exception ex) { } } public void showConsole(boolean showConsole) { if (showConsole) { if (splitPane == null) { splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setTopComponent(renderPanel); splitPane.setBottomComponent(scriptWindow); this.getContentPane().add(splitPane, BorderLayout.CENTER); splitPane.setDividerLocation(getHeight() - 200); scriptWindow.setVisible(true); scriptWindow.validate(); splitPane.validate(); } } else { if (splitPane != null) { splitPane.setVisible(false); } splitPane = null; this.getContentPane().add(renderPanel, BorderLayout.CENTER); } validate(); } class RenderPanel extends JPanel { final Dimension currentSize = new Dimension(); final Rectangle rectClip = new Rectangle(); public void paintComponent(Graphics g) { getSize(currentSize); g.getClipBounds(rectClip); if (jmb.fileLoadingError != null) { g.setColor(Color.black); g.fillRect(0, 0, currentSize.width, currentSize.height); g.setColor(Color.white); g.setFont(new Font("Verdana", Font.BOLD, 14)); g.drawString("Error loading file...", 20, currentSize.height / 2); StringBuffer sb = new StringBuffer(); int lines = 0; for (int e = 0; e < jmb.pdbentry.length; e++) { sb.append(jmb.pdbentry[e].getId()); if (e < jmb.pdbentry.length - 1) { sb.append(","); } if (e == jmb.pdbentry.length - 1 || sb.length() > 20) { lines++; g.drawString(sb.toString(), 20, currentSize.height / 2 - lines * g.getFontMetrics().getHeight()); } } } else if (jmb == null || jmb.viewer == null || !jmb.isFinishedInit()) { g.setColor(Color.black); g.fillRect(0, 0, currentSize.width, currentSize.height); g.setColor(Color.white); g.setFont(new Font("Verdana", Font.BOLD, 14)); g.drawString("Retrieving PDB data....", 20, currentSize.height / 2); } else { jmb.viewer.renderScreenImage(g, currentSize, rectClip); } } } String viewId = null; public String getViewId() { if (viewId == null) { viewId = System.currentTimeMillis() + "." + this.hashCode(); } return viewId; } public void updateTitleAndMenus() { if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0) { repaint(); return; } setChainMenuItems(jmb.chainNames); this.setTitle(jmb.getViewerTitle()); if (jmb.getPdbFile().length > 1 && jmb.sequence.length > 1) { jmolActionMenu.setVisible(true); } if (!jmb.isLoadingFromArchive()) { seqColour_actionPerformed(null); } } protected void buildJmolActionMenu() { if (_alignwith == null) { _alignwith = new Vector(); } if (_alignwith.size() == 0 && ap != null) { _alignwith.add(ap); } ; for (Component c : jmolActionMenu.getMenuComponents()) { if (c != alignStructs) { jmolActionMenu.remove((JMenuItem) c); } } final ItemListener handler; } /* * (non-Javadoc) * * @see * jalview.jbgui.GStructureViewer#alignStructs_actionPerformed(java.awt.event * .ActionEvent) */ @Override protected void alignStructs_actionPerformed(ActionEvent actionEvent) { alignStructs_withAllAlignPanels(); } private void alignStructs_withAllAlignPanels() { if (ap == null) { return; } ; if (_alignwith.size() == 0) { _alignwith.add(ap); } ; try { AlignmentI[] als = new Alignment[_alignwith.size()]; ColumnSelection[] alc = new ColumnSelection[_alignwith.size()]; int[] alm = new int[_alignwith.size()]; int a = 0; for (AlignmentPanel ap : _alignwith) { als[a] = ap.av.getAlignment(); alm[a] = -1; alc[a++] = ap.av.getColumnSelection(); } jmb.superposeStructures(als, alm, alc); } catch (Exception e) { StringBuffer sp = new StringBuffer(); for (AlignmentPanel ap : _alignwith) { sp.append("'" + ap.alignFrame.getTitle() + "' "); } Cache.log.info("Couldn't align structures with the " + sp.toString() + "associated alignment panels.", e); } } public void setJalviewColourScheme(ColourSchemeI ucs) { jmb.setJalviewColourScheme(ucs); } /** * * @param alignment * @return first alignment panel displaying given alignment, or the default * alignment panel */ public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment) { for (AlignmentPanel ap : getAllAlignmentPanels()) { if (ap.av.getAlignment() == alignment) { return ap; } } return ap; } /** * * @param ap2 * @return true if this Jmol instance is linked with the given alignPanel */ public boolean isLinkedWith(AlignmentPanel ap2) { return _aps.contains(ap2.av.getSequenceSetId()); } public boolean isUsedforaligment(AlignmentPanel ap2) { return (_alignwith != null) && _alignwith.contains(ap2); } public boolean isUsedforcolourby(AlignmentPanel ap2) { return (_colourwith != null) && _colourwith.contains(ap2); } /** * * @return TRUE if the view is NOT being coloured by sequence associations. */ public boolean isColouredByJmol() { return !jmb.isColourBySequence(); } }