本章介绍 JFileChooser的用法,并用FileFiter文件过滤器指定可用文件,提供文件选择对话框预览图片,为不同的目录在文件选择对话框中提供不同的图标显示。
代码如下:
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileView;
import org.omg.CORBA.PERSIST_STORE;
/**
*
*/
/**
* @author wangyubin
* 一个简单的图片查看工具程序,运用了文件选择功能。
* bug 1、图标没换掉 2、改初始的文件路径 3、改变图片大小
*/
public class ImageViewer {
/**
* @param args
*/
//定义图片预览组件的大小
final int PREVIEW_SIZE=100;
JFrame jf=new JFrame("简单图片查看器");
JMenuBar menuBar=new JMenuBar();
//该Label用于显示图片
JLabel label=new JLabel();
//以当前路径创建文件选择器
JFileChooser chooser=new JFileChooser(".");
JLabel accessory=new JLabel();
//定义文件过滤器
ExtensionFileFilter filter=new ExtensionFileFilter();
public void init(){
//----------下面开始初始化JFileChooser的相关属性-----------
//创建一个FileFilter
filter.addExtension("jpg");
filter.addExtension("jpeg");
filter.addExtension("gif");
filter.addExtension("png");
filter.setDescription("图片文件(*.jpg,*.jpeg,*.gif,*.png)");//为文本过滤器设置描述
chooser.addChoosableFileFilter(filter);//为JFileChooser添加一个文件过滤器
//禁止“文件类型”下拉列表中显示“所有文件”选项
chooser.setAcceptAllFileFilterUsed(false);
//为文件选择器指定自定义的FileView对象
chooser.setFileView(new FileIconView(filter));
//为文本选择器指定一个预览图片的附件
chooser.setAccessory(accessory);
//设置预览图片组件的大小和边框
accessory.setPreferredSize(new Dimension(PREVIEW_SIZE,PREVIEW_SIZE));
accessory.setBorder(BorderFactory.createEtchedBorder());
//用于检测被选择文件的改变事件
chooser.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
// JFileChooser的被选择文件已经发生了改变
if(event.getPropertyName()==JFileChooser.SELECTED_FILE_CHANGED_PROPERTY){
//获取用户选择的新文件
File f=(File) event.getNewValue();
if(f==null){
accessory.setIcon(null);
return;
}
//将所选文件读入ImageIcon对象中
ImageIcon icon=new ImageIcon(f.getPath());
//如果图像太大,则缩小它
if(icon.getIconWidth()>PREVIEW_SIZE){
icon=new ImageIcon(icon.getImage().getScaledInstance(PREVIEW_SIZE, -1, Image.SCALE_DEFAULT));
}
//改变accessory Label的图标
accessory.setIcon(icon);
}
}
});
//--------下面开始为该窗口安装菜单--------------
JMenu menu=new JMenu("文件");
menuBar.add(menu);
JMenuItem openItem=new JMenuItem("打开");
menu.add(openItem);
//单击openItem菜单项显示“打开文件”对话框
openItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//设置文件对话框的当前路径
chooser.setCurrentDirectory(new File("."));
//显示文件对话框
int result=chooser.showDialog(jf, "打开图片文件");
//如果用户选择了同意按钮,即打开,保存的等效按钮
if(result==JFileChooser.APPROVE_OPTION){
String name =chooser.getSelectedFile().getPath();
//显示指定图片
ImageIcon icon=new ImageIcon(name);
icon.setImage(icon.getImage().getScaledInstance(960,1080,Image.SCALE_DEFAULT));
label.setIcon(icon);
}
}
});
JMenuItem exitItem=new JMenuItem("Exit");
menu.add(exitItem);
//为退出菜单绑定事件监听器
exitItem.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
System.exit(0);
}
});
jf.setJMenuBar(menuBar);
//添加用于显示图片的JLabel组件
jf.add(new JScrollPane(label));
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
new ImageViewer().init();
}
}
class ExtensionFileFilter extends FileFilter{
private String description;
private ArrayList<String> extensions=new ArrayList<>();
//自定义方法,用于添加文件扩展名
public void addExtension(String extension){
if(!extension.startsWith(".")){
extension="."+extension; //让存进来的扩展名前面加上前缀的"."
extensions.add(extension.toLowerCase());//吧扩展名变为小写并存进list中
}
}
//用于设置该文件过滤器的描述文本
public void setDescription(String aDescription){
description=aDescription;
}
@Override
public boolean accept(File f) {
// 如果该文见识路径,则接受该文件
if(f.isDirectory()) return true;
//将文件名转为小写(全部转为小写后比较,用于忽略文件大小写)
String name=f.getName().toLowerCase();
//遍历所有可接受的扩展名,如果扩展名相同,该文件就可以接受
for(String extension:extensions){
if (name.endsWith(extension)){ //extensions列表中存放的是可接受的文件类型,把目标文件名的后缀与列表逐一比较
return true;
}
}
return false;
}
@Override
public String getDescription() {
// TODO 自动生成的方法存根
return description;
}
}
class FileIconView extends FileView{
private FileFilter filter;
public FileIconView(FileFilter filter) {
this.filter = filter;
}
@Override
public Icon getIcon(File f) {
// 为目标文件设置文件选择器中的图标,若是根目录则配dsk图标,若是路径(无目标文件名)即文件夹,则设置folder图标,若是目标文件则设置pict图标
if(!f.isDirectory()&&filter.accept(f)){
return new ImageIcon("ico/pict.png");
}
else if(f.isDirectory()){
//获取所有根路径
File[] fList=File.listRoots();
for(File tmp:fList){
//如果该路径是根路径
if(tmp.equals(f)){
return new ImageIcon("ico/dsk.png");
}
}
return new ImageIcon("ico/folder.png");
}
//使用默认图标
else{
return null;
}
}
}
在原有的基础上,我想控制所显示图片的大小。关键代码如下:
ImageIcon icon=new ImageIcon(name);
icon.setImage(icon.getImage().getScaledInstance(960,1080,Image.SCALE_DEFAULT));
label.setIcon(icon);
首先获取ImageIcon对象,然后通过该对象获得它的Image对象,再用getScaledInstance()方法来设置它的大小。
一开始,我想直接在setIcon()的方法中直接利用(icon)把Image对象直接转型为icon给label设置,但这时会出现找不到图片对象的问题。因此必须用setImage()来设置icon
下一步,我想改写上面的程序,实现一个用于浏览吉他谱的图片浏览器。
需求介绍:喜欢弹吉他的朋友应该有这样的体会,对于一些图片类型的吉他谱,一首曲子通常有好几页,这时如果在弹吉他时翻页的话会影响自己演奏。解决方案有两个并各有缺陷。
1、提供自动向下滚动功能 (下滚速度不好设置,需根据曲子速度来调) 2、把几张图片同时显示在显示器中(每张图片的大小需要自己调节)
目前,我想采用第二中方法,把几张吉他谱同时放在一个JFrame中,做一个较为通用吉他谱图片浏览器。
预计要学习的内容,利用JFileChooser读取多个图片,使图片按比例缩放,根据平均分布在Frame中。下一步还是建一个专门的项目来做吧!