2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
22 package jalview.jbgui;
24 import jalview.datamodel.SequenceI;
25 import jalview.fts.api.FTSDataColumnI;
26 import jalview.fts.core.FTSDataColumnPreferences;
27 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
28 import jalview.fts.service.pdb.PDBFTSRestClient;
29 import jalview.gui.AlignmentPanel;
30 import jalview.gui.Desktop;
31 import jalview.gui.JvSwingUtils;
32 import jalview.util.MessageManager;
34 import java.awt.BorderLayout;
35 import java.awt.CardLayout;
36 import java.awt.Dimension;
37 import java.awt.FlowLayout;
38 import java.awt.GridLayout;
39 import java.awt.event.ActionEvent;
40 import java.awt.event.ItemEvent;
41 import java.awt.event.ItemListener;
42 import java.awt.event.KeyAdapter;
43 import java.awt.event.KeyEvent;
44 import java.awt.event.MouseAdapter;
45 import java.awt.event.MouseEvent;
46 import java.util.Arrays;
47 import java.util.HashMap;
50 import javax.swing.ImageIcon;
51 import javax.swing.JButton;
52 import javax.swing.JCheckBox;
53 import javax.swing.JComboBox;
54 import javax.swing.JFrame;
55 import javax.swing.JInternalFrame;
56 import javax.swing.JLabel;
57 import javax.swing.JPanel;
58 import javax.swing.JScrollPane;
59 import javax.swing.JTabbedPane;
60 import javax.swing.JTable;
61 import javax.swing.JTextField;
62 import javax.swing.event.ChangeEvent;
63 import javax.swing.event.ChangeListener;
64 import javax.swing.event.DocumentEvent;
65 import javax.swing.event.DocumentListener;
66 import javax.swing.event.InternalFrameEvent;
67 import javax.swing.table.TableColumn;
69 @SuppressWarnings("serial")
71 * GUI layout for structure chooser
75 public abstract class GStructureChooser extends JPanel implements
78 protected JPanel statusPanel = new JPanel();
80 public JLabel statusBar = new JLabel();
82 private JPanel pnl_actionsAndStatus = new JPanel(new BorderLayout());
84 protected String frameTitle = MessageManager
85 .getString("label.structure_chooser");
87 protected JInternalFrame mainFrame = new JInternalFrame(frameTitle);
89 protected JComboBox<FilterOption> cmb_filterOption = new JComboBox<FilterOption>();
91 protected AlignmentPanel ap;
93 protected StringBuilder errorWarning = new StringBuilder();
95 protected JLabel lbl_result = new JLabel(
96 MessageManager.getString("label.select"));
98 protected JButton btn_view = new JButton();
100 protected JButton btn_cancel = new JButton();
102 protected JButton btn_pdbFromFile = new JButton();
104 protected JTextField txt_search = new JTextField(14);
106 private JPanel pnl_actions = new JPanel();
108 private JPanel pnl_main = new JPanel();
110 private JPanel pnl_idInput = new JPanel(new FlowLayout());
112 private JPanel pnl_fileChooser = new JPanel(new FlowLayout());
114 private JPanel pnl_idInputBL = new JPanel(new BorderLayout());
116 private JPanel pnl_fileChooserBL = new JPanel(new BorderLayout());
118 private JPanel pnl_locPDB = new JPanel(new BorderLayout());
120 protected JPanel pnl_switchableViews = new JPanel(new CardLayout());
122 protected CardLayout layout_switchableViews = (CardLayout) (pnl_switchableViews
125 private BorderLayout mainLayout = new BorderLayout();
127 protected JCheckBox chk_rememberSettings = new JCheckBox(
128 MessageManager.getString("label.dont_ask_me_again"));
130 protected JCheckBox chk_invertFilter = new JCheckBox(
131 MessageManager.getString("label.invert"));
133 protected ImageIcon loadingImage = new ImageIcon(getClass().getResource(
134 "/images/loading.gif"));
136 protected ImageIcon goodImage = new ImageIcon(getClass().getResource(
137 "/images/good.png"));
139 protected ImageIcon errorImage = new ImageIcon(getClass().getResource(
140 "/images/error.png"));
142 protected ImageIcon warningImage = new ImageIcon(getClass().getResource(
143 "/images/warning.gif"));
145 protected JLabel lbl_warning = new JLabel(warningImage);
147 protected JLabel lbl_loading = new JLabel(loadingImage);
149 protected JLabel lbl_pdbManualFetchStatus = new JLabel(errorImage);
151 protected JLabel lbl_fromFileStatus = new JLabel(errorImage);
153 protected AssciateSeqPanel idInputAssSeqPanel = new AssciateSeqPanel();
155 protected AssciateSeqPanel fileChooserAssSeqPanel = new AssciateSeqPanel();
157 protected static final String VIEWS_FILTER = "VIEWS_FILTER";
159 protected static final String VIEWS_FROM_FILE = "VIEWS_FROM_FILE";
161 protected static final String VIEWS_ENTER_ID = "VIEWS_ENTER_ID";
163 protected static final String VIEWS_LOCAL_PDB = "VIEWS_LOCAL_PDB";
165 protected JTable tbl_local_pdb = new JTable();
167 protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
169 protected JTabbedPane pnl_filter = new JTabbedPane();
171 protected FTSDataColumnPreferences pdbDocFieldPrefs = new FTSDataColumnPreferences(
172 PreferenceSource.STRUCTURE_CHOOSER,
173 PDBFTSRestClient.getInstance());
175 protected FTSDataColumnI[] previousWantedFields;
177 protected static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
179 private JTable tbl_summary = new JTable()
181 private boolean inLayout;
184 public boolean getScrollableTracksViewportWidth()
186 return hasExcessWidth();
191 public void doLayout()
193 if (hasExcessWidth())
195 autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
200 autoResizeMode = AUTO_RESIZE_OFF;
203 protected boolean hasExcessWidth()
205 return getPreferredSize().width < getParent().getWidth();
209 public void columnMarginChanged(ChangeEvent e)
215 TableColumn resizingColumn = getTableHeader().getResizingColumn();
216 // Need to do this here, before the parent's
217 // layout manager calls getPreferredSize().
218 if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF
221 resizingColumn.setPreferredWidth(resizingColumn.getWidth());
222 String colHeader = resizingColumn.getHeaderValue().toString();
223 tempUserPrefs.put(colHeader, resizingColumn.getWidth());
229 public String getToolTipText(MouseEvent evt)
231 String toolTipText = null;
232 java.awt.Point pnt = evt.getPoint();
233 int rowIndex = rowAtPoint(pnt);
234 int colIndex = columnAtPoint(pnt);
238 if (getValueAt(rowIndex, colIndex) == null)
242 toolTipText = getValueAt(rowIndex, colIndex).toString();
243 } catch (Exception e)
245 // e.printStackTrace();
247 toolTipText = (toolTipText == null ? null
248 : (toolTipText.length() > 500 ? JvSwingUtils.wrapTooltip(
249 true, "\"" + toolTipText.subSequence(0, 500)
250 + "...\"") : JvSwingUtils.wrapTooltip(true,
256 protected JScrollPane scrl_foundStructures = new JScrollPane(tbl_summary);
258 public GStructureChooser()
263 mainFrame.setVisible(false);
264 mainFrame.invalidate();
266 } catch (Exception e)
273 * Initializes the GUI default properties
277 private void jbInit() throws Exception
279 Integer width = tempUserPrefs.get("structureChooser.width") == null ? 800
280 : tempUserPrefs.get("structureChooser.width");
281 Integer height = tempUserPrefs.get("structureChooser.height") == null ? 400
282 : tempUserPrefs.get("structureChooser.height");
283 tbl_summary.setAutoCreateRowSorter(true);
284 tbl_summary.getTableHeader().setReorderingAllowed(false);
285 tbl_summary.addMouseListener(new MouseAdapter()
288 public void mouseClicked(MouseEvent e)
290 validateSelections();
294 public void mouseReleased(MouseEvent e)
296 validateSelections();
299 tbl_summary.addKeyListener(new KeyAdapter()
302 public void keyPressed(KeyEvent evt)
304 validateSelections();
305 switch (evt.getKeyCode())
307 case KeyEvent.VK_ESCAPE: // escape key
310 case KeyEvent.VK_ENTER: // enter key
311 if (btn_view.isEnabled())
313 ok_ActionPerformed();
316 case KeyEvent.VK_TAB: // tab key
317 if (evt.isShiftDown())
319 pnl_filter.requestFocus();
323 btn_view.requestFocus();
332 tbl_local_pdb.setAutoCreateRowSorter(true);
333 tbl_local_pdb.getTableHeader().setReorderingAllowed(false);
334 tbl_local_pdb.addMouseListener(new MouseAdapter()
337 public void mouseClicked(MouseEvent e)
339 validateSelections();
343 public void mouseReleased(MouseEvent e)
345 validateSelections();
348 tbl_local_pdb.addKeyListener(new KeyAdapter()
351 public void keyPressed(KeyEvent evt)
353 validateSelections();
354 switch (evt.getKeyCode())
356 case KeyEvent.VK_ESCAPE: // escape key
359 case KeyEvent.VK_ENTER: // enter key
360 if (btn_view.isEnabled())
362 ok_ActionPerformed();
365 case KeyEvent.VK_TAB: // tab key
366 if (evt.isShiftDown())
368 cmb_filterOption.requestFocus();
372 if (btn_view.isEnabled())
374 btn_view.requestFocus();
378 btn_cancel.requestFocus();
388 btn_view.setFont(new java.awt.Font("Verdana", 0, 12));
389 btn_view.setText(MessageManager.getString("action.view"));
390 btn_view.addActionListener(new java.awt.event.ActionListener()
393 public void actionPerformed(ActionEvent e)
395 ok_ActionPerformed();
398 btn_view.addKeyListener(new KeyAdapter()
401 public void keyPressed(KeyEvent evt)
403 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
405 ok_ActionPerformed();
410 btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12));
411 btn_cancel.setText(MessageManager.getString("action.cancel"));
412 btn_cancel.addActionListener(new java.awt.event.ActionListener()
415 public void actionPerformed(ActionEvent e)
417 closeAction(pnl_filter.getHeight());
420 btn_cancel.addKeyListener(new KeyAdapter()
423 public void keyPressed(KeyEvent evt)
425 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
427 closeAction(pnl_filter.getHeight());
432 btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12));
433 String btn_title = MessageManager.getString("label.select_pdb_file");
434 btn_pdbFromFile.setText(btn_title + " ");
435 btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener()
438 public void actionPerformed(ActionEvent e)
440 pdbFromFile_actionPerformed();
443 btn_pdbFromFile.addKeyListener(new KeyAdapter()
446 public void keyPressed(KeyEvent evt)
448 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
450 pdbFromFile_actionPerformed();
455 scrl_foundStructures.setPreferredSize(new Dimension(width, height));
457 scrl_localPDB.setPreferredSize(new Dimension(width, height));
459 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
461 cmb_filterOption.setFont(new java.awt.Font("Verdana", 0, 12));
462 chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12));
463 chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
464 chk_rememberSettings.setVisible(false);
465 txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
466 MessageManager.getString("label.enter_pdb_id")));
467 cmb_filterOption.setToolTipText(MessageManager
468 .getString("info.select_filter_option"));
469 txt_search.getDocument().addDocumentListener(new DocumentListener()
472 public void insertUpdate(DocumentEvent e)
474 txt_search_ActionPerformed();
478 public void removeUpdate(DocumentEvent e)
480 txt_search_ActionPerformed();
484 public void changedUpdate(DocumentEvent e)
486 txt_search_ActionPerformed();
490 cmb_filterOption.addItemListener(this);
491 chk_invertFilter.addItemListener(this);
493 pnl_actions.add(chk_rememberSettings);
494 pnl_actions.add(btn_view);
495 pnl_actions.add(btn_cancel);
497 // pnl_filter.add(lbl_result);
498 pnl_main.add(cmb_filterOption);
499 pnl_main.add(lbl_loading);
500 pnl_main.add(chk_invertFilter);
501 lbl_loading.setVisible(false);
503 pnl_fileChooser.add(btn_pdbFromFile);
504 pnl_fileChooser.add(lbl_fromFileStatus);
505 pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH);
506 pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER);
508 pnl_idInput.add(txt_search);
509 pnl_idInput.add(lbl_pdbManualFetchStatus);
510 pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH);
511 pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER);
513 final String foundStructureSummary = MessageManager
514 .getString("label.found_structures_summary");
515 final String configureCols = MessageManager
516 .getString("label.configure_displayed_columns");
517 ChangeListener changeListener = new ChangeListener()
520 public void stateChanged(ChangeEvent changeEvent)
522 JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
524 int index = sourceTabbedPane.getSelectedIndex();
525 btn_view.setVisible(true);
526 btn_cancel.setVisible(true);
527 if (sourceTabbedPane.getTitleAt(index).equals(configureCols))
529 btn_view.setEnabled(false);
530 btn_cancel.setEnabled(false);
531 btn_view.setVisible(false);
532 btn_cancel.setVisible(false);
533 previousWantedFields = pdbDocFieldPrefs
534 .getStructureSummaryFields().toArray(
535 new FTSDataColumnI[0]);
537 if (sourceTabbedPane.getTitleAt(index)
538 .equals(foundStructureSummary))
540 btn_cancel.setEnabled(true);
541 if (wantedFieldsUpdated())
547 validateSelections();
552 pnl_filter.addChangeListener(changeListener);
553 pnl_filter.setPreferredSize(new Dimension(width, height));
554 pnl_filter.add(foundStructureSummary, scrl_foundStructures);
555 pnl_filter.add(configureCols, pdbDocFieldPrefs);
557 pnl_locPDB.add(scrl_localPDB);
559 pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE);
560 pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID);
561 pnl_switchableViews.add(pnl_filter, VIEWS_FILTER);
562 pnl_switchableViews.add(pnl_locPDB, VIEWS_LOCAL_PDB);
564 this.setLayout(mainLayout);
565 this.add(pnl_main, java.awt.BorderLayout.NORTH);
566 this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
567 // this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
568 statusPanel.setLayout(new GridLayout());
569 pnl_actionsAndStatus.add(pnl_actions, BorderLayout.CENTER);
570 pnl_actionsAndStatus.add(statusPanel, BorderLayout.SOUTH);
571 statusPanel.add(statusBar, null);
572 this.add(pnl_actionsAndStatus, java.awt.BorderLayout.SOUTH);
575 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
578 public void internalFrameClosing(InternalFrameEvent e)
580 closeAction(pnl_filter.getHeight());
583 mainFrame.setVisible(true);
584 mainFrame.setContentPane(this);
585 mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
586 Integer x = tempUserPrefs.get("structureChooser.x");
587 Integer y = tempUserPrefs.get("structureChooser.y");
588 if (x != null && y != null)
590 mainFrame.setLocation(x, y);
592 Desktop.addInternalFrame(mainFrame, frameTitle, width, height);
595 protected void closeAction(int preferredHeight)
597 // System.out.println(">>>>>>>>>> closing internal frame!!!");
598 // System.out.println("width : " + mainFrame.getWidth());
599 // System.out.println("heigh : " + mainFrame.getHeight());
600 // System.out.println("x : " + mainFrame.getX());
601 // System.out.println("y : " + mainFrame.getY());
602 tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
603 tempUserPrefs.put("structureChooser.height", preferredHeight);
604 tempUserPrefs.put("structureChooser.x", mainFrame.getX());
605 tempUserPrefs.put("structureChooser.y", mainFrame.getY());
609 public boolean wantedFieldsUpdated()
611 if (previousWantedFields == null)
616 FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
617 .getStructureSummaryFields().toArray(new FTSDataColumnI[0]);
618 return Arrays.equals(currentWantedFields, previousWantedFields) ? false
625 * Event listener for the 'filter' combo-box and 'invert' check-box
627 public void itemStateChanged(ItemEvent e)
633 * This inner class provides the data model for the structure filter combo-box
638 public class FilterOption
642 private String value;
646 public FilterOption(String name, String value, String view)
653 public String getName()
658 public void setName(String name)
663 public String getValue()
668 public void setValue(String value)
673 public String getView()
678 public void setView(String view)
684 public String toString()
691 * This inner class provides the provides the data model for associate
692 * sequence combo-box - cmb_assSeq
697 public class AssociateSeqOptions
699 private SequenceI sequence;
703 public AssociateSeqOptions(SequenceI seq)
706 this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
707 0, 23) : seq.getName();
710 public AssociateSeqOptions(String name, SequenceI seq)
717 public String toString()
722 public String getName()
727 public void setName(String name)
732 public SequenceI getSequence()
737 public void setSequence(SequenceI sequence)
739 this.sequence = sequence;
745 * This inner class holds the Layout and configuration of the panel which
746 * handles association of manually fetched structures to a unique sequence
747 * when more than one sequence selection is made
752 public class AssciateSeqPanel extends JPanel implements ItemListener
754 private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
756 private JLabel lbl_associateSeq = new JLabel();
758 public AssciateSeqPanel()
760 this.setLayout(new FlowLayout());
761 this.add(cmb_assSeq);
762 this.add(lbl_associateSeq);
763 cmb_assSeq.setToolTipText(MessageManager
764 .getString("info.associate_wit_sequence"));
765 cmb_assSeq.addItemListener(this);
768 public void loadCmbAssSeq()
770 populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
773 public JComboBox<AssociateSeqOptions> getCmb_assSeq()
778 public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
780 this.cmb_assSeq = cmb_assSeq;
784 public void itemStateChanged(ItemEvent e)
786 if (e.getStateChange() == ItemEvent.SELECTED)
788 cmbAssSeqStateChanged();
793 public JTable getResultTable()
798 public JComboBox<FilterOption> getCmbFilterOption()
800 return cmb_filterOption;
803 protected abstract void stateChanged(ItemEvent e);
805 protected abstract void ok_ActionPerformed();
807 protected abstract void pdbFromFile_actionPerformed();
809 protected abstract void txt_search_ActionPerformed();
811 public abstract void populateCmbAssociateSeqOptions(
812 JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
814 public abstract void cmbAssSeqStateChanged();
816 public abstract void tabRefresh();
818 public abstract void validateSelections();