因为SWT的ImageLoader支持读写以上所有格式的图片,所以实现起来比较简单。主要解决了两个问题。第一个问题是播放GIF动画,通过 ImageLoader读入GIF的所有帧以及间隔时间,然后用Display.timerExec实现Timer播放。第二个问题是对图片的 Scrollbar支持以及pack支持。SWT.H_SCROLL和SWT.V_SCROLL 虽然加上了滚动条,但是不起作用,需要监听滚动条的SWT.Selection事件。另外,加上滚动条后,pack无法得到大小,不能正确的pack。需要重载computeSize。
- /**
- * 负责显示各种格式的图片
- *
- * @author 喜来乐哈哈
- */
- public class ImageViewer extends Canvas {
- protected Point origin = new Point( 0 , 0 );
- protected Image image;
- protected ImageData[] imageDatas;
- protected Image[] images;
- protected int current;
- private int repeatCount;
- private Runnable animationTimer;
- private ScrollBar hBar;
- private ScrollBar vBar;
- private Color bg;
- private Display display;
- public ImageViewer(Composite parent) {
- 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(ImageData imageData) {
- checkWidget();
- stopAnimationTimer();
- this .image = new Image(display, imageData);
- this .imageDatas = null ;
- this .images = null ;
- redraw();
- }
- /**
- * @param repeatCount 0 forever
- */
- public void setImages(ImageData[] imageDatas, int repeatCount) {
- checkWidget();
- this .image = null ;
- this .imageDatas = imageDatas;
- this .repeatCount = repeatCount;
- convertImageDatasToImages();
- startAnimationTimer();
- redraw();
- }
- @Override
- public Point computeSize( int wHint, int hHint, boolean changed) {
- checkWidget();
- Image image = getCurrentImage();
- if (image != null ) {
- Rectangle rect = image.getBounds();
- Rectangle trim = 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(Event e) {
- Image image = getCurrentImage();
- if (image == null )
- return ;
- GC gc = e.gc;
- gc.drawImage(image, origin.x, origin.y);
- gc.setBackground(bg);
- Rectangle rect = image.getBounds();
- Rectangle client = 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(Event arg0) {
- hscroll();
- }
- });
- vBar.addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event arg0) {
- vscroll();
- }
- });
- addListener(SWT.Resize, new Listener() {
- public void handleEvent(Event e) {
- resize();
- }
- });
- addListener(SWT.Paint, new Listener() {
- public void handleEvent(Event e) {
- paint(e);
- }
- });
- }
- void hscroll() {
- Image image = getCurrentImage();
- if (image != null ) {
- int hSelection = hBar.getSelection();
- int destX = - hSelection - origin.x;
- Rectangle rect = image.getBounds();
- scroll(destX, 0 , 0 , 0 , rect.width, rect.height, false );
- origin.x = - hSelection;
- }
- }
- void vscroll() {
- Image image = getCurrentImage();
- if (image != null ) {
- int vSelection = vBar.getSelection();
- int destY = - vSelection - origin.y;
- Rectangle rect = image.getBounds();
- scroll( 0 , destY, 0 , 0 , rect.width, rect.height, false );
- origin.y = - vSelection;
- }
- }
- void resize() {
- Image image = getCurrentImage();
- if (image == null )
- return ;
- Rectangle rect = image.getBounds();
- Rectangle client = 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];
- // Step 1: Determine the size of the resulting images.
- int width = imageDatas[ 0 ].width;
- int height = imageDatas[ 0 ].height;
- // Step 2: Construct each image.
- int transition = SWT.DM_FILL_BACKGROUND;
- for ( int i = 0 ; i < imageDatas.length; i ++ ) {
- ImageData id = imageDatas[i];
- images[i] = new Image(display, width, height);
- GC gc = new GC(images[i]);
- // Do the transition from the previous image.
- switch (transition) {
- case SWT.DM_FILL_NONE:
- case SWT.DM_UNSPECIFIED:
- // Start from last image.
- gc.drawImage(images[i - 1 ], 0 , 0 );
- break ;
- case SWT.DM_FILL_PREVIOUS:
- // Start from second last image.
- gc.drawImage(images[i - 2 ], 0 , 0 );
- break ;
- default :
- // DM_FILL_BACKGROUND or anything else,
- // just fill with default background.
- gc.setBackground(bg);
- gc.fillRectangle( 0 , 0 , width, height);
- break ;
- }
- // Draw the current image and clean up.
- Image img = 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();
- // Compute the next transition.
- // Special case: Can't do DM_FILL_PREVIOUS on the
- // second image since there is no "second last"
- // image to use.
- transition = id.disposalMethod;
- if (i == 0 && transition == SWT.DM_FILL_PREVIOUS)
- transition = SWT.DM_FILL_NONE;
- }
- }
- Image getCurrentImage() {
- 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 Point origin = new Point( 0 , 0 ); protected Image image; protected ImageData[] imageDatas; protected Image[] images; protected int current; private int repeatCount; private Runnable animationTimer; private ScrollBar hBar; private ScrollBar vBar; private Color bg; private Display display; public ImageViewer(Composite parent) { 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(ImageData imageData) { checkWidget(); stopAnimationTimer(); this .image = new Image(display, imageData); this .imageDatas = null ; this .images = null ; redraw(); } /** * @param repeatCount 0 forever */ public void setImages(ImageData[] imageDatas, int repeatCount) { checkWidget(); this .image = null ; this .imageDatas = imageDatas; this .repeatCount = repeatCount; convertImageDatasToImages(); startAnimationTimer(); redraw(); } @Override public Point computeSize( int wHint, int hHint, boolean changed) { checkWidget(); Image image = getCurrentImage(); if (image != null ) { Rectangle rect = image.getBounds(); Rectangle trim = 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(Event e) { Image image = getCurrentImage(); if (image == null ) return ; GC gc = e.gc; gc.drawImage(image, origin.x, origin.y); gc.setBackground(bg); Rectangle rect = image.getBounds(); Rectangle client = 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(Event arg0) { hscroll(); } }); vBar.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { vscroll(); } }); addListener(SWT.Resize, new Listener() { public void handleEvent(Event e) { resize(); } }); addListener(SWT.Paint, new Listener() { public void handleEvent(Event e) { paint(e); } }); } void hscroll() { Image image = getCurrentImage(); if (image != null ) { int hSelection = hBar.getSelection(); int destX = - hSelection - origin.x; Rectangle rect = image.getBounds(); scroll(destX, 0 , 0 , 0 , rect.width, rect.height, false ); origin.x = - hSelection; } } void vscroll() { Image image = getCurrentImage(); if (image != null ) { int vSelection = vBar.getSelection(); int destY = - vSelection - origin.y; Rectangle rect = image.getBounds(); scroll( 0 , destY, 0 , 0 , rect.width, rect.height, false ); origin.y = - vSelection; } } void resize() { Image image = getCurrentImage(); if (image == null ) return ; Rectangle rect = image.getBounds(); Rectangle client = 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]; // Step 1: Determine the size of the resulting images. int width = imageDatas[ 0 ].width; int height = imageDatas[ 0 ].height; // Step 2: Construct each image. int transition = SWT.DM_FILL_BACKGROUND; for ( int i = 0 ; i < imageDatas.length; i ++ ) { ImageData id = imageDatas[i]; images[i] = new Image(display, width, height); GC gc = new GC(images[i]); // Do the transition from the previous image. switch (transition) { case SWT.DM_FILL_NONE: case SWT.DM_UNSPECIFIED: // Start from last image. gc.drawImage(images[i - 1 ], 0 , 0 ); break ; case SWT.DM_FILL_PREVIOUS: // Start from second last image. gc.drawImage(images[i - 2 ], 0 , 0 ); break ; default : // DM_FILL_BACKGROUND or anything else, // just fill with default background. gc.setBackground(bg); gc.fillRectangle( 0 , 0 , width, height); break ; } // Draw the current image and clean up. Image img = 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(); // Compute the next transition. // Special case: Can't do DM_FILL_PREVIOUS on the // second image since there is no "second last" // image to use. transition = id.disposalMethod; if (i == 0 && transition == SWT.DM_FILL_PREVIOUS) transition = SWT.DM_FILL_NONE; } } Image getCurrentImage() { 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); } }
测试程序
- public class ImageCanvasTest {
- public static void main(String[] args) {
- Display display = new Display();
- final Shell shell = new Shell(display);
- ImageViewer ic = new ImageViewer(shell);
- shell.setLayout( new FillLayout());
- FileDialog dialog = new FileDialog(shell, SWT.OPEN);
- dialog.setText( " Open an image file or cancel " );
- String string = dialog.open();
- ImageLoader loader = 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 class ImageCanvasTest { public static void main(String[] args) { Display display = new Display(); final Shell shell = new Shell(display); ImageViewer ic = new ImageViewer(shell); shell.setLayout( new FillLayout()); FileDialog dialog = new FileDialog(shell, SWT.OPEN); dialog.setText( " Open an image file or cancel " ); String string = dialog.open(); ImageLoader loader = 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动画了。
相关推荐
压缩包中的图像文件可能是用于模拟SWT控件状态的,如radiobutton_checked.gif和checkbox_checked.gif分别表示单选按钮和复选框的选中状态,而未选中状态的图片则表示它们的非选中状态。textarea_1.gif和textarea_2....
开发者可以通过编程逻辑控制这些图片的显示,来模拟选中和未选中的视觉效果。 实现这个功能的基本步骤包括: 1. 创建一个自定义的Draw2D图形对象,比如继承自GFShape,然后覆盖paint方法来绘制RadioButton和...
此外,文章还提到了动画(GIF animation),解释了如何在SWT中实现图像序列的播放,以创建动态效果。 在图像缩放(`Scaling`)部分,讲述了如何调整图像大小,以适应不同的显示需求。这通常涉及到图像的拉伸或保持...
`16.gif` 文件是用于图标显示的图形资源,`swt.jar` 是SWT库的依赖,它包含了SWT相关的类和方法。 总的来说,了解如何在不同环境下创建系统托盘图标对于开发跨平台的应用程序至关重要,这使得用户即使在应用程序...
* 但这时候图像是平铺的,就是背景图片不断重复,不重复的操作:在上一步显示的图片后/*.jpg ”接着按空格键(选择style,按回车)style=background-repeat(按回车)--no repeat * 把Flash背景设成透明色:先单击...
"显示一个套餐问题修复.txt"可能是一个针对某个特定问题的修复文档,比如当系统只能显示一个套餐时,商家可以参考这个文件来解决这个问题,确保所有套餐都能正常显示。 总的来说,这个压缩包提供的资源涵盖了ECSHOP...
Green UML支持动态添加和删除类图中的关联,还可以将类图导出为jpg和gif格式。 7. **Tribix**:Tribix扩展了BIRT(Business Intelligence and Reporting Tools)的Emitter,增加了PPT和XLS格式的支持,使得BIRT报告...
确保将图片资源添加到项目的`icons`目录,并在`plugin.xml`中引用。 7. **HTML文档**:`ljllql.htm`和`ljllql_files`可能是一份关于如何开发Eclipse视图插件的教程或指南,里面可能包含了详细的步骤和示例代码。 ...
- **goods.swt**:可能是商品相关的一种配置文件,包含商品信息或与套餐相关的设置。 - **需要删除代码说明.txt**:这个文件提供了关于如何删除不需要的代码或功能的指南,可能是因为插件中包含了部分冗余或特定需求...
它具有高效、跨平台的特性,允许开发者快速构建动态网页。 2. **响应式设计**:妇科医院网站源码采用了响应式布局,确保网站在不同设备上(如桌面、平板电脑、智能手机)都能自适应显示,提供良好的用户体验。 3. ...
QString file = QFileDialog::getOpenFileName(this, "Select a Picture of Target File", "", "*.jpg *.png *.tif *.gif"); ``` 这行代码将弹出一个文件选择对话框,让用户选择一个图片文件。 #### 六、自定义...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明...
摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明...
摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明...
- **MTrimmedWindow**:表示应用程序中的一个窗口,其底层的SWT shell使用SWT.SHELL_TRIM属性创建,这意味着它具有标题栏、最小化、最大化和调整大小按钮。 - **MPerspective**:表示透视图模型元素的对象。 - **...