`

Crazy Java Practice 第3章 图片浏览器

    博客分类:
  • Java
 
阅读更多
package com.chenjo.viewer;

import javax.swing.JFrame;
/**
 * 图片浏览器入口类
 * @author chenjo
 *
 */
public class Main {
	public static void main(String args[]){
		ViewerFrame f = new ViewerFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

package com.chenjo.viewer;

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;

import com.chenjo.viewer.action.Action;
/**
 * 工具栏的Action类
 * 
 * @author chenjo
 *
 */
@SuppressWarnings("serial")
public class ViewerAction extends AbstractAction{
	private String actionName = "";
	private ViewerFrame frame = null;
	//此工具栏的AbstractAction所对应的com.chenjo.viewer.action包的某个Action实体
	private Action action = null;
	
	/**
	 * 构造器
	 * 
	 */	
	public ViewerAction(){
		// 调用父构造器
		super();
	}
	
	/**
	 * 构造器
	 * 
	 * @param icon
	 *            ImageIcon 图标
	 * @param name
	 *            Action 名称
	 */	
	public ViewerAction(ImageIcon icon, String actionName, ViewerFrame frame){
		// 调用父构造器
		super("", icon);
		this.actionName = actionName;
		this.frame = frame;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		ViewerService service = ViewerService.getInstance();
		Action action = getAction(this.actionName);
		action.execute(service, frame);
	}
	/**
	 * 通过actionName得到该类的实例
	 * @param actionName
	 * @return
	 */
	private Action getAction(String actionName){
		try{
			if(this.action == null){
				//创建Action实例
				Action action = (Action)Class.forName(actionName).newInstance();
				this.action = action;
			}
			return this.action;
		}catch(Exception e){
			return null;
		}
	}
}

package com.chenjo.viewer;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import java.io.File;

/**
 * 文件选择器对话框
 * @author Jointech
 *
 */
public class ViewerFileChooser extends JFileChooser{
	/**
	 * 使用用户默认路径创建一个ImageFileChooser
	 */
	public ViewerFileChooser(){
		super();
		setAcceptAllFileFilterUsed(false);
		addFilter();
	}
	/**
	 * 使用自定义的路径路径创建一个ViewerFileChooser
	 * 
	 */
	public ViewerFileChooser(String currentDirectoryPath){
		super(currentDirectoryPath);
		setAcceptAllFileFilterUsed(false);
		addFilter();
	}
	/**
	 * 增加文件过滤器
	 */
	private void addFilter(){
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".BMP"}, "BMP (*.BMP)"));
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".JPG", ".JPEG", ".JPE", ".JFIF"}, "JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)"));
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".GIF"}, "GIF (*.GIF)"));
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".TIF", ".TIFF"}, "TIFF (*.TIF;*.TIFF)"));
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".PNG"}, "PNG (*.PNG)"));
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".ICO"}, "ICO (*.ICO)"));
		this.addChoosableFileFilter(new MyFileFilter(new String[] {".BMP",
				".JPG",".JPEG",".JPE",".JFIF",".GIF",".TIF", ".TIFF", 
				".PNG", ".ICO"}, "所有图形文件"));		
	}
	class MyFileFilter extends FileFilter{
		// 后缀名数组
		String[] suffArr;
		String description;
		public MyFileFilter(){
			super();
		}
		/**
		 * 用包含后缀名的数组与描述创建一个MyFileFilter
		 */
		public MyFileFilter(String[] suffArr, String description){
			super();
			this.suffArr = suffArr;
			this.description = description;				
		}
		/**
		 * 
		 */
		@Override
		public boolean accept(File f) {
			// 如果文件的后缀名合法,返回true
			for(String s : suffArr){
				if(f.getName().toUpperCase().endsWith(s)){
					return true;
				}
			}
			// 如果是目录,返回true, 否则返回false
			return f.isDirectory();
		}
		/**
		 * 获取描述信息
		 */
		@Override
		public String getDescription() {
			return this.description;
		}
		
	}	
}

package com.chenjo.viewer;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

/*
 * 主界面类
 * 
 */
@SuppressWarnings("serial")
public class ViewerFrame extends JFrame {
	// 设置读图区的宽和高
	private int width = 800;
	private int height = 600;
	// 用一个JLabel放置图片
	JLabel label = new JLabel();
	ViewerService service = ViewerService.getInstance();
	
	// 加给菜单的事件监听器
	ActionListener menuListener = new ActionListener(){
		public void actionPerformed(ActionEvent e){
			service.menuDo(ViewerFrame.this, e.getActionCommand());
		}
	};
	/**
	 * 构造器
	 */	
	public ViewerFrame(){
		super();
		// 初始化这个JFrame
		init();
	}
	public void init(){
		// 设置标题
		this.setTitle("看图程序");
		// 设置大小
		this.setPreferredSize(new Dimension(width, height));
		// 创建菜单
		createMenuBar();
		// 创建工具栏
		JPanel toolBar = createToolPanel();
		// 把工具栏和读图区加到JFrame里面
		this.add(toolBar, BorderLayout.NORTH);
		this.add(new JScrollPane(label), BorderLayout.CENTER);
		// 设置为可见
		this.setVisible(true);
		this.pack();
	}
	public JLabel getLabel(){
		return this.label;
	}
	/**
	 * 创建工具栏
	 * 
	 * @return JPanel
	 */
	public JPanel createToolPanel(){
		// 创建一个JPanel
		JPanel panel = new JPanel();
		// 创建一个标题为"工具"的工具栏
		JToolBar toolBar = new JToolBar("工具");
		// 设置为不可拖动
		toolBar.setFloatable(false);
		// 设置布局方式
		panel.setLayout(new FlowLayout(FlowLayout.LEFT));
		// 工具数组
		String[] toolArr = {"com.chenjo.viewer.action.OpenAction",
				"com.chenjo.viewer.action.LastAction",
				"com.chenjo.viewer.action.NextAction",
				"com.chenjo.viewer.action.BigAction",
				"com.chenjo.viewer.action.SmallAction"};
		for(int i=0; i<toolArr.length; i++){
			ViewerAction action = new ViewerAction(new ImageIcon("img/"
					+ toolArr[i] + ".gif"), toolArr[i], this);
			// 以图标创建一个新的button
			JButton button = new JButton(action);
			// 把button加到工具栏中
			toolBar.add(button);
		}
		panel.add(toolBar);
		return panel;
	}
	/**
	 * 创建菜单栏
	 */
	public void createMenuBar(){
		// 创建一个JMenuBar以放置菜单
		JMenuBar menuBar = new JMenuBar();
		// 菜单文字数组,以下面的menuItemArr一一对应
		String[] menuArr = {"文件(F)", "工具(T)", "帮助(H)"};
		// 菜单项文字数组
		String[][] menuItemArr = {{"打开(O)", "-", "退出(X)"}, {"放大(M)", "缩小(O)", "-", "上一个(X)", "下一个(P)"}, {"帮助主题", "关于"}};
		// 遍历menuArr与menuItemArr去创建菜单
		for(int i=0; i<menuArr.length; i++){
			// 新建一个JMenu菜单
			JMenu menu = new JMenu(menuArr[i]);
			for(int j=0; j<menuItemArr[i].length; j++){
				// 如果menuItemArr[i][j]等于"-"
				if(menuItemArr[i][j].equals("-")){
					// 设置菜单分隔
					menu.addSeparator();
				}else{
					// 新建一个JMenuItem菜单项
					JMenuItem menuItem = new JMenuItem(menuItemArr[i][j]);
					menuItem.addActionListener(menuListener);
					// 把菜单项加到JMenu菜单里面
					menu.add(menuItem);
				}
			}
			// 把菜单加到JMenuBar上
			menuBar.add(menu);
		}
		// 设置JMenubar
		this.setJMenuBar(menuBar);
	}
}

package com.chenjo.viewer;

import javax.swing.ImageIcon;
import java.awt.Image;
import java.io.File;
import javax.swing.filechooser.FileFilter;
import java.util.List;
import java.util.ArrayList;
/**
 * 图片浏览器业务类
 * @author Jointech
 *
 */
public class ViewerService {
	private static ViewerService service = null;
	// 新建一个ViewerFileChooser
	private ViewerFileChooser fileChooser = new ViewerFileChooser();
	// 放大或者缩小的比例
	private double range = 0.2;
	// 目前的文件夹
	private File currentDirectory = null;
	// 目前文件夹下的所有图片文件
	private List<File> currentFiles = null;
	// 目前图片文件
	private File currentFile = null;
	/*
	 * 私有构造器
	 */
	private ViewerService(){		
	}
	/**
	 * 获取单态实例
	 */
	public static ViewerService getInstance(){
		if(service == null){
			service = new ViewerService();
		}
		return service;
	}
	/**
	 * 
	 */
	public void open(ViewerFrame frame){
		// 如果选择打开
		if(fileChooser.showOpenDialog(frame) == ViewerFileChooser.APPROVE_OPTION){
			// 给目前打开的文件赋值
			this.currentFile = fileChooser.getSelectedFile();
			// 获取文件路径
			String name = this.currentFile.getPath();
			// 获取目前文件夹
			File cd = fileChooser.getCurrentDirectory();
			// 如果文件夹有改变
			if(cd != this.currentDirectory || this.currentDirectory == null){
				// 获取fileChooser的所有FileFilter
				FileFilter[] fileFilters = fileChooser.getChoosableFileFilters();
				File[] files = cd.listFiles();
				this.currentFiles = new ArrayList<File>();
				for(File file : files){
					for(FileFilter filter : fileFilters){
						if(filter.accept(file)){
							// 如果是图片文件不尚未存在于列表中
							if(!currentFiles.contains(file)){
								// 把文件加到currentFiles中
								this.currentFiles.add(file);
							}
						}
					}
				}
			}
			ImageIcon icon = new ImageIcon(name);
			frame.getLabel().setIcon(icon);
		}
	}	
		/**
		 * 
		 */
		public void zoom(ViewerFrame frame, boolean isEnlarge){
			// 获取放大或者缩小的乘比
			double enlargeRange = isEnlarge ? (1+range) : (1-range);
			// 获取目前的图片
			ImageIcon icon = (ImageIcon)frame.getLabel().getIcon();
			if(icon != null){
				// 获取改变大小后的图片
				int width = (int)(icon.getIconWidth() * enlargeRange);
				ImageIcon newIcon = new ImageIcon(icon.getImage()
						.getScaledInstance(width, -1, Image.SCALE_DEFAULT));
				// 改变显示的图片
				frame.getLabel().setIcon(newIcon);
			}
		}
		public void last(ViewerFrame frame){
			// 如果有打开包含图片的文件夹
			if(this.currentFiles != null && !this.currentFiles.isEmpty()){
				int index = this.currentFiles.indexOf(this.currentFile);
				// 打开上一个
				if(index > 0){
					File file = (File)this.currentFiles.get(index - 1);
					ImageIcon icon = new ImageIcon(file.getPath());
					frame.getLabel().setIcon(icon);
					this.currentFile = file;
					
				}
			}
		}
		public void next(ViewerFrame frame){
			// 如果有打开包含图片的文件夹
			if(this.currentFiles != null && !this.currentFiles.isEmpty()){
				int index = this.currentFiles.indexOf(this.currentFile);
				// 打开下一个
				if(index+1 < this.currentFiles.size()){
					File file = (File)this.currentFiles.get(index + 1);
					ImageIcon icon = new ImageIcon(file.getPath());
					frame.getLabel().setIcon(icon);
					this.currentFile = file;
				}
			}
			
		}
		/**
		 * 响应菜单的动作
		 * @param frame
		 * @param cmd
		 */
		public void menuDo(ViewerFrame frame, String cmd){
			if(cmd.equals("打开(O)")){
				open(frame);
			}
			if(cmd.equals("放大(M)")){
				zoom(frame, true);
			}
			if(cmd.equals("缩小(O)")){
				zoom(frame, false);
			}
			if(cmd.equals("上一个(X)")){
				last(frame);
			}
			if(cmd.equals("下一个(P)")){
				next(frame);
			}
			if(cmd.equals("退出(X)")){
				System.exit(0);
			}
		}
}

package com.chenjo.viewer.action;

import com.chenjo.viewer.ViewerFrame;
import com.chenjo.viewer.ViewerService;
/**
 * 图片浏览器的Action接口
 * @author Jointech
 *
 */
public interface Action {
	/**
	 * 具体执行的方法
	 * @param service 图片浏览器的业务处理类
	 * @param frame 主界面对象
	 */
	void execute(ViewerService service, ViewerFrame frame);
}

package com.chenjo.viewer.action;

import com.chenjo.viewer.ViewerFrame;
import com.chenjo.viewer.ViewerService;
/**
 * 放大图片的Action
 * @author Jointech
 *
 */
public class BigAction implements Action {

	@Override
	public void execute(ViewerService service, ViewerFrame frame) {
		service.zoom(frame, true);
	}
	
}

package com.chenjo.viewer.action;

import com.chenjo.viewer.ViewerFrame;
import com.chenjo.viewer.ViewerService;
/**
 * 上一张图片的Action
 * @author Jointech
 *
 */
public class LastAction implements Action {
	public void execute(ViewerService service, ViewerFrame frame){
		service.last(frame);
	}
}

package com.chenjo.viewer.action;

import com.chenjo.viewer.ViewerFrame;
import com.chenjo.viewer.ViewerService;
/**
 * 下一张图片的Action
 * @author Jointech
 *
 */
public class NextAction implements Action {

	@Override
	public void execute(ViewerService service, ViewerFrame frame) {
		service.next(frame);		
	}
}

package com.chenjo.viewer.action;

import com.chenjo.viewer.ViewerFrame;
import com.chenjo.viewer.ViewerService;
/**
 * 打开图片文件的Action
 * @author Jointech
 *
 */
public class OpenAction implements Action {
	public void execute(ViewerService service, ViewerFrame frame){
		service.open(frame);
	}
}

package com.chenjo.viewer.action;

import com.chenjo.viewer.ViewerFrame;
import com.chenjo.viewer.ViewerService;
/**
 * 缩小图片的Action
 * @author Jointech
 *
 */
public class SmallAction implements Action {

	@Override
	public void execute(ViewerService service, ViewerFrame frame) {
		service.zoom(frame, false);		
	}
}
分享到:
评论

相关推荐

    Crazy-JAVA-mind-map.zip_Crazy JAVA mind map_crazy_java-mindmap_m

    这份"Crazy-JAVA-mind-map.zip"压缩包包含了一个名为"Crazy JAVA mind map.mmap"的思维导图文件,这个导图就是对《疯狂JAVA讲义》内容的高度概括和逻辑梳理,旨在帮助学习者更好地理解和记忆书中的知识点。...

    java疯狂讲义源代码项目_CrazyJava.zip

    java疯狂讲义源代码项目_CrazyJava

    crazy pic 图片批量下载

    3. 使用工具:这时,用户打开"Crazy Pic 图片批量下载"软件,并将百度图片的搜索URL复制到软件中。软件会自动解析URL,列出所有可下载的图片链接。 4. 选择下载范围:用户可以选择下载全部图片,也可以根据需要挑选...

    疯狂Java讲义第三版光盘内容

    疯狂Java讲义第三版 光盘内容 内容包括课本中的代码 学习文档 还有一些视频

    微软工程师的最爱,超级稳定高速浏览器-Crazy.rar

    "3"可能表示这是该浏览器的第三版,而"简体中文版"则表明这个版本是为中国用户设计的,具有简体中文界面和本地化服务。 **详细知识点** 1. **浏览器稳定性**:Crazy浏览器的核心卖点之一就是其稳定性。这意味着它...

    Crazy Browser

    Crazy Browser

    java7源码-crazyJava3_4:疯狂java3-4的学习

    crazyJava3_4 疯狂java3-4的学习 简单介绍 此代码,主要是为了学习java基础而创建 本代码中大部分代码是从疯狂java的源码中copy过来的.主要是用于跑一下.演示加强自己对疯狂java讲义中所讲述的含义的理解. 在copy过来...

    Crazy Pic(疯狂图片下载)v1.8中文绿色版

    5. **疯狂图片下载器Crazy Pic(疯狂图片下载)下载 v1.8中文绿色版_ - pc6下载站.url**:这是一条网址链接,指向该软件的下载页面,可能是官方提供的下载来源或第三方网站的推荐。 Crazy Pic的核心功能在于其强大的...

    Crazy Bump大理石生成软件

    多样化纹理生成: Crazy Bump支持从图片、照片或者手绘素材中快速生成各种类型的纹理效果,包括凹凸、法线、光泽等,满足用户的多样化需求。 智能材质转换: 利用先进的算法,Crazy Bump能够自动识别图像中的细节...

    crazy-eights:Crazy Heights,Java 游戏(学者项目,2011)

    【疯狂八人制:Crazy Heights,Java游戏详解】 Crazy Heights是一款基于Java开发的桌面游戏,灵感来源于经典的“疯狂八”(Crazy Eights)纸牌游戏。这个游戏由学术项目开发,旨在提供一个数字化的平台,让玩家可以...

    讲java源码的书-CrazyJava:《疯狂的Java讲义》书籍源代码

    《疯狂的Java讲义》是一本深入探讨Java编程语言的书籍,其源代码库名为"CrazyJava",在开源社区中广泛流传。这本书的核心目标是帮助读者深入理解Java的内部机制,通过源码分析,提升编程技能和问题解决能力。在阅读...

    图片批量下载软件Crazy_Pic-v1.2

    《Crazy_Pic-v1.2:批量图片下载利器详解》 在数字图像时代,我们需要处理和收集大量的图片资源,而手动下载每一张图片显然效率低下。这时,一款优秀的图片批量下载软件就显得尤为重要。本文将详细介绍“Crazy_Pic-...

    Crazy8s:编程 Crazy 8s 游戏介绍 (Java)

    在开始编写Crazy 8s游戏之前,我们需要了解Java的基本语法和面向对象编程的概念。Java是一种强类型、面向对象的语言,具有丰富的类库和跨平台的特性。学习Java的基础包括: 1. 变量和数据类型:Java支持基本数据...

    Crazy Urus浏览器

    自己用VB中的Webbrowser控件制作的浏览器。

    CrazyStone2016疯狂石头深度学习版

    英文破解版 CrazyStone、天顶与银星号称已战胜专业棋手的三大围软,当“狗狗”还不能进入普通个人电脑的当今,这三大围软已足以在2016年掀起冲击人脑的狂风暴雨。 CrazyStone深度学习版比CrazyStone2013强约4子左右...

    test_jni_hooks.rar_crazy

    3. **设置JNI钩子**:在Java层,使用JNI注册机制设置钩子,使得在Java代码调用对应的本地方法时,会先执行预定义的钩子函数。 4. **运行测试**:启动Java程序,执行含有JNI钩子的代码,观察并记录`crazy_context_set...

    Crazy

    3. **自定义字体**:"Crazy"可能是一个定制的字体,设计师通过软件如Adobe Illustrator或Glyphs创建,以满足特定项目的需求。自定义字体可以表达品牌个性,提高辨识度。 4. **字体格式**:常见的字体格式有TrueType...

    java免费下载资源网站

    8. Javadoc (https://javadoc.io/) - 这个网站允许你在线查看和搜索不同Java库的API文档,对于了解和使用第三方库非常有帮助。 在压缩包中,我们看到的文件名涉及多个领域,这表明除了Java编程本身,还有其他相关...

    crazy uncle简洁主题v3.1.1

    《crazy uncle简洁主题v3.1.1:WordPress个人博客的理想选择》 在数字化的世界里,个人博客已经成为人们分享思想、记录生活、展现个性的重要平台。WordPress作为全球最受欢迎的开源博客系统,拥有丰富的主题库,让...

Global site tag (gtag.js) - Google Analytics