Java tutorial
/* * This file is part of the GeOxygene project source files. GeOxygene aims at * providing an open framework which implements OGC/ISO specifications for the * development and deployment of geographic (GIS) applications. It is a open * source contribution of the COGIT laboratory at the Institut Gographique * National (the French National Mapping Agency). See: * http://oxygene-project.sourceforge.net Copyright (C) 2005 Institut * Gographique National This library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the License, * or any later version. This library 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. You should have received a copy of * the GNU Lesser General Public License along with this library (see file * LICENSE if present); if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package fr.ign.cogit.geoxygene.appli.layer; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.image.BufferedImage; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.swing.JPanel; import org.apache.commons.io.FilenameUtils; import org.apache.log4j.Logger; import fr.ign.cogit.geoxygene.api.feature.IFeature; import fr.ign.cogit.geoxygene.api.feature.IFeatureCollection; import fr.ign.cogit.geoxygene.api.spatial.coordgeom.IEnvelope; import fr.ign.cogit.geoxygene.appli.I18N; import fr.ign.cogit.geoxygene.appli.event.CompassPaintListener; import fr.ign.cogit.geoxygene.appli.event.LegendPaintListener; import fr.ign.cogit.geoxygene.appli.event.ScalePaintListener; import fr.ign.cogit.geoxygene.appli.render.MultithreadedRenderingManager; import fr.ign.cogit.geoxygene.style.Layer; import fr.ign.cogit.geoxygene.util.conversion.ImgUtil; /** * Panel displaying layers. * * @author Julien Perret * @author Jrmie Turbet (jul 2013 modifications) */ public class LayerViewAwtPanel extends LayerViewPanel { /** Serializable UID. */ private static final long serialVersionUID = -6502924871341284384L; /** Logger. */ private static Logger logger = Logger.getLogger(LayerViewAwtPanel.class.getName()); /** Rendering manager. */ private MultithreadedRenderingManager renderingManager = null; /** Default visibility Constructor which can be called only by the factory. */ public LayerViewAwtPanel() { super(); this.addPaintListener(new ScalePaintListener()); this.addPaintListener(new CompassPaintListener()); this.addPaintListener(new LegendPaintListener()); this.setDoubleBuffered(true); this.setOpaque(true); this.renderingManager = new MultithreadedRenderingManager(this); // rendering // manager } /** @return The rendering manager handling the rendering of the layers */ @Override public MultithreadedRenderingManager getRenderingManager() { return this.renderingManager; } @Override public final void repaint() { if (this.getRenderingManager() != null) { this.getRenderingManager().renderAll(); } } /** * Repaint the panel using the repaint method of the super class * {@link JPanel}. Called in order to perform the progressive rendering. * * @see #paintComponent(Graphics) */ @Override public final void superRepaint() { Container parent = this.getParent(); if (parent != null) { parent.repaint(); } } @Override public final void paintComponent(final Graphics g) { try { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // // super.paintComponent(g); // // clear the graphics g.setColor(this.getBackground()); g.fillRect(0, 0, this.getWidth(), this.getHeight()); // copy the result of the rendering manager to the panel this.getRenderingManager().copyTo((Graphics2D) g); // if currently editing geometry this.paintGeometryEdition(g); this.paintOverlays(g); // if (this.recording) { this.saveImage(); } } catch (Throwable t) { LayerViewAwtPanel.logger.error(I18N.getString("LayerViewAwtPanel.PaintError")); //$NON-NLS-1$ t.printStackTrace(); // TODO HANDLE EXCEPTIONS } } private void saveImage() { LayerViewAwtPanel.logger.debug("record"); //$NON-NLS-1$ Color bg = this.getBackground(); BufferedImage image = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = image.createGraphics(); graphics.setColor(bg); graphics.fillRect(0, 0, this.getWidth(), this.getHeight()); this.getRenderingManager().copyTo(graphics); this.recording = false; // this.paintOverlays(graphics); graphics.dispose(); try { NumberFormat format = NumberFormat.getInstance(); format.setMinimumIntegerDigits(3); ImgUtil.saveImage(image, this.recordFileName + format.format(this.recordIndex) + ".png"); //$NON-NLS-1$ this.recordIndex++; } catch (IOException e1) { e1.printStackTrace(); } } /** Dispose of the panel and its rendering manager. */ @Override public final void dispose() { if (this.getRenderingManager() != null) { this.getRenderingManager().dispose(); } this.setViewport(null); // TODO } /* * (non-Javadoc) * * @see fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#getEnvelope() */ @Override public final IEnvelope getEnvelope() { if (this.getRenderingManager().getLayers().isEmpty()) { return null; } List<Layer> copy = new ArrayList<Layer>(this.getRenderingManager().getLayers()); Iterator<Layer> layerIterator = copy.iterator(); IEnvelope envelope = layerIterator.next().getFeatureCollection().envelope(); while (layerIterator.hasNext()) { IFeatureCollection<? extends IFeature> collection = layerIterator.next().getFeatureCollection(); if (collection != null) { IEnvelope env = collection.getEnvelope(); if (envelope == null) { envelope = env; } else { envelope.expand(env); } } } return envelope; } @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { if (pageIndex >= 1) { return Printable.NO_SUCH_PAGE; } Graphics2D g2d = (Graphics2D) graphics; // translate to the upper left corner of the page format g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); // translate to the middle of the page format g2d.translate(pageFormat.getImageableWidth() / 2, pageFormat.getImageableHeight() / 2); Dimension d = this.getSize(); double scale = Math.min(pageFormat.getImageableWidth() / d.width, pageFormat.getImageableHeight() / d.height); if (scale < 1.0) { g2d.scale(scale, scale); } // translate of half the size of the graphics to paint for it to be // centered g2d.translate(-d.width / 2.0, -d.height / 2.0); // copy the rendered layers into the graphics this.getRenderingManager().copyTo(g2d); return Printable.PAGE_EXISTS; } @Override public void saveAsImage(String fileName, int width, int height, boolean doSaveWorldFile) { saveAsImage(fileName, width, height, doSaveWorldFile, true); } public void saveAsImage(String fileName, int width, int height, boolean doSaveWorldFile, boolean drawOverlay) { Color bg = this.getBackground(); BufferedImage outImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = outImage.createGraphics(); // TEMP graphics.setColor(bg); graphics.fillRect(0, 0, width, height); int tmpw = this.getWidth(); int tmph = this.getHeight(); // We save the old extent to force the Viewport to keep the old // window in world coordinates. IEnvelope env = this.getViewport().getEnvelopeInModelCoordinates(); // Artificially resize the canvas to the image dimensions. this.setSize(width, height); try { // We zoom to the old extent in the resized canvas. this.getViewport().zoom(env); } catch (NoninvertibleTransformException e2) { logger.error("In Image Export : failed to zoom in the correct extent."); e2.printStackTrace(); } this.renderingManager.renderAll(); long time = System.currentTimeMillis(); long twaited = 0; while (this.renderingManager.isRendering() && twaited < 15000) { // Wait for the rendering to end for a maximum of 15s. If the // rendering is not finished after this delay, // we give up. twaited = System.currentTimeMillis() - time; } if (this.renderingManager.isRendering()) { logger.error("Export to image : waited 15s but the rendering is still not finished. Abort."); return; } // We have to impose a bbox !!! this.getRenderingManager().copyTo(graphics); if (drawOverlay) this.paintOverlays(graphics); graphics.dispose(); try { ImgUtil.saveImage(outImage, fileName); } catch (IOException e1) { e1.printStackTrace(); } if (doSaveWorldFile) { String wld = FilenameUtils.removeExtension(fileName) + ".wld"; try { AffineTransform t = this.getViewport().getModelToViewTransform(); fr.ign.cogit.geoxygene.util.conversion.WorldFileWriter.write(new File(wld), t.getScaleX(), t.getScaleY(), this.getViewport().getViewOrigin().getX(), this.getViewport().getViewOrigin().getY(), this.getHeight()); } catch (NoninvertibleTransformException e) { logger.error("Failed to save the world file associated with the image file " + fileName); e.printStackTrace(); } } // Finally, rollback the canvas to its original size. this.setSize(tmpw, tmph); try { // Zoom back to the "normal" extent this.getViewport().zoom(env); } catch (NoninvertibleTransformException e2) { logger.error("In Image Export : failed to zoom back to the original LayerViewPanel extent."); e2.printStackTrace(); return; } } /* * (non-Javadoc) * * @see fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#saveAsImage(java * .lang .String) */ @Override public void saveAsImage(String fileName) { // TODO: ask for out resolution int widthOut = this.getWidth(); int heightOut = this.getHeight(); this.saveAsImage(fileName, widthOut, heightOut, false); } private boolean recording = false; /* * (non-Javadoc) * * @see fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#isRecording() */ @Override public boolean isRecording() { return this.recording; } /* * (non-Javadoc) * * @see * fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#setRecord(boolean) */ // @Override @Override public void setRecord(boolean b) { this.recording = b; } private String recordFileName = ""; //$NON-NLS-1$ /* * (non-Javadoc) * * @see * fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#getRecordFileName() */ // @Override @Override public String getRecordFileName() { return this.recordFileName; } /* * (non-Javadoc) * * @see * fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#setRecordFileName( * java.lang.String) */ // @Override @Override public void setRecordFileName(String recordFileName) { this.recordFileName = recordFileName; this.recordIndex = 0; } private int recordIndex = 0; // public void setModel(StyledLayerDescriptor sld) { // this.sldmodel = sld; // this.sldmodel.addSldListener(this); // // } /** Evenements SLD */ @Override public void actionPerformed(ActionEvent e) { this.repaint(); } /* * (non-Javadoc) * * @see * fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#layerAdded(fr.ign. * cogit.geoxygene.style.Layer) */ @Override public synchronized void layerAdded(Layer l) { if (this.getRenderingManager() != null) { this.getRenderingManager().addLayer(l); } try { IEnvelope env = l.getFeatureCollection().getEnvelope(); if (env == null) { env = l.getFeatureCollection().envelope(); } this.getViewport().zoom(env); } catch (NoninvertibleTransformException e1) { e1.printStackTrace(); } } /* * (non-Javadoc) * * @see fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#layerOrderChanged * (int , int) */ @Override public void layerOrderChanged(int oldIndex, int newIndex) { this.repaint(); } /* * (non-Javadoc) * * @see * fr.ign.cogit.geoxygene.appli.LayerViewPanelExtracted#layersRemoved(java * .util.Collection) */ @Override public void layersRemoved(Collection<Layer> layers) { this.repaint(); } /* * (non-Javadoc) * * @see fr.ign.cogit.geoxygene.appli.layer.LayerViewPanel#dislplayGui() */ @Override public void displayGui() { // nothing to display } /* * (non-Javadoc) * * @see fr.ign.cogit.geoxygene.appli.layer.LayerViewPanel#hideGui() */ @Override public void hideGui() { // nothing to hide } }