* On select button(s) with Ctrl/click or Shift/click: set button foreground * text to brighter than background. *
* On unselect button(s) with Ctrl/click on selected, or click to release * current selection: reset foreground text to darker than background. *
* Simple click: clear selection (resetting foreground to darker); set clicked * button foreground to brighter *
* Finally, synchronize the colour chooser to the colour of the first button
* in the selected set.
*
* @param e
*/
public void colourButtonPressed(MouseEvent e)
{
JButton pressed = (JButton) e.getSource();
if (e.isShiftDown())
{
JButton start, end = (JButton) e.getSource();
if (selectedButtons.size() > 0)
{
start = selectedButtons.get(selectedButtons.size() - 1);
}
else
{
start = (JButton) e.getSource();
}
int startIndex = 0, endIndex = 0;
for (int b = 0; b < buttonPanel.getComponentCount(); b++)
{
if (buttonPanel.getComponent(b) == start)
{
startIndex = b;
}
if (buttonPanel.getComponent(b) == end)
{
endIndex = b;
}
}
if (startIndex > endIndex)
{
int temp = startIndex;
startIndex = endIndex;
endIndex = temp;
}
for (int b = startIndex; b <= endIndex; b++)
{
JButton button = (JButton) buttonPanel.getComponent(b);
if (!selectedButtons.contains(button))
{
button.setForeground(
ColorUtils.brighterThan(button.getBackground()));
selectedButtons.add(button);
}
}
}
else if (!e.isControlDown())
{
for (int b = 0; b < selectedButtons.size(); b++)
{
JButton button = selectedButtons.get(b);
button.setForeground(ColorUtils.darkerThan(button.getBackground()));
}
selectedButtons.clear();
pressed.setForeground(
ColorUtils.brighterThan(pressed.getBackground()));
selectedButtons.add(pressed);
}
else if (e.isControlDown())
{
if (selectedButtons.contains(pressed))
{
pressed.setForeground(
ColorUtils.darkerThan(pressed.getBackground()));
selectedButtons.remove(pressed);
}
else
{
pressed.setForeground(
ColorUtils.brighterThan(pressed.getBackground()));
selectedButtons.add(pressed);
}
}
if (selectedButtons.size() > 0)
{
colorChooser.setColor((selectedButtons.get(0)).getBackground());
}
}
/**
* A helper method to update or make a colour button, whose background colour
* is the associated colour, and text colour a darker shade of the same. If
* the button is already in the list, then its text and margins are updated,
* if not then it is created and added. This method supports toggling between
* case-sensitive and case-insensitive button panels. The case-sensitive
* version has abbreviated button text in order to fit in more buttons.
*
* @param label
* @param residue
* @param the
* list of buttons
* @param buttonIndex
* the button's position in the list
*/
JButton makeButton(String label, String residue, List
*
*/
@Override
protected void loadbutton_actionPerformed()
{
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.setToolTipText(MessageManager.getString("action.load"));
chooser.setResponseHandler(0, () -> {
File choice = chooser.getSelectedFile();
Cache.setProperty(LAST_DIRECTORY, choice.getParent());
UserColourScheme ucs = ColourSchemeLoader
.loadColourScheme(choice.getAbsolutePath());
Color[] colors = ucs.getColours();
schemeName.setText(ucs.getSchemeName());
if (ucs.getLowerCaseColours() != null)
{
caseSensitive.setSelected(true);
lcaseColour.setEnabled(true);
resetButtonPanel(true);
for (int i = 0; i < lowerCaseButtons.size(); i++)
{
JButton button = lowerCaseButtons.get(i);
button.setBackground(ucs.getLowerCaseColours()[i]);
}
}
else
{
caseSensitive.setSelected(false);
lcaseColour.setEnabled(false);
resetButtonPanel(false);
}
for (int i = 0; i < upperCaseButtons.size(); i++)
{
JButton button = upperCaseButtons.get(i);
button.setBackground(colors[i]);
}
addNewColourScheme(choice.getPath());
});
chooser.showOpenDialog(this);
}
/**
* Loads the user-defined colour scheme from the first file listed in property
* "USER_DEFINED_COLOURS". If this fails, returns an all-white colour scheme.
*
* @return
*/
public static UserColourScheme loadDefaultColours()
{
UserColourScheme ret = null;
String colours = Cache.getProperty(USER_DEFINED_COLOURS);
if (colours != null)
{
if (colours.indexOf("|") > -1)
{
colours = colours.substring(0, colours.indexOf("|"));
}
ret = ColourSchemeLoader.loadColourScheme(colours);
}
if (ret == null)
{
ret = new UserColourScheme("white");
}
return ret;
}
/**
* Action on pressing the Save button.
*
*
* If the scheme is saved to file, the 'changed' flag field is reset to false.
*/
@Override
protected void savebutton_actionPerformed()
{
String name = schemeName.getText().trim();
if (name.length() < 1)
{
JvOptionPane.showInternalMessageDialog(Desktop.desktop,
MessageManager
.getString("label.user_colour_scheme_must_have_name"),
MessageManager.getString("label.no_name_colour_scheme"),
JvOptionPane.WARNING_MESSAGE);
}
if (!Platform.isJS() && ColourSchemes.getInstance().nameExists(name))
{
/**
* java only
*
* @j2sIgnore
*/
{
int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
MessageManager.formatMessage(
"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;
}
}
}
JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
JalviewFileView fileView = new JalviewFileView();
chooser.setFileView(fileView);
chooser.setDialogTitle(
MessageManager.getString("label.save_colour_scheme"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int option = chooser.showSaveDialog(this);
if (option == JalviewFileChooser.APPROVE_OPTION)
{
File file = chooser.getSelectedFile();
UserColourScheme updatedScheme = addNewColourScheme(file.getPath());
saveToFile(file);
changedButNotSaved = 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()))
{
oldColourScheme = updatedScheme;
applyButton_actionPerformed();
}
}
}
/**
* Adds the current colour scheme to the Jalview properties file so it is
* loaded on next startup, and updates the Colour menu in the parent
* AlignFrame (if there is one). Note this action does not including applying
* the colour scheme.
*
* @param filePath
* @return
*/
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);
if (defaultColours.indexOf(filePath) == -1)
{
if (defaultColours.length() > 0)
{
defaultColours = defaultColours.concat("|");
}
defaultColours = defaultColours.concat(filePath);
}
Cache.setProperty(USER_DEFINED_COLOURS, defaultColours);
/*
* construct and register the colour scheme
*/
UserColourScheme ucs = getSchemeFromButtons();
ColourSchemes.getInstance().registerColourScheme(ucs);
/*
* update the Colour menu items
*/
if (ap != null)
{
ap.alignFrame.buildColourMenu();
}
return ucs;
}
/**
* Saves the colour scheme to file in XML format
*
* @param path
*/
protected void saveToFile(File toFile)
{
/*
* build a Java model of colour scheme as XML, and
* marshal to file
*/
JalviewUserColours ucs = new JalviewUserColours();
String name = schemeName.getText();
ucs.setSchemeName(name);
try
{
PrintWriter out = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(toFile), "UTF-8"));
for (int i = 0; i < buttonPanel.getComponentCount(); i++)
{
JButton button = (JButton) buttonPanel.getComponent(i);
Colour col = new Colour();
col.setName(button.getText());
col.setRGB(Format.getHexString(button.getBackground()));
ucs.getColour().add(col);
}
JAXBContext jaxbContext = JAXBContext
.newInstance(JalviewUserColours.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(
new ObjectFactory().createJalviewUserColours(ucs), out);
// ucs.marshal(out);
out.close();
} catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
* On cancel, restores the colour scheme that was selected before the dialogue
* was opened
*/
@Override
protected void cancelButton_actionPerformed()
{
ap.alignFrame.changeColour(oldColourScheme);
ap.paintAlignment(true, true);
try
{
frame.setClosed(true);
} catch (Exception ex)
{
}
}
/**
* 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()
{
boolean selected = caseSensitive.isSelected();
resetButtonPanel(selected);
lcaseColour.setEnabled(selected);
}
}