JAL-3032 adds Java 8 functionality (2/2)
[jalview.git] / src2 / fr / orsay / lri / varna / applications / NussinovDemo.java
1 /*
2  VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3  Copyright (C) 2008  Kevin Darty, Alain Denise and Yann Ponty.
4  electronic mail : Yann.Ponty@lri.fr
5  paper mail : LRI, bat 490 UniversitĂ© Paris-Sud 91405 Orsay Cedex France
6
7  This file is part of VARNA version 3.1.
8  VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10
11  VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16  If not, see http://www.gnu.org/licenses.
17  */
18 package fr.orsay.lri.varna.applications;
19
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Dimension;
23 import java.awt.Font;
24 import java.awt.GridLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.MouseEvent;
28 import java.math.BigInteger;
29 import java.util.ArrayList;
30 import java.util.Collections;
31
32 import javax.swing.BorderFactory;
33 import javax.swing.DefaultComboBoxModel;
34 import javax.swing.JButton;
35 import javax.swing.JComboBox;
36 import javax.swing.JFrame;
37 import javax.swing.JLabel;
38 import javax.swing.JPanel;
39 import javax.swing.JTextArea;
40 import javax.swing.JTextField;
41 import javax.swing.JTextPane;
42 import javax.swing.border.BevelBorder;
43
44 import fr.orsay.lri.varna.VARNAPanel;
45 import fr.orsay.lri.varna.controlers.ControleurInterpolator;
46 import fr.orsay.lri.varna.exceptions.ExceptionDrawingAlgorithm;
47 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
48 import fr.orsay.lri.varna.exceptions.ExceptionModeleStyleBaseSyntaxError;
49 import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
50 import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
51 import fr.orsay.lri.varna.exceptions.ExceptionParameterError;
52 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
53 import fr.orsay.lri.varna.exceptions.MappingException;
54 import fr.orsay.lri.varna.models.VARNAConfig;
55 import fr.orsay.lri.varna.models.VARNAConfig.BP_STYLE;
56 import fr.orsay.lri.varna.models.rna.Mapping;
57 import fr.orsay.lri.varna.models.rna.ModeleBase;
58 import fr.orsay.lri.varna.models.rna.ModelBaseStyle;
59 import fr.orsay.lri.varna.models.rna.RNA;
60 import fr.orsay.lri.varna.interfaces.InterfaceVARNABasesListener;
61 import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;;
62
63 public class NussinovDemo extends JFrame implements InterfaceVARNAListener,InterfaceVARNABasesListener {
64
65         /**
66          * 
67          */
68         private static final long serialVersionUID = -790155708306987257L;
69
70         private static final String SEQUENCE_DUMMY =        "AAAAAAAAAA";
71         private static final String SEQUENCE_A =        "AGGCACGUCU";
72         private static final String SEQUENCE_B =  "GAGUAGCCUC";
73         private static final String SEQUENCE_C = "GCAUAGCUGC";
74         private static final String SEQUENCE_INRIA = "GAGAAGUACUUGAAAUUGGCCUCCUC";
75         
76
77         private static final String SEQUENCE_BIG = "AAAACAAAAACACCAUGGUGUUUUCACCCAAUUGGGUGAAAACAGAGAUCUCGAGAUCUCUGUUUUUGUUUU"; 
78
79         private static final String DEFAULT_STRUCTURE = "..........";
80         // private static final String DEFAULT_STRUCTURE1 = "((((....))))";
81         // private static final String DEFAULT_STRUCTURE2 =
82         // "((((..(((....)))..))))";
83
84         private VARNAPanel _vpMaster;
85
86         private InfoPanel _infos = new InfoPanel();
87         private JPanel _tools = new JPanel();
88         private JPanel _input = new JPanel();
89
90         private JPanel _seqPanel = new JPanel();
91         private JPanel _structPanel = new JPanel();
92         private JLabel _actions = new JLabel();
93         private JLabel _struct = new JLabel(DEFAULT_STRUCTURE);
94         private JComboBox _seq1 = new JComboBox();
95         private JLabel _structLabel = new JLabel("Structure Secondaire");
96         private JLabel _seqLabel = new JLabel("Sequence d'ARN");
97         private JButton _goButton = new JButton("Repliement");
98         private JButton _switchButton = new JButton("Effacer");
99
100
101         private Color _backgroundColor = Color.white;
102         
103         public static Font textFieldsFont = Font.decode("MonoSpaced-BOLD-16");
104         public static Font labelsFont = Font.decode("SansSerif-BOLD-20");
105         public static final int marginTools = 250;
106         public static String APP_TITLE = "FĂȘte de la science 2015 - Inria AMIB - Repliement d'ARN";
107         
108
109         public static ModelBaseStyle createStyle(String txt) 
110         {
111                 ModelBaseStyle result = new ModelBaseStyle();
112                 try {
113                         result.assignParameters(txt);
114                 } catch (ExceptionModeleStyleBaseSyntaxError e) {
115                         // TODO Auto-generated catch block
116                         e.printStackTrace();
117                 } catch (ExceptionParameterError e) {
118                         // TODO Auto-generated catch block
119                         e.printStackTrace();
120                 }
121                 return result;
122         }
123         
124         public void applyTo(VARNAPanel vp, ModelBaseStyle mb, int[] indices)
125         {
126                 for(int i=0;i<indices.length;i++)
127                 { 
128                         ModeleBase m = vp.getRNA().getBaseAt(indices[i]);
129                         m.setStyleBase(mb);
130                         if (m.getElementStructure()!=-1)
131                         {
132                                 vp.getRNA().getBaseAt(m.getElementStructure()).setStyleBase(mb);
133                         }
134                 }
135                 vp.repaint();
136         }
137         
138         
139         public NussinovDemo() {
140                 super();
141                 try {
142                         _vpMaster = new VARNAPanel(getSeq(), "");
143                 } catch (ExceptionNonEqualLength e) {
144                         _vpMaster.errorDialog(e);
145                 }
146                 _vpMaster.setPreferredSize(new Dimension(600, 600));
147                 RNAPanelDemoInit();
148         }
149
150         public static void formatLabel(JLabel j)
151         {
152                 j.setHorizontalTextPosition(JLabel.LEFT);
153                 j.setPreferredSize(new Dimension(marginTools, 15));
154                 j.setFont(labelsFont);
155         }
156         
157         private void RNAPanelDemoInit() {
158                 
159                 
160
161                 _seq1.setFont(textFieldsFont);
162                 String[] seqs = {SEQUENCE_DUMMY,SEQUENCE_INRIA,SEQUENCE_A,SEQUENCE_B,SEQUENCE_C,SEQUENCE_BIG};
163                 _seq1.setModel(new DefaultComboBoxModel(seqs));
164                 _seq1.setEditable(true);
165                 
166
167                 setBackground(_backgroundColor);
168                 _vpMaster.setBackground(_backgroundColor);
169                 _vpMaster.addVARNAListener(this);
170                 _vpMaster.setFlatExteriorLoop(true);
171                 
172
173
174                 formatLabel(_seqLabel);
175                 formatLabel(_structLabel);
176
177                 _goButton.addActionListener(new ActionListener() {
178                         public void actionPerformed(ActionEvent e) {
179                                 showSolution();
180                                 onStructureRedrawn();
181                         }
182                 });
183
184                 _switchButton.addActionListener(new ActionListener() {
185                         public void actionPerformed(ActionEvent e) {
186                                 try {
187                                                         RNA r = new RNA();
188                                                         r.setRNA("", "");
189                                                         _struct.setText("");
190                                                         _vpMaster.setTitle("");
191                                                         _vpMaster.showRNA(r);
192                                                         onStructureRedrawn();
193                                         } 
194                                 catch (ExceptionFileFormatOrSyntax e2) {
195                                         e2.printStackTrace();
196                                 } catch (ExceptionUnmatchedClosingParentheses e2) {
197                                         // TODO Auto-generated catch block
198                                         e2.printStackTrace();
199                                 }
200                                 _vpMaster.repaint();
201                         }
202                 });
203
204                 _seqPanel.setLayout(new BorderLayout());
205                 _seqPanel.add(_seqLabel, BorderLayout.WEST);
206                 _seqPanel.add(_seq1, BorderLayout.CENTER);
207
208                 _structLabel.setPreferredSize(new Dimension(marginTools, 15));
209                 _structLabel.setHorizontalTextPosition(JLabel.LEFT);
210                 _struct.setFont(textFieldsFont);
211                 _structPanel.setLayout(new BorderLayout());
212                 _structPanel.add(_structLabel, BorderLayout.WEST);
213                 _structPanel.add(_struct, BorderLayout.CENTER);
214
215                 _input.setLayout(new GridLayout(0, 1));
216                 _input.add(_seqPanel);
217                 _input.add(_structPanel);
218
219                 JPanel goPanel = new JPanel();
220                 goPanel.setLayout(new BorderLayout());
221
222                 _infos.setFont(labelsFont);
223
224                 
225                 _tools.setLayout(new BorderLayout());
226                 _tools.add(_infos, BorderLayout.SOUTH);
227                 _tools.add(_input, BorderLayout.CENTER);
228                 _tools.add(_actions, BorderLayout.NORTH);
229                 _tools.add(goPanel, BorderLayout.EAST);
230                 _tools.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
231
232                 goPanel.add(_goButton, BorderLayout.CENTER);
233                 goPanel.add(_switchButton, BorderLayout.SOUTH);
234
235                 getContentPane().setLayout(new BorderLayout());
236                 JPanel VARNAs = new JPanel();
237                 VARNAs.setLayout(new GridLayout(1,2));
238                 VARNAs.add(_vpMaster);
239                 VARNAs.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
240                 getContentPane().add(VARNAs, BorderLayout.CENTER);
241                 getContentPane().add(_tools, BorderLayout.SOUTH);
242
243                 setVisible(true);
244
245                 _vpMaster.getVARNAUI().UIRadiate();
246                 _vpMaster.setTitleFontSize(26f);
247                 _vpMaster.setTitleFontStyle(Font.PLAIN);
248                 _vpMaster.addVARNABasesListener(this);
249                 _vpMaster.setBackground(Color.decode("#308099"));
250                 _vpMaster.setModifiable(false);
251                 _vpMaster.setTitle("Repliement cible");
252                 _vpMaster.setBPStyle(BP_STYLE.SIMPLE);
253                 _vpMaster.setBackboneColor(Color.white);
254                 _vpMaster.setDefaultBPColor(Color.white);
255                 _vpMaster.setBaseNumbersColor(Color.white);
256                 _vpMaster.setBaseOutlineColor(Color.white);
257                 _vpMaster.setTitleColor(Color.white);           
258                 _vpMaster.setTitleFontSize(26f);
259
260                 
261                 
262                 this.setTitle(APP_TITLE);
263                 
264                 showSolution();
265                 onStructureRedrawn();
266         }
267
268         private synchronized void showSolution()
269         {
270                 ArrayList<String> sols = getStructs();
271                 _infos.setInfo(sols, count(getSeq()));
272         }
273         
274
275
276
277         public String getSeq()
278         {
279                 return (""+_seq1.getSelectedItem()).toUpperCase();
280         }
281
282         
283         private boolean canBasePairAll(char a, char b)
284         {
285                 return true;
286         }
287
288         private boolean canBasePairBasic(char a, char b)
289         {
290                 if ((a=='G')&&(b=='C'))
291                         return true;
292                 if ((a=='C')&&(b=='G'))
293                         return true;
294                 if ((a=='U')&&(b=='A'))
295                         return true;
296                 if ((a=='A')&&(b=='U'))
297                         return true;
298                 if ((a=='G')&&(b=='U'))
299                         return true;
300                 if ((a=='U')&&(b=='G'))
301                         return true;
302                 return false;
303         }
304
305         private double basePairScoreBasic(char a, char b)
306         {
307                 if ((a=='G')&&(b=='C'))
308                         return 1.0;
309                 if ((a=='C')&&(b=='G'))
310                         return 1.0;
311                 if ((a=='U')&&(b=='A'))
312                         return 1.0;
313                 if ((a=='A')&&(b=='U'))
314                         return 1.0;
315                 if ((a=='G')&&(b=='U'))
316                         return 1.0;
317                 if ((a=='U')&&(b=='G'))
318                         return 1.0;
319                 return Double.NEGATIVE_INFINITY;
320         }
321
322         
323         private boolean canBasePairNussinov(char a, char b)
324         {
325                 if ((a=='G')&&(b=='C'))
326                         return true;
327                 if ((a=='C')&&(b=='G'))
328                         return true;
329                 if ((a=='U')&&(b=='A'))
330                         return true;
331                 if ((a=='A')&&(b=='U'))
332                         return true;
333                 if ((a=='U')&&(b=='G'))
334                         return true;
335                 if ((a=='G')&&(b=='U'))
336                         return true;
337                 return false;
338         }
339
340         private double basePairScoreNussinov(char a, char b)
341         {
342                 if ((a=='G')&&(b=='C'))
343                         return 3.0;
344                 if ((a=='C')&&(b=='G'))
345                         return 3.0;
346                 if ((a=='U')&&(b=='A'))
347                         return 2.0;
348                 if ((a=='A')&&(b=='U'))
349                         return 2.0;
350                 if ((a=='U')&&(b=='G'))
351                         return 1.0;
352                 if ((a=='G')&&(b=='U'))
353                         return 1.0;
354                 return Double.NEGATIVE_INFINITY;
355         }
356
357         private boolean canBasePairINRIA(char a, char b)
358         {
359                 if ((a=='U')&&(b=='A'))
360                         return true;
361                 if ((a=='A')&&(b=='U'))
362                         return true;
363                 if ((a=='G')&&(b=='C'))
364                         return true;
365                 if ((a=='C')&&(b=='G'))
366                         return true;
367
368                 if ((a=='A')&&(b=='G'))
369                         return true;
370                 if ((a=='G')&&(b=='A'))
371                         return true;
372                 if ((a=='U')&&(b=='C'))
373                         return true;
374                 if ((a=='C')&&(b=='U'))
375                         return true;
376                 if ((a=='A')&&(b=='A'))
377                         return true;
378                 if ((a=='U')&&(b=='U'))
379                         return true;
380
381                 if ((a=='U')&&(b=='G'))
382                         return true;
383                 if ((a=='G')&&(b=='U'))
384                         return true;
385                 if ((a=='A')&&(b=='C'))
386                         return true;
387                 if ((a=='C')&&(b=='A'))
388                         return true;
389                 return false;
390         }
391
392         private double basePairScoreINRIA(char a, char b)
393         {
394                 if ((a=='U')&&(b=='A'))
395                         return 3;
396                 if ((a=='A')&&(b=='U'))
397                         return 3;
398                 if ((a=='G')&&(b=='C'))
399                         return 3;
400                 if ((a=='C')&&(b=='G'))
401                         return 3;
402
403                 if ((a=='A')&&(b=='G'))
404                         return 2;
405                 if ((a=='G')&&(b=='A'))
406                         return 2;
407                 if ((a=='U')&&(b=='C'))
408                         return 2;
409                 if ((a=='C')&&(b=='U'))
410                         return 2;
411                 if ((a=='A')&&(b=='A'))
412                         return 2;
413                 if ((a=='U')&&(b=='U'))
414                         return 2;
415
416                 if ((a=='U')&&(b=='G'))
417                         return 1;
418                 if ((a=='G')&&(b=='U'))
419                         return 1;
420                 if ((a=='A')&&(b=='C'))
421                         return 1;
422                 if ((a=='C')&&(b=='A'))
423                         return 1;
424                 return Double.NEGATIVE_INFINITY;
425         }
426         
427         private boolean canBasePair(char a, char b)
428         {
429                 return canBasePairBasic(a,b);
430                 //return canBasePairNussinov(a,b);
431                 //return canBasePairINRIA(a,b);
432         }
433         
434         private double basePairScore(char a, char b)
435         {
436                 return basePairScoreBasic(a,b);
437                 //return basePairScoreNussinov(a,b);
438                 //return basePairScoreINRIA(a,b);
439         }
440         
441         public double[][] fillMatrix(String seq)
442         {
443                 int n = seq.length();
444                 double[][] tab = new double[n][n];
445                 for(int m=1;m<=n;m++)
446                 {
447                         for(int i=0;i<n-m+1;i++)
448                         {
449                                 int j = i+m-1;
450                                 tab[i][j] = 0;
451                                 if (i<j)
452                                 { 
453                                         tab[i][j] = Math.max(tab[i][j], tab[i+1][j]); 
454                                         for (int k=i+1;k<=j;k++)
455                                         {
456                                                 if (canBasePair(seq.charAt(i),seq.charAt(k)))
457                                                 {
458                                                         double fact1 = 0;
459                                                         if (k>i+1)
460                                                         {
461                                                                 fact1 = tab[i+1][k-1];
462                                                         }
463                                                         double fact2 = 0;
464                                                         if (k<j)
465                                                         {
466                                                                 fact2 = tab[k+1][j];
467                                                         }
468                                                         tab[i][j] = Math.max(tab[i][j],basePairScore(seq.charAt(i),seq.charAt(k))+fact1+fact2);
469                                                 } 
470                                         }
471                                 }
472                         }                       
473                 }
474                 return tab;
475         }
476
477         public static ArrayList<Double> combine(double bonus, ArrayList<Double> part1, ArrayList<Double> part2)
478         {
479                 ArrayList<Double> base = new ArrayList<Double>();
480                 for(double d1: part1)
481                 {
482                         for(double d2: part2)
483                         {
484                                 base.add(bonus+d1+d2);
485                         }
486                 }
487                 return base;
488         }
489
490         public static ArrayList<Double> selectBests(ArrayList<Double> base)
491         {
492                 ArrayList<Double> result = new ArrayList<Double>();
493                 double best = Double.NEGATIVE_INFINITY;
494                 for(double val: base)
495                 {
496                         best = Math.max(val, best);
497                 }
498                 for(double val: base)
499                 {
500                         if (val == best)
501                                 result.add(val);
502                 }
503                 return result;
504         }
505
506         
507         private ArrayList<String> backtrack(double[][] tab, String seq)
508         {
509                 return backtrack(tab,seq, 0, seq.length()-1);
510         }
511
512         private ArrayList<String> backtrack(double[][] tab, String seq, int i, int j)
513         {
514                 ArrayList<String> result = new ArrayList<String>();
515                 if (i<j)
516                 { 
517                         ArrayList<Integer> indices = new ArrayList<Integer>();
518                         indices.add(-1);
519                         for (int k=i+1;k<=j;k++)
520                         {
521                                 indices.add(k);
522                         }
523                         for (int k : indices)
524                         {
525                                 if (k==-1)
526                                 {
527                                         if (tab[i][j] == tab[i+1][j])
528                                         {
529                                                 for (String s:backtrack(tab, seq, i+1,j))
530                                                 {
531                                                         result.add("."+s);
532                                                 }
533                                         }
534                                 }
535                                 else
536                                 {
537                                         if (canBasePair(seq.charAt(i),seq.charAt(k)))
538                                         {
539                                                 double fact1 = 0;
540                                                 if (k>i+1)
541                                                 {
542                                                         fact1 = tab[i+1][k-1];
543                                                 }
544                                                 double fact2 = 0;
545                                                 if (k<j)
546                                                 {
547                                                         fact2 = tab[k+1][j];
548                                                 }
549                                                 if (tab[i][j]==basePairScore(seq.charAt(i),seq.charAt(k))+fact1+fact2)
550                                                 { 
551                                                         for (String s1:backtrack(tab, seq, i+1,k-1))
552                                                         {
553                                                                 for (String s2:backtrack(tab, seq, k+1,j))
554                                                                 {
555                                                                         result.add("("+s1+")"+s2);
556                                                                 }
557                                                         }
558                                                 }
559                                         }                                       
560                                 }                               
561                         }
562                 }
563                 else if  (i==j)
564                 {
565                         result.add(".");
566                 }
567                 else 
568                 {
569                         result.add("");
570                 }
571                 return result;
572         }
573         
574         public BigInteger count(String seq)
575         {
576                 int n = seq.length();
577                 
578                 BigInteger[][] tab = new BigInteger[n][n];
579                 for(int m=1;m<=n;m++)
580                 {
581                         for(int i=0;i<n-m+1;i++)
582                         {
583                                 int j = i+m-1;
584                                 tab[i][j] = BigInteger.ZERO;
585                                 if (i<j)
586                                 { 
587                                         tab[i][j] = tab[i][j].add(tab[i+1][j]); 
588                                         for (int k=i+1;k<=j;k++)
589                                         {
590                                                 if (canBasePair(seq.charAt(i),seq.charAt(k)))
591                                                 {
592                                                         BigInteger fact1 = BigInteger.ONE;
593                                                         if (k>i+1)
594                                                         {
595                                                                 fact1 = tab[i+1][k-1];
596                                                         }
597                                                         BigInteger fact2 = BigInteger.ONE;
598                                                         if (k<j)
599                                                         {
600                                                                 fact2 = tab[k+1][j];
601                                                         }
602                                                         tab[i][j] = tab[i][j].add(fact1.multiply(fact2));
603                                                 } 
604                                         }
605                                 }
606                                 else
607                                 {
608                                         tab[i][j] = BigInteger.ONE;
609                                 }
610                         }                       
611                 }
612                 return tab[0][n-1];
613         }
614         
615         private String _cache = "";
616         ArrayList<String> _cacheStructs = new ArrayList<String>(); 
617         
618         public ArrayList<String> getStructs() {
619                 String seq = getSeq();
620                 seq = seq.toUpperCase();
621                 if (!_cache.equals(seq))
622                 {
623                         double[][] mfe = fillMatrix(seq);
624                         _cacheStructs = backtrack(mfe,seq);
625                         _cache = seq;
626                 }
627                 return _cacheStructs;
628         }
629
630         public VARNAPanel get_varnaPanel() {
631                 return _vpMaster;
632         }
633
634         public void set_varnaPanel(VARNAPanel surface) {
635                 _vpMaster = surface;
636         }
637
638
639         public JLabel get_info() {
640                 return _actions;
641         }
642
643         public void set_info(JLabel _info) {
644                 this._actions = _info;
645         }
646
647         public static void main(String[] args) {
648                 NussinovDemo d = new NussinovDemo();
649                 d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
650                 d.pack();
651                 d.setVisible(true);
652         }
653
654         public void onStructureRedrawn() {
655                 _vpMaster.repaint();
656         }
657
658         public void onWarningEmitted(String s) {
659                 // TODO Auto-generated method stub
660                 
661         }
662
663         public void onLoad(String path) {
664                 // TODO Auto-generated method stub
665                 
666         }
667
668         public void onLoaded() {
669                 // TODO Auto-generated method stub
670                 
671         }
672
673         public void onUINewStructure(VARNAConfig v, RNA r) {
674                 // TODO Auto-generated method stub
675                 
676         }
677
678         static final String[] _bases =     {"A","C","G","U"};
679         static final String[] _basesComp = {"U","G","C","A"};
680         
681         public void onBaseClicked(ModeleBase mb, MouseEvent e) {
682         }
683         
684         public void onZoomLevelChanged() {
685                 // TODO Auto-generated method stub
686                 
687         }
688
689         public void onTranslationChanged() {
690                 // TODO Auto-generated method stub
691                 
692         }
693         private class InfoPanel extends JPanel
694         {
695                 ArrayList<String> _sols = new ArrayList<String>();
696                 BigInteger _nbFolds = BigInteger.ZERO;
697                 JTextArea _text = new JTextArea("");
698                 JTextArea _subopts = new JTextArea("");
699                 JPanel _suboptBrowser = new JPanel();
700                 JPanel _suboptCount = new JPanel();
701                 int _selectedIndex = 0;
702                 JButton next = new JButton(">");
703                 JButton previous = new JButton("<");
704                 
705                 InfoPanel()
706                 {
707                         setLayout(new BorderLayout());
708                         add(_suboptBrowser,BorderLayout.SOUTH);
709                         add(_suboptCount,BorderLayout.NORTH);
710                         
711                         next.addActionListener(new ActionListener(){
712                                 public void actionPerformed(ActionEvent arg0) {
713                                         if (_sols.size()>0)
714                                         {
715                                                 setSelectedIndex((_selectedIndex+1)%_sols.size());
716                                         }
717                                 }                               
718                         });
719
720                         previous.addActionListener(new ActionListener(){
721                                 public void actionPerformed(ActionEvent arg0) {
722                                         if (_sols.size()>0)
723                                         {
724                                                 setSelectedIndex((_selectedIndex+_sols.size()-1)%_sols.size());
725                                         }
726                                 }                               
727                         });
728                         next.setEnabled(false);
729                         previous.setEnabled(false);
730                         
731
732                         JLabel nbLab = new JLabel("#Repliements");
733                         NussinovDemo.formatLabel(nbLab);
734
735                         _suboptCount.setLayout(new BorderLayout());
736                         _suboptCount.add(nbLab,BorderLayout.WEST);
737                         _suboptCount.add(_text,BorderLayout.CENTER);
738
739                         JLabel cooptlab = new JLabel("#Co-optimaux");
740                         NussinovDemo.formatLabel(cooptlab);
741                         
742                         JPanel commands = new JPanel();
743                         commands.add(previous);
744                         commands.add(next);
745                         
746                         JPanel jp = new JPanel();
747                         jp.setLayout(new BorderLayout());
748                         jp.add(_subopts,BorderLayout.WEST);
749                         jp.add(commands,BorderLayout.CENTER);
750
751                         _suboptBrowser.setLayout(new BorderLayout());
752                         _suboptBrowser.add(cooptlab,BorderLayout.WEST);
753                         _suboptBrowser.add(jp,BorderLayout.CENTER);
754                         
755                         
756                 }
757                         
758                                 
759                 public void setSelectedIndex(int i)
760                 {
761                         _selectedIndex = i;
762                         RNA rfolded = new RNA();
763                         try {
764                                 rfolded.setRNA(getSeq(), _sols.get(i));
765                                 rfolded.drawRNARadiate(_vpMaster.getConfig());
766                                 rfolded.setBaseNameColor(Color.white);
767                                 rfolded.setBaseOutlineColor(Color.white);
768                                 rfolded.setBaseNumbersColor(Color.white);
769                                 _vpMaster.setBaseNumbersColor(Color.white);
770                                 _vpMaster.setBaseOutlineColor(Color.white);
771                                 _vpMaster.setFillBases(false);
772                                 _vpMaster.setBaseNameColor(Color.white);
773                                 _vpMaster.showRNAInterpolated(rfolded);                 
774                                 
775                         } catch (ExceptionUnmatchedClosingParentheses e) {
776                                 // TODO Auto-generated catch block
777                                 e.printStackTrace();
778                         } catch (ExceptionFileFormatOrSyntax e) {
779                                 // TODO Auto-generated catch block
780                                 e.printStackTrace();
781                         }
782                         _struct.setText(_sols.get(i));
783                         formatDescription();
784                 }
785                 
786                 public void setFont(Font f)
787                 {
788                         super.setFont(f);
789                         if(_text!=null)
790                         {
791                                 _text.setFont(f);
792                                 _text.setOpaque(false);
793                         }
794                         if(_subopts!=null)
795                         {
796                         _subopts.setFont(f);
797                         _subopts.setOpaque(false);
798                         }
799                 }
800                 public void setInfo(ArrayList<String> sols, BigInteger nbFolds)
801                 {
802                         _sols = sols;
803                         _nbFolds = nbFolds;
804                         formatDescription();
805                         setSelectedIndex(0);
806                 }
807                 
808                 private void formatDescription()
809                 {
810                         _text.setText(""+_nbFolds);
811                         _subopts.setText(""+_sols.size());
812                         next.setEnabled(_sols.size()>1);
813                         previous.setEnabled(_sols.size()>1);
814                         
815                 }
816                 
817         }
818         
819 }