org.eurocarbdb.application.glycoworkbench.plugin.PeakAnnotationCalibrationPanel.java Source code

Java tutorial

Introduction

Here is the source code for org.eurocarbdb.application.glycoworkbench.plugin.PeakAnnotationCalibrationPanel.java

Source

/*
*   EuroCarbDB, a framework for carbohydrate bioinformatics
*
*   Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as
*   indicated by the @author tags or express copyright attribution
*   statements applied by the authors.  
*
*   This copyrighted material is made available to anyone wishing to use, modify,
*   copy, or redistribute it subject to the terms and conditions of the GNU
*   Lesser General Public License, as published by the Free Software Foundation.
*   A copy of this license accompanies this distribution in the file LICENSE.txt.
*
*   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 Lesser General Public License
*   for more details.
*
*   Last commit: $Rev: 1930 $ by $Author: david@nixbioinf.org $ on $Date:: 2010-07-29 #$  
*/
/**
   @author Alessio Ceroni (a.ceroni@imperial.ac.uk)
*/

package org.eurocarbdb.application.glycoworkbench.plugin;

import org.eurocarbdb.application.glycanbuilder.*;

import org.eurocarbdb.application.glycoworkbench.*;

import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.print.PrinterJob;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartPanel;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.data.Range;
import org.jfree.chart.plot.XYPlot;

