void update2(Graphics g) {

		if (repaintBlocked) {
			paintPleaseWait(g);
			return;
		}

		super.update2(g);

		Graphics2D g2 = (Graphics2D) g;

		if (grid != null && gridMode > Grid.ATOMIC) {
			boundary.drawReservoir(g2);
			grid.paint(gridMode, g2);
			if (showMirrorImages)
				boundary.paintGridMirrors(getWidth(), getHeight(), g2);
			if (getClockPainted())
				paintInfo(g2);
			return;
		}

		if (isVoronoiStyle()) {
			styleManager.renderFortune(g2);
			return;
		}

		if (gridMode == Grid.ATOMIC && grid != null) {
			float gx0 = grid.getx0();
			float gy0 = grid.gety0();
			float gdx = grid.getdx();
			float gdy = grid.getdy();
			int gnx = grid.getDivisions()[0];
			int gny = grid.getDivisions()[1];
			g2.setColor(Color.lightGray);
			g2.setStroke(ViewAttribute.THIN_DASHED);
			float gw = gnx * gdx;
			float gh = gny * gdy;
			if (tempLine == null)
				tempLine = new Line2D.Double();
			for (int i = 0; i < gny; i++) {
				tempLine.setLine(gx0, gy0 + gdy * i, gx0 + gw, gy0 + gdy * i);
				g2.draw(tempLine);
			}
			for (int i = 0; i < gnx; i++) {
				tempLine.setLine(gx0 + gdx * i, gy0, gx0 + gdx * i, gy0 + gh);
				g2.draw(tempLine);
			}
		}

		boundary.render(g2, actionID);
		boundary.drawReservoir(g2);

		if (obstacles != null && !obstacles.isEmpty()) {
			g2.setStroke(ViewAttribute.THIN);
			synchronized (obstacles.getSynchronizationLock()) {
				for (int iobs = 0, nobs = obstacles.size(); iobs < nobs; iobs++)
					obstacles.get(iobs).render(g2);
			}
		}

		if (nAtom > 0) {

			if (contourPlot && isoCurves != null) {
				g2.setStroke(ViewAttribute.THIN);
				g2.setColor(contrastBackground());
				synchronized (contourLock) {
					int numberOfCurves = isoCurves.length;
					double[] data;
					if (contourLine == null)
						contourLine = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 50);
					for (int i = 0; i < numberOfCurves; i++) {
						int itemp = isoCurves[i].size();
						for (int j = 0; j < itemp; j++) {
							data = (double[]) isoCurves[i].elementAt(j);
							if (data.length > 1) {
								contourLine.reset();
								contourLine.moveTo((float) data[0], (float) data[1]);
								for (int n = 2; n < data.length - 1; n += 2) {
									contourLine.lineTo((float) data[n], (float) data[n + 1]);
								}
								g2.draw(contourLine);
							}
						}
					}
				}
			}

			if (eFieldLines) {
				if (model.getNonLocalField(ElectricField.class.getName()) != null || model.checkCharges()) {
					if (eField == null)
						eField = new ElectricForceField();
					eField.setWindow(getWidth(), getHeight());
					eField.render(g2, model);
				}
			}

			if (showVDWLines)
				drawForceLines(g2, model.getVDWLines(), vdwLineStroke);
			if (showChargeLines)
				drawForceLines(g2, model.getChargeLines(), ViewAttribute.THICKER_DASHED);
			if (showSSLines)
				drawForceLines(g2, model.getSSLines(), ViewAttribute.DASHED);
			if (showBPLines)
				drawForceLines(g2, model.getBPLines(), ViewAttribute.DASHED);

			if (!bonds.isEmpty()) {
				synchronized (bonds.getSynchronizationLock()) {
					RadialBond rBond;
					for (Iterator i = bonds.iterator(); i.hasNext();) {
						rBond = (RadialBond) i.next();
						rBond.render(g2);
					}
					if (boundary.isPeriodic() && showMirrorImages) {
						mirrorBonds = boundary.createMirrorBonds();
						paintMirrorBonds(g2);
					}
				}
			}
			if (!bends.isEmpty()) {
				synchronized (bends.getSynchronizationLock()) {
					if (actionID == BBEN_ID) {
						for (Iterator i = bends.iterator(); i.hasNext();) {
							((AngularBond) i.next()).render(g2, contrastBackground());
						}
					} else {
						AngularBond aBond;
						for (Iterator i = bends.iterator(); i.hasNext();) {
							aBond = ((AngularBond) i.next());
							if (aBond.isSelected())
								aBond.render(g2, contrastBackground());
						}
					}
				}
			}

			if (boundary.isPeriodic() && showMirrorImages) { // create mirror images
				nAtomPBC = boundary.createMirrorAtoms();
			} else {
				nAtomPBC = nAtom;
			}

			if (useJmol)
				jmolRenderer.render(g2);
			mw2dRenderer.render(g2);

			/*
			 * if the selected component is a molecule but not in the molecule's list, render it here (this is used to render the molecule being generated but not yet finalized).
			 */
			if (selectedComponent instanceof Molecule) {
				if (!molecules.contains(selectedComponent))
					((Molecule) selectedComponent).render(g2);
			}

			/* render atomic vectors */
			int noa = getNumberOfAppearingAtoms();
			if (selectedComponent instanceof Atom) {
				int iat = ((Atom) selectedComponent).getIndex();
				for (int i = 0; i < iat; i++)
					renderVectors(atom[i], g2);
				for (int i = iat + 1; i < noa; i++)
					renderVectors(atom[i], g2);
				renderVectors(atom[iat], g2);
			} else {
				for (int i = 0; i < noa; i++)
					renderVectors(atom[i], g2);
			}

		}

		/* render photons */
		List<Photon> photons = model.getPhotons();
		if (photons != null && !photons.isEmpty()) {
			synchronized (photons) {
				for (Photon p : photons)
					p.render(g2);
			}
		}

		/* render free electrons */
		List<Electron> electrons = model.getFreeElectrons();
		if (electrons != null && !electrons.isEmpty()) {
			synchronized (electrons) {
				for (Electron e : electrons)
					e.render(g2);
			}
		}

		// draw the polymer or molecular surface currently being shaped
		if (smartShape != null) {
			if (actionID == SCUR_ID) {
				g2.setColor(MolecularObject.getDefaultBackground());
				g2.fill(smartShape);
			}
			g2.setColor(Color.black);
			g2.setStroke(ViewAttribute.THIN);
			g2.draw(smartShape);
		}

		molecules.render(g2);

		if (shading) {
			if (drawKeShadingRainbow) {
				// Mac OS X has bugs in GradientPaint (09/10/2007)
				if (Modeler.isMac()) {
					g2.drawImage(biRect, 10, 10, null);
				} else {
					g2.setPaint(colorScale);
					g2.fillRect(10, 10, 10, 50);
				}
				g2.setStroke(ViewAttribute.THIN);
				g2.setColor(contrastBackground());
				g2.drawRect(10, 10, 10, 50);
				g2.setFont(ViewAttribute.LITTLE_FONT);
				String s = getInternationalText("High");
				g2.drawString(s != null ? s : "High", 25, 20);
				s = getInternationalText("Low");
				g2.drawString(s != null ? s : "Low", 25, 60);
			}
		}

		paintSteering(g2);

		if (getEnergizer())
			energizer.paint(g2);

		if (model.heatBathActivated() && showHeatBath) {
			g2.setFont(ViewAttribute.SMALL_FONT);
			g2.setColor(contrastBackground());
			IconPool.getIcon("heat bath").paintIcon(this, g2, 8, 8);
		}

		switch (actionID) {
		case CPOS_ID:
		case CNEG_ID:
			if (selectedComponent instanceof Atom) {
				Atom at = (Atom) selectedComponent;
				String str = at.getCharge() + "";
				int sw = g2.getFontMetrics().stringWidth(str) + 8;
				int sh = g2.getFontMetrics().getHeight() + 6;
				g2.setStroke(ViewAttribute.THIN);
				g2.setColor(SystemColor.info);
				g2.fillRect((int) at.getRx(), (int) at.getRy() - sh, sw, sh);
				g2.setColor(contrastBackground());
				g2.drawRect((int) at.getRx(), (int) at.getRy() - sh, sw, sh);
				g2.setColor(Color.black);
				g2.drawString(str, (int) at.getRx() + 4, (int) at.getRy() - sh / 2 + 4);
			}
			break;
		case IRES_ID:
		case DRES_ID:
			if (selectedComponent instanceof Atom) {
				Atom at = (Atom) selectedComponent;
				if (at.getRestraint() != null) {
					g.setColor(contrastBackground());
					g.drawString(at.getRestraint().toString(), (int) at.getRx(), (int) at.getRy());
				}
			}
			break;
		case IDMP_ID:
		case DDMP_ID:
			if (selectedComponent instanceof Atom) {
				Atom at = (Atom) selectedComponent;
				g.setColor(contrastBackground());
				g.drawString(at.getFriction() + "", (int) at.getRx(), (int) at.getRy());
			}
			break;
		case ADDA_ID:
		case ADDB_ID:
		case ADDC_ID:
		case ADDD_ID:
			if (addAtomIndicator.x >= 0 && addAtomIndicator.y >= 0) {
				g2.setStroke(ViewAttribute.THIN_DASHED);
				g2.setColor(contrastBackground(128));
				g2.draw(addAtomIndicator);
			}
			break;
		case ADDI_ID:
		case WATE_ID:
		case BENZ_ID:
		case ADCH_ID:
			if (addObjectIndicator != null && addObjectIndicator.isPainted()) {
				g2.setStroke(ViewAttribute.THIN_DASHED);
				g2.setColor(contrastBackground(128));
				addObjectIndicator.paint(g2);
			}
			break;
		case HEAT_ID:
			g2.setStroke(ViewAttribute.THIN);
			pointHeater.paint(g2, true);
			break;
		case COOL_ID:
			g2.setStroke(ViewAttribute.THIN);
			pointHeater.paint(g2, false);
			break;
		case DELE_ID:
		case ADOB_ID:
		case FILA_ID:
		case FILB_ID:
		case FILC_ID:
		case FILD_ID:
		case MARK_ID:
		case COUN_ID:
			g2.setStroke(ViewAttribute.THIN);
			g2.setColor(contrastBackground());
			g2.draw(selectedArea);
			break;
		case DGBD_ID:
			if (bondAtom1 != null) {
				g2.setStroke(ViewAttribute.DASHED);
				g2.setColor(contrastBackground());
				g2.drawLine((int) bondAtom1.getRx(), (int) bondAtom1.getRy(), mouseHeldX, mouseHeldY);
			}
			break;
		}

		g2.setStroke(ViewAttribute.THIN);
		if (getClockPainted())
			paintInfo(g);
		paintLayeredComponents(g, Layered.IN_FRONT_OF_PARTICLES);
		paintShapeDrawing(g);

	}