*/
package jalview.gui;
-import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
-import jalview.datamodel.SequenceGroup;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
import jalview.jbgui.GUserDefinedColours;
import jalview.schemabinding.version2.Colour;
import jalview.schemabinding.version2.JalviewUserColours;
import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeLoader;
import jalview.schemes.ColourSchemes;
import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
-import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
* @author Andrew Waterhouse
* @author Mungo Carstairs
*/
-public class UserDefinedColours extends GUserDefinedColours implements
- ChangeListener
+public class UserDefinedColours extends GUserDefinedColours
+ implements ChangeListener
{
- private static final Font VERDANA_BOLD_10 = new Font("Verdana",
- Font.BOLD, 10);
+ private static final Font VERDANA_BOLD_10 = new Font("Verdana", Font.BOLD,
+ 10);
public static final String USER_DEFINED_COLOURS = "USER_DEFINED_COLOURS";
private static final String LAST_DIRECTORY = "LAST_DIRECTORY";
- private static final int MY_FRAME_HEIGHT = 420;
+ private static final int MY_FRAME_HEIGHT = 440;
private static final int MY_FRAME_WIDTH = 810;
AlignmentPanel ap;
- SequenceGroup seqGroup;
-
- List<JButton> selectedButtons;
-
+ /*
+ * the colour scheme when the dialog was opened, or
+ * the scheme last saved to file
+ */
ColourSchemeI oldColourScheme;
- JInternalFrame frame;
+ /*
+ * flag is true if the colour scheme has been changed since the
+ * dialog was opened, or the changes last saved to file
+ */
+ boolean changed;
- JalviewStructureDisplayI structureViewer;
+ JInternalFrame frame;
List<JButton> upperCaseButtons;
List<JButton> lowerCaseButtons;
/**
- * Creates a new UserDefinedColours object.
+ * Creates and displays a new UserDefinedColours panel
*
- * @param ap
- * @param sg
+ * @param alignPanel
*/
- public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
+ public UserDefinedColours(AlignmentPanel alignPanel)
{
- super();
+ this();
lcaseColour.setEnabled(false);
- this.ap = ap;
- seqGroup = sg;
+ this.ap = alignPanel;
- if (seqGroup != null)
- {
- oldColourScheme = seqGroup.getColourScheme();
- }
- else
- {
- oldColourScheme = ap.av.getGlobalColourScheme();
- }
+ oldColourScheme = alignPanel.av.getGlobalColourScheme();
if (oldColourScheme instanceof UserColourScheme)
{
schemeName.setText(oldColourScheme.getSchemeName());
- if (((UserColourScheme) oldColourScheme).getLowerCaseColours() != null)
+ if (((UserColourScheme) oldColourScheme)
+ .getLowerCaseColours() != null)
{
caseSensitive.setSelected(true);
lcaseColour.setEnabled(true);
showFrame();
}
- public UserDefinedColours(JalviewStructureDisplayI viewer,
- ColourSchemeI oldcs)
+ UserDefinedColours()
{
super();
- this.structureViewer = viewer;
-
- colorChooser.getSelectionModel().addChangeListener(this);
-
- oldColourScheme = oldcs;
-
- if (oldColourScheme instanceof UserColourScheme)
- {
- schemeName.setText(((UserColourScheme) oldColourScheme)
- .getSchemeName());
- }
-
- resetButtonPanel(false);
-
- showFrame();
-
+ selectedButtons = new ArrayList<>();
}
void showFrame()
Desktop.addInternalFrame(frame,
MessageManager.getString("label.user_defined_colours"),
MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
-
- if (seqGroup != null)
- {
- frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
- }
}
/**
if (upperCaseButtons == null)
{
- upperCaseButtons = new ArrayList<JButton>();
+ upperCaseButtons = new ArrayList<>();
}
for (int i = 0; i < 20; i++)
if (lowerCaseButtons == null)
{
- lowerCaseButtons = new ArrayList<JButton>();
+ lowerCaseButtons = new ArrayList<>();
}
for (int i = 0; i < 20; i++)
}
/**
- * DOCUMENT ME!
+ * ChangeListener handler for when a colour is picked in the colour chooser.
+ * The action is to apply the colour to all selected buttons as their
+ * background colour. Foreground colour (text) is set to a lighter shade in
+ * order to highlight which buttons are selected. If 'Lower Case Colour' is
+ * active, then the colour is applied to all lower case buttons (as well as
+ * the Lower Case Colour button itself).
*
* @param evt
- * DOCUMENT ME!
*/
@Override
public void stateChanged(ChangeEvent evt)
{
- if (selectedButtons != null)
+ JButton button = null;
+ final Color newColour = colorChooser.getColor();
+ if (lcaseColour.isSelected())
{
- JButton button = null;
- final Color newColour = colorChooser.getColor();
- for (int i = 0; i < selectedButtons.size(); i++)
+ selectedButtons.clear();
+ for (int i = 0; i < lowerCaseButtons.size(); i++)
{
- button = selectedButtons.get(i);
+ button = lowerCaseButtons.get(i);
button.setBackground(newColour);
- button.setForeground(ColorUtils.brighterThan(newColour));
- }
- if (button == lcaseColour)
- {
- for (int i = 0; i < lowerCaseButtons.size(); i++)
- {
- button = lowerCaseButtons.get(i);
- button.setBackground(newColour);
- button.setForeground(ColorUtils.brighterThan(button
- .getBackground()));
- }
+ button.setForeground(
+ ColorUtils.brighterThan(button.getBackground()));
}
}
+ for (int i = 0; i < selectedButtons.size(); i++)
+ {
+ button = selectedButtons.get(i);
+ button.setBackground(newColour);
+ button.setForeground(ColorUtils.brighterThan(newColour));
+ }
+
+ changed = true;
}
/**
*/
public void colourButtonPressed(MouseEvent e)
{
- if (selectedButtons == null)
- {
- selectedButtons = new ArrayList<JButton>();
- }
-
JButton pressed = (JButton) e.getSource();
if (e.isShiftDown())
JButton button = (JButton) buttonPanel.getComponent(b);
if (!selectedButtons.contains(button))
{
- button.setForeground(ColorUtils.brighterThan(button
- .getBackground()));
+ button.setForeground(
+ ColorUtils.brighterThan(button.getBackground()));
selectedButtons.add(button);
}
}
button.setForeground(ColorUtils.darkerThan(button.getBackground()));
}
selectedButtons.clear();
- pressed.setForeground(ColorUtils.brighterThan(pressed.getBackground()));
+ pressed.setForeground(
+ ColorUtils.brighterThan(pressed.getBackground()));
selectedButtons.add(pressed);
}
{
if (selectedButtons.contains(pressed))
{
- pressed.setForeground(ColorUtils.darkerThan(pressed.getBackground()));
+ pressed.setForeground(
+ ColorUtils.darkerThan(pressed.getBackground()));
selectedButtons.remove(pressed);
}
else
{
- pressed.setForeground(ColorUtils.brighterThan(pressed
- .getBackground()));
+ pressed.setForeground(
+ ColorUtils.brighterThan(pressed.getBackground()));
selectedButtons.add(pressed);
}
}
{
if (isNoSelectionMade())
{
- JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
- .getString("label.no_colour_selection_in_scheme"),
+ JvOptionPane.showMessageDialog(Desktop.desktop,
+ MessageManager
+ .getString("label.no_colour_selection_in_scheme"),
MessageManager.getString("label.no_colour_selection_warn"),
JvOptionPane.WARNING_MESSAGE);
}
else
{
+ /*
+ * OK is treated as 'apply colours and close'
+ */
applyButton_actionPerformed();
+ /*
+ * If editing a named colour scheme, warn if changes
+ * have not been saved
+ */
+ warnIfUnsavedChanges();
+
try
{
frame.setClosed(true);
}
/**
+ * If we have made changes to an existing user defined colour scheme but not
+ * saved them, show a dialog with the option to save. If the user chooses to
+ * save, do so, else clear the colour scheme name to indicate a new colour
+ * scheme.
+ */
+ protected void warnIfUnsavedChanges()
+ {
+ if (!changed)
+ {
+ return;
+ }
+
+ String name = schemeName.getText().trim();
+ if (oldColourScheme != null && !"".equals(name)
+ && name.equals(oldColourScheme.getSchemeName()))
+ {
+ String message = MessageManager.formatMessage("label.scheme_changed",
+ name);
+ String title = MessageManager.getString("label.save_changes");
+ String[] options = new String[] { title,
+ MessageManager.getString("label.dont_save_changes"), };
+ final String question = JvSwingUtils.wrapTooltip(true, message);
+ int response = JvOptionPane.showOptionDialog(Desktop.desktop,
+ question, title, JvOptionPane.DEFAULT_OPTION,
+ JvOptionPane.PLAIN_MESSAGE, null, options, options[0]);
+
+ boolean saved = false;
+ if (response == 0)
+ {
+ /*
+ * prompt to save changes to file
+ */
+ saved = savebutton_actionPerformed();
+ }
+
+ /*
+ * if user chooses not to save (either in this dialog or in the
+ * save as dialogs), treat this as a new user defined colour scheme
+ */
+ if (!saved)
+ {
+ /*
+ * clear scheme name and re-apply as an anonymous scheme
+ */
+ schemeName.setText("");
+ applyButton_actionPerformed();
+ }
+ }
+ }
+
+ /**
* Returns true if the user has not made any colour selection (including if
* 'case-sensitive' selected and no lower-case colour chosen).
*
}
/**
- * Applies the current colour scheme to the alignment, sequence group or
- * structure view.
+ * Applies the current colour scheme to the alignment or sequence group
*/
@Override
protected void applyButton_actionPerformed()
{
if (isNoSelectionMade())
{
- JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
- .getString("label.no_colour_selection_in_scheme"),
+ JvOptionPane.showMessageDialog(Desktop.desktop,
+ MessageManager
+ .getString("label.no_colour_selection_in_scheme"),
MessageManager.getString("label.no_colour_selection_warn"),
JvOptionPane.WARNING_MESSAGE);
}
UserColourScheme ucs = getSchemeFromButtons();
- if (seqGroup != null)
- {
- seqGroup.setColourScheme(ucs);
- ap.paintAlignment(true);
- }
- else if (ap != null)
- {
- ap.alignFrame.changeColour(ucs);
- }
- else if (structureViewer != null)
- {
- structureViewer.setJalviewColourScheme(ucs);
- }
+ ap.alignFrame.changeColour(ucs);
}
+ /**
+ * Constructs an instance of UserColourScheme with the residue colours
+ * currently set on the buttons on the panel
+ *
+ * @return
+ */
UserColourScheme getSchemeFromButtons()
{
ucs.setLowerCaseColours(newColours);
}
- // if (ap != null)
- // {
- // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
- // }
-
return ucs;
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * Action on clicking Load scheme button.
+ * <ul>
+ * <li>Open a file chooser to browse for files with extension .jc</li>
+ * <li>Load in the colour scheme and transfer it to this panel's buttons</li>
+ * <li>Register the loaded colour scheme</li>
+ * </ul>
*/
@Override
- protected void loadbutton_actionPerformed(ActionEvent e)
+ protected void loadbutton_actionPerformed()
{
- upperCaseButtons = new ArrayList<JButton>();
- lowerCaseButtons = new ArrayList<JButton>();
+ upperCaseButtons = new ArrayList<>();
+ lowerCaseButtons = new ArrayList<>();
JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager
- .getString("label.load_colour_scheme"));
+ chooser.setDialogTitle(
+ MessageManager.getString("label.load_colour_scheme"));
chooser.setToolTipText(MessageManager.getString("action.load"));
int value = chooser.showOpenDialog(this);
File choice = chooser.getSelectedFile();
Cache.setProperty(LAST_DIRECTORY, choice.getParent());
- UserColourScheme ucs = ColourSchemes.loadColourScheme(choice
- .getAbsolutePath());
+ UserColourScheme ucs = ColourSchemeLoader
+ .loadColourScheme(choice.getAbsolutePath());
Color[] colors = ucs.getColours();
schemeName.setText(ucs.getSchemeName());
{
colours = colours.substring(0, colours.indexOf("|"));
}
- ret = ColourSchemes.loadColourScheme(colours);
+ ret = ColourSchemeLoader.loadColourScheme(colours);
}
if (ret == null)
}
/**
- * DOCUMENT ME!
+ * Action on pressing the Save button.
+ * <ul>
+ * <li>Check a name has been entered</li>
+ * <li>Warn if the name already exists, remove any existing scheme of the same
+ * name if overwriting</li>
+ * <li>Do the standard file chooser thing to write with extension .jc</li>
+ * <li>If saving changes (possibly not yet applied) to the currently selected
+ * colour scheme, then apply the changes, as it is too late to back out
+ * now</li>
+ * <li>Don't apply the changes if the currently selected scheme is different,
+ * to allow a new scheme to be configured and saved but not applied</li>
+ * </ul>
+ * Returns true if the scheme is saved to file, false if it is not
*
- * @param e
- * DOCUMENT ME!
+ * @return
*/
@Override
- protected void savebutton_actionPerformed(ActionEvent e)
+ protected boolean savebutton_actionPerformed()
{
String name = schemeName.getText().trim();
if (name.length() < 1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
- .getString("label.user_colour_scheme_must_have_name"),
+ JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ MessageManager
+ .getString("label.user_colour_scheme_must_have_name"),
MessageManager.getString("label.no_name_colour_scheme"),
JvOptionPane.WARNING_MESSAGE);
- return;
+ return false;
}
if (ColourSchemes.getInstance().nameExists(name))
{
int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
MessageManager.formatMessage(
- "label.colour_scheme_exists_overwrite", new Object[] {
- name, name }),
+ "label.colour_scheme_exists_overwrite", new Object[]
+ { name, name }),
MessageManager.getString("label.duplicate_scheme_name"),
JvOptionPane.YES_NO_OPTION);
if (reply != JvOptionPane.YES_OPTION)
{
- return;
+ return false;
}
- ColourSchemes.getInstance().removeColourScheme(name);
}
JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
JalviewFileView fileView = new JalviewFileView();
chooser.setFileView(fileView);
- chooser.setDialogTitle(MessageManager
- .getString("label.save_colour_scheme"));
+ chooser.setDialogTitle(
+ MessageManager.getString("label.save_colour_scheme"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
- if (value == JalviewFileChooser.APPROVE_OPTION)
+ if (value != JalviewFileChooser.APPROVE_OPTION)
+ {
+ return false;
+ }
+
+ File file = chooser.getSelectedFile();
+ UserColourScheme updatedScheme = addNewColourScheme(file.getPath());
+ saveToFile(file);
+ changed = false;
+
+ /*
+ * changes saved - apply to alignment if we are changing
+ * the currently selected colour scheme; also make the updated
+ * colours the 'backout' scheme on Cancel
+ */
+ if (oldColourScheme != null
+ && name.equals(oldColourScheme.getSchemeName()))
{
- File file = chooser.getSelectedFile();
- addNewColourScheme(file.getPath());
- saveToFile(file);
+ oldColourScheme = updatedScheme;
+ applyButton_actionPerformed();
}
+ return true;
}
/**
* the colour scheme.
*
* @param filePath
+ * @return
*/
- protected void addNewColourScheme(String filePath)
+ protected UserColourScheme addNewColourScheme(String filePath)
{
/*
* update the delimited list of user defined colour files in
* Jalview property USER_DEFINED_COLOURS
*/
- String defaultColours = Cache
- .getDefault(USER_DEFINED_COLOURS, filePath);
+ String defaultColours = Cache.getDefault(USER_DEFINED_COLOURS,
+ filePath);
if (defaultColours.indexOf(filePath) == -1)
{
if (defaultColours.length() > 0)
{
ap.alignFrame.buildColourMenu();
}
+
+ return ucs;
}
/**
* marshal to file
*/
JalviewUserColours ucs = new JalviewUserColours();
- ucs.setSchemeName(schemeName.getText());
+ String name = schemeName.getText();
+ ucs.setSchemeName(name);
try
{
PrintWriter out = new PrintWriter(new OutputStreamWriter(
}
/**
- * On cancel, restores the colour scheme before the dialogue was opened
- *
- * @param e
+ * On cancel, restores the colour scheme that was selected before the dialogue
+ * was opened
*/
@Override
- protected void cancelButton_actionPerformed(ActionEvent e)
+ protected void cancelButton_actionPerformed()
{
- if (ap != null)
- {
- if (seqGroup != null)
- {
- seqGroup.setColourScheme(oldColourScheme);
- }
- else
- {
- ap.alignFrame.changeColour(oldColourScheme);
- }
- ap.paintAlignment(true);
- }
-
- if (structureViewer != null)
- {
- structureViewer.setJalviewColourScheme(oldColourScheme);
- }
+ ap.alignFrame.changeColour(oldColourScheme);
+ ap.paintAlignment(true, true);
try
{
}
}
+ /**
+ * Action on selecting or deselecting the Case Sensitive option. When
+ * selected, separate buttons are shown for lower case residues, and the panel
+ * is resized to accommodate them. Also, the checkbox for 'apply colour to all
+ * lower case' is enabled.
+ */
@Override
- public void caseSensitive_actionPerformed(ActionEvent e)
- {
- resetButtonPanel(caseSensitive.isSelected());
- lcaseColour.setEnabled(caseSensitive.isSelected());
- }
-
- @Override
- public void lcaseColour_actionPerformed(ActionEvent e)
+ public void caseSensitive_actionPerformed()
{
- if (selectedButtons == null)
- {
- selectedButtons = new ArrayList<JButton>();
- }
- else
- {
- selectedButtons.clear();
- }
- selectedButtons.add(lcaseColour);
+ boolean selected = caseSensitive.isSelected();
+ resetButtonPanel(selected);
+ lcaseColour.setEnabled(selected);
}
}