package jalview.gui; import jalview.datamodel.AnnotatedCollectionI; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemes; import jalview.schemes.ResidueColourScheme; import jalview.schemes.UserColourScheme; import jalview.util.MessageManager; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.ButtonGroup; import javax.swing.JMenu; import javax.swing.JRadioButtonMenuItem; public class ColourMenuHelper { public interface ColourChangeListener { void changeColour_actionPerformed(String name); } /** * Adds items to the colour menu, as mutually exclusive members of a button * group. The callback handler is responsible for the action on selecting any * of these options. It is returned the name of the selected colour, or "None" * or "User Defined". * * * @param colourMenu * the menu to attach items to * @param client * a callback to handle menu selection * @param coll * the data the menu is being built for */ public static void addMenuItems(final JMenu colourMenu, final ColourChangeListener client, AnnotatedCollectionI coll) { /* * ButtonGroup groups those items whose * selection is mutually exclusive */ ButtonGroup colours = new ButtonGroup(); JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem( MessageManager.getString("label.none")); noColourmenuItem.setName(ResidueColourScheme.NONE); noColourmenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { client.changeColour_actionPerformed(ResidueColourScheme.NONE); } }); colourMenu.add(noColourmenuItem); colours.add(noColourmenuItem); /* * scan registered colour schemes (built-in or user-defined * and add them to the menu (in the order they were added) */ Iterable colourSchemes = ColourSchemes.getInstance() .getColourSchemes(); for (ColourSchemeI scheme : colourSchemes) { /* * button text is i18n'd but the name is the canonical name of * the colour scheme (inspected in changeColour_actionPerformed) */ final String name = scheme.getSchemeName(); String label = MessageManager.getStringOrReturn("label.colourScheme_" + name.toLowerCase().replace(" ", "_"), name); final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(label); radioItem.setName(name); radioItem.setEnabled(scheme.isApplicableTo(coll)); if (scheme instanceof UserColourScheme) { /* * user-defined colour scheme loaded on startup or during the * Jalview session; right-click on this offers the option to * remove it as a colour choice */ 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() { ActionListener al = radioItem.getActionListeners()[0]; radioItem.removeActionListener(al); 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 .getName()); ColourSchemes.getInstance().removeColourScheme( radioItem.getName()); colourMenu.remove(radioItem); } else { radioItem.addActionListener(al); } } }); } radioItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { client.changeColour_actionPerformed(name); } }); colourMenu.add(radioItem); colours.add(radioItem); } final String label = MessageManager.getString("action.user_defined"); JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem(label); userDefinedColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { client.changeColour_actionPerformed(ResidueColourScheme.USER_DEFINED); } }); colourMenu.add(userDefinedColour); colours.add(userDefinedColour); } /** * Marks as selected the colour menu item matching the given name, or the * first item ('None') if no match is found * * @param colourMenu * @param colourName */ public static void setColourSelected(JMenu colourMenu, String colourName) { if (colourName == null) { return; } JRadioButtonMenuItem none = null; /* * select the radio button whose name matches the colour name * (not the button text, as it may be internationalised) */ for (Component menuItem : colourMenu.getMenuComponents()) { if (menuItem instanceof JRadioButtonMenuItem) { String buttonName = ((JRadioButtonMenuItem) menuItem).getName(); if (colourName.equals(buttonName)) { ((JRadioButtonMenuItem) menuItem).setSelected(true); return; } if (ResidueColourScheme.NONE.equals(buttonName)) { none = (JRadioButtonMenuItem) menuItem; } } } if (none != null) { none.setSelected(true); } } /** * Marks as selected the colour menu item matching the given colour scheme, or * the first item ('None') if no match is found * * @param colourMenu * @param cs */ public static void setColourSelected(JMenu colourMenu, ColourSchemeI cs) { setColourSelected(colourMenu, cs == null ? ResidueColourScheme.NONE : cs.getSchemeName()); } }