2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3 * Copyright (C) 2008 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 extends JPanel
38 DasSourceBrowser dassourceBrowser;
40 jalview.ws.DasSequenceFeatureFetcher dasFeatureFetcher;
42 JPanel settingsPane = new JPanel();
44 JPanel dasSettingsPane = new JPanel();
46 final FeatureRenderer fr;
48 public final AlignFrame af;
50 Object[][] originalData;
52 final JInternalFrame frame;
54 JScrollPane scrollPane = new JScrollPane();
60 JSlider transparency = new JSlider();
62 JPanel transPanel = new JPanel(new FlowLayout());
64 public FeatureSettings(AlignFrame af)
67 fr = af.getFeatureRenderer();
69 transparency.setMaximum(100 - (int) (fr.transparency * 100));
74 } catch (Exception ex)
80 table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
81 table.setFont(new Font("Verdana", Font.PLAIN, 12));
82 table.setDefaultRenderer(Color.class, new ColorRenderer());
84 table.setDefaultEditor(Color.class, new ColorEditor());
86 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
88 table.addMouseListener(new MouseAdapter()
90 public void mousePressed(MouseEvent evt)
92 selectedRow = table.rowAtPoint(evt.getPoint());
96 table.addMouseMotionListener(new MouseMotionAdapter()
98 public void mouseDragged(MouseEvent evt)
100 int newRow = table.rowAtPoint(evt.getPoint());
101 if (newRow != selectedRow && selectedRow != -1 && newRow != -1)
103 Object[] temp = new Object[3];
104 temp[0] = table.getValueAt(selectedRow, 0);
105 temp[1] = table.getValueAt(selectedRow, 1);
106 temp[2] = table.getValueAt(selectedRow, 2);
108 table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
109 table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
110 table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
112 table.setValueAt(temp[0], newRow, 0);
113 table.setValueAt(temp[1], newRow, 1);
114 table.setValueAt(temp[2], newRow, 2);
116 selectedRow = newRow;
121 scrollPane.setViewportView(table);
123 dassourceBrowser = new DasSourceBrowser();
124 dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
126 if (af.getViewport().featuresDisplayed == null
127 || fr.renderOrder == null)
129 fr.findAllFeatures(true); // display everything!
133 final PropertyChangeListener change;
134 final FeatureSettings fs = this;
135 fr.addPropertyChangeListener(change = new PropertyChangeListener()
137 public void propertyChange(PropertyChangeEvent evt)
139 if (!fs.resettingTable && !fs.handlingUpdate)
141 fs.handlingUpdate = true;
142 fs.resetTable(null); // new groups may be added with new seuqence
143 // feature types only
144 fs.handlingUpdate = false;
150 frame = new JInternalFrame();
151 frame.setContentPane(this);
152 Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 450);
154 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
156 public void internalFrameClosed(
157 javax.swing.event.InternalFrameEvent evt)
159 fr.removePropertyChangeListener(change);
162 frame.setLayer(JLayeredPane.PALETTE_LAYER);
166 * true when Feature Settings are updating from feature renderer
168 private boolean handlingUpdate = false;
171 * contains a float[3] for each feature type string. created by setTableData
173 Hashtable typeWidth = null;
175 synchronized public void setTableData()
177 if (fr.featureGroups == null)
179 fr.featureGroups = new Hashtable();
181 Vector allFeatures = new Vector();
182 Vector allGroups = new Vector();
183 SequenceFeature[] tmpfeatures;
185 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
187 if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence()
188 .getSequenceFeatures() == null)
193 tmpfeatures = af.getViewport().alignment.getSequenceAt(i)
194 .getDatasetSequence().getSequenceFeatures();
197 while (index < tmpfeatures.length)
199 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
205 if (tmpfeatures[index].getFeatureGroup() != null)
207 group = tmpfeatures[index].featureGroup;
208 if (!allGroups.contains(group))
210 allGroups.addElement(group);
213 checkGroupState(group);
218 if (!allFeatures.contains(tmpfeatures[index].getType()))
220 allFeatures.addElement(tmpfeatures[index].getType());
234 * @return true if group has been seen before and is already added to set.
236 private boolean checkGroupState(String group)
239 if (fr.featureGroups.containsKey(group))
241 visible = ((Boolean) fr.featureGroups.get(group)).booleanValue();
245 visible = true; // new group is always made visible
248 if (groupPanel == null)
250 groupPanel = new JPanel();
253 boolean alreadyAdded = false;
254 for (int g = 0; g < groupPanel.getComponentCount(); g++)
256 if (((JCheckBox) groupPanel.getComponent(g)).getText().equals(group))
259 ((JCheckBox) groupPanel.getComponent(g)).setSelected(visible);
270 fr.featureGroups.put(group, new Boolean(visible));
271 final String grp = group;
272 final JCheckBox check = new JCheckBox(group, visible);
273 check.setFont(new Font("Serif", Font.BOLD, 12));
274 check.addItemListener(new ItemListener()
276 public void itemStateChanged(ItemEvent evt)
278 fr.featureGroups.put(check.getText(), new Boolean(check
280 af.alignPanel.seqPanel.seqCanvas.repaint();
281 if (af.alignPanel.overviewPanel != null)
283 af.alignPanel.overviewPanel.updateOverviewImage();
286 resetTable(new String[]
290 groupPanel.add(check);
294 boolean resettingTable = false;
296 synchronized void resetTable(String[] groupChanged)
298 if (resettingTable == true)
302 resettingTable = true;
303 typeWidth = new Hashtable();
304 // TODO: change avWidth calculation to 'per-sequence' average and use long
306 float[] avWidth = null;
307 SequenceFeature[] tmpfeatures;
308 String group = null, type;
309 Vector visibleChecks = new Vector();
311 // Find out which features should be visible depending on which groups
312 // are selected / deselected
313 // and recompute average width ordering
314 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
317 tmpfeatures = af.getViewport().alignment.getSequenceAt(i)
318 .getDatasetSequence().getSequenceFeatures();
319 if (tmpfeatures == null)
325 while (index < tmpfeatures.length)
327 group = tmpfeatures[index].featureGroup;
329 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
335 if (group == null || fr.featureGroups.get(group) == null
336 || ((Boolean) fr.featureGroups.get(group)).booleanValue())
339 checkGroupState(group);
340 type = tmpfeatures[index].getType();
341 if (!visibleChecks.contains(type))
343 visibleChecks.addElement(type);
346 if (!typeWidth.containsKey(tmpfeatures[index].getType()))
348 typeWidth.put(tmpfeatures[index].getType(),
349 avWidth = new float[3]);
353 avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType());
356 if (tmpfeatures[index].getBegin() > tmpfeatures[index].getEnd())
358 avWidth[1] += 1 + tmpfeatures[index].getBegin()
359 - tmpfeatures[index].getEnd();
363 avWidth[1] += 1 + tmpfeatures[index].getEnd()
364 - tmpfeatures[index].getBegin();
370 int fSize = visibleChecks.size();
371 Object[][] data = new Object[fSize][3];
374 if (fr.renderOrder != null)
377 fr.findAllFeatures(groupChanged != null); // prod to update
378 // colourschemes. but don't
380 // First add the checks in the previous render order,
381 // in case the window has been closed and reopened
382 for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
384 type = fr.renderOrder[ro];
386 if (!visibleChecks.contains(type))
391 data[dataIndex][0] = type;
392 data[dataIndex][1] = fr.getColour(type);
393 data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed
396 visibleChecks.removeElement(type);
400 fSize = visibleChecks.size();
401 for (int i = 0; i < fSize; i++)
403 // These must be extra features belonging to the group
404 // which was just selected
405 type = visibleChecks.elementAt(i).toString();
406 data[dataIndex][0] = type;
408 data[dataIndex][1] = fr.getColour(type);
409 if (data[dataIndex][1] == null)
411 // "Colour has been updated in another view!!"
412 fr.renderOrder = null;
416 data[dataIndex][2] = new Boolean(true);
420 if (originalData == null)
422 originalData = new Object[data.length][3];
423 System.arraycopy(data, 0, originalData, 0, data.length);
426 table.setModel(new FeatureTableModel(data));
427 table.getColumnModel().getColumn(0).setPreferredWidth(200);
429 if (groupPanel != null)
431 groupPanel.setLayout(new GridLayout(fr.featureGroups.size() / 4 + 1,
434 groupPanel.validate();
435 bigPanel.add(groupPanel, BorderLayout.NORTH);
438 updateFeatureRenderer(data, groupChanged != null);
439 resettingTable = false;
443 * reorder data based on the featureRenderers global priority list.
447 private void ensureOrder(Object[][] data)
449 boolean sort = false;
450 float[] order = new float[data.length];
451 for (int i = 0; i < order.length; i++)
453 order[i] = fr.getOrder(data[i][0].toString());
455 order[i] = fr.setOrder(data[i][0].toString(), i / order.length);
457 sort = sort || order[i - 1] > order[i];
460 jalview.util.QuickSort.sort(order, data);
465 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
466 .getProperty("LAST_DIRECTORY"), new String[]
467 { "fc" }, new String[]
468 { "Sequence Feature Colours" }, "Sequence Feature Colours");
469 chooser.setFileView(new jalview.io.JalviewFileView());
470 chooser.setDialogTitle("Load Feature Colours");
471 chooser.setToolTipText("Load");
473 int value = chooser.showOpenDialog(this);
475 if (value == JalviewFileChooser.APPROVE_OPTION)
477 File file = chooser.getSelectedFile();
481 InputStreamReader in = new InputStreamReader(new FileInputStream(
484 jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
485 jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
487 for (int i = jucs.getColourCount() - 1; i >= 0; i--)
490 fr.setColour(name = jucs.getColour(i).getName(), new Color(
491 Integer.parseInt(jucs.getColour(i).getRGB(), 16)));
492 fr.setOrder(name, (i == 0) ? 0 : i / jucs.getColourCount());
497 Object[][] data = ((FeatureTableModel) table.getModel())
500 updateFeatureRenderer(data, false);
503 } catch (Exception ex)
505 System.out.println("Error loading User Colour File\n" + ex);
512 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
513 .getProperty("LAST_DIRECTORY"), new String[]
514 { "fc" }, new String[]
515 { "Sequence Feature Colours" }, "Sequence Feature Colours");
516 chooser.setFileView(new jalview.io.JalviewFileView());
517 chooser.setDialogTitle("Save Feature Colour Scheme");
518 chooser.setToolTipText("Save");
520 int value = chooser.showSaveDialog(this);
522 if (value == JalviewFileChooser.APPROVE_OPTION)
524 String choice = chooser.getSelectedFile().getPath();
525 jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();
526 ucs.setSchemeName("Sequence Features");
529 PrintWriter out = new PrintWriter(new OutputStreamWriter(
530 new FileOutputStream(choice), "UTF-8"));
532 Enumeration e = fr.featureColours.keys();
533 float[] sortOrder = new float[fr.featureColours.size()];
534 String[] sortTypes = new String[fr.featureColours.size()];
536 while (e.hasMoreElements())
538 sortTypes[i] = e.nextElement().toString();
539 sortOrder[i] = fr.getOrder(sortTypes[i]);
542 jalview.util.QuickSort.sort(sortOrder, sortTypes);
544 for (i = 0; i < sortTypes.length; i++)
546 jalview.binding.Colour col = new jalview.binding.Colour();
547 col.setName(sortTypes[i]);
548 col.setRGB(jalview.util.Format.getHexString(fr.getColour(col
554 } catch (Exception ex)
556 ex.printStackTrace();
561 public void invertSelection()
563 for (int i = 0; i < table.getRowCount(); i++)
565 Boolean value = (Boolean) table.getValueAt(i, 2);
567 table.setValueAt(new Boolean(!value.booleanValue()), i, 2);
571 public void orderByAvWidth()
573 if (table == null || table.getModel() == null)
575 Object[][] data = ((FeatureTableModel) table.getModel()).getData();
576 float[] width = new float[data.length];
580 for (int i = 0; i < data.length; i++)
582 awidth = (float[]) typeWidth.get(data[i][0]);
585 width[i] = awidth[1] / awidth[0];// *awidth[0]*awidth[2]; - better
586 // weight - but have to make per
587 // sequence, too (awidth[2])
588 // if (width[i]==1) // hack to distinguish single width sequences.
598 boolean sort = false;
599 for (int i = 0; i < width.length; i++)
601 // awidth = (float[]) typeWidth.get(data[i][0]);
604 width[i] = fr.getOrder(data[i][0].toString());
607 width[i] = fr.setOrder(data[i][0].toString(), i / data.length);
612 width[i] /= max; // normalize
613 fr.setOrder(data[i][0].toString(), width[i]); // store for later
616 sort = sort || width[i - 1] > width[i];
619 jalview.util.QuickSort.sort(width, data);
620 // update global priority order
622 updateFeatureRenderer(data, false);
630 frame.setClosed(true);
631 } catch (Exception exe)
637 public void updateFeatureRenderer(Object[][] data)
639 updateFeatureRenderer(data, true);
642 private void updateFeatureRenderer(Object[][] data, boolean visibleNew)
644 fr.setFeaturePriority(data, visibleNew);
645 af.alignPanel.paintAlignment(true);
648 int selectedRow = -1;
650 JTabbedPane tabbedPane = new JTabbedPane();
652 BorderLayout borderLayout1 = new BorderLayout();
654 BorderLayout borderLayout2 = new BorderLayout();
656 BorderLayout borderLayout3 = new BorderLayout();
658 JPanel bigPanel = new JPanel();
660 BorderLayout borderLayout4 = new BorderLayout();
662 JButton invert = new JButton();
664 JPanel buttonPanel = new JPanel();
666 JButton cancel = new JButton();
668 JButton ok = new JButton();
670 JButton loadColours = new JButton();
672 JButton saveColours = new JButton();
674 JPanel dasButtonPanel = new JPanel();
676 JButton fetchDAS = new JButton();
678 JButton saveDAS = new JButton();
680 JButton cancelDAS = new JButton();
682 JButton optimizeOrder = new JButton();
684 JPanel transbuttons = new JPanel(new BorderLayout());
686 private void jbInit() throws Exception
688 this.setLayout(borderLayout1);
689 settingsPane.setLayout(borderLayout2);
690 dasSettingsPane.setLayout(borderLayout3);
691 bigPanel.setLayout(borderLayout4);
692 invert.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
693 invert.setText("Invert Selection");
694 invert.addActionListener(new ActionListener()
696 public void actionPerformed(ActionEvent e)
701 optimizeOrder.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
702 optimizeOrder.setText("Optimise Order");
703 optimizeOrder.addActionListener(new ActionListener()
705 public void actionPerformed(ActionEvent e)
710 cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
711 cancel.setText("Cancel");
712 cancel.addActionListener(new ActionListener()
714 public void actionPerformed(ActionEvent e)
716 updateFeatureRenderer(originalData);
720 ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
722 ok.addActionListener(new ActionListener()
724 public void actionPerformed(ActionEvent e)
729 loadColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
730 loadColours.setText("Load Colours");
731 loadColours.addActionListener(new ActionListener()
733 public void actionPerformed(ActionEvent e)
738 saveColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
739 saveColours.setText("Save Colours");
740 saveColours.addActionListener(new ActionListener()
742 public void actionPerformed(ActionEvent e)
747 transparency.addChangeListener(new ChangeListener()
749 public void stateChanged(ChangeEvent evt)
751 fr.setTransparency((float) (100 - transparency.getValue()) / 100f);
752 af.alignPanel.paintAlignment(true);
756 transparency.setMaximum(70);
757 fetchDAS.setText("Fetch DAS Features");
758 fetchDAS.addActionListener(new ActionListener()
760 public void actionPerformed(ActionEvent e)
762 fetchDAS_actionPerformed(e);
765 saveDAS.setText("Save as default");
766 saveDAS.addActionListener(new ActionListener()
768 public void actionPerformed(ActionEvent e)
770 saveDAS_actionPerformed(e);
773 dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
774 dasSettingsPane.setBorder(null);
775 cancelDAS.setEnabled(false);
776 cancelDAS.setText("Cancel Fetch");
777 cancelDAS.addActionListener(new ActionListener()
779 public void actionPerformed(ActionEvent e)
781 cancelDAS_actionPerformed(e);
784 this.add(tabbedPane, java.awt.BorderLayout.CENTER);
785 tabbedPane.addTab("Feature Settings", settingsPane);
786 tabbedPane.addTab("DAS Settings", dasSettingsPane);
787 bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
788 transPanel.add(transparency);
789 transbuttons.add(invert, java.awt.BorderLayout.NORTH);
790 transbuttons.add(optimizeOrder, java.awt.BorderLayout.SOUTH);
791 transPanel.add(transbuttons);
793 buttonPanel.add(cancel);
794 buttonPanel.add(loadColours);
795 buttonPanel.add(saveColours);
796 bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);
797 dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);
798 dasButtonPanel.add(fetchDAS);
799 dasButtonPanel.add(cancelDAS);
800 dasButtonPanel.add(saveDAS);
801 settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);
802 settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
805 public void fetchDAS_actionPerformed(ActionEvent e)
807 fetchDAS.setEnabled(false);
808 cancelDAS.setEnabled(true);
809 Vector selectedSources = dassourceBrowser.getSelectedSources();
810 doDasFeatureFetch(selectedSources, true, true);
814 * get the features from selectedSources for all or the current selection
816 * @param selectedSources
818 * @param promptFetchDbRefs
820 private void doDasFeatureFetch(Vector selectedSources,
821 boolean checkDbRefs, boolean promptFetchDbRefs)
823 SequenceI[] dataset, seqs;
825 AlignViewport vp = af.getViewport();
826 if (vp.getSelectionGroup() != null
827 && vp.getSelectionGroup().getSize() > 0)
829 iSize = vp.getSelectionGroup().getSize();
830 dataset = new SequenceI[iSize];
831 seqs = vp.getSelectionGroup().getSequencesInOrder(vp.getAlignment());
835 iSize = vp.getAlignment().getHeight();
836 seqs = vp.getAlignment().getSequencesArray();
839 dataset = new SequenceI[iSize];
840 for (int i = 0; i < iSize; i++)
842 dataset[i] = seqs[i].getDatasetSequence();
845 cancelDAS.setEnabled(true);
846 dasFeatureFetcher = new jalview.ws.DasSequenceFeatureFetcher(dataset,
847 this, selectedSources, checkDbRefs, promptFetchDbRefs);
848 af.getViewport().setShowSequenceFeatures(true);
849 af.showSeqFeatures.setSelected(true);
853 * properly initialise DAS fetcher and then initiate a new thread to fetch
854 * features from the named sources (rather than any turned on by default)
858 public void fetchDasFeatures(Vector sources)
860 Thread thr = new Thread(new Runnable()
864 // this actually initialises the das source list
865 dassourceBrowser.paintComponent(null); // yuk
869 while (dassourceBrowser.loadingDasSources
870 || dassourceBrowser.dasSources == null)
875 } catch (Exception e)
880 Vector resolved = new Vector();
883 for (int i = 0; i < dassourceBrowser.dasSources.length; i++)
885 if (sources.contains(dassourceBrowser.dasSources[i].getNickname()))
887 if (!resolved.contains(dassourceBrowser.dasSources[i]))
889 resolved.addElement(dassourceBrowser.dasSources[i]);
894 if (resolved.size() == 0)
896 resolved = dassourceBrowser.getSelectedSources();
898 if (resolved.size() > 0)
900 final Vector dassources = resolved;
901 SwingUtilities.invokeLater(new Runnable()
906 fetchDAS.setEnabled(false);
907 cancelDAS.setEnabled(true);
908 doDasFeatureFetch(dassources, true, false);
915 public void saveDAS_actionPerformed(ActionEvent e)
918 .saveProperties(jalview.bin.Cache.applicationProperties);
921 public void complete()
923 fetchDAS.setEnabled(true);
924 cancelDAS.setEnabled(false);
927 public void cancelDAS_actionPerformed(ActionEvent e)
929 if (dasFeatureFetcher != null)
931 dasFeatureFetcher.cancel();
933 fetchDAS.setEnabled(true);
934 cancelDAS.setEnabled(false);
937 public void noDasSourceActive()
940 JOptionPane.showInternalConfirmDialog(Desktop.desktop,
941 "No das sources were selected.\n"
942 + "Please select some sources and\n" + " try again.",
943 "No Sources Selected", JOptionPane.DEFAULT_OPTION,
944 JOptionPane.INFORMATION_MESSAGE);
947 // ///////////////////////////////////////////////////////////////////////
948 // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
949 // ///////////////////////////////////////////////////////////////////////
950 class FeatureTableModel extends AbstractTableModel
952 FeatureTableModel(Object[][] data)
957 private String[] columnNames =
958 { "Feature Type", "Colour", "Display" };
960 private Object[][] data;
962 public Object[][] getData()
967 public void setData(Object[][] data)
972 public int getColumnCount()
974 return columnNames.length;
977 public Object[] getRow(int row)
982 public int getRowCount()
987 public String getColumnName(int col)
989 return columnNames[col];
992 public Object getValueAt(int row, int col)
994 return data[row][col];
997 public Class getColumnClass(int c)
999 return getValueAt(0, c).getClass();
1002 public boolean isCellEditable(int row, int col)
1004 return col == 0 ? false : true;
1007 public void setValueAt(Object value, int row, int col)
1009 data[row][col] = value;
1010 fireTableCellUpdated(row, col);
1011 updateFeatureRenderer(data);
1016 class ColorRenderer extends JLabel implements TableCellRenderer
1018 javax.swing.border.Border unselectedBorder = null;
1020 javax.swing.border.Border selectedBorder = null;
1022 public ColorRenderer()
1024 setOpaque(true); // MUST do this for background to show up.
1027 public Component getTableCellRendererComponent(JTable table,
1028 Object color, boolean isSelected, boolean hasFocus, int row,
1031 Color newColor = (Color) color;
1032 setBackground(newColor);
1035 if (selectedBorder == null)
1037 selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
1038 table.getSelectionBackground());
1040 setBorder(selectedBorder);
1044 if (unselectedBorder == null)
1046 unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
1047 table.getBackground());
1049 setBorder(unselectedBorder);
1052 setToolTipText("RGB value: " + newColor.getRed() + ", "
1053 + newColor.getGreen() + ", " + newColor.getBlue());
1059 class ColorEditor extends AbstractCellEditor implements TableCellEditor,
1066 JColorChooser colorChooser;
1070 protected static final String EDIT = "edit";
1072 public ColorEditor()
1074 // Set up the editor (from the table's point of view),
1075 // which is a button.
1076 // This button brings up the color chooser dialog,
1077 // which is the editor from the user's point of view.
1078 button = new JButton();
1079 button.setActionCommand(EDIT);
1080 button.addActionListener(this);
1081 button.setBorderPainted(false);
1082 // Set up the dialog that the button brings up.
1083 colorChooser = new JColorChooser();
1084 dialog = JColorChooser.createDialog(button, "Select new Colour", true, // modal
1085 colorChooser, this, // OK button handler
1086 null); // no CANCEL button handler
1090 * Handles events from the editor button and from the dialog's OK button.
1092 public void actionPerformed(ActionEvent e)
1095 if (EDIT.equals(e.getActionCommand()))
1097 // The user has clicked the cell, so
1098 // bring up the dialog.
1099 button.setBackground(currentColor);
1100 colorChooser.setColor(currentColor);
1101 dialog.setVisible(true);
1103 // Make the renderer reappear.
1104 fireEditingStopped();
1108 { // User pressed dialog's "OK" button.
1109 currentColor = colorChooser.getColor();
1113 // Implement the one CellEditor method that AbstractCellEditor doesn't.
1114 public Object getCellEditorValue()
1116 return currentColor;
1119 // Implement the one method defined by TableCellEditor.
1120 public Component getTableCellEditorComponent(JTable table, Object value,
1121 boolean isSelected, int row, int column)
1123 currentColor = (Color) value;