Java tutorial
/* * 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()); } } }