2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 import java.awt.event.*;
27 import javax.swing.event.*;
28 import javax.swing.table.*;
30 import jalview.datamodel.*;
33 public class FeatureSettings
36 DasSourceBrowser dassourceBrowser;
37 jalview.io.DasSequenceFeatureFetcher dasFeatureFetcher;
38 JPanel settingsPane = new JPanel();
39 JPanel dasSettingsPane = new JPanel();
41 final FeatureRenderer fr;
42 public final AlignFrame af;
43 Object[][] originalData;
44 final JInternalFrame frame;
45 JScrollPane scrollPane = new JScrollPane();
48 JSlider transparency = new JSlider();
50 JPanel transPanel = new JPanel(new FlowLayout());
52 public FeatureSettings(AlignFrame af)
55 fr = af.getFeatureRenderer();
57 transparency.setMaximum(100 - (int) (fr.transparency * 100));
69 table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
70 table.setFont(new Font("Verdana", Font.PLAIN, 12));
71 table.setDefaultRenderer(Color.class,
74 table.setDefaultEditor(Color.class,
77 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
79 table.addMouseListener(new MouseAdapter()
81 public void mousePressed(MouseEvent evt)
83 selectedRow = table.rowAtPoint(evt.getPoint());
87 table.addMouseMotionListener(new MouseMotionAdapter()
89 public void mouseDragged(MouseEvent evt)
91 int newRow = table.rowAtPoint(evt.getPoint());
92 if (newRow != selectedRow
96 Object[] temp = new Object[3];
97 temp[0] = table.getValueAt(selectedRow, 0);
98 temp[1] = table.getValueAt(selectedRow, 1);
99 temp[2] = table.getValueAt(selectedRow, 2);
101 table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
102 table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
103 table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
105 table.setValueAt(temp[0], newRow, 0);
106 table.setValueAt(temp[1], newRow, 1);
107 table.setValueAt(temp[2], newRow, 2);
109 selectedRow = newRow;
114 scrollPane.setViewportView(table);
116 dassourceBrowser = new DasSourceBrowser();
117 dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
119 if (af.getViewport().featuresDisplayed == null || fr.renderOrder == null)
121 fr.findAllFeatures();
126 frame = new JInternalFrame();
127 frame.setContentPane(this);
128 Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 450);
129 frame.setLayer(JLayeredPane.PALETTE_LAYER);
132 synchronized public void setTableData()
134 if (fr.featureGroups == null)
136 fr.featureGroups = new Hashtable();
139 Vector allFeatures = new Vector();
140 Vector allGroups = new Vector();
141 SequenceFeature[] tmpfeatures;
144 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
146 if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().
147 getSequenceFeatures() == null)
152 tmpfeatures = af.getViewport().alignment.getSequenceAt(i).
153 getDatasetSequence().getSequenceFeatures();
156 while (index < tmpfeatures.length)
158 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
164 if (tmpfeatures[index].getFeatureGroup() != null)
166 group = tmpfeatures[index].featureGroup;
167 if (!allGroups.contains(group))
169 allGroups.addElement(group);
171 boolean visible = true;
172 if (fr.featureGroups.containsKey(group))
174 visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();
177 if (groupPanel == null)
179 groupPanel = new JPanel();
182 boolean alreadyAdded = false;
183 for (int g = 0; g < groupPanel.getComponentCount(); g++)
185 if ( ( (JCheckBox) groupPanel.getComponent(g))
186 .getText().equals(group))
198 fr.featureGroups.put(group, new Boolean(visible));
200 final JCheckBox check = new JCheckBox(group, visible);
201 check.setFont(new Font("Serif", Font.BOLD, 12));
202 check.addItemListener(new ItemListener()
204 public void itemStateChanged(ItemEvent evt)
206 fr.featureGroups.put(check.getText(),
207 new Boolean(check.isSelected()));
208 af.alignPanel.seqPanel.seqCanvas.repaint();
209 if (af.alignPanel.overviewPanel != null)
211 af.alignPanel.overviewPanel.updateOverviewImage();
217 groupPanel.add(check);
221 if (!allFeatures.contains(tmpfeatures[index].getType()))
223 allFeatures.addElement(tmpfeatures[index].getType());
234 void resetTable(boolean groupsChanged)
236 SequenceFeature[] tmpfeatures;
237 String group = null, type;
238 Vector visibleChecks = new Vector();
240 //Find out which features should be visible depending on which groups
241 //are selected / deselected
242 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
245 tmpfeatures = af.getViewport().alignment.getSequenceAt(i).
246 getDatasetSequence().getSequenceFeatures();
247 if (tmpfeatures == null)
253 while (index < tmpfeatures.length)
255 group = tmpfeatures[index].featureGroup;
257 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
263 if (group == null || fr.featureGroups.get(group) == null ||
264 ( (Boolean) fr.featureGroups.get(group)).booleanValue())
266 type = tmpfeatures[index].getType();
267 if (!visibleChecks.contains(type))
269 visibleChecks.addElement(type);
276 int fSize = visibleChecks.size();
277 Object[][] data = new Object[fSize][3];
280 if (fr.renderOrder != null)
282 //First add the checks in the previous render order,
283 //in case the window has been closed and reopened
284 for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
286 type = fr.renderOrder[ro];
288 if (!visibleChecks.contains(type))
293 data[dataIndex][0] = type;
294 data[dataIndex][1] = fr.getColour(type);
295 data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed.
298 visibleChecks.removeElement(type);
302 fSize = visibleChecks.size();
303 for (int i = 0; i < fSize; i++)
305 //These must be extra features belonging to the group
306 //which was just selected
307 type = visibleChecks.elementAt(i).toString();
308 data[dataIndex][0] = type;
310 data[dataIndex][1] = fr.getColour(type);
311 if (data[dataIndex][1] == null)
313 //"Colour has been updated in another view!!"
314 fr.renderOrder = null;
318 data[dataIndex][2] = new Boolean(true);
322 if (originalData == null)
324 originalData = new Object[data.length][3];
325 System.arraycopy(data, 0, originalData, 0, data.length);
328 table.setModel(new FeatureTableModel(data));
329 table.getColumnModel().getColumn(0).setPreferredWidth(200);
331 if (groupPanel != null)
333 groupPanel.setLayout(
334 new GridLayout(fr.featureGroups.size() / 4 + 1, 4));
336 groupPanel.validate();
337 bigPanel.add(groupPanel, BorderLayout.NORTH);
340 updateFeatureRenderer(data);
346 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
348 "LAST_DIRECTORY"), new String[]
351 {"Sequence Feature Colours"}, "Sequence Feature Colours");
352 chooser.setFileView(new jalview.io.JalviewFileView());
353 chooser.setDialogTitle("Load Feature Colours");
354 chooser.setToolTipText("Load");
356 int value = chooser.showOpenDialog(this);
358 if (value == JalviewFileChooser.APPROVE_OPTION)
360 File file = chooser.getSelectedFile();
364 InputStreamReader in = new InputStreamReader(new FileInputStream(
367 jalview.binding.JalviewUserColours jucs = new jalview.binding.
368 JalviewUserColours();
369 jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
371 for (int i = 0; i < jucs.getColourCount(); i++)
373 fr.setColour(jucs.getColour(i).getName(),
374 new Color(Integer.parseInt(jucs.getColour(i).getRGB(),
379 af.alignPanel.paintAlignment(true);
383 System.out.println("Error loading User Colour File\n" + ex);
390 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
392 "LAST_DIRECTORY"), new String[]
395 {"Sequence Feature Colours"}, "Sequence Feature Colours");
396 chooser.setFileView(new jalview.io.JalviewFileView());
397 chooser.setDialogTitle("Save Feature Colour Scheme");
398 chooser.setToolTipText("Save");
400 int value = chooser.showSaveDialog(this);
402 if (value == JalviewFileChooser.APPROVE_OPTION)
404 String choice = chooser.getSelectedFile().getPath();
405 jalview.binding.JalviewUserColours ucs = new jalview.binding.
406 JalviewUserColours();
407 ucs.setSchemeName("Sequence Features");
410 PrintWriter out = new PrintWriter(new OutputStreamWriter(
411 new FileOutputStream(choice), "UTF-8"));
413 Enumeration e = fr.featureColours.keys();
414 while (e.hasMoreElements())
416 jalview.binding.Colour col = new jalview.binding.Colour();
417 col.setName(e.nextElement().toString());
418 col.setRGB(jalview.util.Format.getHexString(
419 fr.getColour(col.getName())));
428 ex.printStackTrace();
433 public void invertSelection()
435 for (int i = 0; i < table.getRowCount(); i++)
437 Boolean value = (Boolean) table.getValueAt(i, 2);
440 new Boolean(!value.booleanValue()),
449 frame.setClosed(true);
451 catch (Exception exe)
456 public void updateFeatureRenderer(Object[][] data)
458 fr.setFeaturePriority(data);
459 af.alignPanel.paintAlignment(true);
461 if (af.alignPanel.overviewPanel != null)
463 af.alignPanel.overviewPanel.updateOverviewImage();
467 int selectedRow = -1;
468 JTabbedPane tabbedPane = new JTabbedPane();
469 BorderLayout borderLayout1 = new BorderLayout();
470 BorderLayout borderLayout2 = new BorderLayout();
471 BorderLayout borderLayout3 = new BorderLayout();
472 JPanel bigPanel = new JPanel();
473 BorderLayout borderLayout4 = new BorderLayout();
474 JButton invert = new JButton();
475 JPanel buttonPanel = new JPanel();
476 JButton cancel = new JButton();
477 JButton ok = new JButton();
478 JButton loadColours = new JButton();
479 JButton saveColours = new JButton();
480 JPanel dasButtonPanel = new JPanel();
481 JButton fetchDAS = new JButton();
482 JButton saveDAS = new JButton();
483 JButton cancelDAS = new JButton();
484 private void jbInit()
487 this.setLayout(borderLayout1);
488 settingsPane.setLayout(borderLayout2);
489 dasSettingsPane.setLayout(borderLayout3);
490 bigPanel.setLayout(borderLayout4);
491 invert.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
492 invert.setText("Invert Selection");
493 invert.addActionListener(new ActionListener()
495 public void actionPerformed(ActionEvent e)
500 cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
501 cancel.setText("Cancel");
502 cancel.addActionListener(new ActionListener()
504 public void actionPerformed(ActionEvent e)
506 updateFeatureRenderer(originalData);
510 ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
512 ok.addActionListener(new ActionListener()
514 public void actionPerformed(ActionEvent e)
519 loadColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
520 loadColours.setText("Load Colours");
521 loadColours.addActionListener(new ActionListener()
523 public void actionPerformed(ActionEvent e)
528 saveColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
529 saveColours.setText("Save Colours");
530 saveColours.addActionListener(new ActionListener()
532 public void actionPerformed(ActionEvent e)
537 transparency.addChangeListener(new ChangeListener()
539 public void stateChanged(ChangeEvent evt)
541 fr.setTransparency( (float) (100 - transparency.getValue()) / 100f);
542 af.alignPanel.paintAlignment(true);
546 transparency.setMaximum(70);
547 fetchDAS.setText("Fetch DAS Features");
548 fetchDAS.addActionListener(new ActionListener()
550 public void actionPerformed(ActionEvent e)
552 fetchDAS_actionPerformed(e);
555 saveDAS.setText("Save as default");
556 saveDAS.addActionListener(new ActionListener()
558 public void actionPerformed(ActionEvent e)
560 saveDAS_actionPerformed(e);
563 dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
564 dasSettingsPane.setBorder(null);
565 cancelDAS.setEnabled(false);
566 cancelDAS.setText("Cancel Fetch");
567 cancelDAS.addActionListener(new ActionListener()
569 public void actionPerformed(ActionEvent e)
571 cancelDAS_actionPerformed(e);
574 this.add(tabbedPane, java.awt.BorderLayout.CENTER);
575 tabbedPane.addTab("Feature Settings", settingsPane);
576 tabbedPane.addTab("DAS Settings", dasSettingsPane);
577 bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
578 transPanel.add(transparency);
579 transPanel.add(invert);
581 buttonPanel.add(cancel);
582 buttonPanel.add(loadColours);
583 buttonPanel.add(saveColours);
584 bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);
585 dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);
586 dasButtonPanel.add(fetchDAS);
587 dasButtonPanel.add(cancelDAS);
588 dasButtonPanel.add(saveDAS);
589 settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);
590 settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
593 public void fetchDAS_actionPerformed(ActionEvent e)
595 fetchDAS.setEnabled(false);
596 cancelDAS.setEnabled(true);
597 Vector selectedSources = dassourceBrowser.getSelectedSources();
599 SequenceI[] dataset, seqs;
602 if (af.getViewport().getSelectionGroup() != null
603 && af.getViewport().getSelectionGroup().getSize() > 0)
605 iSize = af.getViewport().getSelectionGroup().getSize();
606 dataset = new SequenceI[iSize];
607 seqs = af.getViewport().getSelectionGroup().
609 af.getViewport().getAlignment());
613 iSize = af.getViewport().getAlignment().getHeight();
614 seqs = af.getViewport().getAlignment().getSequencesArray();
617 dataset = new SequenceI[iSize];
618 for (int i = 0; i < iSize; i++)
620 dataset[i] = seqs[i].getDatasetSequence();
624 new jalview.io.DasSequenceFeatureFetcher(
628 cancelDAS.setEnabled(true);
629 af.getViewport().setShowSequenceFeatures(true);
630 af.showSeqFeatures.setSelected(true);
633 public void saveDAS_actionPerformed(ActionEvent e)
635 dassourceBrowser.saveProperties(jalview.bin.Cache.applicationProperties);
638 public void complete()
640 fetchDAS.setEnabled(true);
641 cancelDAS.setEnabled(false);
644 public void cancelDAS_actionPerformed(ActionEvent e)
646 dasFeatureFetcher.cancel();
647 fetchDAS.setEnabled(true);
648 cancelDAS.setEnabled(false);
651 /////////////////////////////////////////////////////////////////////////
652 // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
653 /////////////////////////////////////////////////////////////////////////
654 class FeatureTableModel
655 extends AbstractTableModel
657 FeatureTableModel(Object[][] data)
662 private String[] columnNames =
664 "Feature Type", "Colour", "Display"};
665 private Object[][] data;
667 public Object[][] getData()
672 public void setData(Object[][] data)
677 public int getColumnCount()
679 return columnNames.length;
682 public Object[] getRow(int row)
687 public int getRowCount()
692 public String getColumnName(int col)
694 return columnNames[col];
697 public Object getValueAt(int row, int col)
699 return data[row][col];
702 public Class getColumnClass(int c)
704 return getValueAt(0, c).getClass();
707 public boolean isCellEditable(int row, int col)
709 return col == 0 ? false : true;
712 public void setValueAt(Object value, int row, int col)
714 data[row][col] = value;
715 fireTableCellUpdated(row, col);
716 updateFeatureRenderer(data);
722 extends JLabel implements TableCellRenderer
724 javax.swing.border.Border unselectedBorder = null;
725 javax.swing.border.Border selectedBorder = null;
727 public ColorRenderer()
729 setOpaque(true); //MUST do this for background to show up.
732 public Component getTableCellRendererComponent(
733 JTable table, Object color,
734 boolean isSelected, boolean hasFocus,
737 Color newColor = (Color) color;
738 setBackground(newColor);
741 if (selectedBorder == null)
743 selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
744 table.getSelectionBackground());
746 setBorder(selectedBorder);
750 if (unselectedBorder == null)
752 unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
753 table.getBackground());
755 setBorder(unselectedBorder);
758 setToolTipText("RGB value: " + newColor.getRed() + ", "
759 + newColor.getGreen() + ", "
760 + newColor.getBlue());
767 extends AbstractCellEditor implements TableCellEditor,
772 JColorChooser colorChooser;
774 protected static final String EDIT = "edit";
778 //Set up the editor (from the table's point of view),
780 //This button brings up the color chooser dialog,
781 //which is the editor from the user's point of view.
782 button = new JButton();
783 button.setActionCommand(EDIT);
784 button.addActionListener(this);
785 button.setBorderPainted(false);
786 //Set up the dialog that the button brings up.
787 colorChooser = new JColorChooser();
788 dialog = JColorChooser.createDialog(button,
792 this, //OK button handler
793 null); //no CANCEL button handler
797 * Handles events from the editor button and from
798 * the dialog's OK button.
800 public void actionPerformed(ActionEvent e)
803 if (EDIT.equals(e.getActionCommand()))
805 //The user has clicked the cell, so
806 //bring up the dialog.
807 button.setBackground(currentColor);
808 colorChooser.setColor(currentColor);
809 dialog.setVisible(true);
811 //Make the renderer reappear.
812 fireEditingStopped();
816 { //User pressed dialog's "OK" button.
817 currentColor = colorChooser.getColor();
821 //Implement the one CellEditor method that AbstractCellEditor doesn't.
822 public Object getCellEditorValue()
827 //Implement the one method defined by TableCellEditor.
828 public Component getTableCellEditorComponent(JTable table,
834 currentColor = (Color) value;