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.*;
26 import java.beans.PropertyChangeEvent;
27 import java.beans.PropertyChangeListener;
30 import javax.swing.event.*;
31 import javax.swing.table.*;
33 import jalview.datamodel.*;
36 public class FeatureSettings
39 DasSourceBrowser dassourceBrowser;
40 jalview.ws.DasSequenceFeatureFetcher dasFeatureFetcher;
41 JPanel settingsPane = new JPanel();
42 JPanel dasSettingsPane = new JPanel();
44 final FeatureRenderer fr;
45 public final AlignFrame af;
46 Object[][] originalData;
47 final JInternalFrame frame;
48 JScrollPane scrollPane = new JScrollPane();
51 JSlider transparency = new JSlider();
53 JPanel transPanel = new JPanel(new FlowLayout());
55 public FeatureSettings(AlignFrame af)
58 fr = af.getFeatureRenderer();
60 transparency.setMaximum(100 - (int) (fr.transparency * 100));
72 table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
73 table.setFont(new Font("Verdana", Font.PLAIN, 12));
74 table.setDefaultRenderer(Color.class,
77 table.setDefaultEditor(Color.class,
80 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
82 table.addMouseListener(new MouseAdapter()
84 public void mousePressed(MouseEvent evt)
86 selectedRow = table.rowAtPoint(evt.getPoint());
90 table.addMouseMotionListener(new MouseMotionAdapter()
92 public void mouseDragged(MouseEvent evt)
94 int newRow = table.rowAtPoint(evt.getPoint());
95 if (newRow != selectedRow
99 Object[] temp = new Object[3];
100 temp[0] = table.getValueAt(selectedRow, 0);
101 temp[1] = table.getValueAt(selectedRow, 1);
102 temp[2] = table.getValueAt(selectedRow, 2);
104 table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
105 table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
106 table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
108 table.setValueAt(temp[0], newRow, 0);
109 table.setValueAt(temp[1], newRow, 1);
110 table.setValueAt(temp[2], newRow, 2);
112 selectedRow = newRow;
117 scrollPane.setViewportView(table);
119 dassourceBrowser = new DasSourceBrowser();
120 dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
122 if (af.getViewport().featuresDisplayed == null || fr.renderOrder == null)
124 fr.findAllFeatures(true); // display everything!
128 final PropertyChangeListener change;
129 final FeatureSettings fs=this;
130 fr.addPropertyChangeListener(change=new PropertyChangeListener() {
131 public void propertyChange(PropertyChangeEvent evt)
133 if (!fs.resettingTable && !fs.handlingUpdate) {
134 fs.handlingUpdate=true;
135 fs.resetTable(null); // new groups may be added with new seuqence feature types only
136 fs.handlingUpdate=false;
142 frame = new JInternalFrame();
143 frame.setContentPane(this);
144 Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 450);
145 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
147 public void internalFrameClosed(
148 javax.swing.event.InternalFrameEvent evt)
150 fr.removePropertyChangeListener(change);
154 frame.setLayer(JLayeredPane.PALETTE_LAYER);
157 * true when Feature Settings are updating from feature renderer
159 private boolean handlingUpdate=false;
162 * contains a float[3] for each feature type string. created by setTableData
164 Hashtable typeWidth=null;
165 synchronized public void setTableData()
167 if (fr.featureGroups == null)
169 fr.featureGroups = new Hashtable();
171 Vector allFeatures = new Vector();
172 Vector allGroups = new Vector();
173 SequenceFeature[] tmpfeatures;
175 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
177 if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().
178 getSequenceFeatures() == null)
183 tmpfeatures = af.getViewport().alignment.getSequenceAt(i).
184 getDatasetSequence().getSequenceFeatures();
187 while (index < tmpfeatures.length)
189 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
195 if (tmpfeatures[index].getFeatureGroup() != null)
197 group = tmpfeatures[index].featureGroup;
198 if (!allGroups.contains(group))
200 allGroups.addElement(group);
203 checkGroupState(group);
208 if (!allFeatures.contains(tmpfeatures[index].getType()))
210 allFeatures.addElement(tmpfeatures[index].getType());
223 * @return true if group has been seen before and is already added to set.
225 private boolean checkGroupState(String group) {
227 if (fr.featureGroups.containsKey(group))
229 visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();
231 visible=true; // new group is always made visible
234 if (groupPanel == null)
236 groupPanel = new JPanel();
239 boolean alreadyAdded = false;
240 for (int g = 0; g < groupPanel.getComponentCount(); g++)
242 if ( ( (JCheckBox) groupPanel.getComponent(g))
243 .getText().equals(group))
246 ((JCheckBox)groupPanel.getComponent(g)).setSelected(visible);
257 fr.featureGroups.put(group, new Boolean(visible));
258 final String grp = group;
259 final JCheckBox check = new JCheckBox(group, visible);
260 check.setFont(new Font("Serif", Font.BOLD, 12));
261 check.addItemListener(new ItemListener()
263 public void itemStateChanged(ItemEvent evt)
265 fr.featureGroups.put(check.getText(),
266 new Boolean(check.isSelected()));
267 af.alignPanel.seqPanel.seqCanvas.repaint();
268 if (af.alignPanel.overviewPanel != null)
270 af.alignPanel.overviewPanel.updateOverviewImage();
273 resetTable(new String[] { grp } );
276 groupPanel.add(check);
279 boolean resettingTable=false;
280 synchronized void resetTable(String[] groupChanged)
282 if (resettingTable==true)
287 typeWidth=new Hashtable();
288 // TODO: change avWidth calculation to 'per-sequence' average and use long rather than float
289 float[] avWidth=null;
290 SequenceFeature[] tmpfeatures;
291 String group = null, type;
292 Vector visibleChecks = new Vector();
294 //Find out which features should be visible depending on which groups
295 //are selected / deselected
296 //and recompute average width ordering
297 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
300 tmpfeatures = af.getViewport().alignment.getSequenceAt(i).
301 getDatasetSequence().getSequenceFeatures();
302 if (tmpfeatures == null)
308 while (index < tmpfeatures.length)
310 group = tmpfeatures[index].featureGroup;
312 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
318 if (group == null || fr.featureGroups.get(group) == null ||
319 ( (Boolean) fr.featureGroups.get(group)).booleanValue())
322 checkGroupState(group);
323 type = tmpfeatures[index].getType();
324 if (!visibleChecks.contains(type))
326 visibleChecks.addElement(type);
329 if (!typeWidth.containsKey(tmpfeatures[index].getType())) {
330 typeWidth.put(tmpfeatures[index].getType(), avWidth=new float[3]);
332 avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType());
335 if (tmpfeatures[index].getBegin()>tmpfeatures[index].getEnd())
337 avWidth[1]+=1+tmpfeatures[index].getBegin()-tmpfeatures[index].getEnd();
339 avWidth[1]+=1+tmpfeatures[index].getEnd()-tmpfeatures[index].getBegin();
345 int fSize = visibleChecks.size();
346 Object[][] data = new Object[fSize][3];
349 if (fr.renderOrder != null)
352 fr.findAllFeatures(groupChanged!=null); // prod to update colourschemes. but don't affect display
353 //First add the checks in the previous render order,
354 //in case the window has been closed and reopened
355 for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
357 type = fr.renderOrder[ro];
359 if (!visibleChecks.contains(type))
364 data[dataIndex][0] = type;
365 data[dataIndex][1] = fr.getColour(type);
366 data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed.containsKey(type));
368 visibleChecks.removeElement(type);
372 fSize = visibleChecks.size();
373 for (int i = 0; i < fSize; i++)
375 //These must be extra features belonging to the group
376 //which was just selected
377 type = visibleChecks.elementAt(i).toString();
378 data[dataIndex][0] = type;
380 data[dataIndex][1] = fr.getColour(type);
381 if (data[dataIndex][1] == null)
383 //"Colour has been updated in another view!!"
384 fr.renderOrder = null;
388 data[dataIndex][2] = new Boolean(true);
392 if (originalData == null)
394 originalData = new Object[data.length][3];
395 System.arraycopy(data, 0, originalData, 0, data.length);
398 table.setModel(new FeatureTableModel(data));
399 table.getColumnModel().getColumn(0).setPreferredWidth(200);
401 if (groupPanel != null)
403 groupPanel.setLayout(
404 new GridLayout(fr.featureGroups.size() / 4 + 1, 4));
406 groupPanel.validate();
407 bigPanel.add(groupPanel, BorderLayout.NORTH);
410 updateFeatureRenderer(data, groupChanged!=null);
411 resettingTable=false;
414 * reorder data based on the featureRenderers global priority list.
417 private void ensureOrder(Object[][] data)
420 float[] order = new float[data.length];
421 for (int i=0;i<order.length; i++)
423 order[i] = fr.getOrder(data[i][0].toString());
425 order[i] = fr.setOrder(data[i][0].toString(), i/order.length);
427 sort = sort || order[i-1]>order[i];
430 jalview.util.QuickSort.sort(order, data);
435 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
437 "LAST_DIRECTORY"), new String[]
440 {"Sequence Feature Colours"}, "Sequence Feature Colours");
441 chooser.setFileView(new jalview.io.JalviewFileView());
442 chooser.setDialogTitle("Load Feature Colours");
443 chooser.setToolTipText("Load");
445 int value = chooser.showOpenDialog(this);
447 if (value == JalviewFileChooser.APPROVE_OPTION)
449 File file = chooser.getSelectedFile();
453 InputStreamReader in = new InputStreamReader(new FileInputStream(
456 jalview.binding.JalviewUserColours jucs = new jalview.binding.
457 JalviewUserColours();
458 jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
460 for (int i = jucs.getColourCount()-1; i >=0; i--)
463 fr.setColour(name=jucs.getColour(i).getName(),
464 new Color(Integer.parseInt(jucs.getColour(i).getRGB(),
466 fr.setOrder(name,(i==0) ? 0 : i/jucs.getColourCount());
470 Object[][] data=((FeatureTableModel) table.getModel()).getData();
472 updateFeatureRenderer(data,false);
478 System.out.println("Error loading User Colour File\n" + ex);
485 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
487 "LAST_DIRECTORY"), new String[]
490 {"Sequence Feature Colours"}, "Sequence Feature Colours");
491 chooser.setFileView(new jalview.io.JalviewFileView());
492 chooser.setDialogTitle("Save Feature Colour Scheme");
493 chooser.setToolTipText("Save");
495 int value = chooser.showSaveDialog(this);
497 if (value == JalviewFileChooser.APPROVE_OPTION)
499 String choice = chooser.getSelectedFile().getPath();
500 jalview.binding.JalviewUserColours ucs = new jalview.binding.
501 JalviewUserColours();
502 ucs.setSchemeName("Sequence Features");
505 PrintWriter out = new PrintWriter(new OutputStreamWriter(
506 new FileOutputStream(choice), "UTF-8"));
508 Enumeration e = fr.featureColours.keys();
509 float[] sortOrder = new float[fr.featureColours.size()];
510 String[] sortTypes = new String[fr.featureColours.size()];
512 while (e.hasMoreElements())
514 sortTypes[i] = e.nextElement().toString();
515 sortOrder[i] = fr.getOrder(sortTypes[i]);
518 jalview.util.QuickSort.sort(sortOrder, sortTypes);
520 for (i=0; i<sortTypes.length; i++) {
521 jalview.binding.Colour col = new jalview.binding.Colour();
522 col.setName(sortTypes[i]);
523 col.setRGB(jalview.util.Format.getHexString(
524 fr.getColour(col.getName())));
532 ex.printStackTrace();
537 public void invertSelection()
539 for (int i = 0; i < table.getRowCount(); i++)
541 Boolean value = (Boolean) table.getValueAt(i, 2);
544 new Boolean(!value.booleanValue()),
548 public void orderByAvWidth() {
549 if (table==null || table.getModel()==null)
551 Object[][] data = ((FeatureTableModel) table.getModel()).getData();
552 float[] width = new float[data.length];
556 for (int i=0;i<data.length;i++) {
557 awidth = (float[]) typeWidth.get(data[i][0]);
559 width[i] = awidth[1]/awidth[0];// *awidth[0]*awidth[2]; - better weight - but have to make per sequence, too (awidth[2])
560 //if (width[i]==1) // hack to distinguish single width sequences.
569 for (int i=0;i<width.length; i++) {
570 //awidth = (float[]) typeWidth.get(data[i][0]);
573 width[i] = fr.getOrder(data[i][0].toString());
576 width[i] = fr.setOrder(data[i][0].toString(), i/data.length);
579 width[i] /=max; // normalize
580 fr.setOrder(data[i][0].toString(), width[i]); // store for later
583 sort = sort || width[i-1]>width[i];
586 jalview.util.QuickSort.sort(width, data);
587 // update global priority order
589 updateFeatureRenderer(data,false);
596 frame.setClosed(true);
598 catch (Exception exe)
603 public void updateFeatureRenderer(Object[][] data)
605 updateFeatureRenderer(data, true);
607 private void updateFeatureRenderer(Object[][] data, boolean visibleNew)
609 fr.setFeaturePriority(data, visibleNew);
610 af.alignPanel.paintAlignment(true);
613 int selectedRow = -1;
614 JTabbedPane tabbedPane = new JTabbedPane();
615 BorderLayout borderLayout1 = new BorderLayout();
616 BorderLayout borderLayout2 = new BorderLayout();
617 BorderLayout borderLayout3 = new BorderLayout();
618 JPanel bigPanel = new JPanel();
619 BorderLayout borderLayout4 = new BorderLayout();
620 JButton invert = new JButton();
621 JPanel buttonPanel = new JPanel();
622 JButton cancel = new JButton();
623 JButton ok = new JButton();
624 JButton loadColours = new JButton();
625 JButton saveColours = new JButton();
626 JPanel dasButtonPanel = new JPanel();
627 JButton fetchDAS = new JButton();
628 JButton saveDAS = new JButton();
629 JButton cancelDAS = new JButton();
630 JButton optimizeOrder = new JButton();
631 JPanel transbuttons = new JPanel(new BorderLayout());
632 private void jbInit()
635 this.setLayout(borderLayout1);
636 settingsPane.setLayout(borderLayout2);
637 dasSettingsPane.setLayout(borderLayout3);
638 bigPanel.setLayout(borderLayout4);
639 invert.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
640 invert.setText("Invert Selection");
641 invert.addActionListener(new ActionListener()
643 public void actionPerformed(ActionEvent e)
648 optimizeOrder.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
649 optimizeOrder.setText("Optimise Order");
650 optimizeOrder.addActionListener(new ActionListener() {
651 public void actionPerformed(ActionEvent e) {
655 cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
656 cancel.setText("Cancel");
657 cancel.addActionListener(new ActionListener()
659 public void actionPerformed(ActionEvent e)
661 updateFeatureRenderer(originalData);
665 ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
667 ok.addActionListener(new ActionListener()
669 public void actionPerformed(ActionEvent e)
674 loadColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
675 loadColours.setText("Load Colours");
676 loadColours.addActionListener(new ActionListener()
678 public void actionPerformed(ActionEvent e)
683 saveColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
684 saveColours.setText("Save Colours");
685 saveColours.addActionListener(new ActionListener()
687 public void actionPerformed(ActionEvent e)
692 transparency.addChangeListener(new ChangeListener()
694 public void stateChanged(ChangeEvent evt)
696 fr.setTransparency( (float) (100 - transparency.getValue()) / 100f);
697 af.alignPanel.paintAlignment(true);
701 transparency.setMaximum(70);
702 fetchDAS.setText("Fetch DAS Features");
703 fetchDAS.addActionListener(new ActionListener()
705 public void actionPerformed(ActionEvent e)
707 fetchDAS_actionPerformed(e);
710 saveDAS.setText("Save as default");
711 saveDAS.addActionListener(new ActionListener()
713 public void actionPerformed(ActionEvent e)
715 saveDAS_actionPerformed(e);
718 dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
719 dasSettingsPane.setBorder(null);
720 cancelDAS.setEnabled(false);
721 cancelDAS.setText("Cancel Fetch");
722 cancelDAS.addActionListener(new ActionListener()
724 public void actionPerformed(ActionEvent e)
726 cancelDAS_actionPerformed(e);
729 this.add(tabbedPane, java.awt.BorderLayout.CENTER);
730 tabbedPane.addTab("Feature Settings", settingsPane);
731 tabbedPane.addTab("DAS Settings", dasSettingsPane);
732 bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
733 transPanel.add(transparency);
734 transbuttons.add(invert, java.awt.BorderLayout.NORTH);
735 transbuttons.add(optimizeOrder,java.awt.BorderLayout.SOUTH);
736 transPanel.add(transbuttons);
738 buttonPanel.add(cancel);
739 buttonPanel.add(loadColours);
740 buttonPanel.add(saveColours);
741 bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);
742 dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);
743 dasButtonPanel.add(fetchDAS);
744 dasButtonPanel.add(cancelDAS);
745 dasButtonPanel.add(saveDAS);
746 settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);
747 settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
750 public void fetchDAS_actionPerformed(ActionEvent e)
752 fetchDAS.setEnabled(false);
753 cancelDAS.setEnabled(true);
754 Vector selectedSources = dassourceBrowser.getSelectedSources();
755 doDasFeatureFetch(selectedSources, true, true);
758 * get the features from selectedSources for all or the current selection
759 * @param selectedSources
761 * @param promptFetchDbRefs
763 private void doDasFeatureFetch(Vector selectedSources, boolean checkDbRefs, boolean promptFetchDbRefs)
765 SequenceI[] dataset, seqs;
767 AlignViewport vp = af.getViewport();
768 if (vp.getSelectionGroup() != null
769 && vp.getSelectionGroup().getSize() > 0)
771 iSize = vp.getSelectionGroup().getSize();
772 dataset = new SequenceI[iSize];
773 seqs = vp.getSelectionGroup().
779 iSize = vp.getAlignment().getHeight();
780 seqs = vp.getAlignment().getSequencesArray();
783 dataset = new SequenceI[iSize];
784 for (int i = 0; i < iSize; i++)
786 dataset[i] = seqs[i].getDatasetSequence();
789 cancelDAS.setEnabled(true);
791 new jalview.ws.DasSequenceFeatureFetcher(
794 selectedSources, checkDbRefs, promptFetchDbRefs);
795 af.getViewport().setShowSequenceFeatures(true);
796 af.showSeqFeatures.setSelected(true);
799 * properly initialise DAS fetcher and then initiate a new thread to fetch features from the named sources (rather than any turned on by default)
802 public void fetchDasFeatures(Vector sources)
804 Thread thr = new Thread(new Runnable() {
806 // this actually initialises the das source list
807 dassourceBrowser.paintComponent(null); // yuk
811 while (dassourceBrowser.loadingDasSources || dassourceBrowser.dasSources==null)
813 try { Thread.sleep(10); } catch (Exception e) {};
815 Vector resolved = new Vector();
818 for (int i=0;i<dassourceBrowser.dasSources.length; i++)
820 if (sources.contains(dassourceBrowser.dasSources[i].getNickname()))
822 if (!resolved.contains(dassourceBrowser.dasSources[i]))
824 resolved.addElement(dassourceBrowser.dasSources[i]);
829 if (resolved.size()==0)
831 resolved = dassourceBrowser.getSelectedSources();
833 if (resolved.size()>0)
835 final Vector dassources = resolved;
836 SwingUtilities.invokeLater(new Runnable() {
840 fetchDAS.setEnabled(false);
841 cancelDAS.setEnabled(true);
842 doDasFeatureFetch(dassources, true, false);
848 public void saveDAS_actionPerformed(ActionEvent e)
850 dassourceBrowser.saveProperties(jalview.bin.Cache.applicationProperties);
853 public void complete()
855 fetchDAS.setEnabled(true);
856 cancelDAS.setEnabled(false);
859 public void cancelDAS_actionPerformed(ActionEvent e)
861 if (dasFeatureFetcher!=null)
863 dasFeatureFetcher.cancel();
865 fetchDAS.setEnabled(true);
866 cancelDAS.setEnabled(false);
868 public void noDasSourceActive()
871 JOptionPane.showInternalConfirmDialog(Desktop.desktop,
872 "No das sources were selected.\n"
873 + "Please select some sources and\n"
875 "No Sources Selected",
876 JOptionPane.DEFAULT_OPTION,
877 JOptionPane.INFORMATION_MESSAGE);
880 /////////////////////////////////////////////////////////////////////////
881 // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
882 /////////////////////////////////////////////////////////////////////////
883 class FeatureTableModel
884 extends AbstractTableModel
886 FeatureTableModel(Object[][] data)
891 private String[] columnNames =
893 "Feature Type", "Colour", "Display"};
894 private Object[][] data;
896 public Object[][] getData()
901 public void setData(Object[][] data)
906 public int getColumnCount()
908 return columnNames.length;
911 public Object[] getRow(int row)
916 public int getRowCount()
921 public String getColumnName(int col)
923 return columnNames[col];
926 public Object getValueAt(int row, int col)
928 return data[row][col];
931 public Class getColumnClass(int c)
933 return getValueAt(0, c).getClass();
936 public boolean isCellEditable(int row, int col)
938 return col == 0 ? false : true;
941 public void setValueAt(Object value, int row, int col)
943 data[row][col] = value;
944 fireTableCellUpdated(row, col);
945 updateFeatureRenderer(data);
951 extends JLabel implements TableCellRenderer
953 javax.swing.border.Border unselectedBorder = null;
954 javax.swing.border.Border selectedBorder = null;
956 public ColorRenderer()
958 setOpaque(true); //MUST do this for background to show up.
961 public Component getTableCellRendererComponent(
962 JTable table, Object color,
963 boolean isSelected, boolean hasFocus,
966 Color newColor = (Color) color;
967 setBackground(newColor);
970 if (selectedBorder == null)
972 selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
973 table.getSelectionBackground());
975 setBorder(selectedBorder);
979 if (unselectedBorder == null)
981 unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
982 table.getBackground());
984 setBorder(unselectedBorder);
987 setToolTipText("RGB value: " + newColor.getRed() + ", "
988 + newColor.getGreen() + ", "
989 + newColor.getBlue());
996 extends AbstractCellEditor implements TableCellEditor,
1001 JColorChooser colorChooser;
1003 protected static final String EDIT = "edit";
1005 public ColorEditor()
1007 //Set up the editor (from the table's point of view),
1008 //which is a button.
1009 //This button brings up the color chooser dialog,
1010 //which is the editor from the user's point of view.
1011 button = new JButton();
1012 button.setActionCommand(EDIT);
1013 button.addActionListener(this);
1014 button.setBorderPainted(false);
1015 //Set up the dialog that the button brings up.
1016 colorChooser = new JColorChooser();
1017 dialog = JColorChooser.createDialog(button,
1018 "Select new Colour",
1021 this, //OK button handler
1022 null); //no CANCEL button handler
1026 * Handles events from the editor button and from
1027 * the dialog's OK button.
1029 public void actionPerformed(ActionEvent e)
1032 if (EDIT.equals(e.getActionCommand()))
1034 //The user has clicked the cell, so
1035 //bring up the dialog.
1036 button.setBackground(currentColor);
1037 colorChooser.setColor(currentColor);
1038 dialog.setVisible(true);
1040 //Make the renderer reappear.
1041 fireEditingStopped();
1045 { //User pressed dialog's "OK" button.
1046 currentColor = colorChooser.getColor();
1050 //Implement the one CellEditor method that AbstractCellEditor doesn't.
1051 public Object getCellEditorValue()
1053 return currentColor;
1056 //Implement the one method defined by TableCellEditor.
1057 public Component getTableCellEditorComponent(JTable table,
1063 currentColor = (Color) value;