前面介绍了AWT的几种基础控件,从按钮到文本标签,从输入框到选择框,无一例外都能显示文字,唯独无法显示某张图片文件。本以为AWT会提供专门的控件来显示图片,然而偏偏没有意料之中的图像控件,这可真是弱爆了,居然不能显示姹紫嫣红的图片,让程序员情何以堪呀。不过咱程序员不是吃素的,与其坐等天上掉馅饼,不如自己动手编写符合要求的图像视图。AWT自带的界面控件,大多由Component类派生而来,该类与展示有关的方法主要有下列两个:
getPreferredSize:该方法可返回控件的推荐宽高。
paint:该方法可使用画笔Graphics绘制具体的图案,包括各种形状、文字与图像。
看来若想自定义一个新控件,只需重写getPreferredSize和paint两个方法就好了,原来就这么简单。可是对于新手来说,天晓得要怎样把图片画到界面上,一方面不知道AWT利用哪种工具读写图片,另一方面也不知道怎样用画笔描绘图像。目前为止只知晓图片文件可以用File工具打开,且AWT控件属于Component家族,其余的中间过程完全是一团抓瞎。譬如下面的流程图描述了AWT显示图片文件的步骤。


上图的好几处地方尚不明确,例如:怎样把图片文件读到AWT的缓存当中?AWT的缓存是什么对象类型?怎样把缓存的图像数据描绘到控件上?这些问题若是不弄清楚,前头说的图像视图根本没法做。当然,AWT确实提供了每个环节需要的工具,尽管有些繁琐,但毕竟能用。这些工具的名称及其用法简要说明如下:
1、图像缓存类BufferedImage,它是AWT专用的图像缓存工具,里面保存着临时的图像数据。
2、图像输入输出工具ImageIO,它是AWT读写图片文件的利器,其中read方法可将图片文件读到图像缓存中,而write方法可将图像缓存保存为图片文件。
3、画笔工具Graphics,前述paint方法的输入参数正是Graphics类型,只要调用画笔对象的drawImage方法,即可在控件上绘制图像缓存。
现在有了上面三个工具,把它们替换进先前AWT显示图片的流程图,完善后的流程图就变成了下面这般:


啧啧,显示图片的流程一下子变得清晰了,通过BufferedImage、ImageIO、Graphics三板斧的协助,在控件上显示图片不再是难事了。依据流程图给出的思路,接着便能编写图像视图的自定义代码了,下面是支持显示图片文件的图像视图代码例子:

