📄 optimizedsvgmenudemo.java
字号:
/*
*
* Copyright © 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
package com.sun.perseus.demo.optimizedmenu;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import javax.microedition.lcdui.*;
import javax.microedition.m2g.SVGImage;
import javax.microedition.m2g.ScalableGraphics;
import javax.microedition.midlet.*;
import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGElement;
import org.w3c.dom.svg.SVGLocatableElement;
import org.w3c.dom.svg.SVGMatrix;
import org.w3c.dom.svg.SVGRect;
import org.w3c.dom.svg.SVGSVGElement;
import com.sun.perseus.demo.SplashCanvas;
/**
* The optimized SVG menu demonstrates how the SVG graphics engine can be used
* to pre-rasterize menu content. The rasterized images can then be shown as
* frames in animations. The trade-off is to reduce computer power while using a
* little more space to hold the rasterized content.
*/
public class OptimizedSVGMenuDemo extends MIDlet implements CommandListener {
private final Command exitCommand = new Command("Exit", Command.EXIT, 1);
MenuCanvas svgCanvas = null;
public OptimizedSVGMenuDemo() {
}
public void startApp() {
System.gc();
String svgImageFile = "/svg/optimizedSVGMenuG.svg";
String splashImageFile = "/images/OptimizedMenuHelp.png";
if (svgCanvas == null) {
SplashCanvas splashCanvas = new SplashCanvas(splashImageFile);
splashCanvas.display(Display.getDisplay(this));
InputStream svgDemoStream = getClass().getResourceAsStream(svgImageFile);
if (svgDemoStream == null) {
throw new Error("Could not load " + svgImageFile);
}
try {
System.out.print("Loading SVGImage .... ");
SVGImage svgImage = (SVGImage)SVGImage.createImage(svgDemoStream, null);
System.out.println(" ... Done");
svgCanvas = new MenuCanvas(svgImage, 3, 3, 0.1f, 8, 0.0625f);
svgCanvas.addCommand(exitCommand);
svgCanvas.setCommandListener(this);
} catch (IOException e) {
e.printStackTrace();
throw new Error("Could not load " + svgImageFile);
}
splashCanvas.switchTo(Display.getDisplay(this), svgCanvas);
}
Display.getDisplay(this).setCurrent(svgCanvas);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
if (c == exitCommand) {
destroyApp(false);
notifyDestroyed();
}
}
/**
* The MenuCanvas class loads the icons found in the SVG image given
* at construction time and turns each icon into a bitmap.
*
*/
class MenuCanvas extends Canvas {
/**
* The SVGImage painted by the canvas.
*/
protected SVGImage svgImage;
/**
* The ScalableGraphics used to paint into the midp
* Graphics instance.
*/
protected ScalableGraphics sg = ScalableGraphics.createInstance();
/**
* The number of icons, vertically.
*/
protected int numRows;
/**
* The number of icons, horizontally.
*/
protected int numCols;
/**
* The size of a single icon.
*/
protected int iconWidth;
/**
* The size of a single icon.
*/
protected int iconHeight;
/**
* Number of frames in focus selection.
*/
protected int numFramesFocus;
/**
* Frame length.
*/
protected float frameLength;
/**
* The menu raster images.
*/
protected Image[][][] menuIcons;
/**
* The index of the current frame for each icon
*/
protected int[][] currentFrame;
/**
* The row/col index of the currently-focused icon.
*/
protected int focusRow;
/**
* The row/col index of the currently-focused icon.
*/
protected int focusCol;
/**
* The padding ratio.
*/
protected float padding;
/**
* @param svgImage the SVGImage this canvas should paint.
* @param numRows the number of rows of icons.
* @param numCols the number of colums of icons.
* @param padding the margin around each icons, as a percentage of the
* icon's bounding box.
* @param numFramesFocus the number of frames to sample in order to get
* from the unselected frame to the focused state.
* @param frameLength the amount of time between frames.
*/
protected MenuCanvas(final SVGImage svgImage, final int numRows, final int numCols,
final float padding, final int numFramesFocus, final float frameLength) {
if ((svgImage == null) || (numRows <= 0) || (numCols <= 0) || (padding < 0) ||
(numFramesFocus < 1) || (frameLength <= 0)) {
throw new IllegalArgumentException();
}
this.svgImage = svgImage;
this.numRows = numRows;
this.numCols = numCols;
this.numFramesFocus = numFramesFocus;
this.frameLength = frameLength;
this.padding = padding;
// The input svgImage should have numRows * numCols icons under the
// root svg element.
final int numIcons = numRows * numCols;
Document doc = svgImage.getDocument();
SVGSVGElement svg = (SVGSVGElement)doc.getDocumentElement();
// Load all the icons in a Vector for future manipulation
Vector iconVector = new Vector();
for (int i = 0; i < numIcons; i++) {
SVGElement iconElt = (SVGElement)doc.getElementById("icon_" + i);
if (iconElt == null) {
throw new IllegalArgumentException("The SVG Image does not have " + numIcons +
" icons under the root svg element" + " icon_" + i +
" does not exist in the document");
}
if (!(iconElt instanceof SVGLocatableElement)) {
throw new IllegalArgumentException("The " + (i + 1) + "th icon under the " +
"root svg element is not a <g>");
}
// Hide all icons initially
iconElt.setTrait("display", "none");
iconVector.addElement(iconElt);
}
// Now, compute the size allocated to each icon.
int width = getWidth();
int height = getHeight();
iconWidth = width / numCols;
iconHeight = height / numRows;
// Render each icon in a bitmap.
svgImage.setViewportWidth(iconWidth);
svgImage.setViewportHeight(iconHeight);
final int numFrames = 1 + numFramesFocus;
menuIcons = new Image[numRows][numCols][numFrames];
currentFrame = new int[numRows][numCols];
// calculate viewBox for each icon
// svg -> screen
SVGMatrix svgCTM = svg.getScreenCTM();
// screen -> svg
SVGMatrix svgICTM = svgCTM.inverse();
SVGRect[] iconViewBox = new SVGRect[numIcons];
for (int i = 0; i < numIcons; ++i) {
SVGLocatableElement icon = (SVGLocatableElement)iconVector.elementAt(i);
// Get the user space bounding box for the icon
SVGRect bbox = icon.getBBox();
if (bbox == null) {
// If someone tampered with the svg menu file, the bbox
// could be null
iconViewBox[i] = null;
continue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -