X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fjbgui%2FGAlignFrame.java;h=b38fab4d1fba9bbc140939b2a1383025292dd97f;hb=b0cee3aaf7d8873910939f97b6acb217d518968d;hp=2a77a5722236b31e2b119be7c40f0444c29e220a;hpb=838e4f91d4a53dd315640dbc9ff6ef7a815ee576;p=jalview.git diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 2a77a57..b38fab4 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b1) - * Copyright (C) 2015 The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * @@ -23,10 +23,17 @@ package jalview.jbgui; import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.api.SplitContainerI; import jalview.bin.Cache; +import jalview.gui.Desktop; +import jalview.gui.JvOptionPane; import jalview.gui.JvSwingUtils; import jalview.gui.Preferences; -import jalview.schemes.ColourSchemeProperty; +import jalview.gui.UserDefinedColours; +import jalview.io.FileFormat; +import jalview.schemes.JalviewColourScheme; +import jalview.schemes.ResidueColourScheme; +import jalview.schemes.UserColourScheme; import jalview.util.MessageManager; +import jalview.util.Platform; import java.awt.BorderLayout; import java.awt.Color; @@ -50,18 +57,18 @@ import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; public class GAlignFrame extends JInternalFrame { + protected static final String USER_DEFINED_COLOUR_SCHEME = "USER_DEFINED"; + protected JMenuBar alignFrameMenuBar = new JMenuBar(); protected JMenuItem closeMenuItem = new JMenuItem(); @@ -72,9 +79,9 @@ public class GAlignFrame extends JInternalFrame protected JMenuItem webServiceNoServices; - public JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem(); protected JMenu sortByAnnotScore = new JMenu(); @@ -82,80 +89,83 @@ public class GAlignFrame extends JInternalFrame protected JMenu outputTextboxMenu = new JMenu(); - protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem textColour; + + protected JRadioButtonMenuItem clustalColour; - protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem zappoColour; - protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem taylorColour; - protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem hydrophobicityColour; - protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem helixColour; - protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem strandColour; - protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem turnColour; - protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem buriedColour; - protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem userDefinedColour; - protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem PIDColour; - protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem BLOSUM62Colour; - protected JRadioButtonMenuItem nucleotideColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem nucleotideColour; - protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem purinePyrimidineColour; - protected JRadioButtonMenuItem RNAInteractionColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem RNAInteractionColour; - // protected JRadioButtonMenuItem covariationColour = new - // JRadioButtonMenuItem(); + // protected JRadioButtonMenuItem covariationColour; - protected JRadioButtonMenuItem tcoffeeColour = new JRadioButtonMenuItem(); + protected JRadioButtonMenuItem tcoffeeColour; - public JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem showNonconservedMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem showNonconservedMenuItem = new JCheckBoxMenuItem(); protected JMenuItem undoMenuItem = new JMenuItem(); protected JMenuItem redoMenuItem = new JMenuItem(); - public JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem conservationMenuItem; - JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem(); + JRadioButtonMenuItem noColourmenuItem; - public JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem abovePIDThreshold = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem abovePIDThreshold; public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem showSeqFeaturesHeight = new JCheckBoxMenuItem(); - JMenuItem copy = new JMenuItem(); JMenuItem cut = new JMenuItem(); JMenu pasteMenu = new JMenu(); - public JCheckBoxMenuItem applyToAllGroups = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem applyToAllGroups; + + protected JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem(); - public JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem(); + protected JMenuItem modifyPID; - protected JMenuItem modifyConservation = new JMenuItem(); + protected JMenuItem modifyConservation; + + protected JMenuItem annotationColour; protected JMenu sortByTreeMenu = new JMenu(); @@ -173,9 +183,15 @@ public class GAlignFrame extends JInternalFrame protected JMenuItem showTranslation = new JMenuItem(); + protected JMenuItem showReverse = new JMenuItem(); + + protected JMenuItem showReverseComplement = new JMenuItem(); + protected JMenu showProducts = new JMenu(); - protected JMenuItem rnahelicesColour = new JMenuItem(); + protected JMenuItem runGroovy = new JMenuItem(); + + protected JMenuItem rnahelicesColour; protected JCheckBoxMenuItem autoCalculate = new JCheckBoxMenuItem(); @@ -241,10 +257,9 @@ public class GAlignFrame extends JInternalFrame setJMenuBar(alignFrameMenuBar); // dynamically fill save as menu with available formats - for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++) + for (String ff : FileFormat.getWritableFormats(true)) { - JMenuItem item = new JMenuItem( - jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]); + JMenuItem item = new JMenuItem(ff); item.addActionListener(new ActionListener() { @@ -262,7 +277,7 @@ public class GAlignFrame extends JInternalFrame System.err.println(e.toString()); } - if (!jalview.util.Platform.isAMac()) + if (!Platform.isAMac()) { closeMenuItem.setMnemonic('C'); outputTextboxMenu.setMnemonic('T'); @@ -273,186 +288,78 @@ public class GAlignFrame extends JInternalFrame pasteMenu.setMnemonic('P'); reload.setMnemonic('R'); } - - if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null) - { - java.util.Enumeration userColours = jalview.gui.UserDefinedColours - .getUserColourSchemes().keys(); - - while (userColours.hasMoreElements()) - { - final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem( - userColours.nextElement().toString()); - radioItem.setName("USER_DEFINED"); - radioItem.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent evt) - { - if (evt.isControlDown() - || SwingUtilities.isRightMouseButton(evt)) - { - radioItem.removeActionListener(radioItem.getActionListeners()[0]); - - int option = JOptionPane.showInternalConfirmDialog( - jalview.gui.Desktop.desktop, - MessageManager - .getString("label.remove_from_default_list"), - MessageManager - .getString("label.remove_user_defined_colour"), - JOptionPane.YES_NO_OPTION); - if (option == JOptionPane.YES_OPTION) - { - jalview.gui.UserDefinedColours - .removeColourFromDefaults(radioItem.getText()); - colourMenu.remove(radioItem); - } - else - { - radioItem.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent evt) - { - userDefinedColour_actionPerformed(evt); - } - }); - } - } - } - }); - radioItem.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent evt) - { - userDefinedColour_actionPerformed(evt); - } - }); - colourMenu.insert(radioItem, 15); - colours.add(radioItem); - } - } - colours.add(noColourmenuItem); - colours.add(clustalColour); - colours.add(zappoColour); - colours.add(taylorColour); - colours.add(hydrophobicityColour); - colours.add(helixColour); - colours.add(strandColour); - colours.add(turnColour); - colours.add(buriedColour); - colours.add(userDefinedColour); - colours.add(PIDColour); - colours.add(BLOSUM62Colour); - colours.add(nucleotideColour); - colours.add(purinePyrimidineColour); - // colours.add(covariationColour); - colours.add(tcoffeeColour); - colours.add(RNAInteractionColour); - setColourSelected(jalview.bin.Cache.getDefault( - Preferences.DEFAULT_COLOUR, "None")); } public void setColourSelected(String defaultColour) { - - if (defaultColour != null) + JalviewColourScheme scheme = JalviewColourScheme.forName(defaultColour); + if (scheme == null) + { + noColourmenuItem.setSelected(true); + return; + } + switch (scheme) { - int index = ColourSchemeProperty - .getColourIndexFromName(defaultColour); - switch (index) - { - case ColourSchemeProperty.CLUSTAL: + case Clustal: clustalColour.setSelected(true); - break; - - case ColourSchemeProperty.BLOSUM: + case Blosum62: BLOSUM62Colour.setSelected(true); - break; - - case ColourSchemeProperty.PID: + case PID: PIDColour.setSelected(true); - break; - - case ColourSchemeProperty.ZAPPO: + case Zappo: zappoColour.setSelected(true); - break; - - case ColourSchemeProperty.TAYLOR: + case Taylor: taylorColour.setSelected(true); break; - - case ColourSchemeProperty.HYDROPHOBIC: + case Hydrophobic: hydrophobicityColour.setSelected(true); - break; - - case ColourSchemeProperty.HELIX: + case Helix: helixColour.setSelected(true); - break; - - case ColourSchemeProperty.STRAND: + case Strand: strandColour.setSelected(true); - break; - - case ColourSchemeProperty.TURN: + case Turn: turnColour.setSelected(true); - break; - - case ColourSchemeProperty.BURIED: + case Buried: buriedColour.setSelected(true); - break; - - case ColourSchemeProperty.NUCLEOTIDE: + case Nucleotide: nucleotideColour.setSelected(true); - break; - - case ColourSchemeProperty.TCOFFEE: + case TCoffee: tcoffeeColour.setSelected(true); break; - - case ColourSchemeProperty.PURINEPYRIMIDINE: + case PurinePyrimidine: purinePyrimidineColour.setSelected(true); - break; - - case ColourSchemeProperty.RNAINTERACTION: - RNAInteractionColour.setSelected(true); - - break; - /* - * case ColourSchemeProperty.COVARIATION: - * covariationColour.setSelected(true); - * - * break; - */ - case ColourSchemeProperty.USER_DEFINED: + // case RNAInteraction: + // RNAInteractionColour.setSelected(true); + // break; + case RNAHelices: + rnahelicesColour.setSelected(true); + break; + case UserDefined: userDefinedColour.setSelected(true); - break; - case ColourSchemeProperty.NONE: default: noColourmenuItem.setSelected(true); break; - } - } - } private void jbInit() throws Exception { + initColourMenu(); + buildColourMenu(); + JMenuItem saveAs = new JMenuItem( MessageManager.getString("action.save_as")); ActionListener al = new ActionListener() @@ -463,6 +370,8 @@ public class GAlignFrame extends JInternalFrame saveAs_actionPerformed(e); } }; + + // FIXME getDefaultToolkit throws an exception in Headless mode KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit .getDefaultToolkit().getMenuShortcutKeyMask() | KeyEvent.SHIFT_MASK, false); @@ -651,7 +560,7 @@ public class GAlignFrame extends JInternalFrame } }); showNonconservedMenuItem.setText(MessageManager - .getString("label.show_non_conversed")); + .getString("label.show_non_conserved")); showNonconservedMenuItem.setState(false); showNonconservedMenuItem.addActionListener(new ActionListener() { @@ -765,146 +674,7 @@ public class GAlignFrame extends JInternalFrame statusBar.setText(MessageManager.getString("label.status_bar")); outputTextboxMenu.setText(MessageManager .getString("label.out_to_textbox")); - clustalColour.setText(MessageManager.getString("label.clustalx")); - clustalColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - clustalColour_actionPerformed(e); - } - }); - zappoColour.setText(MessageManager.getString("label.zappo")); - zappoColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - zappoColour_actionPerformed(e); - } - }); - taylorColour.setText(MessageManager.getString("label.taylor")); - taylorColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - taylorColour_actionPerformed(e); - } - }); - hydrophobicityColour.setText(MessageManager - .getString("label.hydrophobicity")); - hydrophobicityColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - hydrophobicityColour_actionPerformed(e); - } - }); - helixColour.setText(MessageManager.getString("label.helix_propensity")); - helixColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - helixColour_actionPerformed(e); - } - }); - strandColour.setText(MessageManager - .getString("label.strand_propensity")); - strandColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - strandColour_actionPerformed(e); - } - }); - turnColour.setText(MessageManager.getString("label.turn_propensity")); - turnColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - turnColour_actionPerformed(e); - } - }); - buriedColour.setText(MessageManager.getString("label.buried_index")); - buriedColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - buriedColour_actionPerformed(e); - } - }); - userDefinedColour.setText(MessageManager - .getString("action.user_defined")); - userDefinedColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - userDefinedColour_actionPerformed(e); - } - }); - PIDColour - .setText(MessageManager.getString("label.percentage_identity")); - PIDColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - PIDColour_actionPerformed(e); - } - }); - BLOSUM62Colour - .setText(MessageManager.getString("label.blosum62_score")); - BLOSUM62Colour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - BLOSUM62Colour_actionPerformed(e); - } - }); - nucleotideColour.setText(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - nucleotideColour_actionPerformed(e); - } - }); - - purinePyrimidineColour.setText(MessageManager - .getString("label.purine_pyrimidine")); - purinePyrimidineColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - purinePyrimidineColour_actionPerformed(e); - } - }); - RNAInteractionColour.setText("RNA Interaction type"); - RNAInteractionColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - RNAInteractionColour_actionPerformed(e); - } - }); - /* - * covariationColour.setText("Covariation"); - * covariationColour.addActionListener(new ActionListener() { public void - * actionPerformed(ActionEvent e) { covariationColour_actionPerformed(e); } - * }); - */ JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem( MessageManager.getString("label.average_distance_bloslum62")); @@ -1021,7 +791,8 @@ public class GAlignFrame extends JInternalFrame sortAnnotations_actionPerformed(); } }); - colourTextMenuItem.setText(MessageManager + colourTextMenuItem = new JCheckBoxMenuItem( + MessageManager .getString("label.colour_text")); colourTextMenuItem.addActionListener(new ActionListener() { @@ -1093,25 +864,6 @@ public class GAlignFrame extends JInternalFrame }; addMenuActionAndAccelerator(keyStroke, redoMenuItem, al); - conservationMenuItem.setText(MessageManager - .getString("action.by_conservation")); - conservationMenuItem.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - conservationMenuItem_actionPerformed(e); - } - }); - noColourmenuItem.setText(MessageManager.getString("label.none")); - noColourmenuItem.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - noColourmenuItem_actionPerformed(e); - } - }); wrapMenuItem.setText(MessageManager.getString("label.wrap")); wrapMenuItem.addActionListener(new ActionListener() { @@ -1164,16 +916,6 @@ public class GAlignFrame extends JInternalFrame }; addMenuActionAndAccelerator(keyStroke, findMenuItem, al); - abovePIDThreshold.setText(MessageManager - .getString("label.above_identity_threshold")); - abovePIDThreshold.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - abovePIDThreshold_actionPerformed(e); - } - }); showSeqFeatures.setText(MessageManager .getString("label.show_sequence_features")); showSeqFeatures.addActionListener(new ActionListener() @@ -1319,28 +1061,6 @@ public class GAlignFrame extends JInternalFrame } }); - nucleotideColour.setText(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - nucleotideColour_actionPerformed(e); - } - }); - - tcoffeeColour.setText(MessageManager.getString("label.tcoffee_scores")); - tcoffeeColour.setEnabled(false); - tcoffeeColour.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - tcoffeeColorScheme_actionPerformed(e); - } - }); - JMenuItem deleteGroups = new JMenuItem( MessageManager.getString("action.undefine_groups")); keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit @@ -1355,6 +1075,17 @@ public class GAlignFrame extends JInternalFrame }; addMenuActionAndAccelerator(keyStroke, deleteGroups, al); + JMenuItem annotationColumn = new JMenuItem( + MessageManager.getString("action.select_by_annotation")); + annotationColumn.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + annotationColumn_actionPerformed(e); + } + }); + JMenuItem createGroup = new JMenuItem( MessageManager.getString("action.create_groups")); keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit @@ -1452,16 +1183,6 @@ public class GAlignFrame extends JInternalFrame }; addMenuActionAndAccelerator(keyStroke, pasteThis, al); - applyToAllGroups.setText(MessageManager - .getString("label.apply_colour_to_all_groups")); - applyToAllGroups.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - applyToAllGroups_actionPerformed(e); - } - }); JMenuItem createPNG = new JMenuItem("PNG"); createPNG.addActionListener(new ActionListener() { @@ -1586,26 +1307,6 @@ public class GAlignFrame extends JInternalFrame }); - JMenuItem modifyPID = new JMenuItem( - MessageManager.getString("label.modify_identity_thereshold")); - modifyPID.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - modifyPID_actionPerformed(e); - } - }); - modifyConservation.setText(MessageManager - .getString("label.modify_conservation_thereshold")); - modifyConservation.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - modifyConservation_actionPerformed(e); - } - }); sortByTreeMenu .setText(MessageManager.getString("action.by_tree_order")); sort.setText(MessageManager.getString("action.sort")); @@ -1686,74 +1387,72 @@ public class GAlignFrame extends JInternalFrame showTranslation_actionPerformed(e); } }); - - JMenuItem extractScores = new JMenuItem( - MessageManager.getString("label.extract_scores")); - extractScores.addActionListener(new ActionListener() + showReverse.setText(MessageManager.getString("label.reverse")); + showReverse.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - extractScores_actionPerformed(e); + showReverse_actionPerformed(false); } }); - extractScores.setVisible(true); - // JBPNote: TODO: make gui for regex based score extraction - - // for show products actions see AlignFrame.canShowProducts - showProducts.setText(MessageManager.getString("label.get_cross_refs")); - - JMenuItem openFeatureSettings = new JMenuItem( - MessageManager.getString("action.feature_settings")); - openFeatureSettings.addActionListener(new ActionListener() + showReverseComplement.setText(MessageManager + .getString("label.reverse_complement")); + showReverseComplement.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - featureSettings_actionPerformed(e); + showReverse_actionPerformed(true); } }); - JMenuItem fetchSequence = new JMenuItem( - MessageManager.getString("label.fetch_sequences")); - fetchSequence.addActionListener(new ActionListener() + + JMenuItem extractScores = new JMenuItem( + MessageManager.getString("label.extract_scores")); + extractScores.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - fetchSequence_actionPerformed(e); + extractScores_actionPerformed(e); } }); + extractScores.setVisible(true); + // JBPNote: TODO: make gui for regex based score extraction - JMenuItem annotationColour = new JMenuItem( - MessageManager.getString("action.by_annotation")); - annotationColour.addActionListener(new ActionListener() + // for show products actions see AlignFrame.canShowProducts + showProducts.setText(MessageManager.getString("label.get_cross_refs")); + + runGroovy.setText(MessageManager.getString("label.run_groovy")); + runGroovy.setToolTipText(MessageManager + .getString("label.run_groovy_tip")); + runGroovy.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - annotationColour_actionPerformed(e); + runGroovy_actionPerformed(); } }); - JMenuItem annotationColumn = new JMenuItem( - MessageManager.getString("action.select_by_annotation")); - annotationColumn.addActionListener(new ActionListener() + JMenuItem openFeatureSettings = new JMenuItem( + MessageManager.getString("action.feature_settings")); + openFeatureSettings.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - annotationColumn_actionPerformed(e); + featureSettings_actionPerformed(e); } }); - - rnahelicesColour.setText(MessageManager - .getString("action.by_rna_helixes")); - rnahelicesColour.addActionListener(new ActionListener() + JMenuItem fetchSequence = new JMenuItem( + MessageManager.getString("label.fetch_sequences")); + fetchSequence.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - rnahelicesColour_actionPerformed(e); + fetchSequence_actionPerformed(e); } }); @@ -1998,7 +1697,19 @@ public class GAlignFrame extends JInternalFrame @Override public void mousePressed(MouseEvent e) { - tabbedPane_mousePressed(e); + if (e.isPopupTrigger()) // Mac + { + tabbedPane_mousePressed(e); + } + } + + @Override + public void mouseReleased(MouseEvent e) + { + if (e.isPopupTrigger()) // Windows + { + tabbedPane_mousePressed(e); + } } }); tabbedPane.addFocusListener(new FocusAdapter() @@ -2051,16 +1762,7 @@ public class GAlignFrame extends JInternalFrame tabbedPane.setToolTipText("" + MessageManager.getString("label.rename_tab_eXpand_reGroup") + ""); - JMenuItem textColour = new JMenuItem( - MessageManager.getString("action.set_text_colour")); - textColour.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - textColour_actionPerformed(e); - } - }); + formatMenu.setText(MessageManager.getString("action.format")); JMenu selectMenu = new JMenu(MessageManager.getString("action.select")); idRightAlign.setText(MessageManager @@ -2120,6 +1822,19 @@ public class GAlignFrame extends JInternalFrame alignmentProperties(); } }); + JMenuItem selectHighlighted = new JMenuItem( + MessageManager.getString("action.select_highlighted_columns")); + selectHighlighted.setToolTipText(MessageManager + .getString("tooltip.select_highlighted_columns")); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + selectHighlightedColumns_actionPerformed(actionEvent); + } + }; + selectHighlighted.addActionListener(al); JMenu tooltipSettingsMenu = new JMenu( MessageManager.getString("label.sequence_id_tooltip")); JMenu autoAnnMenu = new JMenu( @@ -2137,6 +1852,7 @@ public class GAlignFrame extends JInternalFrame alignFrameMenuBar.add(colourMenu); alignFrameMenuBar.add(calculateMenu); alignFrameMenuBar.add(webService); + fileMenu.add(fetchSequence); fileMenu.add(addSequenceMenu); fileMenu.add(reload); @@ -2155,6 +1871,9 @@ public class GAlignFrame extends JInternalFrame fileMenu.add(associatedData); fileMenu.addSeparator(); fileMenu.add(closeMenuItem); + + pasteMenu.add(pasteNew); + pasteMenu.add(pasteThis); editMenu.add(undoMenuItem); editMenu.add(redoMenuItem); editMenu.add(cut); @@ -2175,6 +1894,13 @@ public class GAlignFrame extends JInternalFrame // editMenu.addSeparator(); editMenu.add(padGapsMenuitem); + showMenu.add(showAllColumns); + showMenu.add(showAllSeqs); + showMenu.add(showAllhidden); + hideMenu.add(hideSelColumns); + hideMenu.add(hideSelSequences); + hideMenu.add(hideAllSelection); + hideMenu.add(hideAllButSelection); viewMenu.add(newView); viewMenu.add(expandViews); viewMenu.add(gatherViews); @@ -2218,33 +1944,12 @@ public class GAlignFrame extends JInternalFrame autoAnnMenu.add(showGroupConsensus); annotationsMenu.add(autoAnnMenu); - colourMenu.add(applyToAllGroups); - colourMenu.add(textColour); - colourMenu.addSeparator(); - colourMenu.add(noColourmenuItem); - colourMenu.add(clustalColour); - colourMenu.add(BLOSUM62Colour); - colourMenu.add(PIDColour); - colourMenu.add(zappoColour); - colourMenu.add(taylorColour); - colourMenu.add(hydrophobicityColour); - colourMenu.add(helixColour); - colourMenu.add(strandColour); - colourMenu.add(turnColour); - colourMenu.add(buriedColour); - colourMenu.add(nucleotideColour); - colourMenu.add(purinePyrimidineColour); - colourMenu.add(RNAInteractionColour); - // colourMenu.add(covariationColour); - colourMenu.add(tcoffeeColour); - colourMenu.add(userDefinedColour); - colourMenu.addSeparator(); - colourMenu.add(conservationMenuItem); - colourMenu.add(modifyConservation); - colourMenu.add(abovePIDThreshold); - colourMenu.add(modifyPID); - colourMenu.add(annotationColour); - colourMenu.add(rnahelicesColour); + + sort.add(sortIDMenuItem); + sort.add(sortLengthMenuItem); + sort.add(sortGroupMenuItem); + sort.add(sortPairwiseMenuItem); + sort.add(sortByTreeMenu); calculateMenu.add(sort); calculateMenu.add(calculateTree); calculateMenu.addSeparator(); @@ -2252,21 +1957,20 @@ public class GAlignFrame extends JInternalFrame calculateMenu.add(PCAMenuItem); calculateMenu.addSeparator(); calculateMenu.add(showTranslation); + calculateMenu.add(showReverse); + calculateMenu.add(showReverseComplement); calculateMenu.add(showProducts); calculateMenu.add(autoCalculate); calculateMenu.add(sortByTree); calculateMenu.addSeparator(); + calculateMenu.add(expandAlignment); calculateMenu.add(extractScores); + calculateMenu.addSeparator(); + calculateMenu.add(runGroovy); + webServiceNoServices = new JMenuItem( MessageManager.getString("label.no_services")); webService.add(webServiceNoServices); - pasteMenu.add(pasteNew); - pasteMenu.add(pasteThis); - sort.add(sortIDMenuItem); - sort.add(sortLengthMenuItem); - sort.add(sortGroupMenuItem); - sort.add(sortPairwiseMenuItem); - sort.add(sortByTreeMenu); exportImageMenu.add(htmlMenuItem); exportImageMenu.add(epsFile); exportImageMenu.add(createPNG); @@ -2278,13 +1982,6 @@ public class GAlignFrame extends JInternalFrame this.getContentPane().add(statusPanel, java.awt.BorderLayout.SOUTH); statusPanel.add(statusBar, null); this.getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER); - showMenu.add(showAllColumns); - showMenu.add(showAllSeqs); - showMenu.add(showAllhidden); - hideMenu.add(hideSelColumns); - hideMenu.add(hideSelSequences); - hideMenu.add(hideAllSelection); - hideMenu.add(hideAllButSelection); formatMenu.add(font); formatMenu.addSeparator(); @@ -2312,7 +2009,7 @@ public class GAlignFrame extends JInternalFrame selectMenu.add(grpsFromSelection); selectMenu.add(deleteGroups); selectMenu.add(annotationColumn); - calculateMenu.add(expandAlignment); + selectMenu.add(selectHighlighted); // TODO - determine if the listenToViewSelections button is needed : see bug // JAL-574 // selectMenu.addSeparator(); @@ -2320,6 +2017,436 @@ public class GAlignFrame extends JInternalFrame } /** + * Rebuilds the Colour menu, including any user-defined colours which have + * been loaded either on startup or during the session + */ + public void buildColourMenu() + { + colourMenu.removeAll(); + colours = new ButtonGroup(); + + colourMenu.add(applyToAllGroups); + colourMenu.add(textColour); + colourMenu.addSeparator(); + colourMenu.add(noColourmenuItem); + colourMenu.add(clustalColour); + colourMenu.add(BLOSUM62Colour); + colourMenu.add(PIDColour); + colourMenu.add(zappoColour); + colourMenu.add(taylorColour); + colourMenu.add(hydrophobicityColour); + colourMenu.add(helixColour); + colourMenu.add(strandColour); + colourMenu.add(turnColour); + colourMenu.add(buriedColour); + colourMenu.add(nucleotideColour); + colourMenu.add(purinePyrimidineColour); + // colourMenu.add(RNAInteractionColour); + // colourMenu.add(covariationColour); + colourMenu.add(tcoffeeColour); + + /* + * add any user-defined colours + */ + Map userColourSchemes = UserDefinedColours + .getUserColourSchemes(); + if (userColourSchemes != null) + { + for (String userColour : userColourSchemes.keySet()) + { + final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem( + userColour); + radioItem.setName(USER_DEFINED_COLOUR_SCHEME); + radioItem.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent evt) + { + if (evt.isPopupTrigger()) // Mac + { + offerRemoval(); + } + } + + @Override + public void mouseReleased(MouseEvent evt) + { + if (evt.isPopupTrigger()) // Windows + { + offerRemoval(); + } + } + + void offerRemoval() + { + radioItem.removeActionListener(radioItem.getActionListeners()[0]); + + int option = JvOptionPane.showInternalConfirmDialog( + Desktop.desktop, MessageManager + .getString("label.remove_from_default_list"), + MessageManager + .getString("label.remove_user_defined_colour"), + JvOptionPane.YES_NO_OPTION); + if (option == JvOptionPane.YES_OPTION) + { + UserDefinedColours.removeColourFromDefaults(radioItem + .getText()); + colourMenu.remove(radioItem); + } + else + { + radioItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent evt) + { + userDefinedColour_actionPerformed(evt); + } + }); + } + } + }); + radioItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent evt) + { + userDefinedColour_actionPerformed(evt); + } + }); + colourMenu.add(radioItem); + colours.add(radioItem); + } + } + + colourMenu.add(userDefinedColour); + colourMenu.addSeparator(); + colourMenu.add(conservationMenuItem); + colourMenu.add(modifyConservation); + colourMenu.add(abovePIDThreshold); + colourMenu.add(modifyPID); + colourMenu.add(annotationColour); + colourMenu.add(rnahelicesColour); + + /* + * add colours to a ButtonGroup to make their + * selection mutually exclusive + */ + colours.add(noColourmenuItem); + colours.add(clustalColour); + colours.add(zappoColour); + colours.add(taylorColour); + colours.add(hydrophobicityColour); + colours.add(helixColour); + colours.add(strandColour); + colours.add(turnColour); + colours.add(buriedColour); + colours.add(userDefinedColour); + colours.add(PIDColour); + colours.add(BLOSUM62Colour); + colours.add(nucleotideColour); + colours.add(purinePyrimidineColour); + // colours.add(covariationColour); + colours.add(tcoffeeColour); + colours.add(RNAInteractionColour); + setColourSelected(Cache.getDefault(Preferences.DEFAULT_COLOUR, + ResidueColourScheme.NONE)); + + } + + /** + * Constructs the entries on the Colour menu (but does not add them to the + * menu) + */ + protected void initColourMenu() + { + applyToAllGroups = new JCheckBoxMenuItem( + MessageManager.getString("label.apply_colour_to_all_groups")); + applyToAllGroups.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + applyToAllGroups_actionPerformed(); + } + }); + + textColour = new JRadioButtonMenuItem( + MessageManager.getString("action.set_text_colour")); + textColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + textColour_actionPerformed(); + } + }); + clustalColour = new JRadioButtonMenuItem( + MessageManager.getString("label.clustalx")); + clustalColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + clustalColour_actionPerformed(); + } + }); + zappoColour = new JRadioButtonMenuItem( + MessageManager.getString("label.zappo")); + zappoColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + zappoColour_actionPerformed(); + } + }); + taylorColour = new JRadioButtonMenuItem( + MessageManager.getString("label.taylor")); + taylorColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + taylorColour_actionPerformed(); + } + }); + hydrophobicityColour = new JRadioButtonMenuItem( + MessageManager + .getString("label.hydrophobicity")); + hydrophobicityColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + hydrophobicityColour_actionPerformed(); + } + }); + helixColour = new JRadioButtonMenuItem( + MessageManager.getString("label.helix_propensity")); + helixColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + helixColour_actionPerformed(); + } + }); + strandColour = new JRadioButtonMenuItem( + MessageManager + .getString("label.strand_propensity")); + strandColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + strandColour_actionPerformed(); + } + }); + turnColour = new JRadioButtonMenuItem( + MessageManager.getString("label.turn_propensity")); + turnColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + turnColour_actionPerformed(); + } + }); + buriedColour = new JRadioButtonMenuItem( + MessageManager.getString("label.buried_index")); + buriedColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + buriedColour_actionPerformed(); + } + }); + userDefinedColour = new JRadioButtonMenuItem( + MessageManager + .getString("action.user_defined")); + userDefinedColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + userDefinedColour_actionPerformed(e); + } + }); + PIDColour = new JRadioButtonMenuItem( + MessageManager.getString("label.percentage_identity")); + PIDColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + PIDColour_actionPerformed(); + } + }); + BLOSUM62Colour = new JRadioButtonMenuItem( + MessageManager.getString("label.blosum62_score")); + BLOSUM62Colour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + BLOSUM62Colour_actionPerformed(); + } + }); + nucleotideColour = new JRadioButtonMenuItem( + MessageManager.getString("label.nucleotide")); + nucleotideColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + nucleotideColour_actionPerformed(); + } + }); + purinePyrimidineColour = new JRadioButtonMenuItem( + MessageManager.getString("label.purine_pyrimidine")); + purinePyrimidineColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + purinePyrimidineColour_actionPerformed(); + } + }); + + tcoffeeColour = new JRadioButtonMenuItem( + MessageManager.getString("label.tcoffee_scores")); + tcoffeeColour.setEnabled(false); + tcoffeeColour.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + tcoffeeColorScheme_actionPerformed(); + } + }); + + RNAInteractionColour = new JRadioButtonMenuItem("RNA Interaction type"); + RNAInteractionColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + RNAInteractionColour_actionPerformed(); + } + }); + /* + * covariationColour = new JRadioButtonMenuItem("Covariation"); + * covariationColour.addActionListener(new ActionListener() { public void + * actionPerformed(ActionEvent e) { covariationColour_actionPerformed(); } + * }); + */ + + conservationMenuItem = new JCheckBoxMenuItem( + MessageManager.getString("action.by_conservation")); + conservationMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + conservationMenuItem_actionPerformed(); + } + }); + noColourmenuItem = new JRadioButtonMenuItem( + MessageManager.getString("label.none")); + noColourmenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + noColourmenuItem_actionPerformed(); + } + }); + + abovePIDThreshold = new JCheckBoxMenuItem( + MessageManager.getString("label.above_identity_threshold")); + abovePIDThreshold.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + abovePIDThreshold_actionPerformed(); + } + }); + modifyPID = new JMenuItem( + MessageManager.getString("label.modify_identity_threshold")); + modifyPID.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + modifyPID_actionPerformed(); + } + }); + modifyConservation = new JMenuItem( + MessageManager + .getString("label.modify_conservation_threshold")); + modifyConservation.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + modifyConservation_actionPerformed(); + } + }); + + annotationColour = new JMenuItem( + MessageManager.getString("action.by_annotation")); + annotationColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + annotationColour_actionPerformed(); + } + }); + + rnahelicesColour = new JMenuItem( + MessageManager.getString("action.by_rna_helixes")); + rnahelicesColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + rnahelicesColour_actionPerformed(); + } + }); + } + + protected void selectHighlightedColumns_actionPerformed( + ActionEvent actionEvent) + { + // TODO Auto-generated method stub + + } + + /** + * Generate the reverse sequence (or reverse complement if the flag is true) + * and add it to the alignment + * + * @param complement + */ + protected void showReverse_actionPerformed(boolean complement) + { + } + + /** + * Try to run script in a Groovy console, having first ensured that this + * alignframe is set as currentAlignFrame in Desktop + */ + protected void runGroovy_actionPerformed() + { + + } + + /** * Adds the given action listener and key accelerator to the given menu item. * Also saves in a lookup table to support lookup of action by key stroke. * @@ -2460,13 +2587,6 @@ public class GAlignFrame extends JInternalFrame } - protected void showSeqFeaturesHeight_actionPerformed( - ActionEvent actionEvent) - { - // TODO Auto-generated method stub - - } - protected void justifyRightMenuItem_actionPerformed(ActionEvent e) { // TODO Auto-generated method stub @@ -2655,35 +2775,35 @@ public class GAlignFrame extends JInternalFrame { } - protected void clustalColour_actionPerformed(ActionEvent e) + protected void clustalColour_actionPerformed() { } - protected void zappoColour_actionPerformed(ActionEvent e) + protected void zappoColour_actionPerformed() { } - protected void taylorColour_actionPerformed(ActionEvent e) + protected void taylorColour_actionPerformed() { } - protected void hydrophobicityColour_actionPerformed(ActionEvent e) + protected void hydrophobicityColour_actionPerformed() { } - protected void helixColour_actionPerformed(ActionEvent e) + protected void helixColour_actionPerformed() { } - protected void strandColour_actionPerformed(ActionEvent e) + protected void strandColour_actionPerformed() { } - protected void turnColour_actionPerformed(ActionEvent e) + protected void turnColour_actionPerformed() { } - protected void buriedColour_actionPerformed(ActionEvent e) + protected void buriedColour_actionPerformed() { } @@ -2691,31 +2811,31 @@ public class GAlignFrame extends JInternalFrame { } - protected void PIDColour_actionPerformed(ActionEvent e) + protected void PIDColour_actionPerformed() { } - protected void BLOSUM62Colour_actionPerformed(ActionEvent e) + protected void BLOSUM62Colour_actionPerformed() { } - protected void purinePyrimidineColour_actionPerformed(ActionEvent e) + protected void purinePyrimidineColour_actionPerformed() { } - protected void RNAInteractionColour_actionPerformed(ActionEvent e) + protected void RNAInteractionColour_actionPerformed() { } /* - * protected void covariationColour_actionPerformed(ActionEvent e) { } + * protected void covariationColour_actionPerformed() { } */ - protected void noColourmenuItem_actionPerformed(ActionEvent e) + protected void noColourmenuItem_actionPerformed() { } - protected void conservationMenuItem_actionPerformed(ActionEvent e) + protected void conservationMenuItem_actionPerformed() { } @@ -2731,7 +2851,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void abovePIDThreshold_actionPerformed(ActionEvent e) + protected void abovePIDThreshold_actionPerformed() { } @@ -2739,7 +2859,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void nucleotideColour_actionPerformed(ActionEvent e) + protected void nucleotideColour_actionPerformed() { } @@ -2775,7 +2895,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void applyToAllGroups_actionPerformed(ActionEvent e) + protected void applyToAllGroups_actionPerformed() { } @@ -2827,11 +2947,8 @@ public class GAlignFrame extends JInternalFrame * Template method to handle the 'Color T-Coffee scores' menu event. *

* Subclasses override this method to provide a custom action. - * - * @param event - * The raised event */ - protected void tcoffeeColorScheme_actionPerformed(ActionEvent event) + protected void tcoffeeColorScheme_actionPerformed() { } @@ -2852,11 +2969,11 @@ public class GAlignFrame extends JInternalFrame { } - protected void modifyPID_actionPerformed(ActionEvent e) + protected void modifyPID_actionPerformed() { } - protected void modifyConservation_actionPerformed(ActionEvent e) + protected void modifyConservation_actionPerformed() { } @@ -2898,17 +3015,15 @@ public class GAlignFrame extends JInternalFrame } - public void annotationColour_actionPerformed(ActionEvent e) + public void annotationColour_actionPerformed() { - } public void annotationColumn_actionPerformed(ActionEvent e) { - } - public void rnahelicesColour_actionPerformed(ActionEvent e) + public void rnahelicesColour_actionPerformed() { } @@ -3003,7 +3118,7 @@ public class GAlignFrame extends JInternalFrame } - public void textColour_actionPerformed(ActionEvent e) + public void textColour_actionPerformed() { } @@ -3107,7 +3222,7 @@ public class GAlignFrame extends JInternalFrame return this.splitFrame; } - protected void showComplement_actionPerformed(boolean state) + protected void showComplement_actionPerformed(boolean complement) { } }