X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FFeatureSettings.java;h=961ff14dd633637db1e36f578817e40f70a61a4f;hb=728cc74b3df1bfb78de1a2a42c3ca81fe6e89c89;hp=35215b44f7f74d7993440b2a4529c940c7edcb78;hpb=de32fd704f78dafa5bed5eb64f9f96fab320971f;p=jalview.git diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 35215b4..961ff14 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -20,10 +20,16 @@ */ package jalview.gui; +import jalview.api.AlignViewControllerGuiI; +import jalview.api.AlignViewportI; import jalview.api.FeatureColourI; import jalview.api.FeatureSettingsControllerI; +import jalview.api.SplitContainerI; +import jalview.api.ViewStyleI; +import jalview.controller.FeatureSettingsControllerGuiI; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; +import jalview.datamodel.features.FeatureMatcher; import jalview.datamodel.features.FeatureMatcherI; import jalview.datamodel.features.FeatureMatcherSet; import jalview.datamodel.features.FeatureMatcherSetI; @@ -34,6 +40,7 @@ import jalview.schemes.FeatureColour; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean; +import jalview.viewmodel.styles.ViewStyle; import jalview.xml.binding.jalview.JalviewUserColours; import jalview.xml.binding.jalview.JalviewUserColours.Colour; import jalview.xml.binding.jalview.JalviewUserColours.Filter; @@ -43,6 +50,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.GridLayout; @@ -92,9 +100,11 @@ import javax.swing.JSlider; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; +import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; @@ -105,7 +115,7 @@ import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; public class FeatureSettings extends JPanel - implements FeatureSettingsControllerI + implements FeatureSettingsControllerI, FeatureSettingsControllerGuiI { private static final String SEQUENCE_FEATURE_COLOURS = MessageManager .getString("label.sequence_feature_colours"); @@ -127,6 +137,8 @@ public class FeatureSettings extends JPanel private static final int MIN_HEIGHT = 400; + private final static String BASE_TOOLTIP = MessageManager.getString("label.click_to_edit"); + final FeatureRenderer fr; public final AlignFrame af; @@ -138,6 +150,8 @@ public class FeatureSettings extends JPanel private float originalTransparency; + private ViewStyleI originalViewStyle; + private Map originalFilters; final JInternalFrame frame; @@ -150,8 +164,6 @@ public class FeatureSettings extends JPanel JSlider transparency = new JSlider(); - JCheckBox showComplement; - /* * when true, constructor is still executing - so ignore UI events */ @@ -159,12 +171,6 @@ public class FeatureSettings extends JPanel int selectedRow = -1; - JButton fetchDAS = new JButton(); - - JButton saveDAS = new JButton(); - - JButton cancelDAS = new JButton(); - boolean resettingTable = false; /* @@ -193,6 +199,7 @@ public class FeatureSettings extends JPanel transparency.setMaximum(100 - originalTransparencyAsPercent); originalFilters = new HashMap<>(fr.getFeatureFilters()); // shallow copy + originalViewStyle = new ViewStyle(af.viewport.getViewStyle()); try { @@ -209,14 +216,20 @@ public class FeatureSettings extends JPanel { String tip = null; int column = table.columnAtPoint(e.getPoint()); + int row = table.rowAtPoint(e.getPoint()); + switch (column) { case TYPE_COLUMN: tip = JvSwingUtils.wrapTooltip(true, MessageManager .getString("label.feature_settings_click_drag")); break; + case COLOUR_COLUMN: + FeatureColourI colour = (FeatureColourI) table.getValueAt(row, + column); + tip = getColorTooltip(colour, true); + break; case FILTER_COLUMN: - int row = table.rowAtPoint(e.getPoint()); FeatureMatcherSet o = (FeatureMatcherSet) table.getValueAt(row, column); tip = o.isEmpty() @@ -227,15 +240,30 @@ public class FeatureSettings extends JPanel default: break; } + return tip; } + + /** + * Position the tooltip near the bottom edge of, and half way across, the + * current cell + */ + @Override + public Point getToolTipLocation(MouseEvent e) + { + Point point = e.getPoint(); + int column = table.columnAtPoint(point); + int row = table.rowAtPoint(point); + Rectangle r = getCellRect(row, column, false); + Point loc = new Point(r.x + r.width / 2, r.y + r.height - 3); + return loc; + } }; - table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12)); + JTableHeader tableHeader = table.getTableHeader(); + tableHeader.setFont(new Font("Verdana", Font.PLAIN, 12)); + tableHeader.setReorderingAllowed(false); table.setFont(new Font("Verdana", Font.PLAIN, 12)); - // table.setDefaultRenderer(Color.class, new ColorRenderer()); - // table.setDefaultEditor(Color.class, new ColorEditor(this)); - // table.setDefaultEditor(FeatureColour.class, new ColorEditor(this)); table.setDefaultRenderer(FeatureColour.class, new ColorRenderer()); @@ -257,7 +285,8 @@ public class FeatureSettings extends JPanel @Override public void mousePressed(MouseEvent evt) { - selectedRow = table.rowAtPoint(evt.getPoint()); + Point pt = evt.getPoint(); + selectedRow = table.rowAtPoint(pt); String type = (String) table.getValueAt(selectedRow, TYPE_COLUMN); if (evt.isPopupTrigger()) { @@ -265,13 +294,15 @@ public class FeatureSettings extends JPanel popupSort(selectedRow, type, colour, fr.getMinMax(), evt.getX(), evt.getY()); } - else if (evt.getClickCount() == 2) + else if (evt.getClickCount() == 2 + && table.columnAtPoint(pt) == TYPE_COLUMN) { boolean invertSelection = evt.isAltDown(); boolean toggleSelection = Platform.isControlDown(evt); boolean extendSelection = evt.isShiftDown(); fr.ap.alignFrame.avc.markColumnsContainingFeatures( invertSelection, extendSelection, toggleSelection, type); + fr.ap.av.sendSelection(); } } @@ -328,7 +359,6 @@ public class FeatureSettings extends JPanel } discoverAllFeatureData(); - final PropertyChangeListener change; final FeatureSettings fs = this; fr.addPropertyChangeListener(change = new PropertyChangeListener() { @@ -345,43 +375,64 @@ public class FeatureSettings extends JPanel } }); - - frame = new JInternalFrame(); - frame.setContentPane(this); - if (Platform.isAMac()) + SplitContainerI splitframe = af.getSplitViewContainer(); + if (splitframe != null) { - Desktop.addInternalFrame(frame, - MessageManager.getString("label.sequence_feature_settings"), - 600, 480); + frame = null; // keeps eclipse happy + splitframe.addFeatureSettingsUI(this); } else { - Desktop.addInternalFrame(frame, - MessageManager.getString("label.sequence_feature_settings"), - 600, 450); - } - frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT)); + frame = new JInternalFrame(); + frame.setContentPane(this); + if (Platform.isAMac()) + { + Desktop.addInternalFrame(frame, + MessageManager.getString("label.sequence_feature_settings"), + 600, 480); + } + else + { + Desktop.addInternalFrame(frame, + MessageManager.getString("label.sequence_feature_settings"), + 600, 450); + } + frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT)); - frame.addInternalFrameListener( - new javax.swing.event.InternalFrameAdapter() - { - @Override - public void internalFrameClosed( - javax.swing.event.InternalFrameEvent evt) + frame.addInternalFrameListener( + new javax.swing.event.InternalFrameAdapter() { - fr.removePropertyChangeListener(change); - }; - }); - frame.setLayer(JLayeredPane.PALETTE_LAYER); + @Override + public void internalFrameClosed( + javax.swing.event.InternalFrameEvent evt) + { + featureSettings_isClosed(); + }; + }); + frame.setLayer(JLayeredPane.PALETTE_LAYER); + } inConstruction = false; } + PropertyChangeListener change; + + @Override + public AlignViewControllerGuiI getAlignframe() + { + return af; + } + + @Override + public void featureSettings_isClosed() + { + fr.removePropertyChangeListener(change); + change = null; + } + protected void popupSort(final int rowSelected, final String type, final Object typeCol, final Map minmax, int x, int y) { - final FeatureColourI featureColour = (FeatureColourI) typeCol; - JPopupMenu men = new JPopupMenu(MessageManager .formatMessage("label.settings_for_param", new String[] { type })); @@ -426,6 +477,7 @@ public class FeatureSettings extends JPanel { fr.ap.alignFrame.avc.markColumnsContainingFeatures(false, false, false, type); + fr.ap.av.sendSelection(); } }); JMenuItem clearCols = new JMenuItem(MessageManager @@ -437,6 +489,7 @@ public class FeatureSettings extends JPanel { fr.ap.alignFrame.avc.markColumnsContainingFeatures(true, false, false, type); + fr.ap.av.sendSelection(); } }); JMenuItem hideCols = new JMenuItem( @@ -447,6 +500,7 @@ public class FeatureSettings extends JPanel public void actionPerformed(ActionEvent arg0) { fr.ap.alignFrame.hideFeatureColumns(type, true); + fr.ap.av.sendSelection(); } }); JMenuItem hideOtherCols = new JMenuItem( @@ -457,6 +511,7 @@ public class FeatureSettings extends JPanel public void actionPerformed(ActionEvent arg0) { fr.ap.alignFrame.hideFeatureColumns(type, false); + fr.ap.av.sendSelection(); } }); men.add(selCols); @@ -520,7 +575,7 @@ public class FeatureSettings extends JPanel { fr.setGroupVisibility(check.getText(), check.isSelected()); resetTable(new String[] { grp }); - af.alignPanel.paintAlignment(true, true); + refreshDisplay(); } }); groupPanel.add(check); @@ -618,7 +673,7 @@ public class FeatureSettings extends JPanel data[dataIndex][FILTER_COLUMN] = featureFilter == null ? new FeatureMatcherSet() : featureFilter; - data[dataIndex][SHOW_COLUMN] = new Boolean( + data[dataIndex][SHOW_COLUMN] = Boolean.valueOf( af.getViewport().getFeaturesDisplayed().isVisible(type)); dataIndex++; displayableTypes.remove(type); @@ -645,7 +700,7 @@ public class FeatureSettings extends JPanel data[dataIndex][FILTER_COLUMN] = featureFilter == null ? new FeatureMatcherSet() : featureFilter; - data[dataIndex][SHOW_COLUMN] = new Boolean(true); + data[dataIndex][SHOW_COLUMN] = Boolean.valueOf(true); dataIndex++; displayableTypes.remove(type); } @@ -1053,7 +1108,16 @@ public class FeatureSettings extends JPanel { try { - frame.setClosed(true); + if (frame != null) + { + frame.setClosed(true); + } + else + { + SplitContainerI sc = af.getSplitViewContainer(); + sc.closeFeatureSettings(this); + af.featureSettings = null; + } } catch (Exception exe) { } @@ -1078,7 +1142,7 @@ public class FeatureSettings extends JPanel if (fr.setFeaturePriority(rowData, visibleNew)) { - af.alignPanel.paintAlignment(true, true); + refreshDisplay(); } } @@ -1176,22 +1240,6 @@ public class FeatureSettings extends JPanel } } }); - help.setFont(JvSwingUtils.getLabelFont()); - help.setText(MessageManager.getString("action.help")); - help.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - try - { - Help.showHelpWindow(HelpId.SequenceFeatureSettings); - } catch (HelpSetException e1) - { - e1.printStackTrace(); - } - } - }); JButton cancel = new JButton(MessageManager.getString("action.cancel")); cancel.setFont(JvSwingUtils.getLabelFont()); @@ -1203,6 +1251,7 @@ public class FeatureSettings extends JPanel fr.setTransparency(originalTransparency); fr.setFeatureFilters(originalFilters); updateFeatureRenderer(originalData); + af.getViewport().setViewStyle(originalViewStyle); close(); } }); @@ -1253,7 +1302,7 @@ public class FeatureSettings extends JPanel if (!inConstruction) { fr.setTransparency((100 - transparency.getValue()) / 100f); - af.alignPanel.paintAlignment(true, true); + refreshDisplay(); } } }); @@ -1263,8 +1312,13 @@ public class FeatureSettings extends JPanel MessageManager.getString("label.transparency_tip")); boolean nucleotide = af.getViewport().getAlignment().isNucleotide(); - showComplement = new JCheckBox( - "Show " + (nucleotide ? "protein" : "CDS") + " features"); + String text = MessageManager.formatMessage("label.show_linked_features", + nucleotide + ? MessageManager.getString("label.protein") + .toLowerCase() + : "CDS"); + JCheckBox showComplement = new JCheckBox(text); + showComplement.setSelected(af.getViewport().isShowComplementFeatures()); showComplement.addActionListener(new ActionListener() { @Override @@ -1272,11 +1326,58 @@ public class FeatureSettings extends JPanel { af.getViewport() .setShowComplementFeatures(showComplement.isSelected()); + refreshDisplay(); } }); - JPanel transPanel = new JPanel(new GridLayout(1, 2)); - bigPanel.add(transPanel, BorderLayout.SOUTH); + JCheckBox showComplementOnTop = new JCheckBox( + MessageManager.getString("label.on_top")); + showComplementOnTop + .setSelected(af.getViewport().isShowComplementFeaturesOnTop()); + showComplementOnTop.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + af.getViewport().setShowComplementFeaturesOnTop( + showComplementOnTop.isSelected()); + refreshDisplay(); + } + }); + // JButton viewComplementSettings = new JButton(MessageManager + // .formatMessage("label.show_linked_feature_settings", + // nucleotide + // ? MessageManager.getString("label.protein") + // .toLowerCase() + // : "CDS")); + // viewComplementSettings.addActionListener(new ActionListener() + // { + // + // @Override + // public void actionPerformed(ActionEvent e) + // { + // AlignViewControllerGuiI complAf = af.getSplitViewContainer() + // .getComplementAlignFrame(af); + // FeatureSettings complFeatureSettings = (FeatureSettings) complAf + // .getFeatureSettingsUI(); + // if (complFeatureSettings != null) + // { + // complFeatureSettings.frame.setVisible(true); + // try + // { + // complFeatureSettings.frame.setSelected(true); + // return; + // } catch (Exception q) + // { + // } + // } + // { + // complAf.showFeatureSettingsUI(); + // } + // } + // }); + JPanel lowerPanel = new JPanel(new GridLayout(1, 2)); + bigPanel.add(lowerPanel, BorderLayout.SOUTH); JPanel transbuttons = new JPanel(new GridLayout(5, 1)); transbuttons.add(optimizeOrder); @@ -1287,14 +1388,18 @@ public class FeatureSettings extends JPanel boolean hasComplement = af.getViewport().getCodingComplement() != null; JPanel transPanelLeft = new JPanel( - new GridLayout(hasComplement ? 2 : 1, 1)); + new GridLayout(hasComplement ? 4 : 2, 1)); + transPanelLeft.add(new JLabel(" Colour transparency" + ":")); transPanelLeft.add(transparency); if (hasComplement) { - transPanelLeft.add(showComplement); + JPanel cp = new JPanel(new FlowLayout(FlowLayout.LEFT)); + cp.add(showComplement); + cp.add(showComplementOnTop); + transPanelLeft.add(cp); } - transPanel.add(transPanelLeft); - transPanel.add(transbuttons); + lowerPanel.add(transPanelLeft); + lowerPanel.add(transbuttons); JPanel buttonPanel = new JPanel(); buttonPanel.add(ok); @@ -1307,6 +1412,106 @@ public class FeatureSettings extends JPanel this.add(settingsPane); } + /** + * Repaints alignment, structure and overview (if shown). If there is a + * complementary view which is showing this view's features, then also + * repaints that. + */ + void refreshDisplay() + { + af.alignPanel.paintAlignment(true, true); + AlignViewportI complement = af.getViewport().getCodingComplement(); + if (complement != null && complement.isShowComplementFeatures()) + { + AlignFrame af2 = Desktop.getAlignFrameFor(complement); + af2.alignPanel.paintAlignment(true, true); + } + } + + /** + * Answers a suitable tooltip to show on the colour cell of the table + * + * @param fcol + * @param withHint + * if true include 'click to edit' and similar text + * @return + */ + public static String getColorTooltip(FeatureColourI fcol, + boolean withHint) + { + if (fcol == null) + { + return null; + } + if (fcol.isSimpleColour()) + { + return withHint ? BASE_TOOLTIP : null; + } + String description = fcol.getDescription(); + description = description.replaceAll("<", "<"); + description = description.replaceAll(">", ">"); + StringBuilder tt = new StringBuilder(description); + if (withHint) + { + tt.append("
").append(BASE_TOOLTIP).append("
"); + } + return JvSwingUtils.wrapTooltip(true, tt.toString()); + } + + public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol, + int w, int h) + { + boolean thr = false; + StringBuilder tx = new StringBuilder(); + + if (gcol.isColourByAttribute()) + { + tx.append(FeatureMatcher + .toAttributeDisplayName(gcol.getAttributeName())); + } + else if (!gcol.isColourByLabel()) + { + tx.append(MessageManager.getString("label.score")); + } + tx.append(" "); + if (gcol.isAboveThreshold()) + { + thr = true; + tx.append(">"); + } + if (gcol.isBelowThreshold()) + { + thr = true; + tx.append("<"); + } + if (gcol.isColourByLabel()) + { + if (thr) + { + tx.append(" "); + } + if (!gcol.isColourByAttribute()) + { + tx.append("Label"); + } + comp.setIcon(null); + } + else + { + Color newColor = gcol.getMaxColour(); + comp.setBackground(newColor); + // System.err.println("Width is " + w / 2); + Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w, h, thr); + comp.setIcon(ficon); + // tt+="RGB value: Max (" + newColor.getRed() + ", " + // + newColor.getGreen() + ", " + newColor.getBlue() + // + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen() + // + ", " + minCol.getBlue() + ")"); + } + comp.setHorizontalAlignment(SwingConstants.CENTER); + comp.setText(tx.toString()); + } + // /////////////////////////////////////////////////////////////////////// // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html // /////////////////////////////////////////////////////////////////////// @@ -1365,13 +1570,22 @@ public class FeatureSettings extends JPanel } /** - * Answers the class of the object in column c of the first row of the table + * Answers the class of column c of the table */ @Override public Class getColumnClass(int c) { - Object v = getValueAt(0, c); - return v == null ? null : v.getClass(); + switch (c) + { + case TYPE_COLUMN: + return String.class; + case COLOUR_COLUMN: + return FeatureColour.class; + case FILTER_COLUMN: + return FeatureMatcherSet.class; + default: + return Boolean.class; + } } @Override @@ -1392,11 +1606,9 @@ public class FeatureSettings extends JPanel class ColorRenderer extends JLabel implements TableCellRenderer { - javax.swing.border.Border unselectedBorder = null; + Border unselectedBorder = null; - javax.swing.border.Border selectedBorder = null; - - final String baseTT = "Click to edit, right/apple click for menu."; + Border selectedBorder = null; public ColorRenderer() { @@ -1411,7 +1623,6 @@ public class FeatureSettings extends JPanel { FeatureColourI cellColour = (FeatureColourI) color; setOpaque(true); - setToolTipText(baseTT); setBackground(tbl.getBackground()); if (!cellColour.isSimpleColour()) { @@ -1518,77 +1729,6 @@ public class FeatureSettings extends JPanel renderGraduatedColor(comp, gcol, w, h); } - public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol, - int w, int h) - { - boolean thr = false; - StringBuilder tt = new StringBuilder(); - StringBuilder tx = new StringBuilder(); - - if (gcol.isColourByAttribute()) - { - tx.append(String.join(":", gcol.getAttributeName())); - } - else if (!gcol.isColourByLabel()) - { - tx.append(MessageManager.getString("label.score")); - } - tx.append(" "); - if (gcol.isAboveThreshold()) - { - thr = true; - tx.append(">"); - tt.append("Thresholded (Above ").append(gcol.getThreshold()) - .append(") "); - } - if (gcol.isBelowThreshold()) - { - thr = true; - tx.append("<"); - tt.append("Thresholded (Below ").append(gcol.getThreshold()) - .append(") "); - } - if (gcol.isColourByLabel()) - { - tt.append("Coloured by label text. ").append(tt); - if (thr) - { - tx.append(" "); - } - if (!gcol.isColourByAttribute()) - { - tx.append("Label"); - } - comp.setIcon(null); - } - else - { - Color newColor = gcol.getMaxColour(); - comp.setBackground(newColor); - // System.err.println("Width is " + w / 2); - Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w, h, thr); - comp.setIcon(ficon); - // tt+="RGB value: Max (" + newColor.getRed() + ", " - // + newColor.getGreen() + ", " + newColor.getBlue() - // + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen() - // + ", " + minCol.getBlue() + ")"); - } - comp.setHorizontalAlignment(SwingConstants.CENTER); - comp.setText(tx.toString()); - if (tt.length() > 0) - { - if (comp.getToolTipText() == null) - { - comp.setToolTipText(tt.toString()); - } - else - { - comp.setToolTipText( - tt.append(" ").append(comp.getToolTipText()).toString()); - } - } - } - class ColorEditor extends AbstractCellEditor implements TableCellEditor, ActionListener { @@ -1824,7 +1964,6 @@ public class FeatureSettings extends JPanel button.setOpaque(true); button.setBackground(me.getBackground()); button.setText(currentFilter.toString()); - button.setToolTipText(currentFilter.toString()); button.setIcon(null); return button; }