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;
48 import javax.swing.ImageIcon;
49 import javax.swing.JButton;
50 import javax.swing.JCheckBox;
51 import javax.swing.JComboBox;
52 import javax.swing.JFrame;
53 import javax.swing.JInternalFrame;
54 import javax.swing.JLabel;
55 import javax.swing.JPanel;
56 import javax.swing.JScrollPane;
57 import javax.swing.JTabbedPane;
58 import javax.swing.JTable;
59 import javax.swing.JTextField;
60 import javax.swing.event.ChangeEvent;
61 import javax.swing.event.ChangeListener;
62 import javax.swing.event.DocumentEvent;
63 import javax.swing.event.DocumentListener;
64 import javax.swing.table.TableColumn;
66 @SuppressWarnings("serial")
68 * GUI layout for structure chooser
72 public abstract class GStructureChooser extends JPanel implements
75 protected JPanel statusPanel = new JPanel();
77 public JLabel statusBar = new JLabel();
79 private JPanel pnl_actionsAndStatus = new JPanel(new BorderLayout());
81 protected String frameTitle = MessageManager
82 .getString("label.structure_chooser");
84 protected JInternalFrame mainFrame = new JInternalFrame(frameTitle);
86 protected JComboBox<FilterOption> cmb_filterOption = new JComboBox<FilterOption>();
88 protected AlignmentPanel ap;
90 protected StringBuilder errorWarning = new StringBuilder();
92 protected JLabel lbl_result = new JLabel(
93 MessageManager.getString("label.select"));
95 protected JButton btn_view = new JButton();
97 protected JButton btn_cancel = new JButton();
99 protected JButton btn_pdbFromFile = new JButton();
101 protected JTextField txt_search = new JTextField(14);
103 private JPanel pnl_actions = new JPanel();
105 private JPanel pnl_main = new JPanel();
107 private JPanel pnl_idInput = new JPanel(new FlowLayout());
109 private JPanel pnl_fileChooser = new JPanel(new FlowLayout());
111 private JPanel pnl_idInputBL = new JPanel(new BorderLayout());
113 private JPanel pnl_fileChooserBL = new JPanel(new BorderLayout());
115 private JPanel pnl_locPDB = new JPanel(new BorderLayout());
117 protected JPanel pnl_switchableViews = new JPanel(new CardLayout());
119 protected CardLayout layout_switchableViews = (CardLayout) (pnl_switchableViews
122 private BorderLayout mainLayout = new BorderLayout();
124 protected JCheckBox chk_rememberSettings = new JCheckBox(
125 MessageManager.getString("label.dont_ask_me_again"));
127 protected JCheckBox chk_invertFilter = new JCheckBox(
128 MessageManager.getString("label.invert"));
130 protected ImageIcon loadingImage = new ImageIcon(getClass().getResource(
131 "/images/loading.gif"));
133 protected ImageIcon goodImage = new ImageIcon(getClass().getResource(
134 "/images/good.png"));
136 protected ImageIcon errorImage = new ImageIcon(getClass().getResource(
137 "/images/error.png"));
139 protected ImageIcon warningImage = new ImageIcon(getClass().getResource(
140 "/images/warning.gif"));
142 protected JLabel lbl_warning = new JLabel(warningImage);
144 protected JLabel lbl_loading = new JLabel(loadingImage);
146 protected JLabel lbl_pdbManualFetchStatus = new JLabel(errorImage);
148 protected JLabel lbl_fromFileStatus = new JLabel(errorImage);
150 protected AssciateSeqPanel idInputAssSeqPanel = new AssciateSeqPanel();
152 protected AssciateSeqPanel fileChooserAssSeqPanel = new AssciateSeqPanel();
154 protected static final String VIEWS_FILTER = "VIEWS_FILTER";
156 protected static final String VIEWS_FROM_FILE = "VIEWS_FROM_FILE";
158 protected static final String VIEWS_ENTER_ID = "VIEWS_ENTER_ID";
160 protected static final String VIEWS_LOCAL_PDB = "VIEWS_LOCAL_PDB";
162 protected JTable tbl_local_pdb = new JTable();
164 protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
166 private JTabbedPane pnl_filter = new JTabbedPane();
168 protected FTSDataColumnPreferences pdbDocFieldPrefs = new FTSDataColumnPreferences(
169 PreferenceSource.STRUCTURE_CHOOSER,
170 PDBFTSRestClient.getInstance());
172 protected FTSDataColumnI[] previousWantedFields;
174 private JTable tbl_summary = new JTable()
176 private boolean inLayout;
179 public boolean getScrollableTracksViewportWidth()
181 return hasExcessWidth();
186 public void doLayout()
188 if (hasExcessWidth())
190 autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
195 autoResizeMode = AUTO_RESIZE_OFF;
198 protected boolean hasExcessWidth()
200 return getPreferredSize().width < getParent().getWidth();
204 public void columnMarginChanged(ChangeEvent e)
210 TableColumn resizingColumn = getTableHeader().getResizingColumn();
211 // Need to do this here, before the parent's
212 // layout manager calls getPreferredSize().
213 if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF
216 resizingColumn.setPreferredWidth(resizingColumn.getWidth());
222 public String getToolTipText(MouseEvent evt)
224 String toolTipText = null;
225 java.awt.Point pnt = evt.getPoint();
226 int rowIndex = rowAtPoint(pnt);
227 int colIndex = columnAtPoint(pnt);
231 if (getValueAt(rowIndex, colIndex) == null)
235 toolTipText = getValueAt(rowIndex, colIndex).toString();
236 } catch (Exception e)
238 // e.printStackTrace();
240 toolTipText = (toolTipText == null ? null
241 : (toolTipText.length() > 500 ? JvSwingUtils.wrapTooltip(
242 true, "\"" + toolTipText.subSequence(0, 500)
243 + "...\"") : JvSwingUtils.wrapTooltip(true,
249 protected JScrollPane scrl_foundStructures = new JScrollPane(tbl_summary);
251 public GStructureChooser()
256 mainFrame.setVisible(false);
257 mainFrame.invalidate();
259 } catch (Exception e)
266 * Initializes the GUI default properties
270 private void jbInit() throws Exception
272 tbl_summary.setAutoCreateRowSorter(true);
273 tbl_summary.getTableHeader().setReorderingAllowed(false);
274 tbl_summary.addMouseListener(new MouseAdapter()
277 public void mouseClicked(MouseEvent e)
279 validateSelections();
283 public void mouseReleased(MouseEvent e)
285 validateSelections();
288 tbl_summary.addKeyListener(new KeyAdapter()
291 public void keyPressed(KeyEvent evt)
293 validateSelections();
294 switch (evt.getKeyCode())
296 case KeyEvent.VK_ESCAPE: // escape key
299 case KeyEvent.VK_ENTER: // enter key
300 if (btn_view.isEnabled())
302 ok_ActionPerformed();
305 case KeyEvent.VK_TAB: // tab key
306 if (evt.isShiftDown())
308 pnl_filter.requestFocus();
312 btn_view.requestFocus();
321 tbl_local_pdb.setAutoCreateRowSorter(true);
322 tbl_local_pdb.getTableHeader().setReorderingAllowed(false);
323 tbl_local_pdb.addMouseListener(new MouseAdapter()
326 public void mouseClicked(MouseEvent e)
328 validateSelections();
332 public void mouseReleased(MouseEvent e)
334 validateSelections();
337 tbl_local_pdb.addKeyListener(new KeyAdapter()
340 public void keyPressed(KeyEvent evt)
342 validateSelections();
343 switch (evt.getKeyCode())
345 case KeyEvent.VK_ESCAPE: // escape key
348 case KeyEvent.VK_ENTER: // enter key
349 if (btn_view.isEnabled())
351 ok_ActionPerformed();
354 case KeyEvent.VK_TAB: // tab key
355 if (evt.isShiftDown())
357 cmb_filterOption.requestFocus();
361 if (btn_view.isEnabled())
363 btn_view.requestFocus();
367 btn_cancel.requestFocus();
376 btn_view.setFont(new java.awt.Font("Verdana", 0, 12));
377 btn_view.setText(MessageManager.getString("action.view"));
378 btn_view.addActionListener(new java.awt.event.ActionListener()
381 public void actionPerformed(ActionEvent e)
383 ok_ActionPerformed();
386 btn_view.addKeyListener(new KeyAdapter()
389 public void keyPressed(KeyEvent evt)
391 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
393 ok_ActionPerformed();
398 btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12));
399 btn_cancel.setText(MessageManager.getString("action.cancel"));
400 btn_cancel.addActionListener(new java.awt.event.ActionListener()
403 public void actionPerformed(ActionEvent e)
408 btn_cancel.addKeyListener(new KeyAdapter()
411 public void keyPressed(KeyEvent evt)
413 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
420 btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12));
421 String btn_title = MessageManager.getString("label.select_pdb_file");
422 btn_pdbFromFile.setText(btn_title + " ");
423 btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener()
426 public void actionPerformed(ActionEvent e)
428 pdbFromFile_actionPerformed();
431 btn_pdbFromFile.addKeyListener(new KeyAdapter()
434 public void keyPressed(KeyEvent evt)
436 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
438 pdbFromFile_actionPerformed();
443 scrl_foundStructures.setPreferredSize(new Dimension(800, 400));
445 scrl_localPDB.setPreferredSize(new Dimension(800, 400));
447 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
449 cmb_filterOption.setFont(new java.awt.Font("Verdana", 0, 12));
450 chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12));
451 chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
452 chk_rememberSettings.setVisible(false);
454 txt_search.setToolTipText(MessageManager
455 .getString("label.enter_pdb_id"));
456 cmb_filterOption.setToolTipText(MessageManager
457 .getString("info.select_filter_option"));
458 txt_search.getDocument().addDocumentListener(new DocumentListener()
461 public void insertUpdate(DocumentEvent e)
463 txt_search_ActionPerformed();
467 public void removeUpdate(DocumentEvent e)
469 txt_search_ActionPerformed();
473 public void changedUpdate(DocumentEvent e)
475 txt_search_ActionPerformed();
479 cmb_filterOption.addItemListener(this);
480 chk_invertFilter.addItemListener(this);
482 pnl_actions.add(chk_rememberSettings);
483 pnl_actions.add(btn_view);
484 pnl_actions.add(btn_cancel);
486 // pnl_filter.add(lbl_result);
487 pnl_main.add(cmb_filterOption);
488 pnl_main.add(lbl_loading);
489 pnl_main.add(chk_invertFilter);
490 lbl_loading.setVisible(false);
492 pnl_fileChooser.add(btn_pdbFromFile);
493 pnl_fileChooser.add(lbl_fromFileStatus);
494 pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH);
495 pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER);
497 pnl_idInput.add(txt_search);
498 pnl_idInput.add(lbl_pdbManualFetchStatus);
499 pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH);
500 pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER);
502 final String foundStructureSummary = MessageManager
503 .getString("label.found_structures_summary");
504 final String configureCols = MessageManager
505 .getString("label.configure_displayed_columns");
506 ChangeListener changeListener = new ChangeListener()
509 public void stateChanged(ChangeEvent changeEvent)
511 JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
513 int index = sourceTabbedPane.getSelectedIndex();
514 btn_view.setVisible(true);
515 btn_cancel.setVisible(true);
516 if (sourceTabbedPane.getTitleAt(index).equals(configureCols))
518 btn_view.setEnabled(false);
519 btn_cancel.setEnabled(false);
520 btn_view.setVisible(false);
521 btn_cancel.setVisible(false);
522 previousWantedFields = pdbDocFieldPrefs
523 .getStructureSummaryFields().toArray(
524 new FTSDataColumnI[0]);
526 if (sourceTabbedPane.getTitleAt(index)
527 .equals(foundStructureSummary))
529 btn_cancel.setEnabled(true);
530 if (wantedFieldsUpdated())
536 validateSelections();
541 pnl_filter.addChangeListener(changeListener);
542 pnl_filter.setPreferredSize(new Dimension(800, 400));
543 pnl_filter.add(foundStructureSummary, scrl_foundStructures);
544 pnl_filter.add(configureCols, pdbDocFieldPrefs);
546 pnl_locPDB.add(scrl_localPDB);
548 pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE);
549 pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID);
550 pnl_switchableViews.add(pnl_filter, VIEWS_FILTER);
551 pnl_switchableViews.add(pnl_locPDB, VIEWS_LOCAL_PDB);
553 this.setLayout(mainLayout);
554 this.add(pnl_main, java.awt.BorderLayout.NORTH);
555 this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
556 // this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
557 statusPanel.setLayout(new GridLayout());
558 pnl_actionsAndStatus.add(pnl_actions, BorderLayout.CENTER);
559 pnl_actionsAndStatus.add(statusPanel, BorderLayout.SOUTH);
560 statusPanel.add(statusBar, null);
561 this.add(pnl_actionsAndStatus, java.awt.BorderLayout.SOUTH);
563 mainFrame.setVisible(true);
564 mainFrame.setContentPane(this);
565 mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
566 Desktop.addInternalFrame(mainFrame, frameTitle, 900, 500);
569 public boolean wantedFieldsUpdated()
571 if (previousWantedFields == null)
576 FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
577 .getStructureSummaryFields()
578 .toArray(new FTSDataColumnI[0]);
579 return Arrays.equals(currentWantedFields, previousWantedFields) ? false
586 * Event listener for the 'filter' combo-box and 'invert' check-box
588 public void itemStateChanged(ItemEvent e)
594 * This inner class provides the data model for the structure filter combo-box
599 public class FilterOption
603 private String value;
607 public FilterOption(String name, String value, String view)
614 public String getName()
619 public void setName(String name)
624 public String getValue()
629 public void setValue(String value)
634 public String getView()
639 public void setView(String view)
645 public String toString()
652 * This inner class provides the provides the data model for associate
653 * sequence combo-box - cmb_assSeq
658 public class AssociateSeqOptions
660 private SequenceI sequence;
664 public AssociateSeqOptions(SequenceI seq)
667 this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
668 0, 23) : seq.getName();
671 public AssociateSeqOptions(String name, SequenceI seq)
678 public String toString()
683 public String getName()
688 public void setName(String name)
693 public SequenceI getSequence()
698 public void setSequence(SequenceI sequence)
700 this.sequence = sequence;
706 * This inner class holds the Layout and configuration of the panel which
707 * handles association of manually fetched structures to a unique sequence
708 * when more than one sequence selection is made
713 public class AssciateSeqPanel extends JPanel implements ItemListener
715 private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
717 private JLabel lbl_associateSeq = new JLabel();
719 public AssciateSeqPanel()
721 this.setLayout(new FlowLayout());
722 this.add(cmb_assSeq);
723 this.add(lbl_associateSeq);
724 cmb_assSeq.setToolTipText(MessageManager
725 .getString("info.associate_wit_sequence"));
726 cmb_assSeq.addItemListener(this);
729 public void loadCmbAssSeq()
731 populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
734 public JComboBox<AssociateSeqOptions> getCmb_assSeq()
739 public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
741 this.cmb_assSeq = cmb_assSeq;
745 public void itemStateChanged(ItemEvent e)
747 if (e.getStateChange() == ItemEvent.SELECTED)
749 cmbAssSeqStateChanged();
754 public JTable getResultTable()
758 public JComboBox<FilterOption> getCmbFilterOption()
760 return cmb_filterOption;
763 protected abstract void stateChanged(ItemEvent e);
765 protected abstract void updateCurrentView();
767 protected abstract void populateFilterComboBox();
769 protected abstract void ok_ActionPerformed();
771 protected abstract void pdbFromFile_actionPerformed();
773 protected abstract void txt_search_ActionPerformed();
775 public abstract void populateCmbAssociateSeqOptions(
776 JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
778 public abstract void cmbAssSeqStateChanged();
780 public abstract void tabRefresh();
782 public abstract void validateSelections();