2 * Jalview - A Sequence Alignment Editor and Viewer
\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
\r
5 * This program is free software; you can redistribute it and/or
\r
6 * modify it under the terms of the GNU General Public License
\r
7 * as published by the Free Software Foundation; either version 2
\r
8 * of the License, or (at your option) any later version.
\r
10 * This program is distributed in the hope that it will be useful,
\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 * GNU General Public License for more details.
\r
15 * You should have received a copy of the GNU General Public License
\r
16 * along with this program; if not, write to the Free Software
\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
\r
19 package jalview.gui;
\r
21 import jalview.datamodel.*;
\r
22 import javax.swing.*;
\r
23 import javax.swing.event.*;
\r
26 import javax.swing.BorderFactory;
\r
27 import java.awt.event.*;
\r
28 import javax.swing.table.*;
\r
30 import jalview.io.JalviewFileChooser;
\r
32 public class FeatureSettings extends JPanel
\r
35 final FeatureRenderer fr;
\r
36 final AlignmentPanel ap;
\r
37 final AlignViewport av;
\r
38 Object [][] originalData;
\r
39 final JInternalFrame frame;
\r
40 JScrollPane scrollPane = new JScrollPane();
\r
43 public FeatureSettings(AlignViewport av, final AlignmentPanel ap)
\r
47 fr = ap.seqPanel.seqCanvas.getFeatureRenderer();
\r
48 av.alignment.getSequences();
\r
49 frame = new JInternalFrame();
\r
50 frame.setContentPane(this);
\r
51 Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 300);
\r
55 final JSlider transparency = new JSlider(0, 70, 0);
\r
56 transparency.addChangeListener(new ChangeListener()
\r
58 public void stateChanged(ChangeEvent evt)
\r
60 fr.setTransparency( (float) (100 - transparency.getValue()) / 100f);
\r
65 JPanel transPanel = new JPanel(new FlowLayout());
\r
66 transPanel.add(new JLabel("Transparency"));
\r
67 transPanel.add(transparency);
\r
69 //////////////////////////////////////////////
\r
70 //We're going to need those OK cancel buttons
\r
71 JPanel buttonPanel = new JPanel(new FlowLayout());
\r
72 JButton button = new JButton("OK");
\r
73 button.addActionListener(new ActionListener()
\r
75 public void actionPerformed(ActionEvent evt)
\r
79 frame.setClosed(true);
\r
81 catch (Exception exe)
\r
85 buttonPanel.add(button);
\r
86 button = new JButton("Cancel");
\r
87 button.addActionListener(new ActionListener()
\r
89 public void actionPerformed(ActionEvent evt)
\r
93 updateFeatureRenderer(originalData);
\r
94 frame.setClosed(true);
\r
96 catch (Exception exe)
\r
100 buttonPanel.add(button);
\r
102 button = new JButton("Load Colours");
\r
103 button.addActionListener(new ActionListener()
\r
105 public void actionPerformed(ActionEvent evt)
\r
110 buttonPanel.add(button);
\r
111 button = new JButton("Save Colours");
\r
112 button.addActionListener(new ActionListener()
\r
114 public void actionPerformed(ActionEvent evt)
\r
119 buttonPanel.add(button);
\r
121 this.setLayout(new BorderLayout());
\r
122 JPanel bigPanel = new JPanel(new BorderLayout());
\r
123 bigPanel.add(transPanel, BorderLayout.SOUTH);
\r
124 bigPanel.add(scrollPane, BorderLayout.CENTER);
\r
126 add(bigPanel, BorderLayout.CENTER);
\r
127 add(buttonPanel, BorderLayout.SOUTH);
\r
132 void setTableData()
\r
134 Vector allFeatures = new Vector();
\r
137 SequenceFeature sf;
\r
139 for(int i=0; i< av.alignment.getHeight(); i++)
\r
141 features = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();
\r
145 e = features.elements();
\r
146 while(e.hasMoreElements())
\r
148 sf = (SequenceFeature)e.nextElement();
\r
149 if(!allFeatures.contains(sf.getType()))
\r
151 allFeatures.addElement(sf.getType());
\r
155 if(allFeatures.size()<1)
\r
158 frame.setClosed(true);
\r
159 }catch(Exception ex){}
\r
163 int fSize = allFeatures.size();
\r
166 boolean originalExists = false;
\r
167 if(originalData!=null)
\r
168 originalExists = true;
\r
170 originalData = new Object[fSize][3];
\r
172 Object [][] data = new Object[fSize][3];
\r
173 for(int i=0; i<fSize; i++)
\r
175 type = allFeatures.elementAt(i).toString();
\r
176 Color col = fr.getColour(type);
\r
179 if(fr.featuresDisplayed!=null)
\r
180 data[i][2] = new Boolean(fr.featuresDisplayed.contains(type));
\r
182 data[i][2] = new Boolean(true);
\r
184 if(!originalExists)
\r
186 originalData[i][0] = type;
\r
187 originalData[i][1] = col;
\r
188 if (fr.featuresDisplayed != null)
\r
189 originalData[i][2] = new Boolean(fr.featuresDisplayed.contains(type));
\r
191 originalData[i][2] = new Boolean(true);
\r
194 ////////////////////////////////////
\r
195 //Now build the table
\r
196 table = new JTable(new FeatureTableModel(data));
\r
197 scrollPane.setViewportView(table);
\r
198 table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
\r
199 table.setFont(new Font("Verdana", Font.PLAIN, 12));
\r
200 table.setDefaultRenderer(Color.class,
\r
201 new ColorRenderer());
\r
203 table.setDefaultEditor(Color.class,
\r
204 new ColorEditor());
\r
206 table.getColumnModel().getColumn(0).setPreferredWidth(200);
\r
208 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
\r
210 table.addMouseListener(new MouseAdapter()
\r
212 public void mousePressed(MouseEvent evt)
\r
214 selectedRow = table.rowAtPoint(evt.getPoint());
\r
218 table.addMouseMotionListener(new MouseMotionAdapter()
\r
220 public void mouseDragged(MouseEvent evt)
\r
222 int newRow = table.rowAtPoint(evt.getPoint());
\r
223 if(newRow!=selectedRow
\r
227 Object[] temp = new Object[3];
\r
228 temp[0] = table.getValueAt(selectedRow, 0);
\r
229 temp[1] = table.getValueAt(selectedRow, 1);
\r
230 temp[2] = table.getValueAt(selectedRow, 2);
\r
232 table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
\r
233 table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
\r
234 table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
\r
236 table.setValueAt(temp[0], newRow, 0);
\r
237 table.setValueAt(temp[1], newRow, 1);
\r
238 table.setValueAt(temp[2], newRow, 2);
\r
240 selectedRow = newRow;
\r
249 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
\r
250 "LAST_DIRECTORY"), new String[] { "fc" },
\r
251 new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");
\r
252 chooser.setFileView(new jalview.io.JalviewFileView());
\r
253 chooser.setDialogTitle("Load Feature Colours");
\r
254 chooser.setToolTipText("Load");
\r
256 int value = chooser.showOpenDialog(this);
\r
258 if (value == JalviewFileChooser.APPROVE_OPTION)
\r
260 File file = chooser.getSelectedFile();
\r
264 InputStreamReader in = new InputStreamReader(new FileInputStream(
\r
267 jalview.binding.JalviewUserColours jucs = new jalview.binding.
\r
268 JalviewUserColours();
\r
269 jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
\r
272 for (int i = 0; i < jucs.getColourCount(); i++)
\r
274 fr.setColour( jucs.getColour(i).getName(),
\r
275 new Color(Integer.parseInt( jucs.getColour(i).getRGB(), 16)));
\r
281 catch (Exception ex)
\r
283 System.out.println("Error loading User ColourFile\n" + ex);
\r
290 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
\r
291 "LAST_DIRECTORY"), new String[] { "fc" },
\r
292 new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");
\r
293 chooser.setFileView(new jalview.io.JalviewFileView());
\r
294 chooser.setDialogTitle("Save Feature Colour Scheme");
\r
295 chooser.setToolTipText("Save");
\r
297 int value = chooser.showSaveDialog(this);
\r
299 if (value == JalviewFileChooser.APPROVE_OPTION)
\r
301 String choice = chooser.getSelectedFile().getPath();
\r
302 jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();
\r
303 ucs.setSchemeName("Sequence Features");
\r
306 PrintWriter out = new PrintWriter(new OutputStreamWriter(
\r
307 new FileOutputStream(choice), "UTF-8"));
\r
309 Enumeration e = fr.featureColours.keys();
\r
310 while(e.hasMoreElements())
\r
314 jalview.binding.Colour col = new jalview.binding.Colour();
\r
315 col.setName(e.nextElement().toString());
\r
316 col.setRGB(jalview.util.Format.getHexString(
\r
317 fr.getColour(col.getName())));
\r
318 ucs.addColour(col);
\r
324 catch (Exception ex)
\r
326 ex.printStackTrace();
\r
332 public void updateFeatureRenderer(Object [][] data)
\r
334 fr.setFeaturePriority( data );
\r
338 int selectedRow =-1;
\r
341 /////////////////////////////////////////////////////////////////////////
\r
342 // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
\r
343 /////////////////////////////////////////////////////////////////////////
\r
344 class FeatureTableModel
\r
345 extends AbstractTableModel
\r
347 FeatureTableModel(Object[][] data)
\r
352 private String[] columnNames = {"Feature Type", "Colour","Display"};
\r
353 private Object[][] data;
\r
355 public Object[][] getData()
\r
360 public int getColumnCount() {
\r
361 return columnNames.length;
\r
364 public Object[] getRow(int row)
\r
369 public int getRowCount() {
\r
370 return data.length;
\r
373 public String getColumnName(int col) {
\r
374 return columnNames[col];
\r
377 public Object getValueAt(int row, int col) {
\r
378 return data[row][col];
\r
381 public Class getColumnClass(int c) {
\r
382 return getValueAt(0, c).getClass();
\r
385 public boolean isCellEditable(int row, int col) {
\r
386 return col==0 ? false:true;
\r
389 public void setValueAt(Object value, int row, int col) {
\r
390 data[row][col] = value;
\r
391 fireTableCellUpdated(row, col);
\r
392 updateFeatureRenderer(data);
\r
396 class ColorRenderer extends JLabel
\r
397 implements TableCellRenderer {
\r
398 javax.swing.border.Border unselectedBorder = null;
\r
399 javax.swing.border.Border selectedBorder = null;
\r
401 public ColorRenderer() {
\r
402 setOpaque(true); //MUST do this for background to show up.
\r
405 public Component getTableCellRendererComponent(
\r
406 JTable table, Object color,
\r
407 boolean isSelected, boolean hasFocus,
\r
408 int row, int column) {
\r
409 Color newColor = (Color)color;
\r
410 setBackground(newColor);
\r
412 if (selectedBorder == null) {
\r
413 selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
\r
414 table.getSelectionBackground());
\r
416 setBorder(selectedBorder);
\r
418 if (unselectedBorder == null) {
\r
419 unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
\r
420 table.getBackground());
\r
422 setBorder(unselectedBorder);
\r
425 setToolTipText("RGB value: " + newColor.getRed() + ", "
\r
426 + newColor.getGreen() + ", "
\r
427 + newColor.getBlue());
\r
433 class ColorEditor extends AbstractCellEditor
\r
434 implements TableCellEditor,
\r
436 Color currentColor;
\r
438 JColorChooser colorChooser;
\r
440 protected static final String EDIT = "edit";
\r
442 public ColorEditor() {
\r
443 //Set up the editor (from the table's point of view),
\r
444 //which is a button.
\r
445 //This button brings up the color chooser dialog,
\r
446 //which is the editor from the user's point of view.
\r
447 button = new JButton();
\r
448 button.setActionCommand(EDIT);
\r
449 button.addActionListener(this);
\r
450 button.setBorderPainted(false);
\r
451 //Set up the dialog that the button brings up.
\r
452 colorChooser = new JColorChooser();
\r
453 dialog = JColorChooser.createDialog(button,
\r
454 "Select new Colour",
\r
457 this, //OK button handler
\r
458 null); //no CANCEL button handler
\r
462 * Handles events from the editor button and from
\r
463 * the dialog's OK button.
\r
465 public void actionPerformed(ActionEvent e) {
\r
467 if (EDIT.equals(e.getActionCommand())) {
\r
468 //The user has clicked the cell, so
\r
469 //bring up the dialog.
\r
470 button.setBackground(currentColor);
\r
471 colorChooser.setColor(currentColor);
\r
472 dialog.setVisible(true);
\r
474 //Make the renderer reappear.
\r
475 fireEditingStopped();
\r
477 } else { //User pressed dialog's "OK" button.
\r
478 currentColor = colorChooser.getColor();
\r
482 //Implement the one CellEditor method that AbstractCellEditor doesn't.
\r
483 public Object getCellEditorValue() {
\r
484 return currentColor;
\r
487 //Implement the one method defined by TableCellEditor.
\r
488 public Component getTableCellEditorComponent(JTable table,
\r
490 boolean isSelected,
\r
493 currentColor = (Color)value;
\r