前两天,看了一本书,上面用java写了一个图片浏览器,突然就觉得比较感兴趣,上面介绍了思路,和大致的功能如何做,做一个图片浏览器,大致的界面是这样的
我们先来看一下这个图片浏览器有什么功能,1.打开图片;2.上一张下一张;3.放大缩小图片
就这么简单的三个功能,我们需要的东西却有很多,首先,外体的frame,然后是JMenuBar,还有用于放工具按钮的JToolBar,最后一个JLable用于放图片的。
我们要实现打开文件功能,那就需要文件选择器和文件过滤器,过滤掉那些不支持的文件格式,这个两个功能我们需要知道两个类:1.JFileChooser类;2.FileFilter类。用这两个类里面的某些功能来实现我们打开图片的操作。然后就是放大和缩小,这个就需要了解Image类里面的getScaledInstance方法。至于上一张下一张就要知道我们所写的这个图片浏览器是可以储存用户最近打开文件的路径的,对于路径最后一级的所有我们支持打开的文件,我们可以存在一个File类型的队列里,然后通过引索来得到上下图片的路径,然后打开它。这就是写简单的功能介绍。
下面我们可以分别建几个类,来实现这些功能,主界面类继承JFrame里面可以把工具栏,菜单栏,和放图片的区域加到上面,这里面工具栏按钮的实例化时,我们用Action来初始化它们,这个Action类可以用API查到,但查到的是这个类是一个接口,我们用一个类来实现这个接口,然后通过重写里面的actionPerformed方法,从而得到监听按钮的目的,我觉得这个方法更简便,可以不用再重新给按钮加监听器,并且直接初始化,而且到后面我们会发现,这有利于后面实现其他的各种功能,如何实现点击按钮后面的功能呢?这里我们可以再用一个类,里面写好各个按钮的功能,要想把按钮个各个功能一一对应,我们可以在监听器里面用很多if....else结构来实现,但是这样难免有些繁琐,而且在传参数时容易出错,我们可以再Action的实现类里面利用反射机制,可以再每次点击后得到点击后类的实例,从而来实现功能,所以我们要把每个按钮对应一个类,这个类里面用一个方法来实现功能,我们所调用的这些功能的方法都需要用到实现功能类和主界面类,所以可以用一个接口,里面定义一个实现功能的方法,然后每个功能用一个实现类,这样就能充分利用反射机制来实现共能了,这里可能我表述的不清楚,没关系,下面看代码就好了。
首先来把界面写好,把工具栏,菜单栏,图片显示区域加上。
import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToolBar; public class ViewerFrame extends JFrame{ //实例化ViewerFrame类 private static ViewerFrame frame = new ViewerFrame(); //实例化一个JLabel对象用于插图片 JLabel imageLabel = new JLabel(); public static void main(String[] args) { frame.FrameUI(); } public void FrameUI(){ //设置大小 this.setSize(new Dimension(600,700)); //设置居中 this.setLocationRelativeTo(null); //设置标题 this.setTitle("PictureViewer"); //调用创建菜单栏方法 creatMenuBar(); //创建工具栏,并加到Frame北边 JPanel jpanel = creatToolPane(); this.add(jpanel,BorderLayout.NORTH); //不要设置布局为流布局,否则图片不容易显示 //this.setLayout(new BorderLayout()); //设置关闭方式 this.setDefaultCloseOperation(3); //添加滚动条 this.add(new JScrollPane(imageLabel),BorderLayout.CENTER); //设置可见 this.setVisible(true); //是窗口更加适应图片,自动 调整大小,这里不建议,可以尝试看看 //this.pack(); } //创建菜单栏方法 public void creatMenuBar(){ JMenuBar menubar = new JMenuBar(); //菜单栏文字选项 String[] menubarArray = {"文件(F)","工具(T)","帮助(H)"}; //二级菜单项文字数组 String[][] menu = {{"打开(O)","-","退出(X)"},{"放大(M)", "缩小(O)","-","上一个(X)","下一个(P)"},{"帮助主题","关于"}}; for(int i=0;i<menubarArray.length;++i){ //实例化菜单项 JMenu jmenu = new JMenu(menubarArray[i]); //添加菜单项 for(int j=0;j<menu[i].length;++j){ if(menu[i][j].equals("-")){ jmenu.addSeparator(); } else{ //实例化JMenuItem对象 JMenuItem jmi = new JMenuItem(menu[i][j]); //添加到JMenu上 jmenu.add(jmi); } } //把menu加到menubar上 menubar.add(jmenu); } //这里要用setJMenuBar方法,而不是add方法 this.setJMenuBar(menubar);; } //得到imageLabel方法 public JLabel getLabel(){ return imageLabel; } //创建工具栏方法 public JPanel creatToolPane(){ //实例化一个JPanel对象,承载ToolPane JPanel toolpane = new JPanel(); //实例化工具栏 JToolBar toolbar = new JToolBar(); //创建路径String数组来添加按钮 String[] buttonArray = {"PictureViewer.openAction","PictureViewer.lastAction","PictureViewer.nextAction", "PictureViewer.lastAction","PictureViewer.bigAction","PictureViewer.smallAction"}; //遍历循环实例化并加入按钮 for(String name : buttonArray){ //实例化ViewerAction对象,用于初始化button ViewerAction action = new ViewerAction(new ImageIcon("images/"+name+".jpg"),name,this); //用Action来初始化Button JButton button = new JButton(action); //button加到toolbar上 toolbar.add(button); } //把toolbar加到panel上 toolpane.add(toolbar); return toolpane; } }
这是主界面类的方法,这里面唯一不知道的东西是ViewerAction类,这个类就是用于我们所说的实例化button用到的,这里面重写actionPerformed方法,下面是这个类的代码
import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ImageIcon; public class ViewerAction extends AbstractAction{ //声明一个ViewerFrame对象 private ViewerFrame frame = null; //用于存储名字的String String ActionName = ""; //声明一个Action对象 Action action = null; //构造方法 public ViewerAction(ImageIcon image,String ActionName,ViewerFrame frame){ //实现父类的构造方法,不要忘记 super("",image); this.ActionName = ActionName; this.frame = frame; } //重写actionPerformed方法 @Override public void actionPerformed(ActionEvent e) { ViewerService service = ViewerService.getInstance(); Action vieweraction = getAction(ActionName); vieweraction.dothis(frame,service); } //得到Action的方法,这里用到了反射 public Action getAction(String ActionName){ try{ if(this.action == null){ Action action = (Action)Class.forName(ActionName).newInstance(); this.action = action; } return this.action; } catch(Exception E){ return null; } } }
这里就是Action类,它可以监听工具栏按钮,并且初始化按钮,getAction方法用到了反射,因为后面要用几个Action类,运行程序运行的时候得到实例用于实现功能。下面来看一下那几个Action的代码,这几个Action都是实现类一个借口
public interface Action { //用于实现功能方法的声明 public void dothis(ViewerService service,ViewerFrame frame); }
public class openAction implements Action{ @Override public void dothis(ViewerService service, ViewerFrame frame) { service.open(frame); } }
public class smallAction implements Action{ @Override public void dothis(ViewerService service, ViewerFrame frame) { service.BigOrSmall(frame,false); } }
public class bigAction implements Action{ @Override public void dothis(ViewerService service, ViewerFrame frame) { service.BigOrSmall(frame,true); } }
public class lastAction implements Action{ @Override public void dothis(ViewerService service, ViewerFrame frame) { service.LastOrNext(frame,true); } }
public class nextAction implements Action{ @Override public void dothis(ViewerService service, ViewerFrame frame) { service.LastOrNext(frame,false); } }
这就是这几个类,由这几个类,就可以看得懂ViewerAction类中的代码了,最后,一个很重要的核心任务就是在 ViewerService类中实现各个功能,但在写这个类之前,我们还要想到,如果打开文件的话,我们需要一个文件过滤器,这个文件过滤器又是由一个文件选择器来承担,所以,要先做好文件这方面的工作才好进行,下一步。文件过滤器类是文件选择器的内部类。
package shane.PictureViewer; import java.io.File; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; public class FileChooser extends JFileChooser{ //构造方法 public FileChooser(){ super(); setAcceptAllFileFilterUsed(false); //增加文件过滤器方法 addFilter(); } public FileChooser(String currentDirectoryPath){ super(currentDirectoryPath); setAcceptAllFileFilterUsed(false); addFilter(); } //添加文件方法 public void addFilter(){ //向用户可选择的文件过滤器列表添加一个过滤器 this.addChoosableFileFilter(new MyFileFilter(new String[] {".JPG","JPEG","JPE","JFIF"},"JPEG(*.JPG,*JPEG,*JPE,*JFIF")); this.addChoosableFileFilter(new MyFileFilter (new String[]{".BMP"},"BMP(*BMP)")); this.addChoosableFileFilter(new MyFileFilter(new String[] {".GIF"},"*.GIF")); this.addChoosableFileFilter(new MyFileFilter(new String[] {".BMP",".JPG",".JPEG",".JPE",".JFIF",".GIF"},"所有图形文件")); } /* * MyFileFilter继承自FileFilter,文件过滤器 * 内部类 */ class MyFileFilter extends FileFilter{ //存储后缀名String数组 String[] suffar; //描述 String discription; //构造方法 public MyFileFilter(String[] suffar,String discription) { super(); this.suffar = suffar; this.discription = discription; } //重写接受文件的方法 @Override public boolean accept(File f) { //遍历suffar数组,比较是否能接受文件 for(String isaccept : suffar){ //先把名字改成大写,然后比较是否是以isaccept结尾 if(f.getName().toUpperCase().endsWith(isaccept));{ return true; } } //如果是目录就返回true,反之则返回false return f.isDirectory(); } @Override public String getDescription() { return this.discription; } } }
打开文件方法
//打开图片方法 public void open(ViewerFrame frame){ if(filechooser.showOpenDialog(frame) == filechooser.APPROVE_OPTION){ //储存此文件路径 currentFile = filechooser.getSelectedFile(); //得到图片路径 String iconDrictory = filechooser.getSelectedFile().getPath(); //为了检验此文件夹是否与上次打开的文件夹一致,我们采取下面的方法 File isSameDirectory = filechooser.getCurrentDirectory(); if(isSameDirectory != currentDirectory || currentDirectory == null){ //用于接受所有的文件过滤器 FileFilter[] filefilter = filechooser.getChoosableFileFilters(); //用于得到该文件夹的所有文件路径 File[] file = isSameDirectory.listFiles(); //用于筛选出适合的文件,添加到this.file的队列中 for(File isfile : file){ for(FileFilter filefle : filefilter){ if(filefle.accept(isfile)){ this.file.add(isfile); } } } } //设置图片到frame的label中 ImageIcon icon = new ImageIcon(iconDrictory); frame.getLabel().setIcon(icon); } }
//放大缩小方法 public void BigOrSmall(ViewerFrame frame, boolean enLarge){ //获取放大或者缩小比例 double enLargeRange = enLarge? 1 + Biger: 1 - Biger; //System.out.println(ScrollAmount); //获取目前的图片 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); } }
就这么多,剩余的还有上下图片方法,就不在这展示了,感觉好像大多数都是代码,上下图片方法下次有机会再上传。
相关推荐
【疯狂java实战演义-第3章 图片浏览器】 在这一章中,我们将探讨如何创建一个简单的图片浏览器,它能够实现基本的图片浏览、导航、缩放和旋转功能。图片浏览器是一个常见且实用的工具,它允许用户查看指定目录中的...
《 疯狂Java实战演义》以15个生动的Java案例,引领读者体验Java开发的乐趣。书中使用Java的Swing技术开发了若干个游戏,从这些游戏中可以了解到,Java一样可以做出优秀的游戏和应用程序。本书知识点丰富,适合有一定...
在《疯狂java实战演义》的第三章中,作者详细介绍了如何构建一个简单的图片浏览器。这个图片浏览器能够实现基本的图片浏览功能,如查看目录中的图片、切换上下张图片、放大缩小图片等。以下是这一章的主要知识点: ...
疯狂java实战演义(包括pdf 和源代码 压缩后17.5m) gobang: 第1章 控制台五子棋 cal: 第2章 仿Windows计算器 viewer: 第3章 图片浏览器 ball: 第4章 桌面弹球 tetris: 第5章 俄罗斯方块 image: 第6章 仿...
《疯狂Java实战演义》是一本深受Java爱好者欢迎的实战指南,它涵盖了众多实用的Java编程实例,旨在帮助读者深入理解和掌握Java技术。这个压缩包包含的源代码正是书中各个章节示例的实现,让我们逐一解析这些实战项目...
viewer: 第3章 图片浏览器 ball: 第4章 桌面弹球 tetris: 第5章 俄罗斯方块 image: 第6章 仿Windows画图 linkgame: 第7章 单机连连看 editor: 第8章 简单Java IDE工具 book: 第9章 图书进存销...
总的来说,这个图片浏览器项目虽然简单,但它涵盖了Java Swing中的一些基础组件和设计模式,如事件处理、界面布局和文件操作。通过实现这样的应用,开发者可以加深对Java图形用户界面编程的理解。
viewer: 第3章 图片浏览器 ball: 第4章 桌面弹球 tetris: 第5章 俄罗斯方块 image: 第6章 仿Windows画图 linkgame: 第7章 单机连连看 editor: 第8章 简单Java IDE工具 book: 第9章 图书进存销...
《疯狂Java实战演义》是一本深度探讨Java编程技术的实战书籍,虽然提及缺少第五章的内容,但从其他章节的标题可以看出这本书涵盖了广泛的Java应用领域。以下是各章节的主要知识点概述: 1. **第7章 - 单机连连看** ...
《疯狂java实战演义》是李刚先生的力作,以word格式呈现,深受广大Java开发者喜爱。本书通过丰富的实例,深入浅出地讲解了Java编程的各个方面,旨在提升读者的实战技能。以下是对压缩包中各个文档内容的概述: 1. *...
这个"基于Swing的图片浏览器源运行例子"是《疯狂Java实战演义》一书中第三章的一个实践项目,旨在帮助读者深入理解如何利用Swing来创建一个功能完备的图片查看器应用程序。以下是对这个案例的详细解析: 首先,...
第3章_图片浏览器.doc 第4章_桌面弹球.doc 第5章_俄罗斯方块.doc 第6章_仿Windows画图.doc 第7章_单机连连看.doc 第8章_简单Java_IDE工具.doc 第9章_图书进存销系统.doc 第10章_事务跟踪系统.doc 第11章_多线程下载...
《疯狂Java讲义(第2版)》是著名Java编程教育专家李刚先生撰写的一本经典教程,由电子工业出版社出版。这本书全面深入地讲解了Java编程语言的基础知识、核心特性以及高级应用,旨在帮助读者从零基础快速掌握Java...
- **Java环境配置**:部分程序可能依赖于Java,因此需要安装JDK 7 Update 3,并正确配置环境变量,包括`JAVA_HOME`、`CLASSPATH`和`PATH`。 - **Tomcat服务器配置**:第18章涉及离线Web应用,这需要Apache Tomcat...
在压缩包内的"疯狂Java讲义1~3",虽然不是直接与Ajax相关的,但考虑到Java在后端开发中的重要地位,这部分内容可能涵盖了Java的基础知识,包括类、对象、继承、多态、异常处理、集合框架等内容。这对于理解Ajax与...
本书提供了配套的答疑网站,如果读者在阅读本书时遇到了技术问题,可以登录疯狂Java联盟发帖,笔者将会及时予以解答。 本书对HTML 5、CSS 3、JavaScript的介绍是“从零开始”的,因此阅读本书并不需要额外的基础。...
本书提供了配套的答疑网站,如果读者在阅读本书时遇到了技术问题,可以登录疯狂Java联盟发帖,笔者将会及时予以解答。 本书对HTML 5、CSS 3、JavaScript的介绍是“从零开始”的,因此阅读本书并不需要额外的基础。...
基于 Android 平台的手机应用开发—音乐播放器 Android 是基于 Linux 内核的操作系统,是 Google 公司在 2008 年推出的开源操作系统。 Android 平台的手机应用开发...[15]李刚 编著,疯狂 Java 讲义,电子工业出版社
1. **远程方法调用(Remote Method Invocation, RMI)**:DWR的核心功能是实现在浏览器和服务器之间的RMI,使得JavaScript可以直接调用Java方法,就像这些方法是在本地定义的一样。这大大减少了前后端交互的复杂性。...