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().
\r
142 getSequenceFeatures();
\r
143 if (features == null)
\r
146 e = features.elements();
\r
147 while (e.hasMoreElements())
\r
149 sf = (SequenceFeature) e.nextElement();
\r
150 if (!allFeatures.contains(sf.getType()))
\r
152 allFeatures.addElement(sf.getType());
\r
156 if(allFeatures.size()<1)
\r
159 frame.setClosed(true);
\r
160 }catch(Exception ex){}
\r
164 int fSize = allFeatures.size();
\r
167 boolean originalExists = false;
\r
168 if(originalData!=null)
\r
169 originalExists = true;
\r
171 originalData = new Object[fSize][3];
\r
173 Object [][] data = new Object[fSize][3];
\r
174 for(int i=0; i<fSize; i++)
\r
176 type = allFeatures.elementAt(i).toString();
\r
177 Color col = fr.getColour(type);
\r
180 if(fr.featuresDisplayed!=null)
\r
181 data[i][2] = new Boolean(fr.featuresDisplayed.contains(type));
\r
183 data[i][2] = new Boolean(true);
\r
185 if(!originalExists)
\r
187 originalData[i][0] = type;
\r
188 originalData[i][1] = col;
\r
189 if (fr.featuresDisplayed != null)
\r
190 originalData[i][2] = new Boolean(fr.featuresDisplayed.contains(type));
\r
192 originalData[i][2] = new Boolean(true);
\r
195 ////////////////////////////////////
\r
196 //Now build the table
\r
197 table = new JTable(new FeatureTableModel(data));
\r
198 scrollPane.setViewportView(table);
\r
199 table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
\r
200 table.setFont(new Font("Verdana", Font.PLAIN, 12));
\r
201 table.setDefaultRenderer(Color.class,
\r
202 new ColorRenderer());
\r
204 table.setDefaultEditor(Color.class,
\r
205 new ColorEditor());
\r
207 table.getColumnModel().getColumn(0).setPreferredWidth(200);
\r
209 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
\r
211 table.addMouseListener(new MouseAdapter()
\r
213 public void mousePressed(MouseEvent evt)
\r
215 selectedRow = table.rowAtPoint(evt.getPoint());
\r
219 table.addMouseMotionListener(new MouseMotionAdapter()
\r
221 public void mouseDragged(MouseEvent evt)
\r
223 int newRow = table.rowAtPoint(evt.getPoint());
\r
224 if(newRow!=selectedRow
\r
228 Object[] temp = new Object[3];
\r
229 temp[0] = table.getValueAt(selectedRow, 0);
\r
230 temp[1] = table.getValueAt(selectedRow, 1);
\r
231 temp[2] = table.getValueAt(selectedRow, 2);
\r
233 table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
\r
234 table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
\r
235 table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
\r
237 table.setValueAt(temp[0], newRow, 0);
\r
238 table.setValueAt(temp[1], newRow, 1);
\r
239 table.setValueAt(temp[2], newRow, 2);
\r
241 selectedRow = newRow;
\r
250 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
\r
251 "LAST_DIRECTORY"), new String[] { "fc" },
\r
252 new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");
\r
253 chooser.setFileView(new jalview.io.JalviewFileView());
\r
254 chooser.setDialogTitle("Load Feature Colours");
\r
255 chooser.setToolTipText("Load");
\r
257 int value = chooser.showOpenDialog(this);
\r
259 if (value == JalviewFileChooser.APPROVE_OPTION)
\r
261 File file = chooser.getSelectedFile();
\r
265 InputStreamReader in = new InputStreamReader(new FileInputStream(
\r
268 jalview.binding.JalviewUserColours jucs = new jalview.binding.
\r
269 JalviewUserColours();
\r
270 jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
\r
273 for (int i = 0; i < jucs.getColourCount(); i++)
\r
275 fr.setColour( jucs.getColour(i).getName(),
\r
276 new Color(Integer.parseInt( jucs.getColour(i).getRGB(), 16)));
\r
282 catch (Exception ex)
\r
284 System.out.println("Error loading User ColourFile\n" + ex);
\r
291 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
\r
292 "LAST_DIRECTORY"), new String[] { "fc" },
\r
293 new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");
\r
294 chooser.setFileView(new jalview.io.JalviewFileView());
\r
295 chooser.setDialogTitle("Save Feature Colour Scheme");
\r
296 chooser.setToolTipText("Save");
\r
298 int value = chooser.showSaveDialog(this);
\r
300 if (value == JalviewFileChooser.APPROVE_OPTION)
\r
302 String choice = chooser.getSelectedFile().getPath();
\r
303 jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();
\r
304 ucs.setSchemeName("Sequence Features");
\r
307 PrintWriter out = new PrintWriter(new OutputStreamWriter(
\r
308 new FileOutputStream(choice), "UTF-8"));
\r
310 Enumeration e = fr.featureColours.keys();
\r
311 while(e.hasMoreElements())
\r
315 jalview.binding.Colour col = new jalview.binding.Colour();
\r
316 col.setName(e.nextElement().toString());
\r
317 col.setRGB(jalview.util.Format.getHexString(
\r
318 fr.getColour(col.getName())));
\r
319 ucs.addColour(col);
\r
325 catch (Exception ex)
\r
327 ex.printStackTrace();
\r
333 public void updateFeatureRenderer(Object [][] data)
\r
335 fr.setFeaturePriority( data );
\r
338 if(ap.overviewPanel!=null)
\r
339 ap.overviewPanel.updateOverviewImage();
\r
342 int selectedRow =-1;
\r
345 /////////////////////////////////////////////////////////////////////////
\r
346 // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
\r
347 /////////////////////////////////////////////////////////////////////////
\r
348 class FeatureTableModel
\r
349 extends AbstractTableModel
\r
351 FeatureTableModel(Object[][] data)
\r
356 private String[] columnNames = {"Feature Type", "Colour","Display"};
\r
357 private Object[][] data;
\r
359 public Object[][] getData()
\r
364 public int getColumnCount() {
\r
365 return columnNames.length;
\r
368 public Object[] getRow(int row)
\r
373 public int getRowCount() {
\r
374 return data.length;
\r
377 public String getColumnName(int col) {
\r
378 return columnNames[col];
\r
381 public Object getValueAt(int row, int col) {
\r
382 return data[row][col];
\r
385 public Class getColumnClass(int c) {
\r
386 return getValueAt(0, c).getClass();
\r
389 public boolean isCellEditable(int row, int col) {
\r
390 return col==0 ? false:true;
\r
393 public void setValueAt(Object value, int row, int col) {
\r
394 data[row][col] = value;
\r
395 fireTableCellUpdated(row, col);
\r
396 updateFeatureRenderer(data);
\r
400 class ColorRenderer extends JLabel
\r
401 implements TableCellRenderer {
\r
402 javax.swing.border.Border unselectedBorder = null;
\r
403 javax.swing.border.Border selectedBorder = null;
\r
405 public ColorRenderer() {
\r
406 setOpaque(true); //MUST do this for background to show up.
\r
409 public Component getTableCellRendererComponent(
\r
410 JTable table, Object color,
\r
411 boolean isSelected, boolean hasFocus,
\r
412 int row, int column) {
\r
413 Color newColor = (Color)color;
\r
414 setBackground(newColor);
\r
416 if (selectedBorder == null) {
\r
417 selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
\r
418 table.getSelectionBackground());
\r
420 setBorder(selectedBorder);
\r
422 if (unselectedBorder == null) {
\r
423 unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
\r
424 table.getBackground());
\r
426 setBorder(unselectedBorder);
\r
429 setToolTipText("RGB value: " + newColor.getRed() + ", "
\r
430 + newColor.getGreen() + ", "
\r
431 + newColor.getBlue());
\r
437 class ColorEditor extends AbstractCellEditor
\r
438 implements TableCellEditor,
\r
440 Color currentColor;
\r
442 JColorChooser colorChooser;
\r
444 protected static final String EDIT = "edit";
\r
446 public ColorEditor() {
\r
447 //Set up the editor (from the table's point of view),
\r
448 //which is a button.
\r
449 //This button brings up the color chooser dialog,
\r
450 //which is the editor from the user's point of view.
\r
451 button = new JButton();
\r
452 button.setActionCommand(EDIT);
\r
453 button.addActionListener(this);
\r
454 button.setBorderPainted(false);
\r
455 //Set up the dialog that the button brings up.
\r
456 colorChooser = new JColorChooser();
\r
457 dialog = JColorChooser.createDialog(button,
\r
458 "Select new Colour",
\r
461 this, //OK button handler
\r
462 null); //no CANCEL button handler
\r
466 * Handles events from the editor button and from
\r
467 * the dialog's OK button.
\r
469 public void actionPerformed(ActionEvent e) {
\r
471 if (EDIT.equals(e.getActionCommand())) {
\r
472 //The user has clicked the cell, so
\r
473 //bring up the dialog.
\r
474 button.setBackground(currentColor);
\r
475 colorChooser.setColor(currentColor);
\r
476 dialog.setVisible(true);
\r
478 //Make the renderer reappear.
\r
479 fireEditingStopped();
\r
481 } else { //User pressed dialog's "OK" button.
\r
482 currentColor = colorChooser.getColor();
\r
486 //Implement the one CellEditor method that AbstractCellEditor doesn't.
\r
487 public Object getCellEditorValue() {
\r
488 return currentColor;
\r
491 //Implement the one method defined by TableCellEditor.
\r
492 public Component getTableCellEditorComponent(JTable table,
\r
494 boolean isSelected,
\r
497 currentColor = (Color)value;
\r