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 * Created on Jul 16, 2006 021 * 022 */ 023package org.biojava.nbio.structure.align.gui; 024 025import java.awt.Dimension; 026import java.awt.event.ActionEvent; 027import java.util.List; 028 029import javax.swing.AbstractAction; 030import javax.swing.Action; 031import javax.swing.Box; 032import javax.swing.JButton; 033import javax.swing.JComboBox; 034import javax.swing.JFrame; 035import javax.swing.JLabel; 036import javax.swing.JMenuBar; 037import javax.swing.JOptionPane; 038import javax.swing.JProgressBar; 039import javax.swing.JTabbedPane; 040 041import org.biojava.nbio.structure.Structure; 042import org.biojava.nbio.structure.StructureException; 043import org.biojava.nbio.structure.StructureIdentifier; 044import org.biojava.nbio.structure.align.MultipleStructureAligner; 045import org.biojava.nbio.structure.align.StructureAlignment; 046import org.biojava.nbio.structure.align.StructureAlignmentFactory; 047import org.biojava.nbio.structure.align.ce.AbstractUserArgumentProcessor; 048import org.biojava.nbio.structure.align.ce.ConfigStrucAligParams; 049import org.biojava.nbio.structure.align.multiple.mc.MultipleMcMain; 050import org.biojava.nbio.structure.align.webstart.AligUIManager; 051import org.biojava.nbio.structure.gui.util.SelectMultiplePanel; 052 053/** 054 * A JFrame that allows to trigger a multiple structure alignment, 055 * either from files in a directory or after manual upload. 056 * <p> 057 * The current version allows to select the parameters of 058 * the pairwise alignment algorithm and the parameters of 059 * the multiple alignment algorithm. 060 * 061 * @author Aleix Lafita 062 * @since 4.2.0 063 * 064 */ 065public class MultipleAlignmentGUI extends JFrame { 066 067 private final static long serialVersionUID =0l; 068 private final static String version = "1.0"; 069 070 private MultipleStructureAligner multiple; 071 private StructureAlignment pairwise; 072 073 private SelectMultiplePanel tab; 074 private JTabbedPane tabPane; 075 076 private Thread thread; 077 private AlignmentCalculationRunnable alicalc; 078 private JProgressBar progress; 079 private JButton abortB; 080 081 private static final String MAIN_TITLE = 082 "Multiple Structure Alignment - Main - V." + version; 083 084 private static final MultipleAlignmentGUI me = 085 new MultipleAlignmentGUI(); 086 087 public static void main(String[] args){ 088 MultipleAlignmentGUI.getInstance(); 089 } 090 091 public static MultipleAlignmentGUI getInstance(){ 092 093 //TODO change about me 094 AbstractUserArgumentProcessor.printAboutMe(); 095 AligUIManager.setLookAndFeel(); 096 097 if (!me.isVisible()) me.setVisible(true); 098 if (!me.isActive()) me.requestFocus(); 099 100 return me; 101 } 102 103 public static MultipleAlignmentGUI getInstanceNoVisibilityChange(){ 104 return me; 105 } 106 107 protected MultipleAlignmentGUI() { 108 super(); 109 110 thread = null; 111 JMenuBar menu = MenuCreator.initAlignmentGUIMenu(this); 112 113 this.setJMenuBar(menu); 114 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 115 this.setTitle(MAIN_TITLE); 116 117 tab = new SelectMultiplePanel(); 118 119 // setup tabPane 120 tabPane = new JTabbedPane(); 121 tabPane.addTab("Select Structures", null, 122 tab, "Input Structure identifiers"); 123 124 Box hBoxPair = setupPairwiseAlgorithm(); 125 Box hBoxMult = setupMultipleAlgorithm(); 126 Box vBox = Box.createVerticalBox(); 127 128 vBox.add(tabPane); 129 vBox.add(Box.createGlue()); 130 131 Box vBoxMain = Box.createVerticalBox(); 132 vBoxMain.add(hBoxPair); 133 vBoxMain.add(hBoxMult); 134 vBoxMain.add(tabPane); 135 136 vBoxMain.add(initButtons()); 137 this.getContentPane().add(vBoxMain); 138 139 this.pack(); 140 this.setVisible(true); 141 } 142 143 private Box setupPairwiseAlgorithm() { 144 145 String[] pairAlgo = StructureAlignmentFactory.getAllAlgorithmNames(); 146 try { 147 pairwise = StructureAlignmentFactory.getAlgorithm(pairAlgo[0]); 148 } catch (StructureException e){ 149 e.printStackTrace(); 150 } 151 JLabel algoLabel = new JLabel("Select pairwise aligner: "); 152 153 JComboBox algorithmList = new JComboBox(pairAlgo); 154 algorithmList.setSelectedIndex(0); 155 156 Action actionAlgorithm = new AbstractAction("Algorithm") { 157 public static final long serialVersionUID = 0l; 158 @Override 159 public void actionPerformed(ActionEvent evt) { 160 JComboBox cb = (JComboBox)evt.getSource(); 161 String algorithmName = (String)cb.getSelectedItem(); 162 updatePairwiseAlgorithm(algorithmName); 163 } 164 }; 165 algorithmList.addActionListener(actionAlgorithm); 166 167 Action paramAction = new AbstractAction("Parameters") { 168 public static final long serialVersionUID = 0l; 169 @Override 170 public void actionPerformed(ActionEvent evt) { 171 StructureAlignment p = getPairwiseStructureAligner(); 172 ConfigStrucAligParams params = p.getParameters(); 173 new ParameterGUI(params, p.getAlgorithmName()); 174 } 175 }; 176 JButton parameterButton = new JButton(paramAction); 177 178 Box hBoxAlgoPair = Box.createHorizontalBox(); 179 hBoxAlgoPair.add(Box.createGlue()); 180 hBoxAlgoPair.add(algoLabel); 181 hBoxAlgoPair.add(algorithmList); 182 hBoxAlgoPair.add(Box.createGlue()); 183 hBoxAlgoPair.add(parameterButton); 184 hBoxAlgoPair.add(Box.createGlue()); 185 186 return hBoxAlgoPair; 187 } 188 189 private Box setupMultipleAlgorithm() { 190 191 //TODO change in the future when more multiple algorithms are added 192 String[] multAlgo = {MultipleMcMain.algorithmName}; 193 multiple = new MultipleMcMain(pairwise); 194 195 JLabel multLabel = new JLabel("Select multiple aligner: "); 196 JComboBox multList = new JComboBox(multAlgo); 197 multList.setSelectedIndex(0); 198 199 Action actionMultiple = new AbstractAction("Algorithm") { 200 public static final long serialVersionUID = 0l; 201 @Override 202 public void actionPerformed(ActionEvent evt) { 203 updateMultipleAlgorithm(); 204 } 205 }; 206 multList.addActionListener(actionMultiple); 207 208 Action paramAction = new AbstractAction("Parameters") { 209 public static final long serialVersionUID = 0l; 210 @Override 211 public void actionPerformed(ActionEvent evt) { 212 MultipleStructureAligner m = getMultipleStructureAligner(); 213 ConfigStrucAligParams params = m.getParameters(); 214 new ParameterGUI(params, m.getAlgorithmName()); 215 } 216 }; 217 JButton parameterButton = new JButton(paramAction); 218 219 Box hBoxAlgo = Box.createHorizontalBox(); 220 hBoxAlgo.add(Box.createGlue()); 221 hBoxAlgo.add(multLabel); 222 hBoxAlgo.add(multList); 223 hBoxAlgo.add(Box.createGlue()); 224 hBoxAlgo.add(parameterButton); 225 hBoxAlgo.add(Box.createGlue()); 226 227 return hBoxAlgo; 228 } 229 230 private Box initButtons(){ 231 232 //Progress Bar 233 progress = new JProgressBar(); 234 progress.setIndeterminate(false); 235 progress.setMaximumSize(new Dimension(10,100)); 236 progress.setVisible(false); 237 238 Action action1 = new AbstractAction("Align") { 239 public static final long serialVersionUID = 0l; 240 // This method is called when the button is pressed 241 @Override 242 public void actionPerformed(ActionEvent evt) { 243 calcAlignment(); 244 } 245 }; 246 JButton submitB = new JButton(action1); 247 248 Action action3 = new AbstractAction("Abort") { 249 public static final long serialVersionUID = 0l; 250 // This method is called when the button is pressed 251 @Override 252 public void actionPerformed(ActionEvent evt) { 253 abortCalc(); 254 } 255 }; 256 abortB = new JButton(action3); 257 abortB.setEnabled(false); 258 259 Action action2 = new AbstractAction("Exit") { 260 public static final long serialVersionUID = 0l; 261 // This method is called when the button is pressed 262 @Override 263 public void actionPerformed(ActionEvent evt) { 264 abortCalc(); 265 dispose(); 266 System.exit(0); 267 } 268 }; 269 JButton closeB = new JButton(action2); 270 271 Box hBox = Box.createHorizontalBox(); 272 hBox.add(closeB); 273 hBox.add(Box.createGlue()); 274 hBox.add(progress); 275 hBox.add(abortB); 276 hBox.add(submitB); 277 278 return hBox; 279 } 280 281 public void cleanUp() { 282 if (alicalc != null) alicalc.cleanup(); 283 } 284 285 private void calcAlignment() { 286 287 try { 288 List<Structure> structures = tab.getStructures(); 289 290 if ( structures.size() < 2) { 291 System.err.println("please input more than 1 structure"); 292 return; 293 } 294 295 List<StructureIdentifier> names = tab.getNames(); 296 297 String message = "aligning: "; 298 for (StructureIdentifier name:names){ 299 message += name.getIdentifier() + " "; 300 } 301 System.out.println(message); 302 303 alicalc = new MultipleAlignmentCalc(this, structures, names); 304 305 thread = new Thread(alicalc); 306 thread.start(); 307 abortB.setEnabled(true); 308 progress.setIndeterminate(true); 309 ProgressThreadDrawer drawer = new ProgressThreadDrawer(progress); 310 drawer.start(); 311 312 } catch (StructureException e){ 313 JOptionPane.showMessageDialog(null,"Could not align structures. " 314 + "Exception: " + e.getMessage()); 315 } 316 317 } 318 319 public void notifyCalcFinished(){ 320 abortB.setEnabled(false); 321 thread = null; 322 progress.setIndeterminate(false); 323 this.repaint(); 324 } 325 326 private void abortCalc(){ 327 System.err.println("Interrupting alignment ..."); 328 if (alicalc != null) alicalc.interrupt(); 329 notifyCalcFinished(); 330 } 331 332 333 public MultipleStructureAligner getMultipleStructureAligner() { 334 return multiple; 335 } 336 337 public StructureAlignment getPairwiseStructureAligner() { 338 return pairwise; 339 } 340 341 private void updatePairwiseAlgorithm(String algorithmName) { 342 try { 343 pairwise = StructureAlignmentFactory.getAlgorithm(algorithmName); 344 //Update also the multiple structure algorithm 345 ConfigStrucAligParams params = multiple.getParameters(); 346 updateMultipleAlgorithm(); 347 multiple.setParameters(params); 348 349 } catch (StructureException ex){ 350 ex.printStackTrace(); 351 } 352 } 353 354 private void updateMultipleAlgorithm() { 355 //TODO a factory would be needed to select the MultipleAligner 356 multiple = new MultipleMcMain(pairwise); 357 } 358}