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);
453 txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
454 MessageManager.getString("label.enter_pdb_id")));
455 cmb_filterOption.setToolTipText(MessageManager
456 .getString("info.select_filter_option"));
457 txt_search.getDocument().addDocumentListener(new DocumentListener()
460 public void insertUpdate(DocumentEvent e)
462 txt_search_ActionPerformed();
466 public void removeUpdate(DocumentEvent e)
468 txt_search_ActionPerformed();
472 public void changedUpdate(DocumentEvent e)
474 txt_search_ActionPerformed();
478 cmb_filterOption.addItemListener(this);
479 chk_invertFilter.addItemListener(this);
481 pnl_actions.add(chk_rememberSettings);
482 pnl_actions.add(btn_view);
483 pnl_actions.add(btn_cancel);
485 // pnl_filter.add(lbl_result);
486 pnl_main.add(cmb_filterOption);
487 pnl_main.add(lbl_loading);
488 pnl_main.add(chk_invertFilter);
489 lbl_loading.setVisible(false);
491 pnl_fileChooser.add(btn_pdbFromFile);
492 pnl_fileChooser.add(lbl_fromFileStatus);
493 pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH);
494 pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER);
496 pnl_idInput.add(txt_search);
497 pnl_idInput.add(lbl_pdbManualFetchStatus);
498 pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH);
499 pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER);
501 final String foundStructureSummary = MessageManager
502 .getString("label.found_structures_summary");
503 final String configureCols = MessageManager
504 .getString("label.configure_displayed_columns");
505 ChangeListener changeListener = new ChangeListener()
508 public void stateChanged(ChangeEvent changeEvent)
510 JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
512 int index = sourceTabbedPane.getSelectedIndex();
513 btn_view.setVisible(true);
514 btn_cancel.setVisible(true);
515 if (sourceTabbedPane.getTitleAt(index).equals(configureCols))
517 btn_view.setEnabled(false);
518 btn_cancel.setEnabled(false);
519 btn_view.setVisible(false);
520 btn_cancel.setVisible(false);
521 previousWantedFields = pdbDocFieldPrefs
522 .getStructureSummaryFields().toArray(
523 new FTSDataColumnI[0]);
525 if (sourceTabbedPane.getTitleAt(index)
526 .equals(foundStructureSummary))
528 btn_cancel.setEnabled(true);
529 if (wantedFieldsUpdated())
535 validateSelections();
540 pnl_filter.addChangeListener(changeListener);
541 pnl_filter.setPreferredSize(new Dimension(800, 400));
542 pnl_filter.add(foundStructureSummary, scrl_foundStructures);
543 pnl_filter.add(configureCols, pdbDocFieldPrefs);
545 pnl_locPDB.add(scrl_localPDB);
547 pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE);
548 pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID);
549 pnl_switchableViews.add(pnl_filter, VIEWS_FILTER);
550 pnl_switchableViews.add(pnl_locPDB, VIEWS_LOCAL_PDB);
552 this.setLayout(mainLayout);
553 this.add(pnl_main, java.awt.BorderLayout.NORTH);
554 this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
555 // this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
556 statusPanel.setLayout(new GridLayout());
557 pnl_actionsAndStatus.add(pnl_actions, BorderLayout.CENTER);
558 pnl_actionsAndStatus.add(statusPanel, BorderLayout.SOUTH);
559 statusPanel.add(statusBar, null);
560 this.add(pnl_actionsAndStatus, java.awt.BorderLayout.SOUTH);
562 mainFrame.setVisible(true);
563 mainFrame.setContentPane(this);
564 mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
565 Desktop.addInternalFrame(mainFrame, frameTitle, 900, 500);
568 public boolean wantedFieldsUpdated()
570 if (previousWantedFields == null)
575 FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
576 .getStructureSummaryFields()
577 .toArray(new FTSDataColumnI[0]);
578 return Arrays.equals(currentWantedFields, previousWantedFields) ? false
585 * Event listener for the 'filter' combo-box and 'invert' check-box
587 public void itemStateChanged(ItemEvent e)
593 * This inner class provides the data model for the structure filter combo-box
598 public class FilterOption
602 private String value;
606 public FilterOption(String name, String value, String view)
613 public String getName()
618 public void setName(String name)
623 public String getValue()
628 public void setValue(String value)
633 public String getView()
638 public void setView(String view)
644 public String toString()
651 * This inner class provides the provides the data model for associate
652 * sequence combo-box - cmb_assSeq
657 public class AssociateSeqOptions
659 private SequenceI sequence;
663 public AssociateSeqOptions(SequenceI seq)
666 this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
667 0, 23) : seq.getName();
670 public AssociateSeqOptions(String name, SequenceI seq)
677 public String toString()
682 public String getName()
687 public void setName(String name)
692 public SequenceI getSequence()
697 public void setSequence(SequenceI sequence)
699 this.sequence = sequence;
705 * This inner class holds the Layout and configuration of the panel which
706 * handles association of manually fetched structures to a unique sequence
707 * when more than one sequence selection is made
712 public class AssciateSeqPanel extends JPanel implements ItemListener
714 private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
716 private JLabel lbl_associateSeq = new JLabel();
718 public AssciateSeqPanel()
720 this.setLayout(new FlowLayout());
721 this.add(cmb_assSeq);
722 this.add(lbl_associateSeq);
723 cmb_assSeq.setToolTipText(MessageManager
724 .getString("info.associate_wit_sequence"));
725 cmb_assSeq.addItemListener(this);
728 public void loadCmbAssSeq()
730 populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
733 public JComboBox<AssociateSeqOptions> getCmb_assSeq()
738 public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
740 this.cmb_assSeq = cmb_assSeq;
744 public void itemStateChanged(ItemEvent e)
746 if (e.getStateChange() == ItemEvent.SELECTED)
748 cmbAssSeqStateChanged();
753 public JTable getResultTable()
757 public JComboBox<FilterOption> getCmbFilterOption()
759 return cmb_filterOption;
762 protected abstract void stateChanged(ItemEvent e);
764 protected abstract void updateCurrentView();
766 protected abstract void populateFilterComboBox();
768 protected abstract void ok_ActionPerformed();
770 protected abstract void pdbFromFile_actionPerformed();
772 protected abstract void txt_search_ActionPerformed();
774 public abstract void populateCmbAssociateSeqOptions(
775 JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
777 public abstract void cmbAssSeqStateChanged();
779 public abstract void tabRefresh();
781 public abstract void validateSelections();