|
公司真bt什么都自己做。不过也不错,彻底了解了图片的低层。学到东西多了去了 之前因为忘记关掉我开启的线程,导致一个BUG,现在已经OK啦。
1
package
com.hactl.eaf.ui.rich.composite.widget;
2
3
import
java.io.InputStream;
4
5
import
org.eclipse.swt.SWT;
6
import
org.eclipse.swt.events.ControlEvent;
7
import
org.eclipse.swt.events.ControlListener;
8
import
org.eclipse.swt.events.DisposeEvent;
9
import
org.eclipse.swt.events.DisposeListener;
10
import
org.eclipse.swt.events.PaintEvent;
11
import
org.eclipse.swt.events.PaintListener;
12
import
org.eclipse.swt.events.SelectionAdapter;
13
import
org.eclipse.swt.events.SelectionEvent;
14
import
org.eclipse.swt.graphics.Color;
15
import
org.eclipse.swt.graphics.GC;
16
import
org.eclipse.swt.graphics.Image;
17
import
org.eclipse.swt.graphics.ImageData;
18
import
org.eclipse.swt.graphics.ImageLoader;
19
import
org.eclipse.swt.graphics.Point;
20
import
org.eclipse.swt.graphics.RGB;
21
import
org.eclipse.swt.graphics.Rectangle;
22
import
org.eclipse.swt.widgets.Canvas;
23
import
org.eclipse.swt.widgets.Composite;
24
import
org.eclipse.swt.widgets.Display;
25
import
org.eclipse.swt.widgets.ScrollBar;
26
27
public
class
HImage
extends
Canvas
{
28
protected
Composite parent;
29
30
protected
Image image;
31
32
protected
ImageLoader loader;
33
34
protected
InputStream input;
35
36
protected
boolean
isGif
=
false
;
37
38
protected
Display display
=
Display.getCurrent();
39
40
protected
int
imageNumber;
41
42
protected
ImageData[] imageDataArray;
43
44
private
int
repartCount;
45
46
protected
Color canvasBackground;
47
48
int
widgetType
=
0
;
49
50
ImageData imageData;
51
52
float
xscale
=
1
, yscale
=
1
;
//
used to scale the image but not use
53
54
int
ix
=
0
, iy
=
0
, py
=
0
;
//
used to scroll the image and palette
55
56
private
GifPaintThread thread;
57
58
private
int
style;
59
60
//
if set this style widget will not care any swt style
61
public
static
int
ISALLOWSCROLLIMAGE
=
1
<<
39
;
62
63
64
class
HImagePaintListener
implements
PaintListener
{
65
66
private
HImage widget;
67
68
public
HImagePaintListener(HImage widget)
{
69
this
.widget
=
widget;
70
}
71
72
public
void
paintControl(PaintEvent e)
{
73
GC gc
=
e.gc;
74
75
//
if input changed redraw background
76
gc.setBackground(canvasBackground);
77
gc.fillRectangle(
0
,
0
,widget.getBounds().width,widget.getBounds().height);
78
79
if
(input
==
null
)
{
80
return
;
81
}
82
83
if
(isGif)
84
drawGifImage(gc);
85
else
86
drawImage(gc, image);
87
}
88
89
}
90
91
class
GifPaintThread
extends
Thread
{
92
93
int
index
=
0
;
94
95
private
HImage widget;
96
97
private
GC gc;
98
99
public
GifPaintThread(GC gc, HImage widget)
{
100
this
.widget
=
widget;
101
this
.gc
=
gc;
102
}
103
104
public
void
run()
{
105
try
{
106
while
(repartCount
>
0
||
repartCount
==
0
)
{
107
108
if
(
!
display.isDisposed())
{
109
Runnable runnable
=
new
Runnable()
{
110
public
void
run()
{
111
112
final
Image offScreenImage
=
new
Image(display, loader.logicalScreenWidth,
113
loader.logicalScreenHeight);
114
final
GC offScreenImageGC
=
new
GC(offScreenImage);
115
ImageData imageData
=
imageDataArray[index];
116
Image temp
=
new
Image(display, imageData);
117
118
if
(imageData.disposalMethod
==
SWT.DM_FILL_BACKGROUND)
{
119
//
Fill with the background color before
120
//
drawing.
121
Color bgColor
=
null
;
122
int
backgroundPixel
=
loader.backgroundPixel;
123
if
(backgroundPixel
!=
-
1
)
{
124
//
Fill with the background color.
125
RGB backgroundRGB
=
imageData.palette.getRGB(backgroundPixel);
126
bgColor
=
new
Color(
null
, backgroundRGB);
127
}
128
try
{
129
offScreenImageGC.setBackground(bgColor
!=
null
?
bgColor : canvasBackground);
130
offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width,
131
imageData.height);
132
}
finally
{
133
if
(bgColor
!=
null
)
134
bgColor.dispose();
135
}
136
}
else
if
(imageData.disposalMethod
==
SWT.DM_FILL_PREVIOUS)
{
137
//
Restore the previous image before
138
//
drawing.
139
offScreenImageGC.drawImage(temp,
0
,
0
, imageData.width, imageData.height, imageData.x,
140
imageData.y, imageData.width, imageData.height);
141
}
142
143
offScreenImageGC.drawImage(temp,
0
,
0
, imageData.width, imageData.height, imageData.x,
144
imageData.y, imageData.width, imageData.height);
145
//
146
drawImage(gc, offScreenImage);
147
//
148
149
offScreenImage.dispose();
150
temp.dispose();
151
offScreenImageGC.dispose();
152
}
153
}
;
154
155
display.asyncExec(runnable);
156
Thread.sleep(imageData.delayTime
*
10
);
157
index
++
;
158
if
(index
==
imageNumber)
159
index
=
0
;
160
161
//
162
}
163
164
}
165
}
catch
(Exception ex)
{
166
}
167
}
168
}
169
170
/** */
/**
171
*
172
*
@param
parent
173
*
@param
style only support SWT.CENTER | ISALLOWSCROLLIMAGE
174
*/
175
public
HImage(Composite parent ,
int
style)
{
176
super
(parent, (style
&
ISALLOWSCROLLIMAGE)
!=
0
?
SWT.BORDER
|
SWT.H_SCROLL
|
SWT.V_SCROLL
|
SWT.NO_BACKGROUND : SWT.BORDER
177
|
SWT.NO_BACKGROUND);
178
179
this
.parent
=
parent;
180
181
this
.style
=
style;
182
183
//
setInputStream(input);
184
canvasBackground
=
this
.getBackground();
185
186
this
.addPaintListener(
new
HImagePaintListener(
this
));
187
this
.addDisposeListener(
new
DisposeListener()
{
188
public
void
widgetDisposed(DisposeEvent e)
{
189
imageDataArray
=
null
;
190
loader
=
null
;
191
}
192
}
);
193
this
.addControlListener(
new
ControlListener()
{
194
195
public
void
controlMoved(ControlEvent e)
{
196
//
TODO Auto-generated method stub
197
198
}
199
200
public
void
controlResized(ControlEvent e)
{
201
//
TODO Auto-generated method stub
202
resetScrollBars();
203
}
204
}
);
205
206
207
}
208
209
public
void
setInputStream(InputStream input)
{
210
if
(input
==
null
)
return
;
211
this
.input
=
input;
212
loader
=
new
ImageLoader();
213
loader.load(input);
214
if
(loader.data.length
>
1
)
{
215
isGif
=
true
;
216
imageNumber
=
loader.data.length;
217
imageDataArray
=
loader.data;
218
repartCount
=
loader.repeatCount;
219
}
220
image
=
new
Image(display, loader.data[
0
]);
221
imageData
=
loader.data[
0
];
222
223
if
((style
&
this
.ISALLOWSCROLLIMAGE)
!=
0
)
{
224
//
Set up the image canvas scroll bars.
225
ScrollBar horizontal
=
this
.getHorizontalBar();
226
horizontal.setVisible(
true
);
227
horizontal.setMinimum(
0
);
228
horizontal.setEnabled(
false
);
229
horizontal.addSelectionListener(
new
SelectionAdapter()
{
230
public
void
widgetSelected(SelectionEvent event)
{
231
scrollHorizontally((ScrollBar) event.widget);
232
}
233
}
);
234
ScrollBar vertical
=
this
.getVerticalBar();
235
vertical.setVisible(
true
);
236
vertical.setMinimum(
0
);
237
vertical.setEnabled(
false
);
238
vertical.addSelectionListener(
new
SelectionAdapter()
{
239
public
void
widgetSelected(SelectionEvent event)
{
240
scrollVertically((ScrollBar) event.widget);
241
}
242
}
);
243
}
244
245
resetScrollBars();
246
this
.redraw();
247
}
248
249
protected
void
checkWidget()
{
250
251
}
252
253
protected
synchronized
void
drawGifImage(GC canvasGC)
{
254
final
GC gc
=
new
GC(
this
);
255
if
(thread
!=
null
)
{
256
thread.interrupt();
257
thread
=
null
;
258
}
259
thread
=
new
GifPaintThread(gc,
this
);
260
thread.setDaemon(
true
);
261
thread.start();
262
}
263
264
protected
synchronized
void
drawImage(
final
GC imagegc, Image image)
{
265
GC gc
=
imagegc;
266
267
/**/
/*
268
* Scale the image when drawing
269
*/
270
int
w
=
Math.round(imageData.width
*
xscale);
271
int
h
=
Math.round(imageData.height
*
yscale);
272
273
/**/
/*
274
* If any of the background is visible, fill it with the background
275
* color.
276
*/
277
Rectangle bounds
=
this
.getBounds();
278
if
(image.getImageData().getTransparencyType()
!=
SWT.TRANSPARENCY_NONE)
{
279
/**/
/*
If there is any transparency at all, fill the whole background.
*/
280
gc.fillRectangle(
0
,
0
, bounds.width, bounds.height);
281
}
else
{
282
/**/
/*
Otherwise, just fill in the backwards L.
*/
283
if
(ix
+
w
<
bounds.width)
284
gc.fillRectangle(ix
+
w,
0
, bounds.width
-
(ix
+
w), bounds.height);
285
if
(iy
+
h
<
bounds.height)
286
gc.fillRectangle(
0
, iy
+
h, ix
+
w, bounds.height
-
(iy
+
h));
287
}
288
289
/**/
/*
Draw the image
*/
290
if
((style
&
this
.ISALLOWSCROLLIMAGE)
!=
0
)
{
291
gc.drawImage(image,
0
,
0
, imageData.width, imageData.height, ix
+
imageData.x, iy
+
imageData.y, w, h);
292
}
else
if
((style
&
SWT.CENTER)
!=
0
)
{
293
Point newpoint
=
checkDrawPoistion(image.getImageData());
294
gc.drawImage(image, newpoint.x, newpoint.y);
295
}
else
{
296
Image scaledImage
=
new
Image(display, image.getImageData().scaledTo(bounds.width, bounds.height));
297
gc.drawImage(scaledImage,
0
,
0
);
298
scaledImage.dispose();
299
}
300
}
301
302
/**/
/*
303
* Called when the image canvas' horizontal scrollbar is selected.
304
*/
305
synchronized
void
scrollHorizontally(ScrollBar scrollBar)
{
306
if
(image
==
null
)
307
return
;
308
Rectangle canvasBounds
=
this
.getClientArea();
309
int
width
=
Math.round(imageData.width
*
xscale);
310
int
height
=
Math.round(imageData.height
*
yscale);
311
if
(width
>
canvasBounds.width)
{
312
//
Only scroll if the image is bigger than the canvas.
313
int
x
=
-
scrollBar.getSelection();
314
if
(x
+
width
<
canvasBounds.width)
{
315
//
Don't scroll past the end of the image.
316
x
=
canvasBounds.width
-
width;
317
}
318
this
.scroll(x, iy, ix, iy, width, height,
false
);
319
ix
=
x;
320
}
321
322
}
323
324
/**/
/*
325
* Called when the image canvas' vertical scrollbar is selected.
326
*/
327
synchronized
void
scrollVertically(ScrollBar scrollBar)
{
328
if
(image
==
null
)
329
return
;
330
Rectangle canvasBounds
=
this
.getClientArea();
331
int
width
=
Math.round(imageData.width
*
xscale);
332
int
height
=
Math.round(imageData.height
*
yscale);
333
if
(height
>
canvasBounds.height)
{
334
//
Only scroll if the image is bigger than the canvas.
335
int
y
=
-
scrollBar.getSelection();
336
if
(y
+
height
<
canvasBounds.height)
{
337
//
Don't scroll past the end of the image.
338
y
=
canvasBounds.height
-
height;
339
}
340
this
.scroll(ix, y, ix, iy, width, height,
false
);
341
iy
=
y;
342
}
343
344
}
345
346
//
Reset the scroll bars to 0.
347
void
resetScrollBars()
{
348
if
(image
==
null
)
349
return
;
350
ix
=
0
;
351
iy
=
0
;
352
py
=
0
;
353
resizeScrollBars();
354
if
(
this
.getHorizontalBar()
!=
null
)
355
this
.getHorizontalBar().setSelection(
0
);
356
if
(
this
.getVerticalBar()
!=
null
)
357
this
.getVerticalBar().setSelection(
0
);
358
359
}
360
361
void
resizeScrollBars()
{
362
//
Set the max and thumb for the image canvas scroll bars.
363
ScrollBar horizontal
=
this
.getHorizontalBar();
364
ScrollBar vertical
=
this
.getVerticalBar();
365
if
(horizontal
!=
null
&&
vertical
!=
null
)
{
366
367
Rectangle canvasBounds
=
this
.getClientArea();
368
int
width
=
Math.round(imageData.width
*
xscale);
369
if
(width
>
canvasBounds.width)
{
370
//
The image is wider than the canvas.
371
horizontal.setEnabled(
true
);
372
horizontal.setMaximum(width);
373
horizontal.setThumb(canvasBounds.width);
374
horizontal.setPageIncrement(canvasBounds.width);
375
}
else
{
376
//
The canvas is wider than the image.
377
horizontal.setEnabled(
false
);
378
if
(ix
!=
0
)
{
379
//
Make sure the image is completely visible.
380
ix
=
0
;
381
this
.redraw();
382
}
383
}
384
int
height
=
Math.round(imageData.height
*
yscale);
385
if
(height
>
canvasBounds.height)
{
386
//
The image is taller than the canvas.
387
vertical.setEnabled(
true
);
388
vertical.setMaximum(height);
389
vertical.setThumb(canvasBounds.height);
390
vertical.setPageIncrement(canvasBounds.height);
391
}
else
{
392
//
The canvas is taller than the image.
393
vertical.setEnabled(
false
);
394
if
(iy
!=
0
)
{
395
//
Make sure the image is completely visible.
396
iy
=
0
;
397
this
.redraw();
398
}
399
}
400
}
401
}
402
403
/** */
/**
404
* just get center of Canvas point
405
*
406
*
@param
imageData
407
*
@return
408
*/
409
protected
Point checkDrawPoistion(ImageData imageData)
{
410
411
int
height
=
Math.round(imageData.height
*
yscale);
412
int
width
=
Math.round(imageData.width
*
xscale);
413
Rectangle canvasBounds
=
this
.getClientArea();
414
Point point
=
new
Point(
0
,
0
);
415
416
if
((style
&
SWT.CENTER)
!=
0
)
{
417
if
(width
<
canvasBounds.width)
418
point.x
=
Math.round(canvasBounds.width
/
2
-
width
/
2
);
419
if
(height
<
canvasBounds.height)
420
point.y
=
Math.round(canvasBounds.height
/
2
-
height
/
2
);
421
}
422
return
point;
423
}
424
}
425
另外极度详细超级good的参考资料,这个控件的大部分代码都是参考他的。 http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html
|