/******************************************************************************* * 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.controlPanel; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JOptionPane; import javax.swing.JPanel; import edu.yu.einstein.genplay.core.manager.project.ProjectManager; import edu.yu.einstein.genplay.core.manager.project.ProjectWindow; import edu.yu.einstein.genplay.core.multiGenome.data.synchronization.MGSOffset; import edu.yu.einstein.genplay.core.multiGenome.utils.FormattedMultiGenomeName; import edu.yu.einstein.genplay.core.multiGenome.utils.ShiftCompute; import edu.yu.einstein.genplay.core.parser.genomeWindowParser.GenomeWindowInputHandler; import edu.yu.einstein.genplay.dataStructure.chromosome.Chromosome; import edu.yu.einstein.genplay.dataStructure.enums.AlleleType; import edu.yu.einstein.genplay.dataStructure.enums.CoordinateSystemType; import edu.yu.einstein.genplay.dataStructure.genomeWindow.GenomeWindow; import edu.yu.einstein.genplay.dataStructure.genomeWindow.SimpleGenomeWindow; import edu.yu.einstein.genplay.dataStructure.gwBookmark.GWBookmark; import edu.yu.einstein.genplay.gui.MGDisplaySettings.MGDisplaySettings; import edu.yu.einstein.genplay.gui.action.project.PABookmarkCurrentPosition; import edu.yu.einstein.genplay.gui.event.genomeWindowEvent.GenomeWindowEvent; import edu.yu.einstein.genplay.gui.event.genomeWindowEvent.GenomeWindowListener; import edu.yu.einstein.genplay.gui.mainFrame.MainFrame; import edu.yu.einstein.genplay.util.Images; import edu.yu.einstein.genplay.util.NumberFormats; /** * The GenomeWindowPanel part of the {@link ControlPanel} * @author Julien Lajugie * @version 0.1 */ final class GenomeWindowPanel extends JPanel implements GenomeWindowListener { private static final long serialVersionUID = 8279801687428218652L; // generated ID private static final int GENOME_WINDOW_COMBO_WIDTH = 415; // width of the genome window combobox private final JComboBox jcbGenomeWindow; // combobox the GenomeWindow private final JButton jbJump; // button jump to position private final JComboBox jcbGenomeSelection; // combobox to select a genome in multi-genome project private final JButton jbBookmark; // button to add current position to bookmark private final ProjectWindow projectWindow; // Instance of the Genome Window Manager /** * Creates an instance of {@link GenomeWindowPanel} * @param genomeWindow a {@link GenomeWindow} */ GenomeWindowPanel() { projectWindow = ProjectManager.getInstance().getProjectWindow(); // Create the genome window (positions) text field jcbGenomeWindow = new JComboBox(); initGenomeWindowCombo(); // Create the "jump" button jbJump = new JButton(); jbJump.setIcon(new ImageIcon(Images.getJumpImage())); jbJump.setRolloverIcon(new ImageIcon(Images.getJumpRolledOverImage())); jbJump.setDisabledIcon(new ImageIcon(Images.getJumpDisabledImage())); jbJump.setBorderPainted(false); jbJump.setFocusPainted(false); jbJump.setMargin(new Insets(0, 0, 0, 0)); jbJump.setContentAreaFilled(false); jbJump.setPreferredSize(new Dimension(24, 24)); jbJump.setMinimumSize(new Dimension(24, 24)); jbJump.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateGenomeWindow(); } }); // Create the genome coordinate selector if (ProjectManager.getInstance().isMultiGenomeProject()) { Object[] genomes = new Object[2]; genomes[0] = CoordinateSystemType.METAGENOME.toString(); genomes[1] = CoordinateSystemType.REFERENCE.toString(); jcbGenomeSelection = new JComboBox(genomes); jcbGenomeSelection.setSelectedIndex(0); jcbGenomeSelection.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { Object object = ((JComboBox) arg0.getSource()).getSelectedItem(); if (object != null) { MainFrame.getInstance().setNewGenomeCoordinate(object.toString()); } } }); } else { jcbGenomeSelection = null; } jbBookmark = new JButton(); // update the combobox with the bookmarks when a bookmark is added jbBookmark.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateBookmarkDropdownList(); } }); jbBookmark.addActionListener(new PABookmarkCurrentPosition()); jbBookmark.setBorderPainted(false); jbBookmark.setMargin(new Insets(0, 0, 0, 0)); jbBookmark.setContentAreaFilled(false); jbBookmark.setFocusPainted(false); jbBookmark.setHideActionText(true); jbBookmark.setPreferredSize(new Dimension(24, 24)); jbBookmark.setMinimumSize(new Dimension(24, 24)); jbBookmark.setIcon(new ImageIcon(Images.getBookmarkImage())); jbBookmark.setRolloverIcon(new ImageIcon(Images.getBookmarkRolledOverImage())); jbBookmark.setDisabledIcon(new ImageIcon(Images.getBookmarkDisabledImage())); // Add the components setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); // Add the the genome window text field gbc.anchor = GridBagConstraints.PAGE_END; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 0; gbc.gridx = 0; gbc.gridy = 0; add(jcbGenomeWindow, gbc); // Add the jump button gbc.fill = GridBagConstraints.NONE; gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 0; add(jbJump, gbc); gbc.fill = GridBagConstraints.NONE; gbc.gridx = 2; gbc.gridy = 0; add(jbBookmark, gbc); // Add the genome coordinate selector if (jcbGenomeSelection != null) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.gridy = 1; add(jcbGenomeSelection, gbc); } setOpaque(false); } @Override public void genomeWindowChanged(GenomeWindowEvent evt) { updateGenomeWindowField(evt.getNewWindow()); } /** * @return the newly defined genome window */ private GenomeWindow getGenomeWindow () { GenomeWindowInputHandler handler; if (jcbGenomeWindow.getSelectedItem() instanceof GWBookmark) { return ((GWBookmark) jcbGenomeWindow.getSelectedItem()).getGenomeWindow(); } else { handler = new GenomeWindowInputHandler((String) jcbGenomeWindow.getSelectedItem()); GenomeWindow newGenomeWindow = handler.getGenomeWindow(); if (newGenomeWindow != null) { String outputGenome = CoordinateSystemType.METAGENOME.toString(); String genomeName = FormattedMultiGenomeName.getFullNameWithoutAllele(MGDisplaySettings.SELECTED_GENOME); AlleleType inputAlleleType = FormattedMultiGenomeName.getAlleleName(MGDisplaySettings.SELECTED_GENOME); int start = ShiftCompute.getPosition(genomeName, inputAlleleType, newGenomeWindow.getStart(), newGenomeWindow.getChromosome(), outputGenome); int stop = ShiftCompute.getPosition(genomeName, inputAlleleType, newGenomeWindow.getStop(), newGenomeWindow.getChromosome(), outputGenome); newGenomeWindow = new SimpleGenomeWindow(newGenomeWindow.getChromosome(), start, stop); } return newGenomeWindow; } } /** * @return the button to jump on a genomic position */ public JButton getJumpButton() { return jbJump; } /** * Initialized the combo box for the genome window address */ public void initGenomeWindowCombo() { jcbGenomeWindow.setPreferredSize(new Dimension(GENOME_WINDOW_COMBO_WIDTH, jcbGenomeWindow.getPreferredSize().height)); jcbGenomeWindow.setMinimumSize(new Dimension(GENOME_WINDOW_COMBO_WIDTH, jcbGenomeWindow.getMinimumSize().height)); jcbGenomeWindow.setEditable(true); jcbGenomeWindow.setPrototypeDisplayValue(new GWBookmark(projectWindow.getGenomeWindow().toString(), projectWindow.getGenomeWindow())); jcbGenomeWindow.setSelectedItem(projectWindow.getGenomeWindow().toString()); jcbGenomeWindow.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (jcbGenomeWindow.getSelectedItem() instanceof GWBookmark) { GWBookmark selectedBookmark = (GWBookmark) jcbGenomeWindow.getSelectedItem(); if ((e.getModifiers() & ActionEvent.ALT_MASK) != 0) { // remove bookmark ProjectManager.getInstance().getProjectBookmarks().remove(selectedBookmark); updateBookmarkDropdownList(); } else { // goto bookmark if (jcbGenomeSelection != null) { MainFrame.getInstance().setNewGenomeCoordinate(CoordinateSystemType.METAGENOME.toString()); } jcbGenomeWindow.setSelectedItem(selectedBookmark.getGenomeWindow().toString()); updateGenomeWindow(); if (jcbGenomeSelection != null) { MainFrame.getInstance().setNewGenomeCoordinate(selectedBookmark.getGenomeName()); } } } } }); updateBookmarkDropdownList(); } /** * @param genomeNames genome names to add to the genome selector (multi genome only) */ public void resetGenomeNames (List<String> genomeNames) { jcbGenomeSelection.removeAllItems(); jcbGenomeSelection.addItem(CoordinateSystemType.METAGENOME.toString()); jcbGenomeSelection.addItem(CoordinateSystemType.REFERENCE.toString()); int width = getFontMetrics(getFont()).stringWidth(CoordinateSystemType.REFERENCE.toString()); if (genomeNames != null) { for (String genomeName: genomeNames) { String name01 = FormattedMultiGenomeName.getFullNameWithAllele(genomeName, AlleleType.ALLELE01); String name02 = FormattedMultiGenomeName.getFullNameWithAllele(genomeName, AlleleType.ALLELE02); width = Math.max(width, getFontMetrics(getFont()).stringWidth(name01)); jcbGenomeSelection.addItem(name01); jcbGenomeSelection.addItem(name02); } } } /** * Enables or disables the genome window panel * @param b a boolean value, where true enables the component and false disables it */ public void setEnaled(boolean b) { jcbGenomeWindow.setEnabled(b); jbJump.setEnabled(b); jbBookmark.setEnabled(b); if (jcbGenomeSelection != null) { jcbGenomeSelection.setEnabled(b); } super.setEnabled(b); } /** * @param genomeName genome name to select in the genome selector (multi genome only) */ public void setSelectedGenomeName (String genomeName) { jcbGenomeSelection.setSelectedItem(genomeName); updateGenomeWindowField(ProjectManager.getInstance().getProjectWindow().getGenomeWindow()); } /** * Updates the list with the items in the bookmark combobox */ private void updateBookmarkDropdownList() { jcbGenomeWindow.removeAllItems(); jcbGenomeWindow.setSelectedItem(projectWindow.getGenomeWindow().toString()); List<GWBookmark> bookmarks = ProjectManager.getInstance().getProjectBookmarks(); for (GWBookmark currentBookmark: bookmarks) { jcbGenomeWindow.addItem(currentBookmark); } } /** * Called when the current {@link GenomeWindow} changes */ void updateGenomeWindow() { GenomeWindow newGenomeWindow = getGenomeWindow(); if (newGenomeWindow == null) { JOptionPane.showMessageDialog(getRootPane(), "Invalid position", "Error", JOptionPane.WARNING_MESSAGE, null); } else if (!newGenomeWindow.equals(projectWindow.getGenomeWindow())) { int middlePosition = (int)newGenomeWindow.getMiddlePosition(); if ((middlePosition < 1) || (middlePosition > newGenomeWindow.getChromosome().getLength())) { JOptionPane.showMessageDialog(getRootPane(), "Invalid position", "Error", JOptionPane.WARNING_MESSAGE, null); } else { projectWindow.setGenomeWindow(newGenomeWindow); updateGenomeWindowField(newGenomeWindow); } } } /** * Actual method when the genome window has changed. * @param genomeWindow the new genome window */ private void updateGenomeWindowField(GenomeWindow genomeWindow) { String text = genomeWindow.toString(); if (ProjectManager.getInstance().isMultiGenomeProject()) { Chromosome currentChromosome = projectWindow.getGenomeWindow().getChromosome(); String genomeName = FormattedMultiGenomeName.getFullNameWithoutAllele(MGDisplaySettings.SELECTED_GENOME); AlleleType inputAlleleType = FormattedMultiGenomeName.getAlleleName(MGDisplaySettings.SELECTED_GENOME); int positionStart = ShiftCompute.getPosition(FormattedMultiGenomeName.META_GENOME_NAME, inputAlleleType, genomeWindow.getStart(), currentChromosome, genomeName); int positionStop = ShiftCompute.getPosition(FormattedMultiGenomeName.META_GENOME_NAME, inputAlleleType, genomeWindow.getStop(), currentChromosome, genomeName); String positionStartStr, positionStopStr; if (positionStart == MGSOffset.MISSING_POSITION_CODE) { positionStartStr = "Insertion"; } else { positionStartStr = NumberFormats.getPositionFormat().format(positionStart); } if (positionStop == MGSOffset.MISSING_POSITION_CODE) { positionStopStr = "Insertion"; } else { positionStopStr = NumberFormats.getPositionFormat().format(positionStop); } text = currentChromosome.toString() + ":" + positionStartStr + "-" + positionStopStr; } jcbGenomeWindow.setSelectedItem(text); } }