//定义一个显示图片用的图像视图
public class ImageView extends Component {
private static final long serialVersionUID = 1L;
private BufferedImage image; // 声明一个缓存图像 // 设置图片路径
public void setImagePath(String path) {
try {
image = ImageIO.read(new File(path)); // 把指定路径的图片文件读到缓存图像
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void paint(Graphics g) { // 绘制控件的方法
if (image != null) {
if (getWidth() > 0 && getHeight() > 0) { // 有指定宽高
g.drawImage(image, 0, 0, getWidth(), getHeight(), null); // 按指定宽高绘制图像
} else { // 未指定宽高
g.drawImage(image, 0, 0, null); // 按原尺寸绘制图像
}
}
} @Override
public Dimension getPreferredSize() { // 获取控件的推荐宽高
if (image != null) {
if (getWidth() > 0 && getHeight() > 0) { // 有指定宽高
return new Dimension(getWidth(), getHeight()); // 返回setSize方法指定的宽高
} else { // 未指定宽高
return new Dimension(image.getWidth(), image.getHeight()); // 返回图像的宽高
}
} else {
return new Dimension(0, 0); // 无图像则隐藏控件
}
}
}

然后回到主界面的代码,先创建图像视图的控件对象,再设置该控件的宽高,以及待显示的图片文件路径,最后将图像控件添加到面板上,主要的调用代码如下所示:

		Panel panel = new Panel(); // 创建一个面板
ImageView imageView = new ImageView(); // 创建一个自定义的图像视图
imageView.setSize(320, 240); // 设置图像视图的宽高
imageView.setImagePath("E:/apple.png"); // 在图像视图上显示指定路径的图片
panel.add(imageView); // 在面板上添加图像视图
frame.add(panel); // 在窗口上添加面板

运行以上的图像控件代码,弹出的窗口界面如下图所示,可见面板成功展示了指定的图片。


更多Java技术文章参见《Java开发笔记(序)章节目录

Java开发笔记(一百二十三)AWT图像视图的更多相关文章

  1. Java开发笔记(二十三)数组工具Arrays

    数组作为一种组合形式的数据类型,必然要求提供一些处理数组的简便办法,包括数组比较.数组复制.数组排序等等.为此Java专门设计了Arrays工具,该工具包含了几个常用方法,方便程序员对数组进行加工操作 ...

  2. Java开发笔记(八十三)利用注解技术检查空指针

    注解属于比较高级的Java开发技术,前面介绍的内置注解专用于编译器检查代码,另外一些注解则由各大框架定义与调用,像Web开发常见的Spring框架.Mybatis框架,Android开发常见的Butt ...

  3. Java开发笔记(二十四)方法的组成形式

    经过前面的学习,我们发现演示的Java代码越来越复杂,而且每个例子的代码都堆在入口方法main内部,这会导致如下问题:1.一个方法内部堆砌了太多的代码行,看着费神,维护起来也吃力:2.部分代码描述的是 ...

  4. Java开发笔记(二十五)方法的输入参数

    前面通过main方法介绍了方法的定义形式,对于方法的输入参数来说,还有几个值得注意的地方,接下来分别对输入参数的几种用法进行阐述.一个方法可以有输入参数,也可以没有输入参数,倘若无需输入参数,则方法定 ...

  5. Java开发笔记(二十六)方法的输出参数

    前面介绍了方法的输入参数,与输入参数相对应的则为输出参数,输出参数也被称作方法的返回值,意思是经过方法的处理最终得到的运算数值.这个返回值可能是整型数,也可能是双精度数,也可能是数组等其它类型,甚至允 ...

  6. Java开发笔记(二十七)数值包装类型

    方法的出现缘起优化代码结构,但它的意义并不局限于此,正因为有了方法定义,编程语言才更像一门能解决实际问题的工具,而不仅仅是只能用于加减乘除的计算器.在数学的发展过程中,为了表示四则运算,人们创造了加减 ...

  7. Java开发笔记(二十八)布尔包装类型

    前面介绍了数值包装类型,因为不管是整数还是小数,它们的运算操作都是类似的,所以只要学会了Integer的用法,其它数值包装类型即可一并掌握.但是对于布尔类型boolean来说,该类型定义的是“true ...

  8. Java开发笔记(二十九)大整数BigInteger

    早期的编程语言为了节约计算机的内存,给数字变量定义了各种存储规格的数值类型,比如字节型byte只占用一个字节大小,短整型short占用两个字节大小,整型int占用四个字节大小,长整型long占用八个字 ...

  9. Java开发笔记(三十三)字符包装类型

    正如整型int有对应的包装整型Integer那样,字符型char也有对应的包装字符型Character.初始化字符包装变量也有三种方式,分别是:直接用等号赋值.调用包装类型的valueOf方法.使用关 ...

  10. Java开发笔记(四十三)更好用的本地日期时间

    话说Java一连设计了两套时间工具,分别是日期类型Date,以及日历类型Calendar,按理说用在编码开发中绰绰有余了.然而随着Java的日益广泛使用,人们还是发现了它们的种种弊端.且不说先天不良的 ...

随机推荐

  1. Mycat 全局系列号(转载)

    概述 本篇文章介绍mycat怎样在分库分表的情况下保证主键的全局唯一方法,接下来就来分析三种方法各自的优缺点. 配置 文件方式获取 1.修改server配置文件 vim server.xml < ...

  2. 解决IE报错:Locale 'chinese' is not well-formed,或RangeError: 区域设置“chinese”的格式不正确的问题

    接之前的此博客问题处理:js处理时间时区问题 由于 toLocaleString():据本地时间格式,把 Date 对象转换为字符串.总是会带有上午/下午,所以我加了参数:new Date('2019 ...

  3. c++ Size capacity Resize reserve shrink_to_fit

  4. 【UVA11988】破损的键盘

    题目链接 维护一个链表,以及当前位置.head.tail的指针,模拟就行了 #include<iostream> #include<cstring> #include<c ...

  5. PHP 之循环创建文件夹

    /** * 循环创建文件夹 * @param string $dir 需要创建的文件夹路径 * @param integer $mode 文件夹权限 * @return bool 返回创建是否成功 * ...

  6. vue+element 表格导出Excel文件

    https://www.cnblogs.com/bobodeboke/p/8867481.html  非常感谢 这个大佬 才让我搞到了Blob.js 和 Export2Excel.js 如果最后运行时 ...

  7. 【大数据作业九】安装关系型数据库MySQL 安装大数据处理框架Hadoop

    作业要求:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 4.简述Hadoop平台的起源.发展历史与应用现状. 列举发展过程中 ...

  8. Linux在线安装Redis

    一.进入Redis官网寻找需要下载的版本:https://redis.io/ 将下载地址链接复制下来:http://download.redis.io/releases/redis-5.0.7.tar ...

  9. 第06组 Beta冲刺(4/5)

    队名:拾光组 组长博客链接 作业博客链接 团队项目情况 燃尽图(组内共享) 组长:宋奕 过去两天完成了哪些任务 继续维护后端代码 继续学习深入python 继续研究匿名拨打电话问题.套牌多结果处理问题 ...

  10. how does SELECT TOP works when no order by is specified?

    how does SELECT TOP works when no order by is specified? There is no guarantee which two rows you ge ...