From 720fee2c68d546822739e618942c178e77d87ea8 Mon Sep 17 00:00:00 2001 From: jprocter Date: Fri, 26 Mar 2010 12:27:17 +0000 Subject: [PATCH] gui/debug: integrate graduated feature colour editor into amend feature and feature settings dialog box. --- src/jalview/gui/FeatureColourChooser.java | 156 ++++++++---- src/jalview/gui/FeatureRenderer.java | 149 ++++++++---- src/jalview/gui/FeatureSettings.java | 371 ++++++++++++++++++++++++----- 3 files changed, 514 insertions(+), 162 deletions(-) diff --git a/src/jalview/gui/FeatureColourChooser.java b/src/jalview/gui/FeatureColourChooser.java index fedcbc5..24662c7 100644 --- a/src/jalview/gui/FeatureColourChooser.java +++ b/src/jalview/gui/FeatureColourChooser.java @@ -29,17 +29,28 @@ import jalview.datamodel.*; import jalview.schemes.*; import java.awt.Dimension; -public class FeatureColourChooser extends JPanel +public class FeatureColourChooser extends JPanel { - JInternalFrame frame; + JDialog frame; - FeatureRenderer fr; - - FeatureSettings fs; - - GraduatedColor cs; - Object oldcs; +// FeatureSettings fs; + FeatureRenderer fr; + + + private GraduatedColor cs; + private Object oldcs; + /** + * + * @return the last colour setting selected by user - either oldcs (which may be a java.awt.Color) or the new GraduatedColor + */ + public Object getLastColour() { + if (cs==null) + { + return oldcs; + } + return cs; + } Hashtable oldgroupColours; AlignmentPanel ap; @@ -51,16 +62,20 @@ public class FeatureColourChooser extends JPanel private float max; String type = null; - public FeatureColourChooser(FeatureSettings fsettings, String type) + public FeatureColourChooser(FeatureRenderer frender, String type) { - this.fs = fsettings; + this(frender,false,type); + } + public FeatureColourChooser(FeatureRenderer frender, boolean block, String type) + { + this.fr = frender; this.type = type; - fr = fsettings.fr; ap = fr.ap; - frame = new JInternalFrame(); + frame = new JDialog(Desktop.instance,true); + frame.setSize(480,185); frame.setContentPane(this); - frame.setLayer(JLayeredPane.PALETTE_LAYER); - Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type, 480, 145); + //frame.setLayer(JLayeredPane.PALETTE_LAYER); + //Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type, 480, 145); slider.addChangeListener(new ChangeListener() { @@ -77,7 +92,7 @@ public class FeatureColourChooser extends JPanel { public void mouseReleased(MouseEvent evt) { - if (fr.ap!=null) { fr.ap.paintAlignment(true); }; + if (ap!=null) { ap.paintAlignment(true); }; } }); @@ -105,8 +120,8 @@ public class FeatureColourChooser extends JPanel cs = new GraduatedColor(Color.white,bl,mm[0],mm[1]); cs.setColourByLabel(false); } - minColour.setBackground(cs.getMinColor()); - maxColour.setBackground(cs.getMaxColor()); + minColour.setBackground(oldminColour=cs.getMinColor()); + maxColour.setBackground(oldmaxColour=cs.getMaxColor()); adjusting = true; try @@ -133,7 +148,19 @@ public class FeatureColourChooser extends JPanel adjusting = false; changeColour(); + if (!block) + { + new Thread(new Runnable() { + public void run() + { + frame.show(); + } + + }).start(); + } else { + frame.show(); + } } public FeatureColourChooser() @@ -149,6 +176,7 @@ public class FeatureColourChooser extends JPanel private void jbInit() throws Exception { + minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); minColour.setBorder(BorderFactory.createEtchedBorder()); minColour.setPreferredSize(new Dimension(40, 20)); @@ -206,6 +234,7 @@ public class FeatureColourChooser extends JPanel threshold_actionPerformed(e); } }); + threshold.setToolTipText("Threshold the feature display by score."); threshold.addItem("No Threshold"); // index 0 threshold.addItem("Above Threshold"); // index 1 threshold.addItem("Below Threshold"); // index 2 @@ -223,21 +252,13 @@ public class FeatureColourChooser extends JPanel slider.setEnabled(false); slider.setOpaque(false); slider.setPreferredSize(new Dimension(100, 32)); + slider.setToolTipText("Adjust threshold"); thresholdValue.setEnabled(false); thresholdValue.setColumns(7); jPanel3.setBackground(Color.white); - currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); - currentColours.setOpaque(false); - currentColours.setText("Use Original Colours"); - currentColours.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - currentColours_actionPerformed(e); - } - }); thresholdIsMin.setBackground(Color.white); thresholdIsMin.setText("Threshold is Min/Max"); + thresholdIsMin.setToolTipText("Toggle between absolute and relative display threshold."); thresholdIsMin.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) @@ -247,6 +268,7 @@ public class FeatureColourChooser extends JPanel }); colourByLabel.setBackground(Color.white); colourByLabel.setText("Colour by Label"); + colourByLabel.setToolTipText("Display features of the same type with a different label using a different colour. (e.g. domain features)"); colourByLabel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) @@ -256,15 +278,15 @@ public class FeatureColourChooser extends JPanel }); jPanel1.add(ok); jPanel1.add(cancel); - // jPanel2.add(currentColours); - jPanel2.add(minColour); - jPanel2.add(maxColour); + jPanel2.add(colourByLabel,java.awt.BorderLayout.WEST); + jPanel2.add(colourPanel,java.awt.BorderLayout.EAST); + colourPanel.add(minColour); + colourPanel.add(maxColour); this.add(jPanel3, java.awt.BorderLayout.CENTER); jPanel3.add(threshold); jPanel3.add(slider); jPanel3.add(thresholdValue); jPanel3.add(thresholdIsMin); - jPanel3.add(colourByLabel); this.add(jPanel1, java.awt.BorderLayout.SOUTH); this.add(jPanel2, java.awt.BorderLayout.NORTH); } @@ -277,7 +299,7 @@ public class FeatureColourChooser extends JPanel JButton ok = new JButton(); JButton cancel = new JButton(); - + JPanel colourPanel = new JPanel(); JPanel jPanel1 = new JPanel(); JPanel jPanel2 = new JPanel(); @@ -295,14 +317,20 @@ public class FeatureColourChooser extends JPanel JSlider slider = new JSlider(); JTextField thresholdValue = new JTextField(20); - // TODO refactor to tolower flag - JCheckBox currentColours = new JCheckBox(); + // TODO implement GUI for tolower flag + // JCheckBox toLower = new JCheckBox(); JCheckBox thresholdIsMin = new JCheckBox(); JCheckBox colourByLabel = new JCheckBox(); private GraphLine threshline; + + private Color oldmaxColour; + + + private Color oldminColour; + public void minColour_actionPerformed() { Color col = JColorChooser.showDialog(this, @@ -348,7 +376,15 @@ public class FeatureColourChooser extends JPanel slider.setEnabled(true); thresholdValue.setEnabled(true); - GraduatedColor acg = new GraduatedColor(minColour.getBackground(), maxColour.getBackground(), min, max); + + GraduatedColor acg; + if (cs.isColourByLabel()) + { + acg = new GraduatedColor(oldminColour, oldmaxColour, min, max); + } else { + acg = new GraduatedColor(oldminColour=minColour.getBackground(), oldmaxColour=maxColour.getBackground(), min, max); + + } if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD) { @@ -397,17 +433,35 @@ public class FeatureColourChooser extends JPanel acg.setAutoScaled(true); } acg.setColourByLabel(colourByLabel.isSelected()); + if (acg.isColourByLabel()) + { + maxColour.setEnabled(false); + minColour.setEnabled(false); + maxColour.setBackground(this.getBackground()); + minColour.setBackground(this.getBackground()); + } else { + maxColour.setEnabled(true); + minColour.setEnabled(true); + maxColour.setBackground(oldmaxColour); + minColour.setBackground(oldminColour); + } fr.featureColours.put(type,acg); cs = acg; ap.paintAlignment(false); } - + private void raiseClosed() { + if (this.colourEditor!=null) + { + colourEditor.actionPerformed(new ActionEvent(this, 0, "CLOSED")); + } + } public void ok_actionPerformed(ActionEvent e) { changeColour(); try { - frame.setClosed(true); + frame.dispose(); + raiseClosed(); } catch (Exception ex) { } @@ -418,7 +472,9 @@ public class FeatureColourChooser extends JPanel reset(); try { - frame.setClosed(true); + frame.dispose(); +// frame.setClosed(true); + raiseClosed(); } catch (Exception ex) { } @@ -427,6 +483,8 @@ public class FeatureColourChooser extends JPanel void reset() { fr.featureColours.put(type, oldcs); + ap.paintAlignment(false); + cs = null; } public void thresholdCheck_actionPerformed(ActionEvent e) @@ -464,19 +522,6 @@ public class FeatureColourChooser extends JPanel ap.paintAlignment(false); } - public void currentColours_actionPerformed(ActionEvent e) - { - if (currentColours.isSelected()) - { - reset(); - } - - maxColour.setEnabled(!currentColours.isSelected()); - minColour.setEnabled(!currentColours.isSelected()); - - changeColour(); - } - public void thresholdIsMin_actionPerformed(ActionEvent actionEvent) { changeColour(); @@ -485,5 +530,14 @@ public class FeatureColourChooser extends JPanel { changeColour(); } + ActionListener colourEditor=null; + public void addActionListener(ActionListener graduatedColorEditor) + { + if (colourEditor!=null) + { + System.err.println("IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser"); + } + colourEditor = graduatedColorEditor; + } } diff --git a/src/jalview/gui/FeatureRenderer.java b/src/jalview/gui/FeatureRenderer.java index 75ce63a..a583d1d 100755 --- a/src/jalview/gui/FeatureRenderer.java +++ b/src/jalview/gui/FeatureRenderer.java @@ -30,6 +30,7 @@ import javax.swing.*; import jalview.datamodel.*; import jalview.schemes.GraduatedColor; +import jalview.util.FeatureColourI; /** * DOCUMENT ME! @@ -818,18 +819,34 @@ public class FeatureRenderer sortOrder = null; System.arraycopy(newf, 0, renderOrder, opos, newf.length); } - - public Color getColour(String featureType) - { + /** + * get a feature style object for the given type string. + * Creates a java.awt.Color for a featureType with no existing + * colourscheme. + * TODO: replace return type with object implementing standard abstract colour/style interface + * @param featureType + * @return java.awt.Color or GraduatedColor + */ + public Object getFeatureStyle(String featureType) { Object fc = featureColours.get(featureType); if (fc == null) { jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(); Color col = ucs.createColourFromName(featureType); - featureColours.put(featureType, col); - return col; + featureColours.put(featureType, fc = col); } - else if (fc instanceof Color) + return fc; + } + /** + * return a nominal colour for this feature + * @param featureType + * @return standard color, or maximum colour for graduated colourscheme + */ + public Color getColour(String featureType) + { + Object fc = getFeatureStyle(featureType); + + if (fc instanceof Color) { return (Color) fc; } @@ -839,28 +856,20 @@ public class FeatureRenderer { return ((GraduatedColor) fc).getMaxColor(); } - // TODO: raise an implementation error here. - return null; // Color.white; } + throw new Error("Implementation Error: Unrecognised render object "+fc.getClass()+" for features of type "+featureType); } /** - * implement graduated colouring for features with scores + * calculate the render colour for a specific feature using current feature settings. * * @param feature * @return render colour for the given feature */ public Color getColour(SequenceFeature feature) { - Object fc = featureColours.get(feature.type); - if (fc == null) - { - jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(); - Color col = ucs.createColourFromName(feature.type); - featureColours.put(feature.type, col); - return col; - } - else if (fc instanceof Color) + Object fc = getFeatureStyle(feature.getType()); + if (fc instanceof Color) { return (Color) fc; } @@ -870,13 +879,12 @@ public class FeatureRenderer { return ((GraduatedColor) fc).findColor(feature); } - // TODO: raise an implementation error here. - return null; // Color.white; } + throw new Error("Implementation Error: Unrecognised render object "+fc.getClass()+" for features of type "+feature.getType()); } private boolean showFeature(SequenceFeature sequenceFeature) { - Object fc = featureColours.get(sequenceFeature.type); + Object fc = getFeatureStyle(sequenceFeature.type); if (fc instanceof GraduatedColor) { return ((GraduatedColor) fc).isColored(sequenceFeature); @@ -889,7 +897,7 @@ public class FeatureRenderer static String lastFeatureGroupAdded; static String lastDescriptionAdded; - + Object oldcol,fcol; int featureIndex = 0; boolean amendFeatures(final SequenceI[] sequences, @@ -899,7 +907,7 @@ public class FeatureRenderer featureIndex = 0; - JPanel bigPanel = new JPanel(new BorderLayout()); + final JPanel bigPanel = new JPanel(new BorderLayout()); final JComboBox overlaps; final JTextField name = new JTextField(25); final JTextField source = new JTextField(25); @@ -908,23 +916,49 @@ public class FeatureRenderer final JSpinner end = new JSpinner(); start.setPreferredSize(new Dimension(80, 20)); end.setPreferredSize(new Dimension(80, 20)); - - final JPanel colour = new JPanel(); - colour.setBorder(BorderFactory.createEtchedBorder()); - colour.setMaximumSize(new Dimension(40, 10)); + final FeatureRenderer me = this; + final JLabel colour = new JLabel(); + colour.setOpaque(true); + //colour.setBorder(BorderFactory.createEtchedBorder()); + colour.setMaximumSize(new Dimension(30, 16)); colour.addMouseListener(new MouseAdapter() { + FeatureColourChooser fcc =null; public void mousePressed(MouseEvent evt) { - // TODO: use featurecolourchooser here + if (fcol instanceof Color) + { Color col = JColorChooser.showDialog(Desktop.desktop, - "Select Feature Colour", colour.getBackground()); + "Select Feature Colour", ((Color)fcol)); if (col != null) - colour.setBackground(col); + { + fcol = col; + updateColourButton(bigPanel,colour,col); + } + } else { + + if (fcc==null) { + final String type = features[featureIndex].getType(); + fcc = new FeatureColourChooser(me, type); + fcc.setRequestFocusEnabled(true); + fcc.requestFocus(); + + fcc.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + fcol = fcc.getLastColour(); + fcc = null; + setColour(type, fcol); + updateColourButton(bigPanel,colour,fcol); + } + } + ); + + } + } } }); - JPanel tmp = new JPanel(); JPanel panel = new JPanel(new GridLayout(3, 1)); @@ -966,14 +1000,14 @@ public class FeatureRenderer ap.seqPanel.seqCanvas.highlightSearchResults(highlight); } - Color col = getColour(name.getText()); + Object col = getFeatureStyle(name.getText()); if (col == null) { col = new jalview.schemes.UserColourScheme() .createColourFromName(name.getText()); } - - colour.setBackground(col); + oldcol = fcol = col; + updateColourButton(bigPanel, colour,col); } }); @@ -1060,8 +1094,7 @@ public class FeatureRenderer start.setValue(new Integer(features[0].getBegin())); end.setValue(new Integer(features[0].getEnd())); description.setText(features[0].getDescription()); - colour.setBackground(getColour(name.getText())); - + updateColourButton(bigPanel, colour, (oldcol = fcol = getFeatureStyle(name.getText()))); Object[] options; if (!newFeatures) { @@ -1110,9 +1143,8 @@ public class FeatureRenderer sf.featureGroup = lastFeatureGroupAdded; sf.description = lastDescriptionAdded; - setColour(sf.type, colour.getBackground()); - av.featuresDisplayed.put(sf.type, new Integer(colour - .getBackground().getRGB())); + setColour(sf.type, fcol); + av.featuresDisplayed.put(sf.type, getColour(sf.type)); try { @@ -1151,11 +1183,8 @@ public class FeatureRenderer featureGroups = new Hashtable(); featureGroups.put(lastFeatureGroupAdded, new Boolean(true)); } - - Color col = colour.getBackground(); - setColour(lastFeatureAdded, colour.getBackground()); - av.featuresDisplayed.put(lastFeatureAdded, - new Integer(col.getRGB())); + setColour(lastFeatureAdded, fcol); + av.featuresDisplayed.put(lastFeatureAdded, getColour(lastFeatureAdded)); findAllFeatures(false); @@ -1174,10 +1203,34 @@ public class FeatureRenderer return true; } - public void setColour(String featureType, Color col) + /** + * update the amend feature button dependent on the given style + * @param bigPanel + * @param col + * @param col2 + */ + protected void updateColourButton(JPanel bigPanel, JLabel colour, Object col2) + { + colour.removeAll(); + colour.setIcon(null); + colour.setToolTipText(null); + colour.setText(""); + if (col2 instanceof Color) { + colour.setBackground((Color)col2); + } else { + colour.setBackground(bigPanel.getBackground()); + colour.setForeground(bigPanel.getForeground()); + FeatureSettings.renderGraduatedColor(colour, (GraduatedColor) col2); + //colour.setForeground(colour.getBackground()); + } + } + + public void setColour(String featureType, Object col) { - Object c = featureColours.get(featureType); - if (c == null || c instanceof Color || (c instanceof GraduatedColor && !((GraduatedColor)c).getMaxColor().equals(col))) + // overwrite +// Color _col = (col instanceof Color) ? ((Color) col) : (col instanceof GraduatedColor) ? ((GraduatedColor) col).getMaxColor() : null; +// Object c = featureColours.get(featureType); +// if (c == null || c instanceof Color || (c instanceof GraduatedColor && !((GraduatedColor)c).getMaxColor().equals(_col))) { featureColours.put(featureType, col); } @@ -1239,7 +1292,7 @@ public class FeatureRenderer for (int i = 0; i < data.length; i++) { String type = data[i][0].toString(); - setColour(type, (Color) data[i][1]); + setColour(type, data[i][1]); // todo : typesafety - feature color interface object if (((Boolean) data[i][2]).booleanValue()) { av.featuresDisplayed.put(type, new Integer(getColour(type) diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 52267d3..d8a674f 100755 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -23,6 +23,8 @@ import java.util.*; import java.awt.*; import java.awt.event.*; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -34,6 +36,7 @@ import jalview.analysis.AlignmentSorter; import jalview.commands.OrderCommand; import jalview.datamodel.*; import jalview.io.*; +import jalview.schemes.AnnotationColourGradient; import jalview.schemes.GraduatedColor; public class FeatureSettings extends JPanel @@ -62,7 +65,7 @@ public class FeatureSettings extends JPanel JSlider transparency = new JSlider(); - JPanel transPanel = new JPanel(new FlowLayout()); + JPanel transPanel = new JPanel(new GridLayout(1, 2)); public FeatureSettings(AlignFrame af) { @@ -84,8 +87,10 @@ public class FeatureSettings extends JPanel table.setFont(new Font("Verdana", Font.PLAIN, 12)); table.setDefaultRenderer(Color.class, new ColorRenderer()); - table.setDefaultEditor(Color.class, new ColorEditor()); + table.setDefaultEditor(Color.class, new ColorEditor(this)); + table.setDefaultEditor(GraduatedColor.class, new ColorEditor(this)); + table.setDefaultRenderer(GraduatedColor.class, new ColorRenderer()); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.addMouseListener(new MouseAdapter() @@ -95,8 +100,9 @@ public class FeatureSettings extends JPanel selectedRow = table.rowAtPoint(evt.getPoint()); if (javax.swing.SwingUtilities.isRightMouseButton(evt)) { - popupSort((String) table.getValueAt(selectedRow, 0), fr.minmax, - evt.getX(), evt.getY()); + popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0), + table.getValueAt(selectedRow, 1), fr.minmax, evt.getX(), + evt.getY()); } } }); @@ -170,8 +176,8 @@ public class FeatureSettings extends JPanel frame.setLayer(JLayeredPane.PALETTE_LAYER); } - protected void popupSort(final String type, final Hashtable minmax, - int x, int y) + protected void popupSort(final int selectedRow, final String type, + final Object typeCol, final Hashtable minmax, int x, int y) { JPopupMenu men = new JPopupMenu("Settings for " + type); JMenuItem scr = new JMenuItem("Sort by Score"); @@ -202,38 +208,74 @@ public class FeatureSettings extends JPanel if (minmax != null) { final Object typeMinMax = minmax.get(type); - final JCheckBoxMenuItem chb = new JCheckBoxMenuItem("Vary Height"); - // this is broken at the moment - chb.setSelected(minmax.get(type) != null); - chb.addActionListener(new ActionListener() - { - - public void actionPerformed(ActionEvent e) - { - chb.setState(chb.getState()); - if (chb.getState()) - { - minmax.put(type, null); - } - else - { - minmax.put(type, typeMinMax); - } - } - - }); - men.add(chb); + /* + * final JCheckBoxMenuItem chb = new JCheckBoxMenuItem("Vary Height"); // + * this is broken at the moment and isn't that useful anyway! + * chb.setSelected(minmax.get(type) != null); chb.addActionListener(new + * ActionListener() { + * + * public void actionPerformed(ActionEvent e) { + * chb.setState(chb.getState()); if (chb.getState()) { minmax.put(type, + * null); } else { minmax.put(type, typeMinMax); } } + * + * }); + * + * men.add(chb); + */ if (typeMinMax != null && ((float[][]) typeMinMax)[0] != null) { - // graduated colourschemes for those where minmax exists for the positional features - JMenuItem mxcol = new JMenuItem("Min Max Colour"); + // if (table.getValueAt(row, column)); + // graduated colourschemes for those where minmax exists for the + // positional features + final JCheckBoxMenuItem mxcol = new JCheckBoxMenuItem( + "Graduated Colour"); + mxcol.setSelected(!(typeCol instanceof Color)); men.add(mxcol); mxcol.addActionListener(new ActionListener() { + JColorChooser colorChooser; public void actionPerformed(ActionEvent e) { - new FeatureColourChooser(me, type); + if (e.getSource() == mxcol) + { + if (typeCol instanceof Color) + { + FeatureColourChooser fc = new FeatureColourChooser(me.fr, + type); + fc.addActionListener(this); + } + else + { + // bring up simple color chooser + colorChooser = new JColorChooser(); + JDialog dialog = JColorChooser.createDialog(me, + "Select new Colour", true, // modal + colorChooser, this, // OK button handler + null); // no CANCEL button handler + colorChooser.setColor(((GraduatedColor) typeCol) + .getMaxColor()); + dialog.setVisible(true); + } + } + else + { + if (e.getSource() instanceof FeatureColourChooser) + { + FeatureColourChooser fc = (FeatureColourChooser) e + .getSource(); + table.setValueAt(fc.getLastColour(), selectedRow, 1); + table.validate(); + } + else + { + // probably the color chooser! + table.setValueAt(colorChooser.getColor(), selectedRow, 1); + table.validate(); + me.updateFeatureRenderer(((FeatureTableModel) table + .getModel()).getData(), false); + } + } } }); @@ -469,7 +511,7 @@ public class FeatureSettings extends JPanel } data[dataIndex][0] = type; - data[dataIndex][1] = fr.getColour(type); + data[dataIndex][1] = fr.getFeatureStyle(type); data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed .containsKey(type)); dataIndex++; @@ -485,7 +527,7 @@ public class FeatureSettings extends JPanel type = visibleChecks.elementAt(i).toString(); data[dataIndex][0] = type; - data[dataIndex][1] = fr.getColour(type); + data[dataIndex][1] = fr.getFeatureStyle(type); if (data[dataIndex][1] == null) { // "Colour has been updated in another view!!" @@ -500,7 +542,10 @@ public class FeatureSettings extends JPanel if (originalData == null) { originalData = new Object[data.length][3]; - System.arraycopy(data, 0, originalData, 0, data.length); + for (int i = 0; i < data.length; i++) + { + System.arraycopy(data[i], 0, originalData[i], 0, 3); + } } table.setModel(new FeatureTableModel(data)); @@ -567,6 +612,7 @@ public class FeatureSettings extends JPanel for (int i = jucs.getColourCount() - 1; i >= 0; i--) { String name; + // TODO: update Colour XML fr.setColour(name = jucs.getColour(i).getName(), new Color( Integer.parseInt(jucs.getColour(i).getRGB(), 16))); fr.setOrder(name, (i == 0) ? 0 : i / jucs.getColourCount()); @@ -765,7 +811,7 @@ public class FeatureSettings extends JPanel JButton sortByDens = new JButton(); - JPanel transbuttons = new JPanel(new BorderLayout()); + JPanel transbuttons = new JPanel(new GridLayout(4, 1)); private void jbInit() throws Exception { @@ -887,16 +933,16 @@ public class FeatureSettings extends JPanel tabbedPane.addTab("Feature Settings", settingsPane); tabbedPane.addTab("DAS Settings", dasSettingsPane); bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH); + transbuttons.add(optimizeOrder); + transbuttons.add(invert); + transbuttons.add(sortByScore); + transbuttons.add(sortByDens); transPanel.add(transparency); - transbuttons.add(invert, java.awt.BorderLayout.NORTH); - transbuttons.add(optimizeOrder, java.awt.BorderLayout.SOUTH); transPanel.add(transbuttons); buttonPanel.add(ok); buttonPanel.add(cancel); buttonPanel.add(loadColours); buttonPanel.add(saveColours); - buttonPanel.add(sortByScore); - buttonPanel.add(sortByDens); bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER); dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH); dasButtonPanel.add(fetchDAS); @@ -1078,7 +1124,7 @@ public class FeatureSettings extends JPanel * nicknames in sources * * @param sources - * Vector of Strings to resolve to DAS source nicknames. + * Vector of Strings to resolve to DAS source nicknames. * @return sources that are present in source list. */ public Vector resolveSourceNicknames(Vector sources) @@ -1102,7 +1148,9 @@ public class FeatureSettings extends JPanel * features from the named sources (rather than any turned on by default) * * @param sources - * @param block if true then runs in same thread, otherwise passes to the Swing executor + * @param block + * if true then runs in same thread, otherwise passes to the Swing + * executor */ public void fetchDasFeatures(Vector sources, boolean block) { @@ -1117,7 +1165,7 @@ public class FeatureSettings extends JPanel final Vector dassources = resolved; fetchDAS.setEnabled(false); // cancelDAS.setEnabled(true); doDasFetch does this. - Runnable fetcher=new Runnable() + Runnable fetcher = new Runnable() { public void run() @@ -1127,10 +1175,13 @@ public class FeatureSettings extends JPanel } }; if (block) - { fetcher.run(); - } else { - SwingUtilities.invokeLater(fetcher); - } + { + fetcher.run(); + } + else + { + SwingUtilities.invokeLater(fetcher); + } } } @@ -1241,6 +1292,8 @@ public class FeatureSettings extends JPanel javax.swing.border.Border selectedBorder = null; + final String baseTT = "Click to edit, right/apple click for menu."; + public ColorRenderer() { setOpaque(true); // MUST do this for background to show up. @@ -1250,25 +1303,30 @@ public class FeatureSettings extends JPanel Object color, boolean isSelected, boolean hasFocus, int row, int column) { + // JLabel comp = new JLabel(); + // comp. + setOpaque(true); + // comp. + // setBounds(getBounds()); Color newColor; - color = fr.featureColours.get((String) table.getModel().getValueAt( - row, 0)); + setToolTipText(baseTT); + setBackground(table.getBackground()); if (color instanceof GraduatedColor) { - newColor = ((GraduatedColor) color).getMaxColor(); - Color minCol = ((GraduatedColor) color).getMinColor();; - setBackground(newColor); - setToolTipText("RGB value: Max (" + newColor.getRed() + ", " - + newColor.getGreen() + ", " + newColor.getBlue() - + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen() - + ", " + minCol.getBlue() + ")"); + Rectangle cr = table.getCellRect(row, column, false); + FeatureSettings.renderGraduatedColor(this, (GraduatedColor) color, + (int) cr.getWidth(), (int) cr.getHeight()); + } else { + this.setText(""); + this.setIcon(null); newColor = (Color) color; + // comp. setBackground(newColor); - setToolTipText("RGB value: " + newColor.getRed() + ", " - + newColor.getGreen() + ", " + newColor.getBlue()); + // comp.setToolTipText("RGB value: " + newColor.getRed() + ", " + // + newColor.getGreen() + ", " + newColor.getBlue()); } if (isSelected) { @@ -1277,6 +1335,7 @@ public class FeatureSettings extends JPanel selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getSelectionBackground()); } + // comp. setBorder(selectedBorder); } else @@ -1286,17 +1345,151 @@ public class FeatureSettings extends JPanel unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getBackground()); } + // comp. setBorder(unselectedBorder); } return this; } } + + /** + * update comp using rendering settings from gcol + * + * @param comp + * @param gcol + */ + public static void renderGraduatedColor(JLabel comp, GraduatedColor gcol) + { + int w = comp.getWidth(), h = comp.getHeight(); + if (w < 20) + { + w = (int) comp.getPreferredSize().getWidth(); + h = (int) comp.getPreferredSize().getHeight(); + if (w < 20) + { + w = 80; + h = 12; + } + } + renderGraduatedColor(comp, gcol, w, h); + } + + public static void renderGraduatedColor(JLabel comp, GraduatedColor gcol, + int w, int h) + { + + String tt = ""; + String tx = ""; + if (gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) + { + tx += "> "; + tt += "Thresholded (Above " + gcol.getThresh() + ") "; + } + if (gcol.getThreshType() == AnnotationColourGradient.BELOW_THRESHOLD) + { + tx += "< "; + tt += "Thresholded (Below " + gcol.getThresh() + ") "; + } + if (gcol.isColourByLabel()) + { + tt = "Coloured by label text. " + tt; + tx += "Label"; + comp.setIcon(null); + } + else + { + Color newColor = gcol.getMaxColor(); + comp.setBackground(newColor); + System.err.println("Width is " + w / 2); + Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w / 2, h); + comp.setIcon(ficon); + // tt+="RGB value: Max (" + newColor.getRed() + ", " + // + newColor.getGreen() + ", " + newColor.getBlue() + // + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen() + // + ", " + minCol.getBlue() + ")"); + } + comp.setText(tx); + if (tt.length() > 0) + { + if (comp.getToolTipText() == null) + { + comp.setToolTipText(tt); + } + else + { + comp.setToolTipText(tt + " " + comp.getToolTipText()); + } + } + } +} + +class FeatureIcon implements Icon +{ + GraduatedColor gcol; + + Color backg; + + int width = 50, height = 20; + + FeatureIcon(GraduatedColor gfc, Color bg, int w, int h) + { + gcol = gfc; + backg = bg; + width = w; + height = h; + } + + public int getIconWidth() + { + return width; + } + + public int getIconHeight() + { + return height; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + + if (gcol.isColourByLabel()) + { + g.setColor(backg); + g.fillRect(0, 0, width, height); + // need an icon here. + g.setColor(gcol.getMaxColor()); + + g.setFont(new Font("Verdana", Font.PLAIN, 9)); + + // g.setFont(g.getFont().deriveFont( + // AffineTransform.getScaleInstance( + // width/g.getFontMetrics().stringWidth("Label"), + // height/g.getFontMetrics().getHeight()))); + + g.drawString("Label", 0, 0); + + } + else + { + Color minCol = gcol.getMinColor(); + g.setColor(minCol); + g.fillRect(0, 0, width, height); + } + } } class ColorEditor extends AbstractCellEditor implements TableCellEditor, ActionListener { + FeatureSettings me; + + GraduatedColor currentGColor; + + FeatureColourChooser chooser; + + String type; + Color currentColor; JButton button; @@ -1307,8 +1500,11 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor, protected static final String EDIT = "edit"; - public ColorEditor() + int selectedRow = 0; + + public ColorEditor(FeatureSettings me) { + this.me = me; // Set up the editor (from the table's point of view), // which is a button. // This button brings up the color chooser dialog, @@ -1334,23 +1530,50 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor, { // The user has clicked the cell, so // bring up the dialog. - button.setBackground(currentColor); - colorChooser.setColor(currentColor); - dialog.setVisible(true); - + if (currentColor != null) + { + // bring up simple color chooser + button.setBackground(currentColor); + colorChooser.setColor(currentColor); + dialog.setVisible(true); + } + else + { + // bring up graduated chooser. + chooser = new FeatureColourChooser(me.fr, type); + chooser.setRequestFocusEnabled(true); + chooser.requestFocus(); + chooser.addActionListener(this); + } // Make the renderer reappear. fireEditingStopped(); } else { // User pressed dialog's "OK" button. - currentColor = colorChooser.getColor(); + if (currentColor != null) + { + currentColor = colorChooser.getColor(); + } + else + { + // class cast exceptions may be raised if the chooser created on a + // non-graduated color + currentGColor = (GraduatedColor) chooser.getLastColour(); + } + me.table.setValueAt(getCellEditorValue(), selectedRow, 1); + fireEditingStopped(); + me.table.validate(); } } // Implement the one CellEditor method that AbstractCellEditor doesn't. public Object getCellEditorValue() { + if (currentColor == null) + { + return currentGColor; + } return currentColor; } @@ -1358,7 +1581,29 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor, public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { - currentColor = (Color) value; + currentGColor = null; + currentColor = null; + this.selectedRow = row; + type = me.table.getValueAt(row, 0).toString(); + button.setOpaque(true); + button.setBackground(me.getBackground()); + if (value instanceof GraduatedColor) + { + currentGColor = (GraduatedColor) value; + JLabel btn = new JLabel(); + btn.setSize(button.getSize()); + FeatureSettings.renderGraduatedColor(btn, currentGColor); + button.setBackground(btn.getBackground()); + button.setIcon(btn.getIcon()); + button.setText(btn.getText()); + } + else + { + button.setText(""); + button.setIcon(null); + currentColor = (Color) value; + button.setBackground(currentColor); + } return button; } } -- 1.7.10.2