001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.symmetry.gui; 022 023import java.awt.Dimension; 024import java.awt.event.ActionEvent; 025import java.io.IOException; 026 027import javax.swing.AbstractAction; 028import javax.swing.Action; 029import javax.swing.Box; 030import javax.swing.JButton; 031import javax.swing.JComboBox; 032import javax.swing.JFrame; 033import javax.swing.JLabel; 034import javax.swing.JMenuBar; 035import javax.swing.JOptionPane; 036import javax.swing.JProgressBar; 037import javax.swing.JTabbedPane; 038 039import org.biojava.nbio.structure.PassthroughIdentifier; 040import org.biojava.nbio.structure.Structure; 041import org.biojava.nbio.structure.StructureException; 042import org.biojava.nbio.structure.StructureIdentifier; 043import org.biojava.nbio.structure.align.ce.AbstractUserArgumentProcessor; 044import org.biojava.nbio.structure.align.gui.AlignmentCalculationRunnable; 045import org.biojava.nbio.structure.align.gui.MenuCreator; 046import org.biojava.nbio.structure.align.gui.ParameterGUI; 047import org.biojava.nbio.structure.align.gui.SelectPDBPanel; 048import org.biojava.nbio.structure.align.util.ResourceManager; 049import org.biojava.nbio.structure.align.webstart.AligUIManager; 050import org.biojava.nbio.structure.gui.util.PDBUploadPanel; 051import org.biojava.nbio.structure.gui.util.ScopSelectPanel; 052import org.biojava.nbio.structure.gui.util.StructurePairSelector; 053import org.biojava.nbio.structure.symmetry.internal.CESymmParameters; 054import org.biojava.nbio.structure.symmetry.internal.CeSymm; 055 056/** 057 * A JFrame that allows to trigger a symmetry analysis, either from files 058 * in a directory or after manual upload 059 * Adapted from the AlignmentGui class in biojava. 060 * Only one structure is inputted and only the CeSymm algorihm can be chosen. 061 * 062 * @author Aleix Lafita 063 * @since 4.2.0 064 * 065 */ 066public class SymmetryGui extends JFrame { 067 068 private final static long serialVersionUID = 0l; 069 070 private CESymmParameters params = new CESymmParameters(); 071 private JButton abortB; 072 073 private SelectPDBPanel tab1 ; 074 private PDBUploadPanel tab2; 075 private ScopSelectPanel tab3; 076 077 private Thread thread; 078 private AlignmentCalculationRunnable alicalc; 079 private JTabbedPane masterPane; 080 private JTabbedPane tabPane; 081 private JProgressBar progress; 082 083 public static void main(String[] args){ 084 SymmetryGui.getInstance(); 085 } 086 087 static final ResourceManager resourceManager = 088 ResourceManager.getResourceManager("ce"); 089 090 private static final String MAIN_TITLE = 091 "Symmetry Analysis Tool: CE-Symm - V.1.0"; 092 093 private static final SymmetryGui me = new SymmetryGui(); 094 095 public static SymmetryGui getInstance(){ 096 097 AbstractUserArgumentProcessor.printAboutMe(); 098 099 AligUIManager.setLookAndFeel(); 100 101 if (!me.isVisible()) me.setVisible(true); 102 if (! me.isActive()) me.requestFocus(); 103 104 return me; 105 } 106 107 public static SymmetryGui getInstanceNoVisibilityChange(){ 108 return me; 109 } 110 111 private SymmetryGui() { 112 super(); 113 114 thread = null; 115 116 JMenuBar menu = MenuCreator.initAlignmentGUIMenu(this); 117 this.setJMenuBar(menu); 118 119 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 120 this.setTitle(MAIN_TITLE); 121 122 tab1 = new SelectPDBPanel(false); 123 tab2 = new PDBUploadPanel(false); 124 tab3 = new ScopSelectPanel(false); 125 126 //setup tabPane 127 tabPane = new JTabbedPane(); 128 129 tabPane.addTab("Select PDB ID", null, tab1, "Select PDB ID to analyze"); 130 tabPane.addTab("Domain",null, tab3,"Select domain to analyze."); 131 tabPane.addTab("Custom file",null, tab2,"Analyze your own file."); 132 133 Box hBoxAlgo = setupAlgorithm(); 134 Box vBox = Box.createVerticalBox(); 135 136 vBox.add(tabPane); 137 vBox.add(Box.createGlue()); 138 139 masterPane = new JTabbedPane(); 140 masterPane.addTab("Symmetry Analysis", vBox); 141 142 Box vBoxMain = Box.createVerticalBox(); 143 vBoxMain.add(hBoxAlgo); 144 145 vBoxMain.add(masterPane); 146 vBoxMain.add(initButtons()); 147 148 this.getContentPane().add(vBoxMain); 149 this.pack(); 150 this.setVisible(true); 151 } 152 153 private Box setupAlgorithm() { 154 155 String[] algorithms = {"JCE-symmetry"}; 156 JLabel algoLabel = new JLabel("Symmetry algorithm: "); 157 158 JComboBox algorithmList = new JComboBox(algorithms); 159 algorithmList.setSelectedIndex(0); 160 161 Action paramAction = new AbstractAction("Parameters") { 162 public static final long serialVersionUID = 0l; 163 // This method is called when the button is pressed 164 @Override 165 public void actionPerformed(ActionEvent evt) { 166 // Perform action... 167 configureParameters(); 168 } 169 }; 170 171 JButton parameterButton = new JButton(paramAction); 172 173 Box hBoxAlgo = Box.createHorizontalBox(); 174 hBoxAlgo.add(Box.createGlue()); 175 hBoxAlgo.add(algoLabel); 176 hBoxAlgo.add(algorithmList); 177 hBoxAlgo.add(Box.createGlue()); 178 hBoxAlgo.add(parameterButton); 179 hBoxAlgo.add(Box.createGlue()); 180 return hBoxAlgo; 181 } 182 183 private Box initButtons(){ 184 185 progress =new JProgressBar(); 186 progress.setIndeterminate(false); 187 progress.setMaximumSize(new Dimension(10,100)); 188 progress.setVisible(false); 189 190 Action action1 = new AbstractAction("Analyze") { 191 public static final long serialVersionUID = 0l; 192 // This method is called when the button is pressed 193 @Override 194 public void actionPerformed(ActionEvent evt) { 195 // Perform action... 196 //System.out.println("calc structure alignment"); 197 int selectedIndex = masterPane.getSelectedIndex(); 198 if (selectedIndex == 0) 199 calcAlignment(); 200 else { 201 System.err.println("Unknown TAB: " + selectedIndex); 202 } 203 } 204 }; 205 206 JButton submitB = new JButton(action1); 207 208 Action action3 = new AbstractAction("Abort") { 209 public static final long serialVersionUID = 0l; 210 // This method is called when the button is pressed 211 @Override 212 public void actionPerformed(ActionEvent evt) { 213 // Perform action... 214 abortCalc(); 215 } 216 }; 217 218 abortB = new JButton(action3); 219 220 abortB.setEnabled(false); 221 222 Action action2 = new AbstractAction("Exit") { 223 public static final long serialVersionUID = 0l; 224 // This method is called when the button is pressed 225 @Override 226 public void actionPerformed(ActionEvent evt) { 227 // Perform action... 228 abortCalc(); 229 dispose(); 230 System.exit(0); 231 } 232 }; 233 234 JButton closeB = new JButton(action2); 235 Box hBox = Box.createHorizontalBox(); 236 hBox.add(closeB); 237 hBox.add(Box.createGlue()); 238 hBox.add(progress); 239 hBox.add(abortB); 240 //hBox.add(Box.createGlue()); 241 hBox.add(submitB); 242 243 return hBox; 244 } 245 246 protected void configureParameters() { 247 System.out.println("configure parameters for " + 248 CeSymm.algorithmName); 249 250 // show a new config GUI 251 new ParameterGUI(params, CeSymm.algorithmName); 252 } 253 254 public void cleanUp() { 255 256 if ( alicalc != null) { 257 alicalc.cleanup(); 258 } 259 } 260 261 private void calcAlignment() { 262 263 int pos = tabPane.getSelectedIndex(); 264 StructurePairSelector tab = null; 265 266 if (pos == 0 ){ 267 tab = tab1; 268 269 } else if (pos == 1){ 270 tab = tab3; 271 272 } else if (pos == 2){ 273 tab = tab2; 274 } 275 276 277 try { 278 Structure s = tab.getStructure1(); 279 280 if ( s == null) { 281 System.err.println("Please select structure"); 282 return ; 283 } 284 285 StructureIdentifier name = new PassthroughIdentifier("custom"); 286 287 if ( pos == 0){ 288 name = tab1.getName1(); 289 } else { 290 name = s.getStructureIdentifier(); 291 } 292 293 System.out.println("Analyzing: " + name); 294 295 296 alicalc = new SymmetryCalc(this, s); 297 298 299 thread = new Thread(alicalc); 300 thread.start(); 301 abortB.setEnabled(true); 302 progress.setIndeterminate(true); 303 ProgressThreadDrawer drawer = new ProgressThreadDrawer(progress); 304 drawer.start(); 305 } catch (StructureException e){ 306 JOptionPane.showMessageDialog(null, 307 "Could not align structures. Exception: " + e.getMessage()); 308 } catch (IOException e) { 309 JOptionPane.showMessageDialog(null, 310 "Could not align structures. Exception: " + e.getMessage()); 311 } 312 } 313 314 public void notifyCalcFinished(){ 315 abortB.setEnabled(false); 316 thread = null; 317 progress.setIndeterminate(false); 318 this.repaint(); 319 } 320 321 private void abortCalc(){ 322 System.err.println("Interrupting alignment ..."); 323 if ( alicalc != null ) 324 alicalc.interrupt(); 325 notifyCalcFinished(); 326 } 327 328 329 public CESymmParameters getParameters() { 330 return params; 331 } 332 333} 334 335class ProgressThreadDrawer extends Thread { 336 337 JProgressBar progress; 338 static int interval = 300; 339 340 public ProgressThreadDrawer(JProgressBar progress) { 341 this.progress = progress; 342 } 343 344 345 @Override 346 public void run() { 347 progress.setVisible(true); 348 boolean finished = false; 349 while ( ! finished) { 350 try { 351 progress.repaint(); 352 if ( ! progress.isIndeterminate() ){ 353 finished =false; 354 break; 355 } 356 357 sleep(interval); 358 } catch (InterruptedException e){ 359 } 360 progress.repaint(); 361 } 362 progress.setVisible(false); 363 progress = null; 364 } 365}