JAL-1697 added ablity to select/view cached structures in the new structure chooser...
[jalview.git] / src / jalview / jbgui / GStructureChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21
22 package jalview.jbgui;
23
24 import jalview.datamodel.SequenceI;
25 import jalview.gui.AlignmentPanel;
26 import jalview.gui.Desktop;
27 import jalview.jbgui.PDBDocFieldPreferences.PreferenceSource;
28 import jalview.util.MessageManager;
29
30 import java.awt.BorderLayout;
31 import java.awt.CardLayout;
32 import java.awt.Dimension;
33 import java.awt.FlowLayout;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ItemEvent;
36 import java.awt.event.ItemListener;
37 import java.awt.event.MouseAdapter;
38 import java.awt.event.MouseEvent;
39
40 import javax.swing.ImageIcon;
41 import javax.swing.JButton;
42 import javax.swing.JCheckBox;
43 import javax.swing.JComboBox;
44 import javax.swing.JFrame;
45 import javax.swing.JInternalFrame;
46 import javax.swing.JLabel;
47 import javax.swing.JPanel;
48 import javax.swing.JScrollPane;
49 import javax.swing.JTabbedPane;
50 import javax.swing.JTable;
51 import javax.swing.JTextField;
52 import javax.swing.event.ChangeEvent;
53 import javax.swing.event.ChangeListener;
54 import javax.swing.event.DocumentEvent;
55 import javax.swing.event.DocumentListener;
56
57 @SuppressWarnings("serial")
58 /**
59  * GUI layout for structure chooser 
60  * @author tcnofoegbu
61  *
62  */
63 public abstract class GStructureChooser extends JPanel implements
64         ItemListener
65 {
66   protected String frameTitle = MessageManager
67           .getString("label.structure_chooser");
68
69   protected JInternalFrame mainFrame = new JInternalFrame(frameTitle);
70
71   protected JComboBox<FilterOption> cmb_filterOption = new JComboBox<FilterOption>();
72
73   protected AlignmentPanel ap;
74
75   protected JLabel lbl_result = new JLabel(
76           MessageManager.getString("label.select"));
77
78   protected JButton btn_view = new JButton();
79
80   protected JButton btn_cancel = new JButton();
81
82   protected JButton btn_pdbFromFile = new JButton();
83
84   protected JTextField txt_search = new JTextField(14);
85
86   private JPanel pnl_actions = new JPanel();
87
88   private JPanel pnl_main = new JPanel();
89
90   private JPanel pnl_idInput = new JPanel(new FlowLayout());
91
92   private JPanel pnl_fileChooser = new JPanel(new FlowLayout());
93
94   private JPanel pnl_idInputBL = new JPanel(new BorderLayout());
95
96   private JPanel pnl_fileChooserBL = new JPanel(new BorderLayout());
97
98   private JPanel pnl_locPDB = new JPanel(new BorderLayout());
99
100   protected JPanel pnl_switchableViews = new JPanel(new CardLayout());
101
102   protected CardLayout layout_switchableViews = (CardLayout) (pnl_switchableViews
103           .getLayout());
104
105   private BorderLayout mainLayout = new BorderLayout();
106
107   protected JCheckBox chk_rememberSettings = new JCheckBox(
108           MessageManager.getString("label.dont_ask_me_again"));
109
110   protected JCheckBox chk_invertFilter = new JCheckBox(
111           MessageManager.getString("label.invert"));
112
113   protected ImageIcon loadingImage = new ImageIcon(getClass().getResource(
114           "/images/loading.gif"));
115
116   protected ImageIcon goodImage = new ImageIcon(getClass().getResource(
117           "/images/good.png"));
118
119   protected ImageIcon errorImage = new ImageIcon(getClass().getResource(
120           "/images/error.png"));
121
122   protected JLabel lbl_loading = new JLabel(loadingImage);
123
124   protected JLabel lbl_pdbManualFetchStatus = new JLabel(errorImage);
125
126   protected JLabel lbl_fromFileStatus = new JLabel(errorImage);
127
128
129   protected AssciateSeqPanel idInputAssSeqPanel = new AssciateSeqPanel();
130
131   protected AssciateSeqPanel fileChooserAssSeqPanel = new AssciateSeqPanel();
132
133   protected static final String VIEWS_FILTER = "VIEWS_FILTER";
134
135   protected static final String VIEWS_FROM_FILE = "VIEWS_FROM_FILE";
136
137   protected static final String VIEWS_ENTER_ID = "VIEWS_ENTER_ID";
138
139   protected static final String VIEWS_LOCAL_PDB = "VIEWS_LOCAL_PDB";
140
141   protected JTable tbl_summary = new JTable();
142
143   protected JScrollPane scrl_foundStructures = new JScrollPane(
144           tbl_summary);
145
146   protected JTable tbl_local_pdb = new JTable();
147
148   protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
149
150   private JTabbedPane pnl_filter = new JTabbedPane();
151
152   private PDBDocFieldPreferences pdbDocFieldPrefs = new PDBDocFieldPreferences(
153           PreferenceSource.STRUCTURE_CHOOSER);
154
155   public GStructureChooser()
156   {
157     try
158     {
159       jbInit();
160       mainFrame.setVisible(false);
161       mainFrame.invalidate();
162       mainFrame.pack();
163     } catch (Exception e)
164     {
165       e.printStackTrace();
166     }
167   }
168
169   /**
170    * Initializes the GUI default properties
171    * 
172    * @throws Exception
173    */
174   private void jbInit() throws Exception
175   {
176     tbl_summary.setAutoCreateRowSorter(true);
177     tbl_local_pdb.setAutoCreateRowSorter(true);
178     tbl_local_pdb.addMouseListener(new MouseAdapter()
179     {
180       public void mouseClicked(MouseEvent e)
181       {
182         updateCurrentView();
183       }
184     });
185
186     btn_view.setFont(new java.awt.Font("Verdana", 0, 12));
187     btn_view.setText(MessageManager.getString("action.view"));
188     btn_view.addActionListener(new java.awt.event.ActionListener()
189     {
190       public void actionPerformed(ActionEvent e)
191       {
192         ok_ActionPerformed();
193       }
194     });
195     btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12));
196     btn_cancel.setText(MessageManager.getString("action.cancel"));
197     btn_cancel.addActionListener(new java.awt.event.ActionListener()
198     {
199       public void actionPerformed(ActionEvent e)
200       {
201         mainFrame.dispose();
202       }
203     });
204
205     btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12));
206     String btn_title = MessageManager.getString("label.select_pdb_file");
207     btn_pdbFromFile.setText(btn_title + "              ");
208     btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener()
209     {
210       public void actionPerformed(ActionEvent e)
211       {
212         pdbFromFile_actionPerformed();
213       }
214     });
215
216     scrl_foundStructures.setPreferredSize(new Dimension(500, 300));
217     scrl_foundStructures
218             .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
219
220     scrl_localPDB.setPreferredSize(new Dimension(500, 300));
221     scrl_localPDB
222             .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
223
224     cmb_filterOption.setFont(new java.awt.Font("Verdana", 0, 12));
225     chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12));
226     chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
227
228
229     txt_search.setToolTipText(MessageManager
230             .getString("label.enter_pdb_id"));
231     cmb_filterOption.setToolTipText(MessageManager
232             .getString("info.select_filter_option"));
233     txt_search.getDocument().addDocumentListener(new DocumentListener()
234     {
235       @Override
236       public void insertUpdate(DocumentEvent e)
237       {
238         txt_search_ActionPerformed();
239       }
240
241       @Override
242       public void removeUpdate(DocumentEvent e)
243       {
244         txt_search_ActionPerformed();
245       }
246
247       @Override
248       public void changedUpdate(DocumentEvent e)
249       {
250         txt_search_ActionPerformed();
251       }
252     });
253
254     cmb_filterOption.addItemListener(this);
255     chk_invertFilter.addItemListener(this);
256
257     pnl_actions.add(chk_rememberSettings);
258     pnl_actions.add(btn_view);
259     pnl_actions.add(btn_cancel);
260
261     // pnl_filter.add(lbl_result);
262     pnl_main.add(cmb_filterOption);
263     pnl_main.add(lbl_loading);
264     pnl_main.add(chk_invertFilter);
265     lbl_loading.setVisible(false);
266
267
268     pnl_fileChooser.add(btn_pdbFromFile);
269     pnl_fileChooser.add(lbl_fromFileStatus);
270     pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH);
271     pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER);
272
273     pnl_idInput.add(txt_search);
274     pnl_idInput.add(lbl_pdbManualFetchStatus);
275     pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH);
276     pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER);
277     
278     final String foundStructureSummary = MessageManager
279             .getString("label.found_structures_summary");
280
281     ChangeListener changeListener = new ChangeListener()
282     {
283       public void stateChanged(ChangeEvent changeEvent)
284       {
285         JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
286                 .getSource();
287         int index = sourceTabbedPane.getSelectedIndex();
288         if (sourceTabbedPane.getTitleAt(index)
289                 .equals(foundStructureSummary))
290         {
291           tabRefresh();
292         }
293       }
294     };
295     pnl_filter.addChangeListener(changeListener);
296     pnl_filter.setPreferredSize(new Dimension(500, 300));
297     pnl_filter.add(foundStructureSummary, scrl_foundStructures);
298     pnl_filter.add(
299             MessageManager.getString("label.configure_displayed_columns"),
300             pdbDocFieldPrefs);
301     
302     pnl_locPDB.add(scrl_localPDB);
303
304     pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE);
305     pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID);
306     pnl_switchableViews.add(pnl_filter, VIEWS_FILTER);
307     pnl_switchableViews.add(pnl_locPDB, VIEWS_LOCAL_PDB);
308     
309     this.setLayout(mainLayout);
310     this.add(pnl_main, java.awt.BorderLayout.NORTH);
311     this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
312     this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
313
314     mainFrame.setVisible(true);
315     mainFrame.setContentPane(this);
316     mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
317     Desktop.addInternalFrame(mainFrame, frameTitle, 800, 400);
318   }
319
320   
321   @Override
322   /**
323    * Event listener for the 'filter' combo-box and 'invert' check-box
324    */
325   public void itemStateChanged(ItemEvent e)
326   {
327     stateChanged(e);
328   }
329
330   /**
331    * This inner class provides the data model for the structure filter combo-box
332    * 
333    * @author tcnofoegbu
334    *
335    */
336   public class FilterOption
337   {
338     private String name;
339
340     private String value;
341
342     private String view;
343
344     public FilterOption(String name, String value, String view)
345     {
346       this.name = name;
347       this.value = value;
348       this.view = view;
349     }
350
351     public String getName()
352     {
353       return name;
354     }
355
356     public void setName(String name)
357     {
358       this.name = name;
359     }
360
361     public String getValue()
362     {
363       return value;
364     }
365
366     public void setValue(String value)
367     {
368       this.value = value;
369     }
370
371     public String getView()
372     {
373       return view;
374     }
375
376     public void setView(String view)
377     {
378       this.view = view;
379     }
380
381     public String toString()
382     {
383       return this.name;
384     }
385   }
386
387   /**
388    * This inner class provides the provides the data model for associate
389    * sequence combo-box - cmb_assSeq
390    * 
391    * @author tcnofoegbu
392    *
393    */
394   public class AssociateSeqOptions
395   {
396     private SequenceI sequence;
397     private String name;
398
399     public AssociateSeqOptions(SequenceI seq)
400     {
401       this.sequence = seq;
402       this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
403               0, 23) : seq.getName();
404     }
405
406     public AssociateSeqOptions(String name, SequenceI seq)
407     {
408       this.name = name;
409       this.sequence = seq;
410     }
411
412     public String toString()
413     {
414       return name;
415     }
416
417     public String getName()
418     {
419       return name;
420     }
421
422     public void setName(String name)
423     {
424       this.name = name;
425     }
426
427     public SequenceI getSequence()
428     {
429       return sequence;
430     }
431
432     public void setSequence(SequenceI sequence)
433     {
434       this.sequence = sequence;
435     }
436
437   }
438
439   /**
440    * This inner class holds the Layout and configuration of the panel which
441    * handles association of manually fetched structures to a unique sequence
442    * when more than one sequence selection is made
443    * 
444    * @author tcnofoegbu
445    *
446    */
447   public class AssciateSeqPanel extends JPanel implements ItemListener
448   {
449     private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
450
451     private JLabel lbl_associateSeq = new JLabel();
452
453     public AssciateSeqPanel()
454     {
455       this.setLayout(new FlowLayout());
456       this.add(cmb_assSeq);
457       this.add(lbl_associateSeq);
458       cmb_assSeq.setToolTipText(MessageManager
459               .getString("info.associate_wit_sequence"));
460       cmb_assSeq.addItemListener(this);
461     }
462
463     public void loadCmbAssSeq()
464     {
465       populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
466     }
467
468     public JComboBox<AssociateSeqOptions> getCmb_assSeq()
469     {
470       return cmb_assSeq;
471     }
472
473     public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
474     {
475       this.cmb_assSeq = cmb_assSeq;
476     }
477
478     @Override
479     public void itemStateChanged(ItemEvent e)
480     {
481       if (e.getStateChange() == ItemEvent.SELECTED)
482       {
483         cmbAssSeqStateChanged();
484       }
485     }
486   }
487
488   public JComboBox<FilterOption> getCmbFilterOption()
489   {
490     return cmb_filterOption;
491   }
492
493   protected abstract void stateChanged(ItemEvent e);
494
495   protected abstract void updateCurrentView();
496
497   protected abstract void populateFilterComboBox();
498
499   protected abstract void ok_ActionPerformed();
500
501   protected abstract void pdbFromFile_actionPerformed();
502
503   protected abstract void txt_search_ActionPerformed();
504
505   public abstract void populateCmbAssociateSeqOptions(
506           JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
507
508   public abstract void cmbAssSeqStateChanged();
509
510   public abstract void tabRefresh();
511 }