public class PeakAnnotationCalibrationPanel extends DocumentPanel<AnnotatedPeakList> implements ActionListener,
        ComponentListener, GlycanWorkspace.Listener, BaseDocument.DocumentChangeListener {

    private static final int MOD_MASK = MouseEvent.CTRL_MASK | MouseEvent.SHIFT_MASK | MouseEvent.ALT_MASK
            | MouseEvent.META_MASK | MouseEvent.ALT_GRAPH_MASK;

    // components

    protected JLabel theStructure;

    protected DefaultXYDataset theDataset;
    protected XYPlot thePlot;
    protected JFreeChart theChart;
    protected ChartPanel theChartPanel;

    protected JToolBar theToolBarDocument;
    protected JToolBar theToolBarEdit;

    // data
    protected int current_ind = 0;
    protected String accuracy_unit;

    // actions    

    protected JButton accunit_button = null;

    protected boolean was_moving = false;
    protected boolean is_moving = false;
    protected Point2D mouse_start_point = null;
    protected Cursor hand_cursor = null;

    //

    public PeakAnnotationCalibrationPanel() {
        super();
    }

    protected void initSingletons() {
        super.initSingletons();
        accuracy_unit = "da";
    }

    protected void initComponents() {
        setLayout(new BorderLayout());

        // create structure viewer    
        theStructure = new JLabel();
        theStructure.setBorder(new BevelBorder(BevelBorder.RAISED));
        add(theStructure, BorderLayout.NORTH);

        // create chart
        theDataset = new DefaultXYDataset();
        theChart = org.jfree.chart.ChartFactory.createScatterPlot("Calibration", "m/z ratio", "accuracy (Da)",
                theDataset, org.jfree.chart.plot.PlotOrientation.VERTICAL, true, false, false);
        thePlot = (XYPlot) theChart.getPlot();
        theChartPanel = new ChartPanel(theChart);
        theChartPanel.setDomainZoomable(true);
        theChartPanel.setRangeZoomable(true);
        theChartPanel.setPopupMenu(null);
        add(theChartPanel, BorderLayout.CENTER);

        // create toolbar
        JPanel theToolBarPanel = new JPanel(new BorderLayout());
        theToolBarDocument = createToolBarDocument();
        theToolBarEdit = createToolBarEdit();
        theToolBarPanel.add(theToolBarDocument, BorderLayout.NORTH);
        theToolBarPanel.add(theToolBarEdit, BorderLayout.CENTER);
        add(theToolBarPanel, BorderLayout.SOUTH);

        // load cursors
        hand_cursor = FileUtils.createCursor("hand");
    }

    protected void finalSettings() {
        super.finalSettings();

        theChartPanel.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                onMouseDragged(e);
            }
        });

        theChartPanel.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                onMousePressed(e);
            }

            public void mouseReleased(MouseEvent e) {
                onMouseReleased(e);
            }

            public void mouseClicked(MouseEvent e) {
                onMouseClicked(e);
            }
        });
    }

    public AnnotatedPeakList getDocumentFromWorkspace(GlycanWorkspace workspace) {
        return (workspace != null) ? workspace.getAnnotatedPeakList() : null;
    }

    public void setDocumentFromWorkspace(GlycanWorkspace workspace) {
        if (theDocument != null)
            theDocument.removeDocumentChangeListener(this);

        theDocument = getDocumentFromWorkspace(workspace);
        if (theDocument == null)
            theDocument = new AnnotatedPeakList();

        theDocument.addDocumentChangeListener(this);

        current_ind = 0;
        updateView();
        updateActions();
    }

    protected void createActions() {
        theActionManager.add("accunit=da", FileUtils.defaultThemeManager.getImageIcon("da"), "Show accuracy in Da",
                -1, "", this);
        theActionManager.add("accunit=ppm", FileUtils.defaultThemeManager.getImageIcon("ppm"),
                "Show accuracy in PPM", -1, "", this);

        theActionManager.add("new", FileUtils.defaultThemeManager.getImageIcon("new"), "Clear", KeyEvent.VK_N, "",
                this);

        theActionManager.add("close", FileUtils.defaultThemeManager.getImageIcon("close"), "Close structure",
                KeyEvent.VK_S, "", this);
        theActionManager.add("last", FileUtils.defaultThemeManager.getImageIcon("last"), "Last structure",
                KeyEvent.VK_L, "", this);
        theActionManager.add("next", FileUtils.defaultThemeManager.getImageIcon("next"), "Next structure",
                KeyEvent.VK_N, "", this);

        theActionManager.add("print", FileUtils.defaultThemeManager.getImageIcon("print"), "Print...",
                KeyEvent.VK_P, "", this);

        //theActionManager.add("undo",FileUtils.defaultThemeManager.getImageIcon("undo"),"Undo",KeyEvent.VK_U, "",this);
        //theActionManager.add("redo",FileUtils.defaultThemeManager.getImageIcon("redo"),"Redo", KeyEvent.VK_R, "",this);

        theActionManager.add("arrow", FileUtils.defaultThemeManager.getImageIcon("arrow"), "Activate zoom", -1, "",
                this);
        theActionManager.add("hand", FileUtils.defaultThemeManager.getImageIcon("hand"), "Activate moving", -1, "",
                this);

        theActionManager.add("zoomnone", FileUtils.defaultThemeManager.getImageIcon("zoomnone"), "Reset zoom", -1,
                "", this);
        theActionManager.add("zoomin", FileUtils.defaultThemeManager.getImageIcon("zoomin"), "Zoom in", -1, "",
                this);
        theActionManager.add("zoomout", FileUtils.defaultThemeManager.getImageIcon("zoomout"), "Zoom out", -1, "",
                this);
    }

    protected void updateActions() {
        theActionManager.get("close").setEnabled(theDocument.getNoStructures() != 0);
        theActionManager.get("last").setEnabled(current_ind > 0);
        theActionManager.get("next").setEnabled(current_ind < (theDocument.getNoStructures() - 1));

        //theActionManager.get("undo").setEnabled(theDocument.getUndoManager().canUndo());
        //theActionManager.get("redo").setEnabled(theDocument.getUndoManager().canRedo());

        theActionManager.get("arrow").setEnabled(is_moving);
        theActionManager.get("hand").setEnabled(!is_moving);

        theActionManager.get("zoomnone").setEnabled(true);
        theActionManager.get("zoomin").setEnabled(true);
        theActionManager.get("zoomout").setEnabled(true);
    }

    private JToolBar createToolBarDocument() {
        JToolBar toolbar = new JToolBar();
        toolbar.setFloatable(false);

        toolbar.add(theActionManager.get("last"));
        toolbar.add(theActionManager.get("close"));
        toolbar.add(theActionManager.get("next"));

        toolbar.addSeparator();

        toolbar.add(accunit_button = new JButton(theActionManager.get("accunit=ppm")));
        accunit_button.setText(null);
        toolbar.add(theActionManager.get("new"));

        toolbar.addSeparator();

        toolbar.add(theActionManager.get("print"));

        //toolbar.addSeparator();

        //toolbar.add(theActionManager.get("undo"));
        //toolbar.add(theActionManager.get("redo"));

        return toolbar;
    }

    private JToolBar createToolBarEdit() {
        JToolBar toolbar = new JToolBar();
        toolbar.setFloatable(false);

        toolbar.addSeparator();

        toolbar.add(theActionManager.get("arrow"));
        toolbar.add(theActionManager.get("hand"));

        toolbar.addSeparator();

        toolbar.add(theActionManager.get("zoomnone"));
        toolbar.add(theActionManager.get("zoomin"));
        toolbar.add(theActionManager.get("zoomout"));

        return toolbar;
    }

    protected JPopupMenu createPopupMenu() {

        JPopupMenu menu = new JPopupMenu();

        menu.add(theActionManager.get("zoomnone"));
        menu.add(theActionManager.get("zoomin"));
        menu.add(theActionManager.get("zoomout"));

        return menu;
    }

    //-----------------
    // data

    public boolean isChartEmpty() {
        return (theDocument.getNoStructures() == 0 || theDocument.getNoAnnotatedPeaks(current_ind) == 0);
    }

    public double screenToDataX(double length) {
        Rectangle2D data_area = theChartPanel.getScreenDataArea();
        double mz_unit = thePlot.getDomainAxis().lengthToJava2D(1., data_area, thePlot.getDomainAxisEdge());
        return length / mz_unit;
    }

    public double screenToDataY(double length) {
        Rectangle2D data_area = theChartPanel.getScreenDataArea();
        double int_unit = thePlot.getRangeAxis().lengthToJava2D(1., data_area, thePlot.getRangeAxisEdge());
        return length / int_unit;
    }

    public Point2D screenToDataCoords(Point2D p) {

        Rectangle2D data_area = theChartPanel.getScreenDataArea();
        double x = thePlot.getDomainAxis().java2DToValue(p.getX(), data_area, thePlot.getDomainAxisEdge());
        double y = thePlot.getRangeAxis().java2DToValue(p.getY(), data_area, thePlot.getRangeAxisEdge());
        return new Point2D.Double(x, y);
    }

    public double screenToDataCoordX(double x) {
        Rectangle2D data_area = theChartPanel.getScreenDataArea();
        return thePlot.getDomainAxis().java2DToValue(x, data_area, thePlot.getDomainAxisEdge());
    }

    public double screenToDataCoordY(double y) {
        Rectangle2D data_area = theChartPanel.getScreenDataArea();
        return thePlot.getRangeAxis().java2DToValue(y, data_area, thePlot.getRangeAxisEdge());
    }

    public void clear() {
        current_ind = 0;
        theDocument.clear();
    }

    //-----------
    // Visualization

    protected void updateData() {
        current_ind = Math.min(current_ind, theDocument.getNoStructures() - 1);
        current_ind = Math.max(current_ind, 0);
    }

    protected void updateView() {
        if (theStructure != null) {
            if (theDocument.getNoStructures() > 0)
                theStructure.setIcon(new ImageIcon(theWorkspace.getGlycanRenderer()
                        .getImage(theDocument.getStructure(current_ind), false, true, true, 0.667)));
            else
                theStructure.setIcon(null);
        }

        // update data
        if (theDocument.getNoStructures() > 0) {
            theDataset.removeSeries("best");
            theDataset.removeSeries("all");
            if (accuracy_unit.equals("ppm")) {
                theDataset.addSeries("best", theDocument.getBestCalibrationDataPPM(current_ind));
                theDataset.addSeries("all", theDocument.getCalibrationDataPPM(current_ind));
            } else {
                theDataset.addSeries("best", theDocument.getBestCalibrationData(current_ind));
                theDataset.addSeries("all", theDocument.getCalibrationData(current_ind));
            }
        }

        // update axis
        if (accuracy_unit.equals("ppm"))
            thePlot.getRangeAxis().setLabel("accuracy (PPM)");
        else
            thePlot.getRangeAxis().setLabel("accuracy (Da)");

        theChartPanel.setDomainZoomable(!is_moving);
        theChartPanel.setRangeZoomable(!is_moving);

        onZoomNone();
    }

    //-----------------
    // actions    

    public void closeCurrent() {
        if (theDocument.getNoStructures() > 0) {
            int old_ind = current_ind;
            current_ind = Math.min(current_ind, theDocument.getNoStructures() - 2);
            current_ind = Math.max(current_ind, 0);

            // long action
            theApplication.haltInteractions();
            theDocument.removePeakAnnotationsAt(old_ind);
            theApplication.restoreInteractions();
        }
    }

    public void showLast() {
        if (theDocument.getNoStructures() > 0 && current_ind > 0) {
            current_ind--;
            updateView();
        }
    }

    public void showNext() {
        if (theDocument.getNoStructures() > 0 && current_ind < (theDocument.getNoStructures() - 1)) {
            current_ind++;
            updateView();
        }
    }

    public void showStructure(int s_ind) {
        if (s_ind >= 0 && s_ind < theDocument.getNoStructures()) {
            current_ind = s_ind;
            updateView();
        }
    }

    public void onNew() {
        clear();
    }

    public void onPrint() {
        PrinterJob pj = theWorkspace.getPrinterJob();
        if (pj == null)
            return;

        try {
            pj.setPrintable(theChartPanel);
            if (pj.printDialog())
                pj.print();
        } catch (Exception e) {
            LogUtils.report(e);
        }
    }

    /*public void onUndo()  {
    try {
    theDocument.getUndoManager().undo();
    }
    catch(Exception e) {
    LogUtils.report(e);
    }
    }
        
    public void onRedo()  {
    try {
    theDocument.getUndoManager().redo();
    }
    catch(Exception e) {
    LogUtils.report(e);
    }
    } 
    */

    public void onActivateZooming() {
        is_moving = false;
        theChartPanel.setCursor(Cursor.getDefaultCursor());
        theChartPanel.setDomainZoomable(true);
        theChartPanel.setRangeZoomable(true);
    }

    public void onActivateMoving() {
        is_moving = true;
        theChartPanel.setCursor(hand_cursor);
        theChartPanel.setRangeZoomable(false);
        theChartPanel.setDomainZoomable(false);
    }

    public void onZoomNone() {
        if (!isChartEmpty()) {
            Range mz_range = theDocument.getMZRange();
            if (mz_range.getLength() == 0.)
                mz_range = new Range(mz_range.getLowerBound() - 10, mz_range.getLowerBound() + 10);
            thePlot.getDomainAxis().setRange(mz_range);

            if (accuracy_unit.equals("da")) {
                Range acc_range = theDocument.getAccuracyRange(current_ind);
                if (acc_range.getLength() == 0.)
                    acc_range = new Range(acc_range.getLowerBound() - 0.1, acc_range.getLowerBound() + 0.1);
                thePlot.getRangeAxis().setRange(acc_range);
            } else {
                Range acc_range = theDocument.getAccuracyRangePPM(current_ind);
                if (acc_range.getLength() == 0.)
                    acc_range = new Range(acc_range.getLowerBound() - 100, acc_range.getLowerBound() + 100);
                thePlot.getRangeAxis().setRange(acc_range);
            }
        } else {
            thePlot.getDomainAxis().setRange(new Range(0., 1.));
            if (accuracy_unit.equals("da"))
                thePlot.getRangeAxis().setRange(new Range(-1., 1.));
            else
                thePlot.getRangeAxis().setRange(new Range(-1000., 1000.));
        }
    }

    public void onZoomIn() {
        thePlot.getDomainAxis().resizeRange(0.5);
        thePlot.getRangeAxis().resizeRange(0.5);
    }

    public void onZoomOut() {
        thePlot.getDomainAxis().resizeRange(2.0);
        thePlot.getRangeAxis().resizeRange(2.0);
    }

    public void onSetAccuracyUnit(String accunit) {
        if (accunit.equals("da")) {
            accuracy_unit = "da";
            accunit_button.setAction(theActionManager.get("accunit=ppm"));
            accunit_button.setText(null);
            updateView();
        } else if (accunit.equals("ppm")) {
            accuracy_unit = "ppm";
            accunit_button.setAction(theActionManager.get("accunit=da"));
            accunit_button.setText(null);
            updateView();
        }
    }

    //-----------
    // listeners

    public void actionPerformed(ActionEvent e) {

        String action = GlycanAction.getAction(e);
        String param = GlycanAction.getParam(e);

        if (action.equals("last"))
            showLast();
        else if (action.equals("next"))
            showNext();
        else if (action.equals("close"))
            closeCurrent();

        else if (action.equals("accunit"))
            onSetAccuracyUnit(param);

        else if (action.equals("new"))
            onNew();

        else if (action.equals("print"))
            onPrint();

        /*else if( action.equals("undo") )
            onUndo();
        else if( action.equals("redo") )
            onRedo();
        */

        else if (action.equals("arrow"))
            onActivateZooming();
        else if (action.equals("hand"))
            onActivateMoving();

        else if (action.equals("zoomnone"))
            onZoomNone();
        else if (action.equals("zoomin"))
            onZoomIn();
        else if (action.equals("zoomout"))
            onZoomOut();

        updateActions();
    }

    public void onMousePressed(MouseEvent e) {
        was_moving = is_moving;
        if (e.getButton() == e.BUTTON1 && theChartPanel.getScreenDataArea().contains(e.getPoint())) {
            mouse_start_point = e.getPoint();
            if ((e.getModifiers() & MOD_MASK) == e.SHIFT_MASK)
                onActivateMoving();
        } else
            mouse_start_point = null;
    }

    private void onMouseDragged(MouseEvent e) {
        if (mouse_start_point != null) {
            if (is_moving) {
                // moving
                double mz_delta = screenToDataX(mouse_start_point.getX() - e.getPoint().getX());
                double acc_delta = screenToDataY(e.getPoint().getY() - mouse_start_point.getY());

                // update mz
                if (mz_delta > 0.) {
                    double old_upper_bound = thePlot.getDomainAxis().getUpperBound();
                    double old_lower_bound = thePlot.getDomainAxis().getLowerBound();
                    double new_upper_bound = old_upper_bound + mz_delta;
                    double new_lower_bound = old_lower_bound + new_upper_bound - old_upper_bound;

                    thePlot.getDomainAxis().setRange(new Range(new_lower_bound, new_upper_bound));
                } else {
                    double old_upper_bound = thePlot.getDomainAxis().getUpperBound();
                    double old_lower_bound = thePlot.getDomainAxis().getLowerBound();
                    double new_lower_bound = old_lower_bound + mz_delta;
                    double new_upper_bound = old_upper_bound + new_lower_bound - old_lower_bound;

                    thePlot.getDomainAxis().setRange(new Range(new_lower_bound, new_upper_bound));
                }

                // update acc
                if (acc_delta > 0.) {
                    double old_upper_bound = thePlot.getRangeAxis().getUpperBound();
                    double old_lower_bound = thePlot.getRangeAxis().getLowerBound();
                    double new_upper_bound = old_upper_bound + acc_delta;
                    double new_lower_bound = old_lower_bound + new_upper_bound - old_upper_bound;

                    thePlot.getRangeAxis().setRange(new Range(new_lower_bound, new_upper_bound));
                } else {
                    double old_upper_bound = thePlot.getRangeAxis().getUpperBound();
                    double old_lower_bound = thePlot.getRangeAxis().getLowerBound();
                    double new_lower_bound = old_lower_bound + acc_delta;
                    double new_upper_bound = old_upper_bound + new_lower_bound - old_lower_bound;

                    thePlot.getRangeAxis().setRange(new Range(new_lower_bound, new_upper_bound));
                }

                mouse_start_point = e.getPoint();
            }
        }
    }

    public void onMouseReleased(MouseEvent e) {
        // restore zooming
        if (!was_moving && is_moving)
            onActivateZooming();

        mouse_start_point = null;
    }

    public void onMouseClicked(MouseEvent e) {

        // find peak under mouse
        if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 1
                && (e.getModifiers() & MOD_MASK) == e.BUTTON3_MASK) {
            // open popup
            createPopupMenu().show(theChartPanel, e.getX(), e.getY());
        }
    }

}