Java开发笔记(一百二十三)AWT图像视图
前面介绍了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图像视图的更多相关文章
- Java开发笔记(二十三)数组工具Arrays
数组作为一种组合形式的数据类型,必然要求提供一些处理数组的简便办法,包括数组比较.数组复制.数组排序等等.为此Java专门设计了Arrays工具,该工具包含了几个常用方法,方便程序员对数组进行加工操作 ...
- Java开发笔记(八十三)利用注解技术检查空指针
注解属于比较高级的Java开发技术,前面介绍的内置注解专用于编译器检查代码,另外一些注解则由各大框架定义与调用,像Web开发常见的Spring框架.Mybatis框架,Android开发常见的Butt ...
- Java开发笔记(二十四)方法的组成形式
经过前面的学习,我们发现演示的Java代码越来越复杂,而且每个例子的代码都堆在入口方法main内部,这会导致如下问题:1.一个方法内部堆砌了太多的代码行,看着费神,维护起来也吃力:2.部分代码描述的是 ...
- Java开发笔记(二十五)方法的输入参数
前面通过main方法介绍了方法的定义形式,对于方法的输入参数来说,还有几个值得注意的地方,接下来分别对输入参数的几种用法进行阐述.一个方法可以有输入参数,也可以没有输入参数,倘若无需输入参数,则方法定 ...
- Java开发笔记(二十六)方法的输出参数
前面介绍了方法的输入参数,与输入参数相对应的则为输出参数,输出参数也被称作方法的返回值,意思是经过方法的处理最终得到的运算数值.这个返回值可能是整型数,也可能是双精度数,也可能是数组等其它类型,甚至允 ...
- Java开发笔记(二十七)数值包装类型
方法的出现缘起优化代码结构,但它的意义并不局限于此,正因为有了方法定义,编程语言才更像一门能解决实际问题的工具,而不仅仅是只能用于加减乘除的计算器.在数学的发展过程中,为了表示四则运算,人们创造了加减 ...
- Java开发笔记(二十八)布尔包装类型
前面介绍了数值包装类型,因为不管是整数还是小数,它们的运算操作都是类似的,所以只要学会了Integer的用法,其它数值包装类型即可一并掌握.但是对于布尔类型boolean来说,该类型定义的是“true ...
- Java开发笔记(二十九)大整数BigInteger
早期的编程语言为了节约计算机的内存,给数字变量定义了各种存储规格的数值类型,比如字节型byte只占用一个字节大小,短整型short占用两个字节大小,整型int占用四个字节大小,长整型long占用八个字 ...
- Java开发笔记(三十三)字符包装类型
正如整型int有对应的包装整型Integer那样,字符型char也有对应的包装字符型Character.初始化字符包装变量也有三种方式,分别是:直接用等号赋值.调用包装类型的valueOf方法.使用关 ...
- Java开发笔记(四十三)更好用的本地日期时间
话说Java一连设计了两套时间工具,分别是日期类型Date,以及日历类型Calendar,按理说用在编码开发中绰绰有余了.然而随着Java的日益广泛使用,人们还是发现了它们的种种弊端.且不说先天不良的 ...
随机推荐
- LeetCode 732. My Calendar III
原题链接在这里:https://leetcode.com/problems/my-calendar-iii/ 题目: Implement a MyCalendarThree class to stor ...
- MySQL 中间件 - DBLE 简单使用
DBLE 是企业级开源分布式中间件,江湖人送外号 “MyCat Plus”:以其简单稳定,持续维护,良好的社区环境和广大的群众基础得到了社区的大力支持: 环境准备 DBLE项目资料 DBLE官方网 ...
- 持续集成学习1 gitlab和jenkins安装
一.gitlab安装参照链接 https://www.cnblogs.com/linuxk/p/10100431.html 二.安装jenkins 1.获取jenkins源码包 https://blo ...
- Redis存储字符串
1.set和get实现字符串存取: 键的名字相同,会对以前的值进行覆盖: 2.++操作: 3.--操作: 4.加任意数值的数字: 5.减任意数值的数字: 6.拼接字符串: 7.删除:
- svn项目迁移至gitlab
关于svn项目迁移有人可能会说,新建一个git项目,把原来的代码直接扔进去提交不完了吗.恩,是的,没错.但是为了保留之前的历史提交记录,还是得做下面的步骤 首先确保本地正常安装配置好git,具体步骤不 ...
- HAVING 搜索条件在进行分组操作之后应用
HAVING 搜索条件在进行分组操作之后应用: 如:查询帖子访问量大于15的用户id: select t.user_id,u.name,sum(count_view) from t_topic t l ...
- A. Vova and Train ( Codeforces Round #515 (Div. 3) )
题意:一条 L 长的路,一列车长在这条路的 l 到 r 之间,只有在 v 倍数时有灯,但是在 l 到 r 之间的灯是看不见的,问最大看见的灯的个数? 题解:L / v 表示总共的灯的个数, r / v ...
- 备份和还原 Linux 上的 SQL Server 数据库
备份数据库 在下面的示例sqlcmd连接到本地 SQL Server 实例,并采用完整备份的名为的用户数据库demodb. sqlcmd -S localhost -U SA -Q "BAC ...
- OpenFOAM——90度T型管
本算例来自<ANSYS Fluid Dynamics Verification Manual>中的VMFL010: Laminar Flow in a 90° Tee-Junction. ...
- 除法运算时的一个常见异常之java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
一.背景 今天在计算库存消耗百分比(消耗的库存/总库存)的时候遇到了一个错误,java.lang.ArithmeticException: Non-terminating decimal expans ...