因为SWT的ImageLoader支持读写以上所有格式的图片,所以实现起来比较简单。主要解决了两个问题。第一个问题是播放GIF动画,通过ImageLoader读入GIF的所有帧以及间隔时间,然后用Display.timerExec实现Timer播放。第二个问题是对图片的Scrollbar支持以及pack支持。SWT.H_SCROLL和SWT.V_SCROLL 虽然加上了滚动条,但是不起作用,需要监听滚动条的SWT.Selection事件。另外,加上滚动条后,pack无法得到大小,不能正确的pack。需要重载computeSize。
测试程序
在对GIF图片的支持上,Swing要做的好很多,一句label.setIcon(new ImageIcon(name))就搞定GIF动画了。
转载请保留 http://www.blogjava.net/xilaile/archive/2007/04/10/109547.html
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
/**
* 负责显示各种格式的图片
*
* @author 喜来乐哈哈
*/
public class ImageViewer extends Canvas{
protected Pointorigin = new Point( 0 , 0 );
protected Imageimage;
protected ImageData[]imageDatas;
protected Image[]images;
protected int current;
private int repeatCount;
private RunnableanimationTimer;
private ScrollBarhBar;
private ScrollBarvBar;
private Colorbg;
private Displaydisplay;
public ImageViewer(Compositeparent){
super (parent,SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL
| SWT.H_SCROLL);
hBar = getHorizontalBar();
vBar = getVerticalBar();
bg = getBackground();
display = getDisplay();
addListeners();
}
public void setImage(ImageDataimageData){
checkWidget();
stopAnimationTimer();
this .image = new Image(display,imageData);
this .imageDatas = null ;
this .images = null ;
redraw();
}
/**
* @param repeatCount0forever
*/
public void setImages(ImageData[]imageDatas, int repeatCount){
checkWidget();
this .image = null ;
this .imageDatas = imageDatas;
this .repeatCount = repeatCount;
convertImageDatasToImages();
startAnimationTimer();
redraw();
}
@Override
public PointcomputeSize( int wHint, int hHint, boolean changed){
checkWidget();
Imageimage = getCurrentImage();
if (image != null ){
Rectanglerect = image.getBounds();
Rectangletrim = computeTrim( 0 , 0 ,rect.width,rect.height);
return new Point(trim.width,trim.height);
}
return new Point(wHint,hHint);
}
@Override
public void dispose(){
if (image != null )
image.dispose();
if (images != null )
for ( int i = 0 ;i < images.length;i ++ )
images[i].dispose();
super .dispose();
}
protected void paint(Evente){
Imageimage = getCurrentImage();
if (image == null )
return ;
GCgc = e.gc;
gc.drawImage(image,origin.x,origin.y);
gc.setBackground(bg);
Rectanglerect = image.getBounds();
Rectangleclient = getClientArea();
int marginWidth = client.width - rect.width;
if (marginWidth > 0 ){
gc.fillRectangle(rect.width, 0 ,marginWidth,client.height);
}
int marginHeight = client.height - rect.height;
if (marginHeight > 0 ){
gc.fillRectangle( 0 ,rect.height,client.width,marginHeight);
}
}
void addListeners(){
hBar.addListener(SWT.Selection, new Listener(){
public void handleEvent(Eventarg0){
hscroll();
}
});
vBar.addListener(SWT.Selection, new Listener(){
public void handleEvent(Eventarg0){
vscroll();
}
});
addListener(SWT.Resize, new Listener(){
public void handleEvent(Evente){
resize();
}
});
addListener(SWT.Paint, new Listener(){
public void handleEvent(Evente){
paint(e);
}
});
}
void hscroll(){
Imageimage = getCurrentImage();
if (image != null ){
int hSelection = hBar.getSelection();
int destX = - hSelection - origin.x;
Rectanglerect = image.getBounds();
scroll(destX, 0 , 0 , 0 ,rect.width,rect.height, false );
origin.x = - hSelection;
}
}
void vscroll(){
Imageimage = getCurrentImage();
if (image != null ){
int vSelection = vBar.getSelection();
int destY = - vSelection - origin.y;
Rectanglerect = image.getBounds();
scroll( 0 ,destY, 0 , 0 ,rect.width,rect.height, false );
origin.y = - vSelection;
}
}
void resize(){
Imageimage = getCurrentImage();
if (image == null )
return ;
Rectanglerect = image.getBounds();
Rectangleclient = getClientArea();
hBar.setMaximum(rect.width);
vBar.setMaximum(rect.height);
hBar.setThumb(Math.min(rect.width,client.width));
vBar.setThumb(Math.min(rect.height,client.height));
int hPage = rect.width - client.width;
int vPage = rect.height - client.height;
int hSelection = hBar.getSelection();
int vSelection = vBar.getSelection();
if (hSelection >= hPage){
if (hPage <= 0 )
hSelection = 0 ;
origin.x = - hSelection;
}
if (vSelection >= vPage){
if (vPage <= 0 )
vSelection = 0 ;
origin.y = - vSelection;
}
redraw();
}
void convertImageDatasToImages(){
images = new Image[imageDatas.length];
// Step1:Determinethesizeoftheresultingimages.
int width = imageDatas[ 0 ].width;
int height = imageDatas[ 0 ].height;
// Step2:Constructeachimage.
int transition = SWT.DM_FILL_BACKGROUND;
for ( int i = 0 ;i < imageDatas.length;i ++ ){
ImageDataid = imageDatas[i];
images[i] = new Image(display,width,height);
GCgc = new GC(images[i]);
// Dothetransitionfromthepreviousimage.
switch (transition){
case SWT.DM_FILL_NONE:
case SWT.DM_UNSPECIFIED:
// Startfromlastimage.
gc.drawImage(images[i - 1 ], 0 , 0 );
break ;
case SWT.DM_FILL_PREVIOUS:
// Startfromsecondlastimage.
gc.drawImage(images[i - 2 ], 0 , 0 );
break ;
default :
// DM_FILL_BACKGROUNDoranythingelse,
// justfillwithdefaultbackground.
gc.setBackground(bg);
gc.fillRectangle( 0 , 0 ,width,height);
break ;
}
// Drawthecurrentimageandcleanup.
Imageimg = new Image(display,id);
gc.drawImage(img, 0 , 0 ,id.width,id.height,id.x,id.y,id.width,
id.height);
img.dispose();
gc.dispose();
// Computethenexttransition.
// Specialcase:Can'tdoDM_FILL_PREVIOUSonthe
// secondimagesincethereisno"secondlast"
// imagetouse.
transition = id.disposalMethod;
if (i == 0 && transition == SWT.DM_FILL_PREVIOUS)
transition = SWT.DM_FILL_NONE;
}
}
ImagegetCurrentImage(){
if (image != null )
return image;
if (images == null )
return null ;
return images[current];
}
void startAnimationTimer(){
if (images == null || images.length < 2 )
return ;
final int delay = imageDatas[current].delayTime * 10 ;
display.timerExec(delay,animationTimer = new Runnable(){
public void run(){
if (isDisposed())
return ;
current = (current + 1 ) % images.length;
redraw();
if (current + 1 == images.length && repeatCount != 0
&& -- repeatCount <= 0 )
return ;
display.timerExec(delay, this );
}
});
}
void stopAnimationTimer(){
if (animationTimer != null )
display.timerExec( - 1 ,animationTimer);
}
}
* 负责显示各种格式的图片
*
* @author 喜来乐哈哈
*/
public class ImageViewer extends Canvas{
protected Pointorigin = new Point( 0 , 0 );
protected Imageimage;
protected ImageData[]imageDatas;
protected Image[]images;
protected int current;
private int repeatCount;
private RunnableanimationTimer;
private ScrollBarhBar;
private ScrollBarvBar;
private Colorbg;
private Displaydisplay;
public ImageViewer(Compositeparent){
super (parent,SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL
| SWT.H_SCROLL);
hBar = getHorizontalBar();
vBar = getVerticalBar();
bg = getBackground();
display = getDisplay();
addListeners();
}
public void setImage(ImageDataimageData){
checkWidget();
stopAnimationTimer();
this .image = new Image(display,imageData);
this .imageDatas = null ;
this .images = null ;
redraw();
}
/**
* @param repeatCount0forever
*/
public void setImages(ImageData[]imageDatas, int repeatCount){
checkWidget();
this .image = null ;
this .imageDatas = imageDatas;
this .repeatCount = repeatCount;
convertImageDatasToImages();
startAnimationTimer();
redraw();
}
@Override
public PointcomputeSize( int wHint, int hHint, boolean changed){
checkWidget();
Imageimage = getCurrentImage();
if (image != null ){
Rectanglerect = image.getBounds();
Rectangletrim = computeTrim( 0 , 0 ,rect.width,rect.height);
return new Point(trim.width,trim.height);
}
return new Point(wHint,hHint);
}
@Override
public void dispose(){
if (image != null )
image.dispose();
if (images != null )
for ( int i = 0 ;i < images.length;i ++ )
images[i].dispose();
super .dispose();
}
protected void paint(Evente){
Imageimage = getCurrentImage();
if (image == null )
return ;
GCgc = e.gc;
gc.drawImage(image,origin.x,origin.y);
gc.setBackground(bg);
Rectanglerect = image.getBounds();
Rectangleclient = getClientArea();
int marginWidth = client.width - rect.width;
if (marginWidth > 0 ){
gc.fillRectangle(rect.width, 0 ,marginWidth,client.height);
}
int marginHeight = client.height - rect.height;
if (marginHeight > 0 ){
gc.fillRectangle( 0 ,rect.height,client.width,marginHeight);
}
}
void addListeners(){
hBar.addListener(SWT.Selection, new Listener(){
public void handleEvent(Eventarg0){
hscroll();
}
});
vBar.addListener(SWT.Selection, new Listener(){
public void handleEvent(Eventarg0){
vscroll();
}
});
addListener(SWT.Resize, new Listener(){
public void handleEvent(Evente){
resize();
}
});
addListener(SWT.Paint, new Listener(){
public void handleEvent(Evente){
paint(e);
}
});
}
void hscroll(){
Imageimage = getCurrentImage();
if (image != null ){
int hSelection = hBar.getSelection();
int destX = - hSelection - origin.x;
Rectanglerect = image.getBounds();
scroll(destX, 0 , 0 , 0 ,rect.width,rect.height, false );
origin.x = - hSelection;
}
}
void vscroll(){
Imageimage = getCurrentImage();
if (image != null ){
int vSelection = vBar.getSelection();
int destY = - vSelection - origin.y;
Rectanglerect = image.getBounds();
scroll( 0 ,destY, 0 , 0 ,rect.width,rect.height, false );
origin.y = - vSelection;
}
}
void resize(){
Imageimage = getCurrentImage();
if (image == null )
return ;
Rectanglerect = image.getBounds();
Rectangleclient = getClientArea();
hBar.setMaximum(rect.width);
vBar.setMaximum(rect.height);
hBar.setThumb(Math.min(rect.width,client.width));
vBar.setThumb(Math.min(rect.height,client.height));
int hPage = rect.width - client.width;
int vPage = rect.height - client.height;
int hSelection = hBar.getSelection();
int vSelection = vBar.getSelection();
if (hSelection >= hPage){
if (hPage <= 0 )
hSelection = 0 ;
origin.x = - hSelection;
}
if (vSelection >= vPage){
if (vPage <= 0 )
vSelection = 0 ;
origin.y = - vSelection;
}
redraw();
}
void convertImageDatasToImages(){
images = new Image[imageDatas.length];
// Step1:Determinethesizeoftheresultingimages.
int width = imageDatas[ 0 ].width;
int height = imageDatas[ 0 ].height;
// Step2:Constructeachimage.
int transition = SWT.DM_FILL_BACKGROUND;
for ( int i = 0 ;i < imageDatas.length;i ++ ){
ImageDataid = imageDatas[i];
images[i] = new Image(display,width,height);
GCgc = new GC(images[i]);
// Dothetransitionfromthepreviousimage.
switch (transition){
case SWT.DM_FILL_NONE:
case SWT.DM_UNSPECIFIED:
// Startfromlastimage.
gc.drawImage(images[i - 1 ], 0 , 0 );
break ;
case SWT.DM_FILL_PREVIOUS:
// Startfromsecondlastimage.
gc.drawImage(images[i - 2 ], 0 , 0 );
break ;
default :
// DM_FILL_BACKGROUNDoranythingelse,
// justfillwithdefaultbackground.
gc.setBackground(bg);
gc.fillRectangle( 0 , 0 ,width,height);
break ;
}
// Drawthecurrentimageandcleanup.
Imageimg = new Image(display,id);
gc.drawImage(img, 0 , 0 ,id.width,id.height,id.x,id.y,id.width,
id.height);
img.dispose();
gc.dispose();
// Computethenexttransition.
// Specialcase:Can'tdoDM_FILL_PREVIOUSonthe
// secondimagesincethereisno"secondlast"
// imagetouse.
transition = id.disposalMethod;
if (i == 0 && transition == SWT.DM_FILL_PREVIOUS)
transition = SWT.DM_FILL_NONE;
}
}
ImagegetCurrentImage(){
if (image != null )
return image;
if (images == null )
return null ;
return images[current];
}
void startAnimationTimer(){
if (images == null || images.length < 2 )
return ;
final int delay = imageDatas[current].delayTime * 10 ;
display.timerExec(delay,animationTimer = new Runnable(){
public void run(){
if (isDisposed())
return ;
current = (current + 1 ) % images.length;
redraw();
if (current + 1 == images.length && repeatCount != 0
&& -- repeatCount <= 0 )
return ;
display.timerExec(delay, this );
}
});
}
void stopAnimationTimer(){
if (animationTimer != null )
display.timerExec( - 1 ,animationTimer);
}
}
测试程序
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
public
class
ImageCanvasTest{
public static void main(String[]args){
Displaydisplay = new Display();
final Shellshell = new Shell(display);
ImageVieweric = new ImageViewer(shell);
shell.setLayout( new FillLayout());
FileDialogdialog = new FileDialog(shell,SWT.OPEN);
dialog.setText( " Openanimagefileorcancel " );
Stringstring = dialog.open();
ImageLoaderloader = new ImageLoader();
ImageData[]imageDatas = loader.load(string);
if (imageDatas.length == 0 )
return ;
else if (imageDatas.length == 1 ){
ic.setImage(imageDatas[ 0 ]);
} else {
ic.setImages(imageDatas,loader.repeatCount);
}
ic.pack();
shell.pack();
shell.open();
while ( ! shell.isDisposed()){
if ( ! display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
public static void main(String[]args){
Displaydisplay = new Display();
final Shellshell = new Shell(display);
ImageVieweric = new ImageViewer(shell);
shell.setLayout( new FillLayout());
FileDialogdialog = new FileDialog(shell,SWT.OPEN);
dialog.setText( " Openanimagefileorcancel " );
Stringstring = dialog.open();
ImageLoaderloader = new ImageLoader();
ImageData[]imageDatas = loader.load(string);
if (imageDatas.length == 0 )
return ;
else if (imageDatas.length == 1 ){
ic.setImage(imageDatas[ 0 ]);
} else {
ic.setImages(imageDatas,loader.repeatCount);
}
ic.pack();
shell.pack();
shell.open();
while ( ! shell.isDisposed()){
if ( ! display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
在对GIF图片的支持上,Swing要做的好很多,一句label.setIcon(new ImageIcon(name))就搞定GIF动画了。
转载请保留 http://www.blogjava.net/xilaile/archive/2007/04/10/109547.html