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 private 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();
387 btn_view.setFont(new java.awt.Font("Verdana", 0, 12));
388 btn_view.setText(MessageManager.getString("action.view"));
389 btn_view.addActionListener(new java.awt.event.ActionListener()
392 public void actionPerformed(ActionEvent e)
394 ok_ActionPerformed();
397 btn_view.addKeyListener(new KeyAdapter()
400 public void keyPressed(KeyEvent evt)
402 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
404 ok_ActionPerformed();
409 btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12));
410 btn_cancel.setText(MessageManager.getString("action.cancel"));
411 btn_cancel.addActionListener(new java.awt.event.ActionListener()
414 public void actionPerformed(ActionEvent e)
419 btn_cancel.addKeyListener(new KeyAdapter()
422 public void keyPressed(KeyEvent evt)
424 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
431 btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12));
432 String btn_title = MessageManager.getString("label.select_pdb_file");
433 btn_pdbFromFile.setText(btn_title + " ");
434 btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener()
437 public void actionPerformed(ActionEvent e)
439 pdbFromFile_actionPerformed();
442 btn_pdbFromFile.addKeyListener(new KeyAdapter()
445 public void keyPressed(KeyEvent evt)
447 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
449 pdbFromFile_actionPerformed();
454 scrl_foundStructures.setPreferredSize(new Dimension(width, height));
456 scrl_localPDB.setPreferredSize(new Dimension(width, height));
458 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
460 cmb_filterOption.setFont(new java.awt.Font("Verdana", 0, 12));
461 chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12));
462 chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
463 chk_rememberSettings.setVisible(false);
464 txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
465 MessageManager.getString("label.enter_pdb_id")));
466 cmb_filterOption.setToolTipText(MessageManager
467 .getString("info.select_filter_option"));
468 txt_search.getDocument().addDocumentListener(new DocumentListener()
471 public void insertUpdate(DocumentEvent e)
473 txt_search_ActionPerformed();
477 public void removeUpdate(DocumentEvent e)
479 txt_search_ActionPerformed();
483 public void changedUpdate(DocumentEvent e)
485 txt_search_ActionPerformed();
489 cmb_filterOption.addItemListener(this);
490 chk_invertFilter.addItemListener(this);
492 pnl_actions.add(chk_rememberSettings);
493 pnl_actions.add(btn_view);
494 pnl_actions.add(btn_cancel);
496 // pnl_filter.add(lbl_result);
497 pnl_main.add(cmb_filterOption);
498 pnl_main.add(lbl_loading);
499 pnl_main.add(chk_invertFilter);
500 lbl_loading.setVisible(false);
502 pnl_fileChooser.add(btn_pdbFromFile);
503 pnl_fileChooser.add(lbl_fromFileStatus);
504 pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH);
505 pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER);
507 pnl_idInput.add(txt_search);
508 pnl_idInput.add(lbl_pdbManualFetchStatus);
509 pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH);
510 pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER);
512 final String foundStructureSummary = MessageManager
513 .getString("label.found_structures_summary");
514 final String configureCols = MessageManager
515 .getString("label.configure_displayed_columns");
516 ChangeListener changeListener = new ChangeListener()
519 public void stateChanged(ChangeEvent changeEvent)
521 JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
523 int index = sourceTabbedPane.getSelectedIndex();
524 btn_view.setVisible(true);
525 btn_cancel.setVisible(true);
526 if (sourceTabbedPane.getTitleAt(index).equals(configureCols))
528 btn_view.setEnabled(false);
529 btn_cancel.setEnabled(false);
530 btn_view.setVisible(false);
531 btn_cancel.setVisible(false);
532 previousWantedFields = pdbDocFieldPrefs
533 .getStructureSummaryFields().toArray(
534 new FTSDataColumnI[0]);
536 if (sourceTabbedPane.getTitleAt(index)
537 .equals(foundStructureSummary))
539 btn_cancel.setEnabled(true);
540 if (wantedFieldsUpdated())
546 validateSelections();
551 pnl_filter.addChangeListener(changeListener);
552 pnl_filter.setPreferredSize(new Dimension(width, height));
553 pnl_filter.add(foundStructureSummary, scrl_foundStructures);
554 pnl_filter.add(configureCols, pdbDocFieldPrefs);
556 pnl_locPDB.add(scrl_localPDB);
558 pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE);
559 pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID);
560 pnl_switchableViews.add(pnl_filter, VIEWS_FILTER);
561 pnl_switchableViews.add(pnl_locPDB, VIEWS_LOCAL_PDB);
563 this.setLayout(mainLayout);
564 this.add(pnl_main, java.awt.BorderLayout.NORTH);
565 this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
566 // this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
567 statusPanel.setLayout(new GridLayout());
568 pnl_actionsAndStatus.add(pnl_actions, BorderLayout.CENTER);
569 pnl_actionsAndStatus.add(statusPanel, BorderLayout.SOUTH);
570 statusPanel.add(statusBar, null);
571 this.add(pnl_actionsAndStatus, java.awt.BorderLayout.SOUTH);
574 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
577 public void internalFrameClosing(InternalFrameEvent e)
582 mainFrame.setVisible(true);
583 mainFrame.setContentPane(this);
584 mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
585 Integer x = tempUserPrefs.get("structureChooser.x");
586 Integer y = tempUserPrefs.get("structureChooser.y");
587 if (x != null && y != null)
589 mainFrame.setLocation(x, y);
591 Desktop.addInternalFrame(mainFrame, frameTitle, width, height);
594 protected void closeAction()
596 // System.out.println(">>>>>>>>>> closing internal frame!!!");
597 // System.out.println("width : " + mainFrame.getWidth());
598 // System.out.println("heigh : " + mainFrame.getHeight());
599 // System.out.println("x : " + mainFrame.getX());
600 // System.out.println("y : " + mainFrame.getY());
601 tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
602 tempUserPrefs.put("structureChooser.height", pnl_filter.getHeight());
603 tempUserPrefs.put("structureChooser.x", mainFrame.getX());
604 tempUserPrefs.put("structureChooser.y", mainFrame.getY());
607 public boolean wantedFieldsUpdated()
609 if (previousWantedFields == null)
614 FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
615 .getStructureSummaryFields()
616 .toArray(new FTSDataColumnI[0]);
617 return Arrays.equals(currentWantedFields, previousWantedFields) ? false
624 * Event listener for the 'filter' combo-box and 'invert' check-box
626 public void itemStateChanged(ItemEvent e)
632 * This inner class provides the data model for the structure filter combo-box
637 public class FilterOption
641 private String value;
645 public FilterOption(String name, String value, String view)
652 public String getName()
657 public void setName(String name)
662 public String getValue()
667 public void setValue(String value)
672 public String getView()
677 public void setView(String view)
683 public String toString()
690 * This inner class provides the provides the data model for associate
691 * sequence combo-box - cmb_assSeq
696 public class AssociateSeqOptions
698 private SequenceI sequence;
702 public AssociateSeqOptions(SequenceI seq)
705 this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
706 0, 23) : seq.getName();
709 public AssociateSeqOptions(String name, SequenceI seq)
716 public String toString()
721 public String getName()
726 public void setName(String name)
731 public SequenceI getSequence()
736 public void setSequence(SequenceI sequence)
738 this.sequence = sequence;
744 * This inner class holds the Layout and configuration of the panel which
745 * handles association of manually fetched structures to a unique sequence
746 * when more than one sequence selection is made
751 public class AssciateSeqPanel extends JPanel implements ItemListener
753 private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
755 private JLabel lbl_associateSeq = new JLabel();
757 public AssciateSeqPanel()
759 this.setLayout(new FlowLayout());
760 this.add(cmb_assSeq);
761 this.add(lbl_associateSeq);
762 cmb_assSeq.setToolTipText(MessageManager
763 .getString("info.associate_wit_sequence"));
764 cmb_assSeq.addItemListener(this);
767 public void loadCmbAssSeq()
769 populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
772 public JComboBox<AssociateSeqOptions> getCmb_assSeq()
777 public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
779 this.cmb_assSeq = cmb_assSeq;
783 public void itemStateChanged(ItemEvent e)
785 if (e.getStateChange() == ItemEvent.SELECTED)
787 cmbAssSeqStateChanged();
792 public JTable getResultTable()
796 public JComboBox<FilterOption> getCmbFilterOption()
798 return cmb_filterOption;
801 protected abstract void stateChanged(ItemEvent e);
803 protected abstract void updateCurrentView();
805 protected abstract void populateFilterComboBox();
807 protected abstract void ok_ActionPerformed();
809 protected abstract void pdbFromFile_actionPerformed();
811 protected abstract void txt_search_ActionPerformed();
813 public abstract void populateCmbAssociateSeqOptions(
814 JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
816 public abstract void cmbAssSeqStateChanged();
818 public abstract void tabRefresh();
820 public abstract void validateSelections();