⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractrenderer2d.java

📁 化学图形处理软件
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*  $Revision: 8742 $ $Author: egonw $ $Date: 2007-08-28 11:46:31 +0200 (Tue, 28 Aug 2007) $ * *  Copyright (C) 2005-2007  Christoph Steinbeck <steinbeck@users.sf.net> * *  Contact: cdk-devel@lists.sourceforge.net * *  This program 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 (at your option) any later version. *  All we ask is that proper credit is given for our work, which includes *  - but is not limited to - adding the above copyright notice to the beginning *  of your source code files, and to any copyright notice that you may distribute *  with programs based on this work. * *  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. * *  You should have received a copy of the GNU Lesser General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */package org.openscience.cdk.renderer;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Font;import java.awt.FontMetrics;import java.awt.Graphics2D;import java.awt.Point;import java.awt.RenderingHints;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionListener;import java.util.ArrayList;import java.util.Iterator;import java.util.Vector;import javax.vecmath.Point2d;import javax.vecmath.Vector2d;import org.openscience.cdk.CDKConstants;import org.openscience.cdk.config.AtomTypeFactory;import org.openscience.cdk.config.IsotopeFactory;import org.openscience.cdk.geometry.GeometryTools;import org.openscience.cdk.geometry.GeometryToolsInternalCoordinates;import org.openscience.cdk.interfaces.IAtom;import org.openscience.cdk.interfaces.IAtomContainer;import org.openscience.cdk.interfaces.IBond;import org.openscience.cdk.interfaces.IChemObject;import org.openscience.cdk.interfaces.IIsotope;import org.openscience.cdk.interfaces.IPseudoAtom;import org.openscience.cdk.interfaces.IRing;import org.openscience.cdk.interfaces.IRingSet;import org.openscience.cdk.tools.LoggingTool;import org.openscience.cdk.tools.manipulator.RingSetManipulator;import org.openscience.cdk.validate.ProblemMarker;/** *  A Renderer class which draws 2D representations of molecules onto a given *  graphics objects using information from a Renderer2DModel. * *  <p>This renderer uses two coordinate systems. One that is a world coordinates *  system which is generated from the document coordinates. Additionally, the *  screen coordinates make up the second system, and are calculated by applying *  a zoom factor to the world coordinates. * *  <p>The coordinate system used for display has its origin in the left-bottom *  corner, with the x axis to the right, and the y axis towards the top of the *  screen. The system is thus right handed. * *  <p>The two main methods are paintMolecule() and paintChemModel(). Others might *  not show full rendering, e.g. anti-aliasing. * *  <p>This modules tries to adhere to guidelines being developed by the IUPAC *  which results can be found at <a href="http://www.angelfire.com/sc3/iupacstructures/"> *  http://www.angelfire.com/sc3/iupacstructures/</a> . * * @author         steinbeck * @author         egonw * @cdk.module     render * @cdk.created    2002-10-03 * @cdk.keyword    viewer, 2D-viewer *  * @see            org.openscience.cdk.renderer.Renderer2DModel */abstract class AbstractRenderer2D implements MouseMotionListener{	final static BasicStroke stroke = new BasicStroke(1.0f);	protected LoggingTool logger;	boolean debug = true;	IsotopeFactory isotopeFactory;	int[] tooltiparea = null;	protected Renderer2DModel r2dm;	int graphicsHeight;        public boolean useScreenSize=true;	/**	 *  Constructs a Renderer2D with a default settings model.	 */	AbstractRenderer2D()	{		this(new Renderer2DModel());	}	/**	 *  Constructs a Renderer2D.	 *	 *@param  r2dm  The settings model to use for rendering.	 */	AbstractRenderer2D(Renderer2DModel r2dm)	{		this.r2dm = r2dm;		logger = new LoggingTool(this);	}		protected void setupIsotopeFactory(IChemObject object) {		if (isotopeFactory == null) {			try {				isotopeFactory = IsotopeFactory.getInstance(object.getBuilder());			} catch (Exception exception) {				logger.error("Error while instantiating IsotopeFactory");				logger.warn("Will not be able to display undefault isotopes");				logger.debug(exception);			}		}	}		protected void customizeRendering(Graphics2D graphics)	{		if (r2dm.getUseAntiAliasing())		{			graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);		}		graphics.setStroke(stroke);	}	/**	 *@param  minmax    array of length for with min and max 2D coordinates	 */	public void paintBoundingBox(double[] minmax, String caption,			int side, Graphics2D graphics)	{		int[] ints = new int[4];		ints[0] = (int) minmax[0] - side;		// min x		ints[1] = (int) minmax[1] - side;		// min y		ints[2] = (int) minmax[2] + side;		// max x		ints[3] = (int) minmax[3] + side;		// max y		int[] screenCoords = getScreenCoordinates(ints);		int heigth = screenCoords[1] - screenCoords[3];		int width = screenCoords[2] - screenCoords[0];		graphics.drawRect((int) screenCoords[0], (int) screenCoords[3], width, heigth);		// draw reaction ID		Font unscaledFont = r2dm.getFont();		if (unscaledFont == null)		{			unscaledFont = graphics.getFont();		}		float fontSize = getScreenSize(unscaledFont.getSize());		graphics.setFont(unscaledFont.deriveFont(fontSize));		graphics.drawString(caption, (int) screenCoords[0], (int) screenCoords[3]);		graphics.setFont(unscaledFont);	}	public void paintLassoLines(Graphics2D graphics)	{		Vector points = r2dm.getLassoPoints();		if (points.size() > 1)		{			Point point1 = (Point) points.elementAt(0);			Point point2;			for (int i = 1; i < points.size(); i++)			{				point2 = (Point) points.elementAt(i);				graphics.drawLine(point1.x, point1.y, point2.x, point2.y);				point1 = point2;			}		}	}	/**	 *  Searches through all the atoms in the given array of atoms, triggers the	 *  paintColouredAtoms method if the atom has got a certain color and triggers	 *  the paintAtomSymbol method if the symbol of the atom is not C.	 */	public void paintAtoms(IAtomContainer atomCon, Graphics2D graphics)	{		for (int i = 0; i < atomCon.getAtomCount(); i++)		{			paintAtom(atomCon, atomCon.getAtom(i), graphics);		}	}	public void paintAtom(IAtomContainer container, IAtom atom, Graphics2D graphics)	{		if (!r2dm.getShowExplicitHydrogens() && atom.getSymbol().equals("H")) return;		logger.debug("Painting atom ");		Color atomBackColor = r2dm.getAtomBackgroundColor(atom);		if (atom.equals(r2dm.getHighlightedAtom()))		{			paintColouredAtomBackground(atom, r2dm.getHoverOverColor(), graphics);		}		if((r2dm.getSelectedPart()!=null && (r2dm.getSelectedPart().contains(r2dm.getHighlightedAtom()) || r2dm.getSelectedPart().contains(r2dm.getHighlightedBond())) && r2dm.getSelectedPart().contains(atom)) || (r2dm.getSelectedPart()!=null && r2dm.getSelectedPart().getAtomCount()==1 && r2dm.getSelectedPart().getAtom(0)==atom)){			paintColouredAtomBackground(atom, r2dm.getSelectedPartColor(), graphics);		}			if(r2dm.getExternalSelectedPart()!=null && r2dm.getExternalSelectedPart().contains(atom)){			paintColouredAtomBackground(atom, r2dm.getExternalHighlightColor(), graphics);			atomBackColor=r2dm.getExternalHighlightColor();		}			if(r2dm.getMerge().get(atom)!=null || r2dm.getMerge().values().contains(atom)){			paintColouredAtomBackground(atom, r2dm.getHoverOverColor(),graphics);		}		int alignment = GeometryTools.getBestAlignmentForLabel(container, atom, r2dm.getRenderingCoordinates());		boolean drawSymbol = false;		boolean isRadical = (container.getConnectedSingleElectronsCount(atom) > 0);		if (atom instanceof IPseudoAtom)		{			drawSymbol = false;//			if (atom instanceof FragmentAtom) {//				paintFragmentAtom((FragmentAtom)atom, atomBackColor, graphics,//						alignment, isRadical);//			} else {				paintPseudoAtomLabel((IPseudoAtom) atom, atomBackColor, graphics,					alignment, isRadical);//			}			return;		} else if (!atom.getSymbol().equals("C"))		{			/*			 *  only show element for non-carbon atoms,			 *  unless (see below)...			 */			drawSymbol = true;		} else if (r2dm.getKekuleStructure())		{			// ... unless carbon must be drawn because in Kekule mode			drawSymbol = true;		} else if (atom.getFormalCharge() != 0)		{			// ... unless carbon is charged			drawSymbol = true;		} else if (container.getConnectedBondsList(atom).size() < 1)		{			// ... unless carbon is unbonded			drawSymbol = true;		} else if (r2dm.getShowEndCarbons() && (container.getConnectedBondsList(atom).size() == 1))		{			drawSymbol = true;		} else if (atom.getProperty(ProblemMarker.ERROR_MARKER) != null)		{			// ... unless carbon is unbonded			drawSymbol = true;		} else if (atom.getMassNumber() != 0)		{			try			{				if (atom.getMassNumber() != IsotopeFactory.getInstance(container.getBuilder()).						getMajorIsotope(atom.getSymbol()).getMassNumber())				{					drawSymbol = true;				}			} catch (Exception exception) {                logger.debug("Could not get an instance of IsotopeFactory");            }		}		if (r2dm.drawNumbers() && !drawSymbol && !r2dm.getIsCompact())		{			paintNumberOnly(atom, atomBackColor, graphics, atom.getProperty("OriginalNumber")!=null ? ((Integer)atom.getProperty("OriginalNumber")).intValue()+1 : container.getAtomNumber(atom) + 1);		}		if (drawSymbol || isRadical)		{			paintAtomSymbol(atom, atomBackColor, graphics, alignment,			atom.getProperty("OriginalNumber")!=null ? ((Integer)atom.getProperty("OriginalNumber")).intValue()+1 : container.getAtomNumber(atom) + 1, isRadical);		}		if (r2dm.getShowTooltip() && (atom == r2dm.getHighlightedAtom() ||( r2dm.getExternalSelectedPart()!=null &&  r2dm.getExternalSelectedPart().contains(atom))) && r2dm.getToolTipText(atom) != null)		{			paintToolTip(atom, graphics, container.getAtomNumber(atom) + 1);		}	}	/**	 *  Paints a rectangle of the given color at the position of the given atom.	 *  For example when the atom is highlighted.	 *	 *@param  atom      The atom to be drawn	 *@param  color     The color of the atom to be drawn	 */	public void paintColouredAtomBackground(org.openscience.cdk.interfaces.IAtom atom, Color color, Graphics2D graphics)	{		if(r2dm.getRenderingCoordinate(atom)==null)			return;		int atomRadius = r2dm.getAtomRadius();		graphics.setColor(color);		int[] coords = {(int) r2dm.getRenderingCoordinate(atom).x - (atomRadius / 2),				(int) r2dm.getRenderingCoordinate(atom).y + (atomRadius / 2)};		int radius = (int) getScreenSize(atomRadius);		coords = getScreenCoordinates(coords);		if(r2dm.getIsCompact())			graphics.drawRect(coords[0], coords[1], radius, radius);		else			graphics.fillRect(coords[0], coords[1], radius, radius);	}	/**	 *  Paints the given atom symbol. It first outputs some empty space using the	 *  background color, slightly larger than the space that the symbol occupies.	 *  The atom symbol is then printed into the empty space. <p>	 *	 *  The algorithm uses four steps:	 *  <ol>	 *    <li> it calculates the widths and heights of all label parts	 *    <li> it calculates the x's and y's of all label parts	 *    <li> it creates empty backgrounds for all label parts	 *    <li> it draws all label parts	 *  </ol>	 *	 *	 *@param  atom        The atom to be drawn	 *@param  graphics    Graphics2D to draw too	 *@param  alignment   How to align the H's	 *@param  atomNumber  Number of the atom in the AtomContainer, 0 is not in	 *      container	 */	public void paintAtomSymbol(IAtom atom, Color backColor, Graphics2D graphics,			int alignment, int atomNumber, boolean isRadical)	{		if (r2dm.getRenderingCoordinate(atom) == null)		{			logger.warn("Cannot draw atom without 2D coordinate");			return;		}		//This is for the compact version just with a square in the right color		if (r2dm.getIsCompact())		{			if (!atom.getSymbol().equals("C"))			{				int labelX = (int) (r2dm.getRenderingCoordinate(atom).x - 2);				int labelY = (int) (r2dm.getRenderingCoordinate(atom).y + 2);				try{					AtomTypeFactory factory = AtomTypeFactory.getInstance("org/openscience/cdk/config/jmol_atomtypes.txt",atom.getBuilder());					factory.configure(atom);				}catch(Exception ex){					//We choose black if reading not possible					logger.debug(ex);				}				Color atomColor = r2dm.getAtomColor(atom, Color.BLACK);				paintEmptySpace(labelX, labelY, 5, 5, 0, atomColor, graphics);			}			return;		}		// The fonts for calculating geometries		float subscriptFraction = 0.7f;		Font normalFont = r2dm.getFont();		if (normalFont == null)		{			normalFont = graphics.getFont();		}		int normalFontSize = normalFont.getSize();		Font subscriptFont = normalFont.deriveFont(				normalFontSize * subscriptFraction);		// get drawing fonts		float normalScreenFontSize = getScreenSize(normalFontSize);		Font normalScreenFont = normalFont.deriveFont(normalScreenFontSize);		Font subscriptScreenFont = normalScreenFont.deriveFont(				normalScreenFontSize * subscriptFraction);		// STEP 1: calculate widths and heights for all parts in the label		// calculate SYMBOL width, height		String atomSymbol = atom.getSymbol();		if (r2dm.drawNumbers())		{			if (atomNumber != 0 && !atomSymbol.equals(""))			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -