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.io.File;
028import java.io.IOException;
029
030import javax.swing.AbstractAction;
031import javax.swing.Action;
032import javax.swing.Box;
033import javax.swing.JButton;
034import javax.swing.JComboBox;
035import javax.swing.JFrame;
036import javax.swing.JLabel;
037import javax.swing.JMenuBar;
038import javax.swing.JOptionPane;
039import javax.swing.JProgressBar;
040import javax.swing.JTabbedPane;
041
042import org.biojava.nbio.structure.Structure;
043import org.biojava.nbio.structure.StructureException;
044import org.biojava.nbio.structure.align.StructureAlignment;
045import org.biojava.nbio.structure.align.StructureAlignmentFactory;
046import org.biojava.nbio.structure.align.ce.AbstractUserArgumentProcessor;
047import org.biojava.nbio.structure.align.util.ResourceManager;
048import org.biojava.nbio.structure.align.util.UserConfiguration;
049import org.biojava.nbio.structure.align.webstart.AligUIManager;
050import org.biojava.nbio.structure.align.webstart.WebStartMain;
051import org.biojava.nbio.structure.gui.util.PDBUploadPanel;
052import org.biojava.nbio.structure.gui.util.ScopSelectPanel;
053import org.biojava.nbio.structure.gui.util.StructurePairSelector;
054
055/** A JFrame that allows to trigger a pairwise structure alignment,
056 * either from files in a directory,
057 * or after manual upload.
058 *
059 * @author Andreas Prlic
060 *
061 * @since 1.7
062 *
063 *
064 *
065 */
066public class AlignmentGui extends JFrame{
067
068        private final static long serialVersionUID =0l;
069
070        StructureAlignment algorithm;
071
072        JButton abortB;
073
074        SelectPDBPanel  tab1 ;
075        PDBUploadPanel  tab2;
076        ScopSelectPanel tab3;
077
078        Thread thread;
079        AlignmentCalculationRunnable alicalc;
080        JTabbedPane masterPane;
081        JTabbedPane tabPane;
082        JProgressBar progress;
083
084
085        public static void main(String[] args){
086
087                AlignmentGui.getInstance();
088
089        }
090
091        static final ResourceManager resourceManager = ResourceManager.getResourceManager("ce");
092
093        private static final String MAIN_TITLE = "Pairwise Structure Alignment - Main - V." + resourceManager.getString("ce.version");;
094
095        private static final AlignmentGui me = new AlignmentGui();
096
097        public static AlignmentGui getInstance(){
098
099                AbstractUserArgumentProcessor.printAboutMe();
100
101                AligUIManager.setLookAndFeel();
102
103                if (!  me.isVisible())
104                        me.setVisible(true);
105
106                if ( ! me.isActive())
107                        me.requestFocus();
108
109
110                return me;
111        }
112
113        public static AlignmentGui getInstanceNoVisibilityChange(){
114
115                return me;
116        }
117
118
119        protected AlignmentGui() {
120                super();
121
122                thread = null;
123
124                JMenuBar menu = MenuCreator.initAlignmentGUIMenu(this);
125
126                this.setJMenuBar(menu);
127
128                this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
129
130                this.setTitle(MAIN_TITLE);
131
132                tab1 = new SelectPDBPanel();
133                tab2 = new PDBUploadPanel();
134                tab3 = new ScopSelectPanel();
135
136                // setup tabPane
137                tabPane = new JTabbedPane();
138
139                tabPane.addTab("Select PDB ID", null, tab1, "Select PDB ID to align");
140
141                tabPane.addTab("Domains",null, tab3,"Select domains to align.");
142
143                tabPane.addTab("Custom files",null, tab2,"Align your own files.");
144
145
146
147                Box hBoxAlgo = setupAlgorithm();
148
149                Box vBox = Box.createVerticalBox();
150
151
152                //vBox.add(hBoxAlgo);
153
154                vBox.add(tabPane);
155                vBox.add(Box.createGlue());
156
157                //vBox.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
158
159                masterPane = new JTabbedPane();
160
161                masterPane.addTab("Pairwise Comparison", vBox);
162
163                //JPanel dir = tab1.getPDBDirPanel(pdbDir);
164
165                Box vBoxMain = Box.createVerticalBox();
166                vBoxMain.add(hBoxAlgo);
167
168                // pairwise or db search
169
170                vBoxMain.add(masterPane);
171
172                // algorithm selection
173
174                // PDB install config
175                //vBoxMain.add(dir);
176                // buttons
177                vBoxMain.add(initButtons());
178
179                this.getContentPane().add(vBoxMain);
180
181                //SwingUtilities.updateComponentTreeUI( me);
182
183                this.pack();
184                this.setVisible(true);
185
186
187        }
188
189        private Box setupAlgorithm()
190        {
191                String[] algorithms = StructureAlignmentFactory.getAllAlgorithmNames();
192                try {
193                        algorithm = StructureAlignmentFactory.getAlgorithm(algorithms[0]);
194                } catch (StructureException e){
195                        e.printStackTrace();
196                }
197
198                JLabel algoLabel = new JLabel("Select alignment algorithm: ");
199
200                JComboBox algorithmList = new JComboBox(algorithms);
201                algorithmList.setSelectedIndex(0);
202
203                Action actionAlgorithm = new AbstractAction("Algorithm") {
204                        public static final long serialVersionUID = 0l;
205                        // This method is called when the button is pressed
206                        @Override
207                        public void actionPerformed(ActionEvent evt) {
208                                JComboBox cb = (JComboBox)evt.getSource();
209                                String algorithmName = (String)cb.getSelectedItem();
210                                // Perform action...
211                                //System.out.println("calc structure alignment");
212                                updateAlgorithm(algorithmName);
213
214                        }
215                };
216
217
218                algorithmList.addActionListener(actionAlgorithm);
219
220
221                Action paramAction = new AbstractAction("Parameters") {
222                        public static final long serialVersionUID = 0l;
223                        // This method is called when the button is pressed
224                        @Override
225                        public void actionPerformed(ActionEvent evt) {
226                                // Perform action...
227                                //System.out.println("calc structure alignment");
228                                configureParameters();
229
230                        }
231
232                };
233
234                JButton parameterButton = new JButton(paramAction);
235
236
237
238                Box hBoxAlgo = Box.createHorizontalBox();
239                hBoxAlgo.add(Box.createGlue());
240                hBoxAlgo.add(algoLabel);
241                hBoxAlgo.add(algorithmList);
242                hBoxAlgo.add(Box.createGlue());
243                hBoxAlgo.add(parameterButton);
244                hBoxAlgo.add(Box.createGlue());
245                return hBoxAlgo;
246        }
247
248
249
250
251
252        private Box initButtons(){
253
254                //        Box hBox42 = Box.createHorizontalBox();
255                progress =new JProgressBar();
256                progress.setIndeterminate(false);
257                progress.setMaximumSize(new Dimension(10,100));
258                progress.setVisible(false);
259
260                //        hBox42.add(Box.createGlue());
261                //        hBox42.add(progress);
262                //        hBox42.add(Box.createGlue());
263                //        vBox.add(hBox42);
264                Action action1 = new AbstractAction("Align") {
265                        public static final long serialVersionUID = 0l;
266                        // This method is called when the button is pressed
267                        @Override
268                        public void actionPerformed(ActionEvent evt) {
269                                // Perform action...
270                                //System.out.println("calc structure alignment");
271                                int selectedIndex = masterPane.getSelectedIndex();
272                                if (selectedIndex == 0)
273                                        calcAlignment();
274                                else {
275                                        System.err.println("Unknown TAB: " + selectedIndex);
276                                }
277
278                        }
279                };
280
281                JButton submitB = new JButton(action1);
282
283                Action action3 = new AbstractAction("Abort") {
284                        public static final long serialVersionUID = 0l;
285                        // This method is called when the button is pressed
286                        @Override
287                        public void actionPerformed(ActionEvent evt) {
288                                // Perform action...
289                                abortCalc();
290                        }
291                };
292
293                abortB = new JButton(action3);
294
295                abortB.setEnabled(false);
296
297                Action action2 = new AbstractAction("Exit") {
298                        public static final long serialVersionUID = 0l;
299                        // This method is called when the button is pressed
300                        @Override
301                        public void actionPerformed(ActionEvent evt) {
302                                // Perform action...
303                                abortCalc();
304                                dispose();
305                                System.exit(0);
306                        }
307                };
308                JButton closeB = new JButton(action2);
309                Box hBox = Box.createHorizontalBox();
310                hBox.add(closeB);
311                hBox.add(Box.createGlue());
312                hBox.add(progress);
313                hBox.add(abortB);
314                //hBox.add(Box.createGlue());
315                hBox.add(submitB);
316
317                return hBox;
318        }
319
320        protected void configureParameters() {
321                StructureAlignment algorithm = getStructureAlignment();
322                System.out.println("configure parameters for " + algorithm.getAlgorithmName());
323
324                // show a new config GUI
325                new ParameterGUI(algorithm.getParameters(), algorithm.getAlgorithmName());
326        }
327
328
329
330        public void cleanUp() {
331
332                if ( alicalc != null) {
333                        alicalc.cleanup();
334                }
335        }
336
337
338
339
340
341        private void calcAlignment() {
342
343                int pos = tabPane.getSelectedIndex();
344                StructurePairSelector tab = null;
345
346                if (pos == 0 ){
347                        tab = tab1;
348
349                } else if (pos == 1){
350                        tab = tab3;
351
352                } else if (pos == 2){
353                        tab = tab2;
354                }
355
356
357                try {
358                        Structure s1 = tab.getStructure1();
359                        Structure s2 = tab.getStructure2();
360
361                        if ( s1 == null) {
362                                System.err.println("please select structure 1");
363                                return ;
364                        }
365
366                        if ( s2 == null) {
367                                System.err.println("please select structure 2");
368                                return;
369                        }
370
371                        String name1 = "custom1";
372                        String name2 = "custom2";
373
374                        if  ( pos == 0){
375                                name1 = tab1.getName1().getIdentifier();
376                                name2 = tab1.getName2().getIdentifier();
377                        } else {
378                                name1 = s1.getName();
379                                name2 = s2.getName();
380                        }
381
382                        System.out.println("aligning: " + name1 + " " + name2);
383
384
385                        alicalc = new AlignmentCalc(this,s1,s2, name1, name2);
386
387
388                        thread = new Thread(alicalc);
389                        thread.start();
390                        abortB.setEnabled(true);
391                        progress.setIndeterminate(true);
392                        ProgressThreadDrawer drawer = new ProgressThreadDrawer(progress);
393                        drawer.start();
394                } catch (StructureException e){
395                        JOptionPane.showMessageDialog(null,"Could not align structures. Exception: " + e.getMessage());
396                } catch (IOException e) {
397                        JOptionPane.showMessageDialog(null,"Could not align structures. Exception: " + e.getMessage());
398                }
399
400        }
401
402        public void notifyCalcFinished(){
403                abortB.setEnabled(false);
404                thread = null;
405                progress.setIndeterminate(false);
406                this.repaint();
407        }
408
409        private void abortCalc(){
410                System.err.println("Interrupting alignment ...");
411                if ( alicalc != null )
412                        alicalc.interrupt();
413                notifyCalcFinished();
414
415
416        }
417
418
419        public StructureAlignment getStructureAlignment() {
420
421                return algorithm;
422        }
423
424        private void updateAlgorithm(String algorithmName) {
425
426                //String algorithmName = (String)algorithmList.getSelectedItem();
427                try {
428                        algorithm = StructureAlignmentFactory.getAlgorithm(algorithmName);
429                } catch (StructureException ex){
430                        ex.printStackTrace();
431                }
432
433        }
434
435}
436
437class ProgressThreadDrawer extends Thread {
438
439        JProgressBar progress;
440        static int interval = 300;
441
442        public ProgressThreadDrawer(JProgressBar progress) {
443                this.progress = progress;
444        }
445
446
447        @Override
448        public void run() {
449                progress.setVisible(true);
450                boolean finished = false;
451                while ( ! finished) {
452                        try {
453                                progress.repaint();
454                                if ( ! progress.isIndeterminate() ){
455                                        finished =false;
456                                        break;
457                                }
458
459                                sleep(interval);
460                        } catch (InterruptedException e){
461                        }
462                        progress.repaint();
463                }
464                progress.setVisible(false);
465                progress = null;
466        }
467
468}