设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

创建一个Swing组件—JImageComponent

2014-7-18 12:03| 发布者: joejoe0332| 查看: 4555| 评论: 0|原作者: LeoXu, -多啦A梦-|来自: oschina

摘要: 下载示例项目 - 19.2 KB下载示例 - 15.7 KB下载源代码 - 13.4 KB 介绍Introduction 本文展示了如何使用Java™来创建一个用来在Java™ 的applet和/或应用程序中展示图片的Swing类. 它还包括了使得图片渲染加快需要 ...


5.实现绘制图像的功能

这是你的类真正的核心功能。你将需要确保你的类在图像只部分可见时,能够只画出其自身的一部分, 还要确保其在设置、加载、修改或者编辑时能够重新绘制其自身. 依赖于你扩展的父类,你可能需要重写和绘制图像有关的几个方法.

Swing 的 JComponent 为我们做了大部分的重要工作 . JImageComponent 重写了 paint(java.awt.Graphics) 方法, 还有两个 paintImmediately() 方法. 注意力主要需要放在由组件的可见矩形所指定的图像的绘制上. 这将会在讨论用于滚动容器中的功能的实现时解释.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
     * @see javax.swing.JComponent#paint(java.awt.Graphics)
     */
    @Override
    public void paint(Graphics g) {
         
        // Exit if no image is loaded.
        if (this.bufferedImage == null) {
            return;
        }
         
        // Paint the visible region.
        Rectangle rectangle = this.getVisibleRect();
        paintImmediately(g, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
    };
 
    /*
     * @see javax.swing.JComponent#paintImmediately(int, int, int, int)
     */
    @Override
    public void paintImmediately(int x, int y, int width, int height) {
         
        // Exit if no image is loaded.
        if (this.bufferedImage == null) {
            return;
        }
         
        // Paint the region specified.
        this.paintImmediately(super.getGraphics(), x, y, width, height);
    }
 
    /*
     * @see javax.swing.JComponent#paintImmediately(java.awt.Rectangle)
     */
    @Override
    public void paintImmediately(Rectangle rectangle) {
         
        // Exit if no image is loaded.
        if (this.bufferedImage == null) {
            return;
        }
         
        // Paint the region specified.
        this.paintImmediately(super.getGraphics(), rectangle.x, rectangle.y, rectangle.width, rectangle.height);
    }

简单起见,JImageComponent 会有一个私有的方法 ,paintImmediately(Graphics, int, int, int, int) ,来做实际上的图形的绘制.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
     * Paints the image onto the component.
     
     * @param g
     *        The <code>Graphics object of the component onto which the
     *        image region will be painted.
     * @param x
     *        The x value of the region to be painted.
     * @param y
     *        The y value of the region to be painted.
     * @param width
     *        The width of the region to be painted.
     * @param height
     *        The width of the region to be painted.
     */
    private void paintImmediately(Graphics g, int x, int y, int width, int height) {
         
        // Exit if no image is loaded.
        if (this.bufferedImage == null) {
            return;
        }
         
        int imageWidth = this.bufferedImage.getWidth();
        int imageHeight = this.bufferedImage.getHeight();
         
        // Exit if the dimension is beyond that of the image.
        if (x >= imageWidth || y >= imageHeight) {
            return;
        }
         
        // Calculate the rectangle of the image that should be rendered.
        int x1 = x < 0 0 : x;
        int y1 = y < 0 0 : y;
        int x2 = x + width - 1;
        int y2 = y + height - 1;
         
        if (x2 >= imageWidth) {
            x2 = imageWidth - 1;
        }
         
        if (y2 >= imageHeight) {
            y2 = imageHeight - 1;
        }
         
        // Draw the image.
        g.drawImage(this.bufferedImage, x1, y1, x2, y2, x1, y1, x2, y2, null);
    }

6. 实现当处在一个滚动容器中时的组件绘制

需要解决的一个挑战是,如何绘制一张被用于滚动容器中的图像. 例如,一个开发者可能会想要将一张尺寸超出可视边界的图像放到一个 JScrollPane 容器中.

JImageComponent通过做下面三件事情来解决了这个问题:

  • 当图片被设置/加载时,设置组件的边界.
    (这已经是完成了的.)

  • 在绘制图像时,注意组件的可是矩形.
    (这也已经是完成了的.)

  • 提供带有适当布局细节的布局管理器.

你可能需要实现在你想要确保你的组件在滚动容器中可以被正确渲染时,能提供带有适当布局细节的布局管理器的功能.

JImageComponent 通过重写如下的方法提供必要的布局详细:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
     * Returns the height of the image.
     */
    @Override
    public int getHeight() {
        if (this.bufferedImage == null) {
            return 0;
        }
         
        return this.bufferedImage.getHeight();
    }
 
    /**
     * Returns the size of the image.
     */
    @Override
    public Dimension getPreferredSize() {
        if (this.bufferedImage == null) {
            return new Dimension(00);
        }
         
        return new Dimension(this.bufferedImage.getWidth(), this.bufferedImage.getHeight());
    }
 
    /**
     * Returns the size of the image.
     */
    @Override
    public Dimension getSize() {
        if (this.bufferedImage == null) {
            return new Dimension(00);
        }
         
        return new Dimension(this.bufferedImage.getWidth(), this.bufferedImage.getHeight());
    }
 
    /**
     * Returns the width of the image.
     */
    @Override
    public int getWidth() {
        if (this.bufferedImage == null) {
            return 0;
        }
         
        return this.bufferedImage.getWidth();
    }

7. 实现编辑图像的功能

在编辑图像时许多的实例将会比持续的修改图像来得更加高效. 一个例子就是当你想要展示一个动画的时候,修改每张动画图像改变的区域,会比在内存中创建一张图像并在组件中对其进行设置更加高效.

JImageComponent 通过提供一个访问其 BufferedImage的方法,以及一个访问图像的 Graphics 对象的方法来允许这个功能.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
     * Returns the <code>BufferedImage object for the image.
     
     * @return The buffered image.
     */
    public BufferedImage getBufferedImage() {
        return this.bufferedImage;
    }
 
    /**
     * Returns the Graphics object for the image.
     */
    @Override
    public Graphics getGraphics() {
        return this.imageGraphics;
    }

JImageComponent 还提供了一个用来调整/转换图像的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
     * Resizes the image to the given dimensions and type. 
 
     * Note that the image is "cropped" from the left top corner).
     
     * @param width
     *        The new width of the image.
     * @param height
     *        The new height of the image.
     * @param imageType
     *        The new image type (<code>BufferedImage type)
     * @see type java.awt.image.BufferedImage#BufferedImage(int, int, int)
     */
    public void resize(int width, int height, int imageType) {
         
        // Create a new image if none is loaded.
        if (this.bufferedImage == null) {
            setBufferedImage(new BufferedImage(width, height, imageType));
            return;
        }
         
        // Create a new temporary image.
        BufferedImage tempImage = new BufferedImage(width, height, imageType);
        int w = this.bufferedImage.getWidth();
        int h = this.bufferedImage.getHeight();
         
        // Crop width if necessary.
        if (width < w) {
            w = width;
        }
         
        // Crop height if necessary.
        if (height < h) {
            h = height;
        }
         
        // Copy if the type is the same.
        if (this.bufferedImage.getType() == imageType) {
             
            Graphics g = tempImage.getGraphics();
            g.drawImage(this.bufferedImage, 00, w, h, null);
        }
         
        // Copy pixels to force conversion.
        else {
             
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    tempImage.setRGB(x, y, this.bufferedImage.getRGB(x, y));
                }
            }
        }
         
        // Set the new image.
        setBufferedImage(tempImage);
    }



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部