?? skin.java
字號:
package mwt;
/*
* MWT - Micro Window Toolkit
* Copyright (C) 2007 Lucas Domanico - lucazd@gmail.com
*
* Licensed under the terms of the GNU Lesser General Public License:
* http://www.opensource.org/licenses/lgpl-license.php
*
* For further information visit:
* http://j2me-mwt.sourceforge.net/
*/
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
/**
* <p>A skin is used to paint regions of different sizes using the same look and feel.</p>
*
* <p>A skin can be created giving images (an "image skin"), or giving colors
* ("colour rectangle skin").</p>
*
* <h3><a name="imageskin">Image Skin</a></h3>
* <p>To create an image skin, you must provide an array of 9 images.<br>
* The next example shows how they will be used:</p>
*
*
<table width="600" border="0" cellspacing="4" cellpadding="0">
<tr>
<td width="128"><table width="50px" border="0" cellpadding="0" cellspacing="8">
<tr>
<td><img src="{@docRoot}/resources/skiny7.png" border="0" /></td>
<td><img src="{@docRoot}/resources/skiny0.png" border="0" /></td>
<td><img src="{@docRoot}/resources/skiny1.png" border="0" /></td>
</tr>
<tr>
<td><img src="{@docRoot}/resources/skiny6.png" border="0" /></td>
<td><img src="{@docRoot}/resources/skiny8.png" border="0" /></td>
<td><img src="{@docRoot}/resources/skiny2.png" border="0" /></td>
</tr>
<tr>
<td><img src="{@docRoot}/resources/skiny5.png" border="0" /></td>
<td><img src="{@docRoot}/resources/skiny4.png" border="0" /></td>
<td><img src="{@docRoot}/resources/skiny3.png" border="0" /></td>
</tr>
</table></td>
<td width="460">Each image of the given array maps in the next way:<pre>
7 0 1 0, 2, 4, 5: sides
6 8 2 1, 3, 5, 7: borders
5 4 3 8: fill
</pre></td>
</tr>
</table>
* <p>"Middle" sides (2 and 6), are repeated in y axis until they fill the desired area.<br>
* "Center" sides (0 and 4), are repeated in x axis until they fill the desired area.<br>
* The "fill" image is repeated in both axis.<br>
* Border images are blitted as they are.</p>
*
* <p>If images are repeated too many times, the application may run slower.<br>
* To improve this, you can resize the images when the skin is created. However, this requires
* more memory.<br>
* Another drawback is that if the images are resized, they may lose the alpha channel info.</p>
*
* The next screens illustrate how an image skin is stretched.
<table width="532" border="0" cellspacing="4" cellpadding="0">
<tr>
<td width="128"><img src="{@docRoot}/resources/skin_bmp_1.png" width="128" height="128" /></td>
<td width="128"><img src="{@docRoot}/resources/skin_bmp_2.png" width="128" height="128" /></td>
<td width="128"><img src="{@docRoot}/resources/skin_bmp_3.png" width="128" height="128" /></td>
<td width="128"><img src="{@docRoot}/resources/skin_bmp_4.png" width="128" height="128" /></td>
</tr>
</table>
*
*
*
* <h3><a name="colourrect">Colour Rectangle Skin</a></h3>
* <p>A colour rectangle skin is created by giving an array of integers.</p>
* <p>The skin will draw a rectangle using this colour data which must contain at least 1 value.<br>
* The first index value is the background fill, next values are frames from outside to inside.</p>
* Example:
<table width="600" border="0" cellspacing="4" cellpadding="0">
<tr>
<td><img src="{@docRoot}/resources/skin_rect_1.png" width="30" height="20" /></td>
<td bgcolor="#FFE220"><div align="center">0xFFE220</div></td>
<td bgcolor="#000000"><div align="center"><span style="color: #FFFFFF;">0x000000</span></div></td>
<td bgcolor="#5999FF"><div align="center">0x5999FF</div></td>
<td bgcolor="#000000"><div align="center"><span style="color: #FFFFFF;">0x000000</span></div></td>
<td bgcolor="#D9C01C"><div align="center">0xD9C01C</div></td>
</tr>
<tr>
<td><img src="{@docRoot}/resources/skin_rect_2.png" width="30" height="20" /></td>
<td bgcolor="#FFCCCF"><div align="center">0xFFCCCF</div></td>
<td bgcolor="#A34184"><div align="center"><span style="color: #FFFFFF;">0xA34184</span></div></td>
<td bgcolor="#FF66CF"><div align="center">0xFF66CF</div></td>
<td bgcolor="#FF66CF"><div align="center">0xFF66CF</div></td>
<td><div align="center"></div></td>
</tr>
<tr>
<td><img src="{@docRoot}/resources/skin_rect_3.png" width="30" height="20" /></td>
<td><div align="center">0xFFFFFF</div></td>
<td bgcolor="#000000"><div align="center"><span style="color: #FFFFFF;">0x000000</span></div></td>
<td bgcolor="#A1C632"><div align="center">0xA1C632</div></td>
<td bgcolor="#CFFF40"><div align="center">0xCFFF40</div></td>
<td><div align="center"></div></td>
</tr>
</table>
*
*
*
* <h3><a name="extending">Extending</a></h3>
* <p>Classes that extend a Skin must override the following methods:
* <ul>
* <li>{@link #clone()}</li>
* <li>{@link #copy(Skin)}</li>
* <li>{@link #paint(Graphics, int, int)}</li>
* </ul>
* The contructor must call the default constructor {@link #Skin()}.
* </p>
* Example:
* <pre>
* class MySkin extends Skin {
* int newAttribute = ...;
*
* public MySkin(int newAttribute) {
* super(); // this is not necessary
* this.newAttribute = newAttribute;
* }
*
* protected void copy(MySkin s) {
* super.copy(s);
* s.newAttribute = this.newAttribute;
* }
*
* private MySkin() {}
* public Skin clone() {
* MySkin s = new MySkin();
* copy(s);
* return s;
* }
*
* protected void paint(Graphics g, int width, int height) {
* // new implementation
* }
* }
* </pre>
*
*
* <h3>Caching</h3>
* <p>To improve performance, there's a mechanism to create a cache if the component calling
* is double buffered.<br>
* The default implementation has an important drawback; alpha values are ignored.<br>
* You can extend this class and implement a better cache mechanism overriding the
* {@link #createBuffer(int, int)} method.</p>
*
*/
public class Skin {
// static final private int TOP_CENTER = 0;
// static final private int TOP_RIGHT = 1;
// static final private int MIDDLE_RIGHT = 2;
// static final private int BOTTOM_RIGHT = 3;
// static final private int BOTTOM_CENTER = 4;
// static final private int BOTTOM_LEFT = 5;
// static final private int MIDDLE_LEFT = 6;
// static final private int TOP_LEFT = 7;
// static final private int MIDDLE_CENTER = 0;
private Image images;
private int[] colors;
private Button button;
// private int[] argb;
// If the component is doubleBuffered, this class will try to create
// a cache to improve performance.
// However, if the component is changing its size permanently,
// the effect will be not good.
// That is why, there's countdown before creating the cache.
// (If COUNT is 0, there's no countdown)
final static private int COUNT = 4;
/** Creates a "dummy" skin, paint calls are ignored. */
public Skin() {
images = null;
colors = null;
}
/** Creates a "colour rectangle" skin.
* @see <a href="#colourrect">Colour Rectangle Skin</> */
public Skin(int[] colors) {
this.colors = new int[colors.length];
System.arraycopy(colors,0,this.colors,0,colors.length);
images = null;
}
/**
* Creates an image skin.
* @param images The array with 9 images in the correspoding order
* @param newSize The new size, or 0 to skip resizing
* @see <a href="#imageskin">Image Skin</a>
*/
public Skin(Image images, int newSize) {
colors = null;
// if(images.length != 9) throw new IllegalArgumentException();
this.images = images;
// System.arraycopy(images,0,this.images,0,1);
if(newSize == 0) return;
// for(int index=TOP_CENTER; ;index=BOTTOM_CENTER) {
// if(this.images[index].getWidth() != newSize) {
// final Image t = this.images[index];
// this.images[index] = Image.createImage(newSize,t.getHeight());
// for(int i=0; i<newSize ;i+=t.getWidth())
// this.images[index].getGraphics().drawImage(t,i,0,0);
// }
// if(index == BOTTOM_CENTER) break;
// }
// for(int index=MIDDLE_LEFT; ;index=MIDDLE_RIGHT) {
// if(this.images[index].getHeight() != newSize) {
// final Image t = this.images[index];
// this.images[index] = Image.createImage(t.getWidth(),newSize);
// for(int i=0; i<newSize ;i+=t.getHeight())
// this.images[index].getGraphics().drawImage(t,0,i,0);
// }
// if(index == MIDDLE_RIGHT) break;
// }
// final Image t = this.images;
// if(t.getWidth() != newSize || t.getHeight() != newSize) {
// this.images = Image.createImage(newSize,newSize);
// for(int x=0; x<this.images.getWidth() ;x+=t.getWidth())
// for(int y=0; y<this.images.getHeight() ;y+=t.getHeight())
// this.images.getGraphics().drawImage(t,x,y,0);
// }
}
/**
* Gets a clone of this skin.<br>
* @see <a href="#extending">Extending a Skin</a>
*/
public Skin clone() {
Skin s = new Skin();
copy(s);
return s;
}
/**
* Copies this skin into the given skin.<br>
* @see <a href="#extending">Extending a Skin</a>
*/
protected void copy(Skin skin) {
skin.images = images;
skin.colors = colors;
}
/**
* Paints a component into the given graphics object.<br>
* If the component is double buffered, this method may call {@link #createBuffer(int, int)}.
*/
final public void paint(Component c, Graphics g) {
if(c instanceof Button)button = (Button)c;
if(!c.isDoubleBuffered()) { paint(g,c.getWidth(),c.getHeight()); return; }
// if component is resized, start counting
if(c.getWidth() != c.skinWidth || c.getHeight() != c.skinHeight) {
c.skinWidth = c.getWidth(); // ojo si se cambia de lugar!
c.skinHeight = c.getHeight();
c.skinImage = null;
c.skinCount = COUNT;
}
// if the count is done, create the cache
if(c.skinCount != 0)
if(--c.skinCount == 0 && c.getWidth() > 0 && c.getHeight() > 0)
c.skinImage = createBuffer(c.getWidth(), c.getHeight());
if(c.skinImage != null) g.drawImage(c.skinImage,0,0,0);
else paint(g,c.getWidth(),c.getHeight());
}
/**
* Creates an image that will be used as a buffer.<br>
* This method must return an image for the given component size.<br>
* An implementation can return null, in such case, no cache is created.<br>
* The default implementation is:
* <pre>
* Image buf = Image.createImage(c.getWidth(),c.getHeight());
* this.paint(buf.getGraphics(),c.getWidth(),c.getHeight());
* return buf;
* </pre>
* MWT handles memory management automatically.<br>
* References to this image will be garbage collected when the given component is
* garbage collected, or when its double buffer property is set to false.
*/
protected Image createBuffer(int width, int height) {
Image buf = Image.createImage(width, height);
this.paint(buf.getGraphics(),width, height);
return buf;
}
// public void fillRect(Graphics g, int x, int y,int w, int h,int ARGBColor) {
// int argb[] = new int[w * h];
//// for(int i=0;i<argb.length;i++){
//// argb[i] = ARGBColor;
//// }
// int a = 100;
// for(int i=0;i<argb.length;i++){
// argb[i]=(a<<24) |(argb[i] & 0x00FFFFFF);
// }
// g.drawRGB(argb, 0, w, x, y,w, h, true);
// }
public void fillRect(Graphics g, int x, int y,int w, int h,int ARGBColor) {
if (w <= 0 || h <= 0)
return;
if ( (ARGBColor & 0xff000000) == 0xff000000) {
g.setColor(ARGBColor);
g.fillRect(x, y, w, h);
}
else if ( (ARGBColor & 0xff000000) != 0x00000000) {
int[] ARGB = new int[w * h];
ARGB[0] = ARGBColor;
int TempPos = 1;
while (TempPos < ARGB.length) {
int TempLen = TempPos;
if (TempPos + TempLen > ARGB.length) {
TempLen = ARGB.length - TempPos;
}
System.arraycopy(ARGB, 0, ARGB, TempPos, TempLen);
TempPos += TempLen;
}
g.drawRGB(ARGB, 0, w, x, y,w, h, true);
}
}
/** Paints this skin into the given graphics object with the given width and height. */
protected void paint(Graphics g, int width, int height) {
if(images == null) {
if(colors == null) return;
try{
if(button.getIconImage()!=null){
g.setClip(0, 0, button.getIconImage().getWidth(), height);
g.drawImage(button.getIconImage(), 0, 0, Graphics.LEFT | Graphics.TOP);
g.setClip(button.getIconImage().getWidth(), 0, width, height);
}
}catch(Exception e){
// System.out.println(e.toString());
}
g.setColor(colors[0]);
// g.fillRect(0,0,width,height);
// g.drawLine(0, 0, width-1, 0);
g.drawLine(0, height-1, width-2, height-1);
// fillRect(g,0,0,width,height,colors[0]);
for(int i=0; i<colors.length-1 ;i++) {
g.setColor(colors[i+1]);
g.fillRect(i,i,width-i*2-2,height-i*2-1);
// g.drawRect(i,i,width-i*2-1,height-i*2-1);
}
return;
}
// final int cx = g.getClipX();
// final int cy = g.getClipY();
// final int cw = g.getClipWidth();
// final int ch = g.getClipHeight();
if(images.getWidth()>16){
g.drawRect(0, 0, width-1, height-1);
g.setColor(0xFFC125);
g.fillRect(0,0,width,height);
}
g.drawImage(images, 0, 0, 0);
// g.drawRGB(argb,0,images.getWidth(),0,100,images.getWidth(),images.getHeight(),true);
// int ww = width-images[MIDDLE_RIGHT].getWidth() - cx;
// ww = (ww < cw)? ww : cw;
// int hh = height-images[BOTTOM_CENTER].getHeight() - cy;
// hh = (hh < ch)? hh : ch;
// Center
// g.setClip(cx,cy,ww,hh);
// for(int xx=images[MIDDLE_LEFT].getWidth(); xx<width-images[MIDDLE_RIGHT].getWidth() ; xx += images[MIDDLE_CENTER].getWidth())
// for(int yy=images[TOP_CENTER].getHeight(); yy<height-images[BOTTOM_CENTER].getHeight() ; yy += images[MIDDLE_CENTER].getHeight())
// g.drawImage(images[MIDDLE_CENTER],xx,yy,0);
// Horizontal
// g.setClip(cx,cy,ww,ch);
// for(int i=images[MIDDLE_LEFT].getWidth(); i<=width ;i+=images[BOTTOM_CENTER].getWidth()) {
// g.drawImage(images[TOP_CENTER],i,0,0);
// g.drawImage(images[BOTTOM_CENTER],i,height-images[BOTTOM_CENTER].getHeight(),0);
// }
// Vertical
// g.setClip(cx,cy,cw,hh);
// for(int i=images[TOP_LEFT].getHeight(); i<=height-images[BOTTOM_LEFT].getHeight() ;i+=images[MIDDLE_RIGHT].getHeight()) {
// g.drawImage(images[MIDDLE_LEFT],0,i,0);
// g.drawImage(images[MIDDLE_RIGHT],width-images[MIDDLE_RIGHT].getWidth(),i,0);
// }
// Diagonals
// g.setClip(cx,cy,cw,ch);
// g.drawImage(images[TOP_RIGHT],width-images[TOP_RIGHT].getWidth(),0,0);
// g.drawImage(images[BOTTOM_RIGHT],width-images[BOTTOM_RIGHT].getWidth(),height-images[BOTTOM_RIGHT].getHeight(),0);
// g.drawImage(images[BOTTOM_LEFT],0,height-images[BOTTOM_LEFT].getHeight(),0);
// g.drawImage(images[TOP_LEFT],0,0,0);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -