/* * Jalview - A Sequence Alignment Editor and Viewer * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package jalview.gui; import jalview.datamodel.*; import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.util.*; import javax.swing.BorderFactory; import java.awt.event.*; import javax.swing.table.*; import java.io.*; import jalview.io.JalviewFileChooser; public class FeatureSettings extends JPanel { final FeatureRenderer fr; final AlignmentPanel ap; final AlignViewport av; Object [][] originalData; final JInternalFrame frame; JScrollPane scrollPane = new JScrollPane(); JTable table; JPanel groupPanel; boolean alignmentHasFeatures = false; public FeatureSettings(AlignViewport av, final AlignmentPanel ap) { this.ap = ap; this.av = av; fr = ap.seqPanel.seqCanvas.getFeatureRenderer(); av.alignment.getSequences(); frame = new JInternalFrame(); frame.setContentPane(this); Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 300); frame.setLayer(JLayeredPane.PALETTE_LAYER); setTableData(); final JSlider transparency = new JSlider(0, 70, 100 - (int)(fr.transparency*100) ); transparency.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent evt) { fr.setTransparency( (float) (100 - transparency.getValue()) / 100f); ap.repaint(); } }); JPanel transPanel = new JPanel(new FlowLayout()); transPanel.add(new JLabel("Transparency")); transPanel.add(transparency); ////////////////////////////////////////////// //We're going to need those OK cancel buttons JPanel buttonPanel = new JPanel(new FlowLayout()); JButton button = new JButton("OK"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { try { frame.setClosed(true); } catch (Exception exe) {} } }); buttonPanel.add(button); button = new JButton("Cancel"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { try { updateFeatureRenderer(originalData); frame.setClosed(true); } catch (Exception exe) {} } }); buttonPanel.add(button); button = new JButton("Load Colours"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { load(); } }); buttonPanel.add(button); button = new JButton("Save Colours"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { save(); } }); buttonPanel.add(button); this.setLayout(new BorderLayout()); JPanel bigPanel = new JPanel(new BorderLayout()); bigPanel.add(transPanel, BorderLayout.SOUTH); bigPanel.add(scrollPane, BorderLayout.CENTER); if(groupPanel!=null) { groupPanel.setLayout( new GridLayout(fr.featureGroups.size() / 4 + 1, 4)); groupPanel.validate(); bigPanel.add(groupPanel, BorderLayout.NORTH); } add(bigPanel, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); } void setTableData() { alignmentHasFeatures = false; if (fr.featureGroups == null) fr.featureGroups = new Hashtable(); Vector allFeatures = new Vector(); Vector allGroups = new Vector(); SequenceFeature[] tmpfeatures; String group; for (int i = 0; i < av.alignment.getHeight(); i++) { if (av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures() == null) continue; alignmentHasFeatures = true; tmpfeatures = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures(); int index = 0; while (index < tmpfeatures.length) { if(tmpfeatures[index].getFeatureGroup()!=null) { group = tmpfeatures[index].featureGroup; if(!allGroups.contains(group)) { allGroups.addElement(group); boolean visible = true; if (fr.featureGroups.containsKey(group)) { visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue(); } fr.featureGroups.put(group, new Boolean(visible)); if (groupPanel == null) { groupPanel = new JPanel(); } final JCheckBox check = new JCheckBox(group, visible); check.setFont(new Font("Serif", Font.BOLD, 12)); check.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent evt) { fr.featureGroups.put(check.getText(), new Boolean(check.isSelected())); ap.seqPanel.seqCanvas.repaint(); if (ap.overviewPanel != null) ap.overviewPanel.updateOverviewImage(); resetTable(true); } }); groupPanel.add(check); } } if (!allFeatures.contains(tmpfeatures[index].getType())) { allFeatures.addElement(tmpfeatures[index].getType()); } index ++; } } if(!alignmentHasFeatures) { try { frame.setClosed(true); } catch (Exception ex){} JOptionPane.showInternalMessageDialog( Desktop.desktop, "No features have been added to this alignment!", "No Sequence Features", JOptionPane.WARNING_MESSAGE); return; } resetTable(false); } void resetTable(boolean groupsChanged) { SequenceFeature [] tmpfeatures; String group=null, type; Vector visibleChecks = new Vector(); //Find out which features should be visible depending on which groups //are selected / deselected for (int i = 0; i < av.alignment.getHeight(); i++) { if (av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures() == null) continue; tmpfeatures = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures(); int index = 0; while (index < tmpfeatures.length) { group = tmpfeatures[index].featureGroup; if (group==null || fr.featureGroups.get(group)==null || ((Boolean) fr.featureGroups.get(group)).booleanValue()) { type = tmpfeatures[index].getType(); if(!visibleChecks.contains(type) ) { visibleChecks.addElement(type); } } index++; } } int fSize = visibleChecks.size(); Object [][] data = new Object[fSize][3]; int dataIndex = 0; if(fr.renderOrder!=null) { //First add the checks in the previous render order, //in case the window has been closed and reopened for(int ro=fr.renderOrder.length-1; ro>-1; ro--) { type = fr.renderOrder[ro]; if(!visibleChecks.contains(type)) continue; data[dataIndex][0] = type; data[dataIndex][1] = fr.getColour(type); data[dataIndex][2] = new Boolean(av.featuresDisplayed.containsKey(type)); dataIndex++; visibleChecks.removeElement(type); } } fSize = visibleChecks.size(); for(int i=0; i