abstractregionpainter.java
来自「Mobile 应用程序使用 Java Micro Edition (Java M」· Java 代码 · 共 718 行 · 第 1/3 页
JAVA
718 行
/* * @(#)AbstractRegionPainter.java 1.10 08/06/27 * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.java.swing.plaf.nimbus;import java.awt.*;import java.awt.image.*;import java.lang.reflect.Method;import javax.swing.*;import javax.swing.plaf.UIResource;import com.sun.java.swing.Painter;import java.awt.print.PrinterGraphics;import static com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel.deriveARGB;/** * Convenient base class for defining Painter instances for rendering a * region or component in Nimbus. * * @author Jasper Potts * @author Richard Bair */public abstract class AbstractRegionPainter implements Painter<JComponent> { /** * PaintContext, which holds a lot of the state needed for cache hinting and x/y value decoding * The data contained within the context is typically only computed once and reused over * multiple paint calls, whereas the other values (w, h, f, leftWidth, etc) are recomputed * for each call to paint. * * This field is retrieved from subclasses on each paint operation. It is up * to the subclass to compute and cache the PaintContext over multiple calls. */ private PaintContext ctx; /** * The scaling factor. Recomputed on each call to paint. */ private float f; /* Various metrics used for decoding x/y values based on the canvas size and stretching insets. On each call to paint, we first ask the subclass for the PaintContext. From the context we get the canvas size and stretching insets, and whether the algorithm should be "inverted", meaning the center section remains a fixed size and the other sections scale. We then use these values to compute a series of metrics (listed below) which are used to decode points in a specific axis (x or y). The leftWidth represents the distance from the left edge of the region to the first stretching inset, after accounting for any scaling factor (such as DPI scaling). The centerWidth is the distance between the leftWidth and the rightWidth. The rightWidth is the distance from the right edge, to the right inset (after scaling has been applied). The same logic goes for topHeight, centerHeight, and bottomHeight. The leftScale represents the proportion of the width taken by the left section. The same logic is applied to the other scales. The various widths/heights are used to decode control points. The various scales are used to decode bezier handles (or anchors). */ /** * The width of the left section. Recomputed on each call to paint. */ private float leftWidth; /** * The height of the top section. Recomputed on each call to paint. */ private float topHeight; /** * The width of the center section. Recomputed on each call to paint. */ private float centerWidth; /** * The height of the center section. Recomputed on each call to paint. */ private float centerHeight; /** * The width of the right section. Recomputed on each call to paint. */ private float rightWidth; /** * The height of the bottom section. Recomputed on each call to paint. */ private float bottomHeight; /** * The scaling factor to use for the left section. Recomputed on each call to paint. */ private float leftScale; /** * The scaling factor to use for the top section. Recomputed on each call to paint. */ private float topScale; /** * The scaling factor to use for the center section, in the horizontal * direction. Recomputed on each call to paint. */ private float centerHScale; /** * The scaling factor to use for the center section, in the vertical * direction. Recomputed on each call to paint. */ private float centerVScale; /** * The scaling factor to use for the right section. Recomputed on each call to paint. */ private float rightScale; /** * The scaling factor to use for the bottom section. Recomputed on each call to paint. */ private float bottomScale; /** * Create a new AbstractRegionPainter */ protected AbstractRegionPainter() { } /** * @inheritDoc */ @Override public final void paint(Graphics2D g, JComponent c, int w, int h) { //don't render if the width/height are too small if (w <= 0 || h <=0) return; Object[] extendedCacheKeys = getExtendedCacheKeys(c); ctx = getPaintContext(); PaintContext.CacheMode cacheMode = ctx == null ? PaintContext.CacheMode.NO_CACHING : ctx.cacheMode; if (cacheMode == PaintContext.CacheMode.NO_CACHING || !ImageCache.getInstance().isImageCachable(w, h) || g instanceof PrinterGraphics) { // no caching so paint directly paint0(g, c, w, h, extendedCacheKeys); } else if (cacheMode == PaintContext.CacheMode.FIXED_SIZES) { paintWithFixedSizeCaching(g, c, w, h, extendedCacheKeys); } else { // 9 Square caching paintWith9SquareCaching(g, ctx, c, w, h, extendedCacheKeys); } } /** * Get any extra attributes which the painter implementation would like * to include in the image cache lookups. This is checked for every call * of the paint(g, c, w, h) method. * * @param c The component on the current paint call * @return Array of extra objects to be included in the cache key */ protected Object[] getExtendedCacheKeys(JComponent c) { return null; } /** * <p>Gets the PaintContext for this painting operation. This method is called on every * paint, and so should be fast and produce no garbage. The PaintContext contains * information such as cache hints. It also contains data necessary for decoding * points at runtime, such as the stretching insets, the canvas size at which the * encoded points were defined, and whether the stretching insets are inverted.</p> * * <p> This method allows for subclasses to package the painting of different states * with possibly different canvas sizes, etc, into one AbstractRegionPainter implementation.</p> * * @return a PaintContext associated with this paint operation. */ protected abstract PaintContext getPaintContext(); /** * <p>Configures the given Graphics2D. Often, rendering hints or compositiing rules are * applied to a Graphics2D object prior to painting, which should affect all of the * subsequent painting operations. This method provides a convenient hook for configuring * the Graphics object prior to rendering, regardless of whether the render operation is * performed to an intermediate buffer or directly to the display.</p> * * @param g The Graphics2D object to configure. Will not be null. */ protected void configureGraphics(Graphics2D g) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } /** * Actually performs the painting operation. Subclasses must implement this method. * The graphics object passed may represent the actual surface being rendererd to, * or it may be an intermediate buffer. It has also been pre-translated. Simply render * the component as if it were located at 0, 0 and had a width of <code>width</code> * and a height of <code>height</code>. For performance reasons, you may want to read * the clip from the Graphics2D object and only render within that space. * * @param g The Graphics2D surface to paint to * @param c The JComponent related to the drawing event. For example, if the * region being rendered is Button, then <code>c</code> will be a * JButton. If the region being drawn is ScrollBarSlider, then the * component will be JScrollBar. This value may be null. * @param width The width of the region to paint. Note that in the case of * painting the foreground, this value may differ from c.getWidth(). * @param height The height of the region to paint. Note that in the case of * painting the foreground, this value may differ from c.getHeight(). * @param extendedCacheKeys The result of the call to getExtendedCacheKeys() */ protected abstract void doPaint(Graphics2D g, JComponent c, int width, int height, Object[] extendedCacheKeys); /** * Decodes and returns a float value representing the actual pixel location for * the given encoded X value. * * @param x an encoded x value (0...1, or 1...2, or 2...3) * @return the decoded x value */ protected final float decodeX(float x) { if (ctx.canvasSize == null) return x; if (x >= 0 && x <= 1) { return x * leftWidth; } else if (x > 1 && x < 2) { return ((x-1) * centerWidth) + leftWidth; } else if (x >= 2 && x <= 3) { return ((x-2) * rightWidth) + leftWidth + centerWidth; } else { throw new AssertionError("Invalid x"); } } /** * Decodes and returns a float value representing the actual pixel location for * the given encoded y value. * * @param y an encoded y value (0...1, or 1...2, or 2...3) * @return the decoded y value */ protected final float decodeY(float y) { if (ctx.canvasSize == null) return y; if (y >= 0 && y <= 1) { return y * topHeight; } else if (y > 1 && y < 2) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?