/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.gui.customComponent.customComboBox; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.Image; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.customComboBoxEvent.CustomComboBoxEvent; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.customComboBoxEvent.CustomComboBoxEventsGenerator; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.customComboBoxEvent.CustomComboBoxListener; import edu.yu.einstein.genplay.util.Images; /** * This class is the custom renderer for {@link CustomComboBox}. * Selected item is in bold and italic. It is editable clicking on icons for editing and removing. * Items can also be added. * * @author Nicolas Fourel * @version 0.1 */ public class CustomComboBoxRenderer implements ListCellRenderer, CustomComboBoxEventsGenerator { private final List<CustomComboBoxListener> listenerList; // list of GenomeWindowListener private final CustomComboBoxRenderer instance; // instance of the class, needed for the CustomComboBoxEventsGenerator. private int x; // x position of the mouse /** * Constructor of {@link CustomComboBoxRenderer} */ public CustomComboBoxRenderer () { listenerList = new ArrayList<CustomComboBoxListener>(); instance = this; } @Override public void addCustomComboBoxListener( CustomComboBoxListener customComboBoxListener) { listenerList.add(customComboBoxListener); //System.out.println(customComboBoxListener.toString()); } @Override public CustomComboBoxListener[] getCustomComboBoxListeners() { CustomComboBoxListener[] customComboBoxListeners = new CustomComboBoxListener[listenerList.size()]; return listenerList.toArray(customComboBoxListeners); } /** * Creates a square icon using the given path * @param path icon path * @param side size of the side * @return the icon */ private ImageIcon getIcon (Image image, int side) { //ImageIcon icon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(this.getClass().getClassLoader().getResource(path))); //Image img = icon.getImage(); Image newImg = image.getScaledInstance(side, side, Image.SCALE_SMOOTH); ImageIcon icon = new ImageIcon(newImg); return icon; } @Override public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { list.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { x = e.getX(); // we always store the x position of the mouse on the jlist. } }); list.addMouseListener(new MouseAdapter() { // The principle is to save the x position of the mouse on the jlist, // when the user clicks we know where it was on the list and it is possible to know which button was activated. @Override public void mouseReleased(MouseEvent e) { Object element = list.getSelectedValue(); // gets the selected value of the jlist int side = getSide(list); // button side calculation (dependent of the jlist height) int action = CustomComboBoxEvent.NO_ACTION; // action involved by the position of the mouse if (element.toString().equals(CustomComboBox.ADD_TEXT)) { // if the item corresponds to the adding action. if (x < list.getWidth()) { action = CustomComboBoxEvent.ADD_ACTION; } } else { // if not, if (x < side) { // user clicked on the left button (edit) action = CustomComboBoxEvent.REPLACE_ACTION; // the item must be replaced } else if ( x < (side * 2)) { // user clicked on the right button (delete) action = CustomComboBoxEvent.REMOVE_ACTION; // the item must be deleted } else { // user clicked on the item action = CustomComboBoxEvent.SELECT_ACTION; // the item must be simply selected } } x = list.getWidth() + 50; // mouse position set to 0 if (action != CustomComboBoxEvent.NO_ACTION) { CustomComboBoxEvent event = new CustomComboBoxEvent(instance, list.getSelectedValue(), action); // creates the custom combo box event for (CustomComboBoxListener currentListener: listenerList) { // warns the listener currentListener.customComboBoxChanged(event); } } } }); JPanel panel = new JPanel(); // panel used for displaying: item, buttons (add or edit and delete) panel.setLayout(new BorderLayout()); JLabel label = new JLabel(""); // label displaying the item panel.add(label, BorderLayout.CENTER); if (value != null) { // if there is a value String text = value.toString(); // we get it into a string label.setText(text); // and set it into the label // index '-1' means a simple click on the combo box (not its JList), there is no need to return a full panel. // if the full panel is returned, button(s) will be displayed in the combo box and it will look like a bug. if (index == -1) { return panel; } if (isSelected) { // if the item is selected (mouse is over it) Font font = new Font(label.getFont().getName(), Font.BOLD | Font.ITALIC, label.getFont().getSize()); // creates a different Font label.setFont(font); // sets the font to the label JPanel buttonPanel = new JPanel(); // creates a new panel for buttons int side = getSide(list); // gets the side of a button (button is square) Insets buttonInset = new Insets(0, 0, 0, 0); // button insets are set to 0 if (text.equals(CustomComboBox.ADD_TEXT)) { // if the value is the one related to the adding action // Sets the panel buttonPanel.setLayout(new GridLayout(1, 1)); // with one line and two columns Dimension buttonDim = new Dimension(side , side); // creates a dimension for the panel (contains two buttons max) buttonPanel.setPreferredSize(buttonDim); // sets the dimension to the panel size ImageIcon addIcon = getIcon(Images.getAddImage(), side); // get the add icon JButton addButton = new JButton(addIcon); // creates the button containing the icon addButton.setContentAreaFilled(false); // set the button background to transparent addButton.setBorder(null); // disable any border addButton.setMargin(buttonInset); // sets the insets buttonPanel.add(addButton); // add the button on the second cell of the panel } else { // Sets the panel buttonPanel.setLayout(new GridLayout(1, 2)); // with one line and two columns Dimension buttonDim = new Dimension(side * 2, side); // creates a dimension for the panel (contains two buttons max) buttonPanel.setPreferredSize(buttonDim); // sets the dimension to the panel size // Creates the edit button (same principle as the add button above) ImageIcon editIcon = getIcon(Images.getEditImage(), side); JButton replaceButton = new JButton(editIcon); replaceButton.setContentAreaFilled(false); replaceButton.setBorder(null); replaceButton.setMargin(buttonInset); // Creates the delete button (same principle as the add button above) ImageIcon deleteIcon = getIcon(Images.getDeleteImage(), side); JButton deleteButton = new JButton(deleteIcon); deleteButton.setContentAreaFilled(false); deleteButton.setBorder(null); deleteButton.setMargin(buttonInset); // Adds buttons to the panel buttonPanel.add(replaceButton); buttonPanel.add(deleteButton); } // add the button panel to the global panel panel.add(buttonPanel, BorderLayout.WEST); } } return panel; } /** * Calculation of the button side size according to the size of the list. * The side is equal to the height of a line of the list. * @param list the list * @return the size of a side */ private int getSide (JList list) { return (list.getHeight() / list.getModel().getSize()); } @Override public void removeCustomComboBoxListener( CustomComboBoxListener customComboBoxListener) { listenerList.remove(customComboBoxListener); } }