/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.biolegato.sequence.canvas; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import java.util.Arrays; import java.util.Scanner; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTextField; import org.biolegato.sequence.data.DataFormat; import org.biolegato.sequence.data.Dataset; import org.biolegato.sequence.data.SequenceWindow; /** * The JList of sequences in the Sequence canvas (to the left of the text-area). ** * @author Graham Alvare * @author Brian Fristensky */ public final class SequenceList extends JList implements SequenceCanvasObject { /** * The last time the mouse was clicked (used for double click detection). */ private long lastClickTime = -1000; /** * The entry (i.e. sequence) selected on the last click. */ private int lastClickEntry = -1; /** * Self reference (for inner classes). */ private final SequenceList list = this; /** * Used for the relationship between the data model and the list. */ protected Dataset datamodel; /** * Canvas object which owns this SequenceList instance. */ protected SequenceCanvas canvas; /** * The amount of time (ms) between clicks to be considered a double click. */ public static final int DBL_CLICK_TIME = 300; ////////////////// //**************// //* MENU ITEMS *// //**************// ////////////////// /** * The menu item "Select group" */ public final AbstractAction selectGroupAction = new AbstractAction("Select group") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622776157L; /** * Sets the mnemonic for the event. */ { putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_S)); } /** * Event handler - selects all items within the same group as the * sequence selected by the user (if more than one group was selected, * then use the first sequence in the sequence list's group. ** * @param evt ignored by this method. */ public void actionPerformed(java.awt.event.ActionEvent evt) { int[] group = null; for (int index : getSelectedIndices()) { // getLine the currently selected sequence group = datamodel.getgroup(index); if (group != null) { // set the selection indicies setSelectedIndices(group); } } } }; /** * The menu item "Get info..." */ public final AbstractAction getInfoAction = new AbstractAction("Get info...") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622776157L; /** * Sets the mnemonic for the event. */ { putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_G)); } /** * Event handler - display a sequence information window for the * sequences selected. ** * @param evt ignored by this method. */ public void actionPerformed(java.awt.event.ActionEvent evt) { if (!isSelectionEmpty()) { new SequenceWindow(canvas, datamodel, canvas.getJFrame(), getSelectedIndices()).setVisible(true); // see Bugzilla #1201 - GetInfo - Colourmask: new colours don't display // Only part of the SequenceTextArea is repainted. You have to // perform an action like resizing or scrolling to get the entire // SequenceTextArea to repaint. // I'd think repainting at this point would fix, it but apparently // not. Could this be a bug in Java? //canvas.repaint(); } } }; /** * The menu item "Delete" */ private final AbstractAction deleteAction = new AbstractAction("Delete") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622776157L; /** * Sets the mnemonic for the event. */ { putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_D)); } /** * Event handler - deletes the sequences selected. ** * @param evt ignored by this method. */ public void actionPerformed(java.awt.event.ActionEvent evt) { deleteSelection(); } }; /** * The menu item "Select All" */ public final AbstractAction selectAllAction = new AbstractAction("Select All") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622777033L; /** * Sets the mnemonic for the event. */ { putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_A)); } /** * Event handler - select all of the sequences in the canvas. ** * @param evt ignored by this method. */ public void actionPerformed(java.awt.event.ActionEvent evt) { list.setSelectionInterval(0, datamodel.getSize() - 1); list.requestFocus(); } }; /** * The abstract action "Select sequence by name" */ public final AbstractAction selectByNameAction = new AbstractAction("Select sequence by name") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622777033L; /** * Sets the mnemonic for the event. */ { putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_S)); } /** * Event handler - open a window to select, or deselect sequences in the * canvas by sequence-name. ** * @param evt ignored by this method. */ public void actionPerformed(java.awt.event.ActionEvent evt) { // Request focus for the canvas window. list.requestFocus(); list.requestFocusInWindow(); // The actual select by name window. final JDialog window = new JDialog(canvas.getJFrame(), "Select by name"); // Used for obtaining the name to search for. final JTextField nameSelector = new JTextField(); // The button used to select the sequences based on their name. final Action selectAction = new AbstractAction("Select") { /** * Event handler - deselect sequences in the canvas by name, * when clicked. ** * @param evt ignored by this method. */ public void actionPerformed(ActionEvent e) { // The text to search for when selecting or deselecting. String test = nameSelector.getText().toLowerCase(); // Select the sequences based on name. for (int count = 0; count < datamodel.getSize(); count ++) { if (datamodel.getElementAt(count).toString( ).toLowerCase().contains(test)) { list.addSelectionInterval(count, count); } } } }; // The button used to deselect the sequences based on their name. final Action deselectAction = new AbstractAction("Deselect") { /** * Event handler - select sequences in the canvas by name, * when clicked. ** * @param evt ignored by this method. */ public void actionPerformed(ActionEvent e) { // The text to search for when selecting or deselecting. String test = nameSelector.getText().toLowerCase(); // Deselect the sequences based on name. for (int count = 0; count < datamodel.getSize(); count ++) { if (datamodel.getElementAt(count).toString( ).toLowerCase().contains(test)) { list.removeSelectionInterval(count, count); } } } }; // The button used to close the select or deselect by name window. final Action closeAction = new AbstractAction("Close") { /** * Event handler - close the select/deselect by name window. ** * @param evt ignored by this method. */ public void actionPerformed(ActionEvent e) { window.dispose(); } }; // create the main panel Box mainPanel = new Box(BoxLayout.PAGE_AXIS); // create a panel for entering the name to search for Box entryPanel = new Box(BoxLayout.LINE_AXIS); entryPanel.add(new JLabel("Name:")); entryPanel.add(nameSelector); mainPanel.add(entryPanel); // create a panel to contain all of the buttons Box buttonPanel = new Box(BoxLayout.LINE_AXIS); buttonPanel.add(new JButton(selectAction)); buttonPanel.add(new JButton(deselectAction)); buttonPanel.add(new JButton(closeAction)); mainPanel.add(buttonPanel); // configure the name textbox button nameSelector.addActionListener(selectAction); // display the window window.add(mainPanel); window.pack(); window.setLocationRelativeTo(canvas.getJFrame()); window.setVisible(true); window.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); } }; /** * Action for grouping sequences in the canvas */ public final AbstractAction groupAction = new AbstractAction("Group") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622777032L; /** * Event handler - group the sequences. ** * @param evt ignored by this method. */ public void actionPerformed(ActionEvent e) { datamodel.group(list.getSelectedIndices()); } }; /** * Action for ungrouping/degrouping sequences in the canvas */ public final AbstractAction ungroupAction = new AbstractAction("Ungroup") { /** * Serialization number - required for no warnings. */ private static final long serialVersionUID = 7526472295622777032L; /** * Event handler - ungroup the sequences. ** * @param evt ignored by this method. */ public void actionPerformed(ActionEvent e) { datamodel.ungroup(list.getSelectedIndices()); } }; /** * The right click menu for the Sequence sequence list. */ protected final JPopupMenu popup = new JPopupMenu(); /** * The mouse adapter to handle mouse clicks for the list's popup menu */ private final MouseAdapter popupMouseAdapter = new MouseAdapter() { /** * Checks for double clicks. On a double click, this method opens * up a sequence properties window. ** * @param event the mouse event to check for the double click. */ @Override public void mouseClicked(MouseEvent event) { // If double click select the entire group. if (event.getClickCount() > 2 || (getSelectedIndex() == lastClickEntry && event.getWhen() - lastClickTime < DBL_CLICK_TIME)) { selectGroupAction.actionPerformed(null); } // Update the last selected sequence and last time clicked // counter/trracker variables. lastClickTime = event.getWhen(); lastClickEntry = getSelectedIndex(); } /** * Checks for right clicks. On a right click, this method opens * up a popup menu. This is the same method as: mousePressed. ** * @param event the mouse event to check for the right click. */ @Override public void mousePressed(MouseEvent event) { if (event.isPopupTrigger()) { popup.show(event.getComponent(), event.getX() - getX(), event.getY() - getY()); } } /** * Checks for right clicks. On a right click, this method opens * up a popup menu. This is the same method as: mouseReleased. ** * @param event the mouse event to check for the right click. */ @Override public void mouseReleased(MouseEvent event) { if (event.isPopupTrigger()) { popup.show(event.getComponent(), event.getX() - getX(), event.getY() - getY()); } } }; /** * Used in serialization. */ private static final long serialVersionUID = 7526472295622777009L; /////////////////////// //*******************// //** CLASS METHODS **// //*******************// /////////////////////// /** * Constructs a new SequenceList ** * @param canvas the sequence canvas parent to the sequence list object. * @param datamodel the data model object storing the sequence data. */ public SequenceList(SequenceCanvas canvas, Dataset datamodel) { super(datamodel); // initialize variables this.datamodel = datamodel; this.canvas = canvas; // Add the menu items to the pop-up items. // First, handle the read only property (i.e. prevent any // possible data manipulation if editable is set to false!) if (canvas.editable) { // add all of the canvas actions to the popup menu popup.add(new JMenuItem(canvas.cutAct)); popup.add(new JMenuItem(canvas.copyAct)); popup.add(new JMenuItem(canvas.pasteAct)); popup.add(new JMenuItem(deleteAction)); } popup.add(new JMenuItem(groupAction)); popup.add(new JMenuItem(ungroupAction)); popup.add(new JMenuItem(selectAllAction)); popup.add(new JMenuItem(selectGroupAction)); popup.add(new JMenuItem(selectByNameAction)); popup.add(new JMenuItem(getInfoAction)); // Add the menu item listeners. addMouseListener(popupMouseAdapter); // Set the display properties. setForeground(Color.BLACK); setBackground(new Color(255, 255, 240)); setSize(getPreferredSize()); setFont(canvas.currentFont); setFixedCellHeight(getFontMetrics(canvas.currentFont).getHeight()); repaint(); } /** *
xYzJWwa23 --- will become ---> WYZJWWA23