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: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$ */ /** @author Alessio Ceroni (a.ceroni@imperial.ac.uk) */ package org.eurocarbdb.application.glycoworkbench.plugin.reporting; import org.eurocarbdb.application.glycoworkbench.plugin.*; import org.eurocarbdb.application.glycoworkbench.*; import org.eurocarbdb.application.glycanbuilder.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.image.*; import java.awt.geom.*; import java.awt.event.*; import java.awt.print.*; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.Plot; import org.jfree.chart.plot.CategoryPlot; import org.jfree.data.general.Dataset; import org.jfree.data.category.CategoryDataset; import org.jfree.chart.renderer.category.CategoryItemRenderer; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.ui.TextAnchor; import static org.eurocarbdb.application.glycanbuilder.Geometry.*; public class ProfilesComparisonReportChartCanvas extends JComponent implements SVGUtils.Renderable, Printable { private static final int DRAW_X_MARGIN = 20; private static final int DRAW_Y_MARGIN = 20; private static final int CHART_X_MARGIN = 20; private static final int CHART_Y_MARGIN = 20; private static final int CHART_WIDTH = 800; private static final int CHART_WIDTH_TICK = 15; private static final int CHART_HEIGHT = 600; private GlycoWorkbench theApplication; private ProfilesComparisonReportDocument theDocument; private GlycanRenderer theGlycanRenderer; private JScrollPane theScrollPane = null; private ProfilesComparisonReportOptions theOptions; private GraphicOptions theGraphicOptions; private CategoryDataset theDataset; private CategoryPlot thePlot; private JFreeChart theChart; // drawing private double scale; private boolean is_printing; private Rectangle view_area; private Rectangle draw_area; private Rectangle chart_area; private Rectangle2D data_area; // construction public ProfilesComparisonReportChartCanvas(GlycoWorkbench application, ProfilesComparisonReportDocument doc, ProfilesComparisonReportOptions opt) { theApplication = application; theDocument = doc; theOptions = opt; theGraphicOptions = theApplication.getWorkspace().getGraphicOptions(); theGlycanRenderer = theApplication.getWorkspace().getGlycanRenderer(); // create chart createChart(); // finish setting up is_printing = false; setScale(1.); } public void setScrollPane(JScrollPane sp) { theScrollPane = sp; } // drawing public void beforeRendering() { is_printing = true; } public void afterRendering() { is_printing = false; } public Dimension getRenderableSize() { return getPreferredSize(); } public void paintRenderable(Graphics2D g2d) { paintComponent(g2d); } protected void paintComponent(Graphics g) { // prepare graphic object Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // set clipping area if (is_printing) { g2d.translate(-draw_area.x, -draw_area.y); g2d.setClip(draw_area); } //paint canvas background if (!is_printing) { g2d.setColor(getBackground()); g2d.fillRect(0, 0, getWidth(), getHeight()); } // paint white background on drawing area g2d.setColor(Color.white); g2d.fillRect(draw_area.x, draw_area.y, draw_area.width, draw_area.height); if (!is_printing) { g2d.setColor(Color.black); g2d.draw(draw_area); } // paint paintChart(g2d); // dispose graphic object g2d.dispose(); revalidate(); } protected void paintChart(Graphics2D g2d) { org.jfree.chart.ChartRenderingInfo cri = new org.jfree.chart.ChartRenderingInfo(); theChart.draw(g2d, chart_area, cri); data_area = cri.getPlotInfo().getDataArea(); } public Dimension getPreferredSize() { if (is_printing) return draw_area.getSize(); return view_area.getSize(); } public Dimension getMinimumSize() { return new Dimension(0, 0); } // actions public void print(PrinterJob job) throws PrinterException { // do something before is_printing = true; job.print(); // do something after is_printing = false; } public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException { if (pageIndex > 0) { return NO_SUCH_PAGE; } else { Graphics2D g2d = (Graphics2D) g; g2d.setBackground(Color.white); g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); Dimension td = this.getPreferredSize(); double sx = pageFormat.getImageableWidth() / td.width; double sy = pageFormat.getImageableHeight() / td.height; double s = Math.min(sx, sy); if (s < 1.) g2d.scale(s, s); RepaintManager.currentManager(this).setDoubleBufferingEnabled(false); this.paint(g2d); RepaintManager.currentManager(this).setDoubleBufferingEnabled(true); return PAGE_EXISTS; } } public void setScale(double scale) { this.scale = scale; updateView(); } public double getScale() { return this.scale; } public void getScreenshot() { ClipUtils.setContents(SVGUtils.getImage(this)); } public void updateView() { updateDrawArea(); repaint(); } private void createChart() { // create dataset theDataset = createDataset(); // create axis CategoryAxis categoryAxis = new CategoryAxis(""); categoryAxis.setCategoryLabelPositions(org.jfree.chart.axis.CategoryLabelPositions.UP_45); ValueAxis valueAxis = new NumberAxis("Normalized Intensities"); // create renderer CategoryItemRenderer renderer = null; if (theOptions.REPRESENTATION == theOptions.BARS) renderer = new org.jfree.chart.renderer.category.BarRenderer(); else if (theOptions.REPRESENTATION == theOptions.ERRORBARS) renderer = new org.jfree.chart.renderer.category.StatisticalBarRenderer(); else if (theOptions.REPRESENTATION == theOptions.DISTRIBUTIONS) renderer = new org.jfree.chart.renderer.category.ScatterRenderer(); ItemLabelPosition position1 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER); renderer.setBasePositiveItemLabelPosition(position1); ItemLabelPosition position2 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER); renderer.setBaseNegativeItemLabelPosition(position2); // create plot thePlot = new CategoryPlot(theDataset, categoryAxis, valueAxis, renderer); thePlot.setOrientation(org.jfree.chart.plot.PlotOrientation.VERTICAL); // add mean values if (theOptions.REPRESENTATION == theOptions.DISTRIBUTIONS) { thePlot.setDataset(1, createMeansDataset()); thePlot.mapDatasetToRangeAxis(1, 0); CategoryItemRenderer lr = new org.jfree.chart.renderer.category.LevelRenderer(); lr.setPaint(Color.black); thePlot.setRenderer(1, lr); } // create chart theChart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, thePlot, true); theChart.setBackgroundPaint(Color.white); theChart.setBorderVisible(false); } private CategoryDataset createDataset() { GlycanRenderer theRenderer = theApplication.getWorkspace().getGlycanRenderer(); if (theOptions.REPRESENTATION == theOptions.BARS) { org.jfree.data.category.DefaultCategoryDataset ret = new org.jfree.data.category.DefaultCategoryDataset(); for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) { for (int i = 0; i < theDocument.getNoColumns(); i++) ret.addValue(row.getColumn(i), theDocument.getNames().get(i), row.name); } return ret; } else if (theOptions.REPRESENTATION == theOptions.ERRORBARS) { org.jfree.data.statistics.DefaultStatisticalCategoryDataset ret = new org.jfree.data.statistics.DefaultStatisticalCategoryDataset(); for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) { ret.add(mean(row.intensities_firstgroup), stddev(row.intensities_firstgroup), "First group", row.name); ret.add(mean(row.intensities_secondgroup), stddev(row.intensities_secondgroup), "Second group", row.name); } return ret; } else if (theOptions.REPRESENTATION == theOptions.DISTRIBUTIONS) { org.jfree.data.statistics.DefaultMultiValueCategoryDataset ret = new org.jfree.data.statistics.DefaultMultiValueCategoryDataset(); for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) { ret.add(tolist(row.intensities_firstgroup), "First group", row.name); ret.add(tolist(row.intensities_secondgroup), "Second group", row.name); } return ret; } return null; } private CategoryDataset createMeansDataset() { GlycanRenderer theRenderer = theApplication.getWorkspace().getGlycanRenderer(); org.jfree.data.category.DefaultCategoryDataset ret = new org.jfree.data.category.DefaultCategoryDataset(); for (ProfilesComparisonReportDocument.Row row : theDocument.getRows()) { ret.addValue(mean(row.intensities_firstgroup), "First group", row.name); ret.addValue(mean(row.intensities_secondgroup), "Second group", row.name); } return ret; } private ArrayList<Double> tolist(double[] array) { ArrayList<Double> ret = new ArrayList<Double>(); for (double d : array) ret.add(d); return ret; } private ArrayList<Double> tolist(double value) { ArrayList<Double> ret = new ArrayList<Double>(); ret.add(value); return ret; } private double mean(double[] array) { if (array == null || array.length == 0) return 0.; double mean = 0.; for (int i = 0; i < array.length; i++) mean += array[i]; return mean / (double) array.length; } private double stddev(double[] array) { if (array == null || array.length == 0) return 0.; double mean = mean(array); double smean = 0.; for (int i = 0; i < array.length; i++) smean += array[i] * array[i]; return Math.sqrt(smean / (double) array.length - mean * mean); } private Rectangle getViewArea(double scale) { int chart_width = Math.max(CHART_WIDTH, CHART_WIDTH_TICK * theDocument.getNoRows()); return new Rectangle(0, 0, (int) (2 * DRAW_X_MARGIN + scale * (2 * CHART_X_MARGIN + chart_width)), (int) (2 * DRAW_Y_MARGIN + scale * (2 * CHART_X_MARGIN + CHART_HEIGHT))); } private Rectangle getDrawArea(double scale) { int chart_width = Math.max(CHART_WIDTH, CHART_WIDTH_TICK * theDocument.getNoRows()); return new Rectangle(DRAW_X_MARGIN, DRAW_Y_MARGIN, (int) (scale * (2 * CHART_X_MARGIN + chart_width)), (int) (scale * (2 * CHART_Y_MARGIN + CHART_HEIGHT))); } private Rectangle getChartArea(double scale) { int chart_width = Math.max(CHART_WIDTH, CHART_WIDTH_TICK * theDocument.getNoRows()); return new Rectangle((int) (DRAW_X_MARGIN + scale * CHART_X_MARGIN), (int) (DRAW_Y_MARGIN + scale * CHART_Y_MARGIN), (int) (scale * chart_width), (int) (scale * CHART_HEIGHT)); } protected void updateDrawArea() { // update data area view_area = getViewArea(scale); draw_area = getDrawArea(scale); chart_area = getChartArea(scale); data_area = null; paintChart(GraphicUtils.createImage(view_area.getSize(), true).createGraphics()); } }