`
zhuyifeng
  • 浏览: 44714 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

文件搜索的简单实现

阅读更多

快一个月没写总结了,这个星期总算做出了一个还算满意的成果,就来和大家分享一下经验吧。

 

首先将下思路:一开始当然是一个JFrame了,然后我把它分成左右两个部分,左边那部分是用来进行搜索相关设置的,包括需要搜索的内容,搜索的范围以及是否忽略大小写和是否搜索隐藏文件这些功能。而右边那个部分则当然是用来展示搜索结果的啦~~

 

 

这是我的程序运行之后的界面。

 

简单的功能就不说了,首先是左侧面板的两个JTextField,一个是输入需要搜索的内容,这个必须得自己手动输入,另外一个是搜索的路径,这个可以自己手动输入,也可以通过选择文件夹按钮来选择输出。当使用按钮输出时就需要用到一个文件类:JFileChooser。基本思想是当点击选择文件夹按钮后弹出一个对话框:(JFileChooser对象)jfc.showDialog(null,null);在这之前得设置只能选择文件夹:jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

最后当选择结束之后要得到选中的目录,而且在这里最好处理一个异常,即如果你什么都没选返回,就会抛出异常,所以我的代码是:

try {
     selectedfile = jfc.getSelectedFile().getAbsolutePath();
    } catch (Exception ef) {
     System.out.println("未选中任何文件");
    }

当然,如果你导出jar文件的话,catch语句可能就没用了。

最后记得与之相对应的JTextField对象.setText(selectedfile);

以上所有操作在一个匿名内部类JButton对象.addActionListener(new ActionListener(){.......});里面,这样基本就完成了,还有一点值得提醒的是:在匿名内部类中的所有外部变量都必须是final类型的,以后在各种匿名监听器中都会出现左侧面板的各种组件,所以在那些组件创建对象的时候都已经事先定义成final属性了。

 

 

点击搜索按钮后,然后就是进行系统的搜索了,这一点和在课堂练习时在控制台输出没什么区别,无非是创建File对象,然后列目录列文件,再进行递归等。至于多选框的区分大小写和不寻找隐藏的文件和文件夹则两个功能则需在递归的时候设置两个bool值当做开关,进行判断。下面是一点实现技巧。

区分大小写:如果不勾上的话当然就是正常的搜索了,只需要两个String,(搜索的路径).contains((搜索的内容));如果勾上的话就是需要区分大小写了,因为java提供的String判断方法只有.equalsIgnoreCase();即判断两个字符串完全相等,这显然和我们所要求的效果不一致,所以我的方法是先将两个字符串同时.toLowerCase();当然.toUpperCase();也是没问题的,当然这样的话每个遍历的路径都必须先进行这一操作,必然会导致程序运行慢下来,如果读者有更好的方法欢迎探讨。

不寻找隐藏的文件和文件夹:这里可以直接使用File类里的方法.isHidden();没多大问题,那么我们现在这里有一个小问题:我们是先判断一个文件是否为隐藏文件再判断我们隐藏文件的复选框是否选中了,还是先判断我们隐藏文件的复选框是否选中了再判断一个文件是否是隐藏文件呢?假设总共有x个文件。然后有y个隐藏文件(y<=x);如果选用第一种方法,总共需要判断(x+y)次,而第二种方法如果未选中的话,只需x次(对每个文件进行判断是否选中,可能可以再循环体外判断,这样就只需要判断一次,但是一个这是一个递归的方法,二个在体系内不仅要判断这一点还有其他的判断,三个我的个人水平还不是很高,所以暂时我就将他写入循环体内),而第二种方法选中的话就需要判断2x次,于是我们折中取1.5x次,那么哪种方法好呢?相信大家都知道一个电脑里的隐藏文件数量是远远比不上未隐藏的。即y《x-y;所以总体来说还是第一种方法好点。

最后,不管是哪种搜索,将每个符合要求的结果存入一个静态队列数组,交由右边的面板对象调用。记得将每次调用完后队列清空~~

 

 

 

现在来说一下右边面板的一些实现,首先由一个问题就是刚开始运行的时候JFrame已经加载完全了,之后需要对按钮操作使得结果显示出来,则需要一些动态方法。我的基本思路是每次搜索时先将右边面板所有组件卸载,然后进行添加,最后调用javax.swing.SwingUtilities.updateComponentTreeUI(Component);方法来刷新。我是用JTable来显示结果的,鉴于JTable的麻烦使用和我已经写了相当长的时间,就直接将按下搜索按钮后的代码复制过来吧。。

 

 

 

public void show() {
                                Image image = Toolkit.getDefaultToolkit().createImage("showpanelXP.jpg");
                                Font fnt = new Font("", Font.CENTER_BASELINE, 12);
		// 移除所有组件
		MainWindow.sp.removeAll();
		MainWindow.sp.getGraphics().drawImage(image, 0, 0, null);
		/**
		 * 得到SearchPanel的结果数组
		 */
		final String str[] = SearchPanel.str;

		/**
		 * 设置JTable单元格透明
		 */
		final JTable jt = new JTable(50, 2) {

			// 设置JTable单元格透明函数
			public Component prepareRenderer(TableCellRenderer renderer,
					int row, int column) {
				Component c = super.prepareRenderer(renderer, row, column);
				if (c instanceof JComponent) {
					((JComponent) c).setOpaque(false);
				}
				return c;
			}

			// 设置JTable单元格不可被编辑函数
			public boolean isCellEditable(int row, int col) {
				return false;
			}

		};
		jt.setOpaque(false);

		/**
		 * 设置JTable一些其他相关信息
		 */
		// 设置字体颜色及样式
		jt.setForeground(new Color(255, 255, 255));
		jt.setFont(fnt);
		// 用内部类方法设置所有单元格不可被编辑
		jt.isCellEditable(0, 0);
		// 设置单元格高度,默认为16
		jt.setRowHeight(60);
		// 设置不可多选行
		jt.setRowSelectionAllowed(false);
		
		/**
		 * error,由于DefaultTableMode中dtm重新设置了列名,所以以下程序并未获得真正的对象,
		 * 保留以作警示,具体实现代码在dtm设置列名下一行
		 */
		// 得到JTable中的列对象,并设置其宽度
//		TableColumnModel tcm = jt.getColumnModel();
//		TableColumn tc = tcm.getColumn(0);
//		tc.setPreferredWidth(500);

		JScrollPane jsp = new JScrollPane(jt);

		// 设置JScrollPane组件透明
		jsp.setOpaque(false);
		jsp.getViewport().setOpaque(false);

		final DefaultTableModel dtm = (DefaultTableModel) jt.getModel();
		dtm.setRowCount(0);
		dtm.setColumnIdentifiers(new String[] { "文件名(双击以打开)", "大小" });
		// 设置列宽度
		jt.getColumn("文件名(双击以打开)").setPreferredWidth(1050);
		
		for (int i = 0; i < str.length; i++) {
			String element[] = new String[] { str[i],
					count((new File(str[i]).length())) };
			dtm.addRow(element);
		}

		MainWindow.sp.add(jsp);
		javax.swing.SwingUtilities.updateComponentTreeUI(MainWindow.sp);
		
		//给JTable添加监听器,使得双击可以打开该文件夹或文件
		jt.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				if (e.getClickCount() == 2) {
					for (int i = 0; i < dtm.getRowCount(); i++) {
						if (jt.getSelectedRow() != -1) {
							File file = new File((String)jt.getValueAt(jt.getSelectedRow(), 0));
							try {
									Desktop.getDesktop().open(file);
								} catch (IOException e1) {
									// TODO Auto-generated catch block
									JOptionPane.showMessageDialog(null, "无法打开指定的文件", "警告", 2);
								}
							break;
						}
					}
				}
			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub

			}

		});
	}

 

这里有几个难点,一个就是JTable,DefaultTableMode,TableColumnMode,TableColumn,TableMode这几个类的相互转换以及它们各自方法的调用。不过我想熟练了之后这个就不是很难了。

然后是设置JTable行列不可被编辑,这个的实现方法是在创建JTable对象时定义的,以及不可多选行,这些在上述代码中都有注释。

另外还有得到JTable的行对象,我试过,结果无果,但是可以通过某些方法得到其中的Object内容,最后将其转换为String类型,再通过JTable的鼠标监听器,当点击两次时打开windows下的该文件或目录。有些文件是无法通过这个程序打开的,于是我在打开文件操作时用了try…catch语句,当打开失败时弹出警告对话框,不过令我郁闷的是我居然在测试mp4文件时它弹出了对话框,各种囧……

还有一些小问题像是字体设置啊,以及和背景对应的字体颜色设置用到setForeground(…);函数等。。

另外如果你有兴趣的话也可以添加一些键盘监听器以便于键盘操作,我在这个程序里只添加了两个按钮的键盘监听:当按下Alt+L时选择文件夹,当按下Alt+R时进行搜索。

 

 

最后重要加一点的就是背景设置,因为在程序运行时我们必须加载两个面板在setVisible(true);但是面板设置图片又必须在setVisible(true);后再getGraphics().drawImage( , , , );所以怎么看也不合逻辑,为了解决这一问题,我们需要采用重绘组件的方法,即先加载JFrame窗体,这样当然图片背景设置就不成功,因为得到的Graphics对象还是空的,不过让它自动重绘一下就OK了。在这里调用方法继续贴出来:

 

 

public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(image, 0, 0, null);
	}

 image对象在外部已经定义过。这样就解决了,当然这个解决指的是对于左边的面板,因为左边就那么几个组件,而右边的组件是一个JTable全部覆盖了,这就要设置表格透明,我一直认为迅雷7的下载界面很好看,现在大概这个效果也可以媲美了吧。设置一个组件透明的函数是setOpaque(false);当然对于JTable来说不是这么简单实现的。但对于JCheckBox和JLabel等这样就OK了,事实上左边的面板我也这么设置了,所以看起来没有遮盖,不过对于左边的JButton,这样设置也是不行的,所以它还是覆盖了。言归正传,对于JTable的设置透明方法,我上网参考了很多资料,所以我自身还是不太懂,只知道在创建该对象的时候重写其中的一个方法,在上述代码中有说明,然后在外面设置setOpaque(false);再设置JScrollPane对象setOpaque(false);大功告成~~~

 

JTable列的宽度设置也一直是困扰我的难题,不过还是被我找出了问题所在,在代码中也有说明~~

 

 

最后一点,是关于JTable第二列中的文件大小问题,这里只需要得到每个文件的大小,默认是Byte,你可以把它转换成1~1024的任意一个数加上他的单位再输出就行。如果你只需要得到整数,那非常简单,但是如果需要得到几位小数,那就有点曲折了,思路是:将得到的大小数据转换成double型,然后进行单位换算直至它的数值在1~1024,以及得到这时相应的单位。最后通过一个格式化函数将它格式化,我的格式化是输出两个小数。然后将结果输出就行了,以下是一个格式化函数,当传入的参数是File.length();时返回的就是两个的浮点数+单位~~~

 

 

// 格式化输出单位
	public String count(long len) {
		int k = 0;
		double db = (double) len;
		String a[] = new String[] { "B", "KB", "MB", "GB", "TB" };
		while (db >= 1024) {
			db /= 1024;
			k++;
		}
		DecimalFormat df = new DecimalFormat("#.00");
		return df.format(db) + a[k];
	}

 

 

好吧,花了两个多小时,终于大功告成了,欢迎大家批评指教,文件我本想打包成jar上传上来,后来发现(这是我首次打包)打包后文件的路径设置有所改变,所以暂时还无法完成,下次成功了再上传上来吧~~

 

 

补充:

呼~~图片的相对路径终于被我搞好了,原来打包成jar文件后的路径要有所改变,在定义时需要用到this.getClass().getRssource("相对于bin目录的路径");,而且貌似在打分隔符的时候"\\"是没有用的,会报空指针,只有用"/"才行。

分享到:
评论

相关推荐

    简单文件搜索器的实现

    这个"简单文件搜索器的实现"项目旨在教你如何构建一个能够快速查找计算机中特定文件的工具。我们将通过分析给出的源码文件来理解其工作原理。 首先,`MenuItemLis.java`可能包含了程序的菜单项列表及其相关事件处理...

    C++实现快速查找文件 C++实现快速查找文件

    然而,如果需要在大量文件中快速查找,简单的线性搜索可能效率低下。这时可以考虑使用哈希表或二叉搜索树等数据结构。例如,先将文件名存入哈希表,然后进行查找,时间复杂度可降低到O(1)。这里以哈希表为例: ```...

    文件搜索功能普通功能的实现

    一个简单的文件搜索功能通常会遍历文件系统的目录结构,根据用户输入的关键字对文件名和内容进行匹配。以下是这一过程的详细步骤: 1. **目录遍历**:程序首先需要获取到文件系统的所有目录和文件信息。这可以通过...

    C# 快速文件搜索 查找

    对于简单的文件搜索,可以使用`File.Exists()`方法检查单个文件是否存在,但这种方式并不适用于大量文件的搜索。 在进行文件搜索时,`Directory.GetFiles()`方法是一个常用的选择。它允许我们指定一个目录路径,...

    C#文件搜索_C#_文件搜索_

    本项目提供了一套C#文件搜索的源码,对于初学者来说,这是一个很好的学习实例,可以帮助理解如何在C#环境中实现文件和目录的搜索功能。 首先,我们要了解C#中的`System.IO`命名空间,它提供了对文件、目录和流的...

    生成CHM文件中添加搜索功能

    当用户进行搜索时,CHM查看器会查询这个索引文件,快速定位到包含搜索词的页面,从而实现快速的搜索功能。 最后,在完成CHM文件的重新编译之后,重新打开CHM文件,您就应该能发现新增加的搜索功能了。现在,您可以...

    autoit写的一个文件搜索工具

    标题中的“autoit写的一个文件搜索工具”指的是一个利用AutoIt编程语言开发的软件,用于在计算机中快速查找和定位文件。AutoIt是一种轻量级、面向Windows操作系统的自动化脚本语言,它允许用户编写简单的到复杂的...

    易语言文件搜索器

    总结,易语言文件搜索器通过易语言的编程特性,结合高效的搜索算法和用户友好的界面设计,实现了快速查找文件的功能。通过理解易语言的基本语法和文件操作,我们可以进一步改进和扩展这个工具,以适应更复杂的文件...

    一种简单方法的实现文件递归搜索

    1)指定任意目录,实现文件递归搜索,并且可将搜索到的文件拷贝到指定位置,且保持原目录结构; 2)对于搜索到的文件,加上指定后缀(以.bak为例),然后拷贝到指定目录; 3)实现将指定目录下的指定后缀(以.bak为...

    Tomm闪电文件搜索

    《Tomm闪电文件搜索:高速精准的文件检索神器》 在日常的工作与学习中,我们常常需要快速定位到存储在电脑中的某个文件,这是一项看似简单却往往让人头疼的任务。传统的文件搜索方式可能存在搜索速度慢、匹配不准确...

    java 根据文件名实现文件搜索

    java实现根据文件名查找本地文件,该程序可直接放在eclipse或者Myeclipse中则可运行,不需要下载其他什么工具包,为开发人员节省了很多时间

    c#实现计算器和制定目录下的文件搜索

    在本文中,我们将深入探讨如何使用C#编程语言在Visual Studio 2010环境下实现一个简单的计算器功能以及一个文件搜索功能。这两个功能都涉及到Windows窗体应用程序的基础知识,包括控件的使用、事件处理以及文件系统...

    搜索文件的工具Tommsearch

    标题中的“Tommsearch”是一款专门用于搜索文件的工具,它设计的目标是帮助用户快速、高效地定位到电脑中的特定文件。...通过这样的工具,可以有效地克服Windows自带搜索功能的不足,实现更加高效和精确的文件查找。

    简单的文件搜索器

    【标题】:“简单的文件搜索器” 【描述】:在信息技术领域,文件搜索是日常工作中一个不可或缺的功能。一个简单的文件搜索器通常是指一个程序或工具,它允许用户在计算机上快速定位和查找特定的文件或文件夹。这个...

    简单的文件搜索系统

    标题中的“简单的文件搜索系统”指的是一个用于查找特定文件或文件夹的应用程序,它能够帮助用户在指定的磁盘(在这个例子中是F盘)快速定位到他们需要的文件。这个系统可能是用C语言或C++编写的,两种都是常用的...

    磁盘文件搜索(易语言源码)

    源码中的搜索功能体现了这一点,通过简单的控制结构和函数调用,就能实现复杂的文件搜索任务。 四、自定义后缀名搜索的应用场景 自定义后缀名搜索在日常工作中非常实用,例如: - 查找特定类型的项目文件,如图片...

    易语言本地文件搜索(支持不同类型和不同文件夹及全盘)

    易语言作为一款中国本土的编程语言,提供了简单易懂的语法,让开发者可以轻松实现文件搜索功能。本文将围绕“易语言本地文件搜索”这一主题,深入探讨如何利用易语言来实现不同类型和不同文件夹的文件搜索,并支持...

    文件搜索神器——HotKey

    为此,一种名为"HotKey"的文件搜索神器应运而生,它旨在提供更快速、更精准的文件搜索体验。 "HotKey"是一款专门优化文件搜索的软件,它的主要特点在于其快捷键操作和高效的搜索算法。通过创建自定义的热键组合,...

    android 文件搜索器

    【Android 文件搜索器】是一款专为Android平台设计的应用程序,旨在帮助用户快速、高效地在设备上查找指定的文件。这个工具可能包含了源代码,因此对于开发者来说,它不仅是一个实用工具,也是一个学习和研究的对象...

Global site tag (gtag.js) - Google Analytics