因为SWT的ImageLoader支持读写以上所有格式的图片,所以实现起来比较简单。主要解决了两个问题。第一个问题是播放GIF动画,通过ImageLoader读入GIF的所有帧以及间隔时间,然后用Display.timerExec实现Timer播放。第二个问题是对图片的Scrollbar支持以及pack支持。SWT.H_SCROLL和SWT.V_SCROLL 虽然加上了滚动条,但是不起作用,需要监听滚动条的SWT.Selection事件。另外,加上滚动条后,pack无法得到大小,不能正确的pack。需要重载computeSize。
<!--<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);
}
}
测试程序
<!--<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();
}
}
在对GIF图片的支持上,Swing要做的好很多,一句label.setIcon(new ImageIcon(name))就搞定GIF动画了。
转载请保留
http://www.blogjava.net/xilaile/archive/2007/04/10/109547.html