??xml version="1.0" encoding="utf-8" standalone="yes"?>
通常的做法是调用JFileChooser.showXXX()Ҏ(gu)昄文g选取对话框ƈ且选择一个文件后Q点?font face="Courier New">Approve 按钮Q默认情况下标有 "Open" ?"Save"Q?/font>Q?/font>当对话框关闭后用JFileChooser.getSelectedFile()Ҏ(gu)得到选取的文Ӟ或用JFileChooser.getSelectedFiles()取得选取的文件数l)Q然后再对被选取的文件有效性进行验证(例如Q文件的文g名是否合法、选取的\径下是否已有同名文g存在{等Q,如果验证不通过Q需要再ơ打开文g选择对话框进行选取?br />
昄Q验证没有通过的情况下Q文仉取对话框被反复的打开和关闭,影响用户体验?br />
我现在介l一个方法,在点M文g选取对话框上?font face="Courier New">Approve 按钮后,文g选取对话框关闭前寚w取的文件进行验证,如果验证没有通过Q那么对话框不关闭,直接q行下一ơ选择?br />
查看JFileChooser的APIQ可以发现这样一个方?public void approveSelection() Q这个方法会在用户单?Approve 按钮时由 UI 调用此方法。导致用等?APPROVE_SELECTION
的命令字W串Ȁ发一个操作事件?br />
那么Q我们现在可以选择l承JFileChooser再覆写这个方法,对选中文g的有效性验证写入这个方法中Q只有当验证通过时才调用类的approveSelection() 完成文g选取Q否则直接返回,l箋选择新的文g?br />
下面是我写的一个demo以供参考:
import java.io.File;
import javax.swing.JOptionPane;
/**
* ?JFileChooser 中进行文仉证的技?br /> * @author Chen Wei
* @email chenwei.mobi@gmail.com
*/
public class JFileChooserDemo extends javax.swing.JFileChooser{
public void approveSelection(){
File file = getSelectedFile();
// 验证文g名是否合?br /> if (!validateFileName(file.getName())) {
JOptionPane.showMessageDialog(getParent(), "文g名不能包含下列Q何字W之一Q\n \\ / : * ? \" < > |");
return;
}else{
super.approveSelection();
}
}
/**
* 验证输入字符串参数是否ؓ有效文g名?br /> * @param name 待验证的文g名字W串?br /> * @return 通过验证Q文件名无效q回 falseQ有效返?true?br /> */
public static boolean validateFileName(String name) {
if (name.indexOf('\\') != -1 || name.indexOf('/') != -1 ||
name.indexOf(':') != -1 || name.indexOf('*') != -1 ||
name.indexOf('?') != -1 || name.indexOf('"') != -1 ||
name.indexOf('<') != -1 || name.indexOf('>') != -1 ||
name.indexOf('|') != -1) {
return false;
} else {
return true;
}
}
public static void main(String[] args){
JFileChooserDemo chooser = new JFileChooserDemo();
chooser.showOpenDialog(null);
}
}
E序q行截图Q?br />
使用q个Ҏ(gu)前需要先图像文件从盘上读C?java.awt.image.BufferedImage 对象中,我们可以?J2SE 包含?ImageIO 库?/p>
AWT 使用 ImageProducer / ImagConsumer 模式Q支持加载和昄 GIF 囑փ文g格式?JPEG 囑փ文g格式。因为图像的加蝲和显C是异步方式q行的,所以有大量加蝲和显C的技术?BR>
?AWT 中,提供了一?java.awt.Image cRjava.awt.Image cM表一个图像对象被作ؓ参数传递给其他用来昄和处理图像的其他 AWT 对象使用。例如,通过调用 Graphics.drawImage(java.awt.Image, int, int, ImageObserver) Ҏ(gu)Q可以在lg中画出图像?BR>
java.awt.Image 是一个定义方法的抽象c,它定义的Ҏ(gu)提供的对囑փ信息的访问。而创建和处理囑փ的基本结构则?java.awt.image 包中。注意,q里不要?java.awt.Image 发生h?BR>
AWT 加蝲和显C图像用的?ImageProducer / ImagConsumer 模式Q我们必M?个术语,ImageProducerQ图像生产者)QImageConsumerQ图像消费者)和ImageObserverQ图像观察者)?BR>
ImageProducer 负责生囑փ的位QImagConsumer 接受囑փ的位QImageObserver 监视 ImageProducer 的图像生产过E。ImageProducer 生传递给 ImagConsumer 与图像相关的位。因为图像生产过E是异步q行的,q不是一ơ性生产所有图像位Q所以当 ImageProducer 加蝲囑փӞImageObserver 用来监视它的q展情况。因?java.awt.Component 实现?ImageObserver 接口Q所?AWT 中的每个lg都可以是ImageObserverQ当一个给定的 ImageProducer q行异步操作Ӟq个 ImageObserver 可以选择是否被更新。java.awt.image 包ؓ ImageProducerQImagConsumer ?ImageObserver 都定义了接口?BR>
ImageProducer
和图像相关的位ƈ不存储在 java.awt.Image 中,每个囑փ都维护一个和一?ImageProducer 的关联。这?ImageProducer 的责L生囑փ的位q将它们传送给 ImagConsumerQ用于过滤该囑փ?BR>
java.awt.image软g包中QFilteredImageSourceQ被qo的图像源Q和 MemoryImageSourceQ内存的囑փ源)实现?ImageProducer 接口Q是 ImageProducer ?BR>
ImagConsumer
java.awt.image软g包中QImageFilterQ图像过滤器Q和 PixelGrabberQ像素抓取器Q实C ImagConsumer 接口Q是 ImagConsumer?BR>
ImageProducer ?ImagConsumer 的详l介l请阅读 使用 ImageProducer / ImagConsumer q行囑փqo
ImageObserver
ImageObserver接口中,定义了一个常数集合和一个方法:
public boolean imageUpdate(image img, int flags, int x, int y, int width, int height);
ImageObserver的常?/TD> | |
标志 | 含义 |
ABORT | 囑փ加蝲被中?/TD> |
ALLBITS | 所有的位都已加载给囑փ |
ERROR | 在加载过E中发生错误 |
FRAMEBITS | 多囑փ的一个被传送,一般用?SPAN lang=en-us>GIF |
HEIGHT | 囑փ的高度已l可?/TD> |
PROPERTIES | 囑փ的属性已l可?/TD> |
SOMEBITS | 囑փ的羃攑֏体的多个位已l可?/TD> |
WIDTH | 囑փ的宽度已l可?/TD> |
输出l果Q?BR>image width = -1 height = -1
囑փ的高度和宽度只有在图像被完全加蝲后才是有效的Q输出结果说?java.awt.image 相关的图像位在需要之前不被生产?BR>
?Q图像异步生?/P>
输出l果Q?BR>drawing image...
false
drawing image...
false
drawing image...
false
drawing image...
true
输出l果说明lg作ؓ ImageObserver Q监?ImageProducer 异步生囑փQ一旦有新的囑փ位被生时就重绘囑փQ图像完全加载后 drawImage() Ҏ(gu)q回 true?BR>
?Q重?ImageObserver ?imageUpdate() Ҏ(gu)Q在囑փ完全加蝲前不调用 repaint()
?Q重q?Component.update() Ҏ(gu)Q被调用时不清除背景囑փQ直接调?paint() Ҏ(gu)l制囑փQ消除闪?/P>
囑փ的加载和昄是异步进行的Q图? 的生产?ImageProducer)传递给囑փ的消费?ImageConsumer)一个与囑փ相关的位Q因为图像的生q程是一个异步行为,所? AWT 也提供一个图像观?ImageObserver)Q用来监视图像生产者的囑փ生q程?/font>
因ؓ java.awt.Component 实现 ImageObserver 接口Q所?AWT 中每个构仉是ImageObserver Q当一个给定的 ImageProducer 采取异步操作Ӟq个 ImageObserver 可以选择是否被更新?/font>
现在看一个例子:
当这?Applet W一ơ被调用Ӟ打印出下面的结果:
drawing image...
false
drawing image...
false
drawing image...
false
drawing image...
true
?
行结果说?drawImage() 在第一ơ被调用Ӟ没有囑փ被加载,drawImage() 只是向和囑փ相关?ImageProducer
注册 ImageObserverQ图像被完全加蝲?drawImage() Ҏ(gu)q回 false 直到囑փ被完全加载返?true?/font>
?drawImage() q回之后Q只要有囑փ的新的部分被加蝲QImageObserver 中的 imageUpdate() Ҏ(gu)׃被调用。当 ImageObserver ?AWT 构gӞComponent.imageUpdate() 调用 repaint() Ҏ(gu)清除构g背景q调?paint() Ҏ(gu)重绘刚刚得到的图像位。重复@环,ImageProducer 加蝲囑փ的下一块,调用 ImageObserver ?imageUpdate()。当囑փ被完全加载时QImageProducer 停止调用 ImageObserver ?imageUpdate()Q@环中断?/font>
load -> imageUpdate() -> repaint() -> update() -> paint()
{待囑փ的完全加?br />
上面的例子介l了囑փ的异步加载,现在介绍2个方法囑փ完全加蝲前不昄?br />
·重蝲 ImageObserver 中的 imageUpdate() Ҏ(gu)Q其在囑փ完全加蝲前不调用 repaint()?/font>
import
java.awt.Graphics;
import
java.awt.Image;
public
class
ImageTestAppletWithUpdate
extends
Applet {
private
Image im;
public
void
init() {
im
=
getImage(getCodeBase(),
"
lena.jpg
"
);
}
public
void
paint(Graphics g) {
g.drawImage(im,
0
,
0
,
this
);
}
public
boolean
imageUpdate(Image image,
int
flags,
int
x,
int
y,
int
w,
int
h) {
System.out.println(
"
imageUpdate():x=
"
+
x
+
"
,y=
"
+
y
+
"
,w=
"
+
w
+
"
,h=
"
+
h);
if
( (flags
&
ALLBITS)
==
0
) {
return
true
;
//
need more updates
}
else
{
repaint();
return
false
;
//
image is fully loaded
}
}
}
使用 java.awt.MediaTracker c跟t图像的加蝲Q不必重?imageUpdate() Ҏ(gu)?/font>
import
java.applet.Applet;
import
java.awt.Graphics;
import
java.awt.Image;
import
java.awt.MediaTracker;
public
class
ImageTestAppletWithMediaTracker
extends
Applet {
private
Image im;
public
void
init() {
im
=
getImage(getCodeBase(),
"
lena.jpg
"
);
MediaTracker tracker
=
new
MediaTracker(
this
);
tracker.addImage(im,
0
);
try
{
tracker.waitForID(
0
);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
System.out.print(
"
Image width =
"
+
im.getWidth(
this
));
System.out.println(
"
height =
"
+
im.getHeight(
this
));
}
public
void
paint(Graphics g) {
g.drawImage(im,
0
,
0
,
this
);
}
}
我们可以把?java.awt.MediaTracker cd囑փ完全加蝲的方法包装成一个实用方?/font>
* 使用 java.awt.MediaTracker 图像完全加载?br /> *
@param
component Component
*
@param
img Image
*/
public
static
void
waitForImage(Component component, Image img) {
MediaTracker tracker
=
new
MediaTracker(component);
try
{
tracker.addImage(img,
0
);
tracker.waitForID(
0
);
}
catch
(InterruptedException ex) {
ex.printStackTrace();
}
}