`
lg_asus
  • 浏览: 190794 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

SWT初学写的小工具

 
阅读更多
背景:我们项目中多语言文件是放在xml文件中,时间一长,一些多语言在代码中并没有用到,老大要我写个小工具将未使用到的多语言ID给找出来,需要考虑的就是:查找源代码文件的效率和判断ID是否被使用(注释中用到的不算),想用windows下的find findstr命令的,但java注释不好区分,因此还是只能对每个文件进行读取判断。

其中注释中出现ID的情况有以下几种情况:
1:// 开头的行,对应正则是 ^\\s*//.*
2:*开头的行,java的块注释中除首末两行其它是以*开头,对应正则是 ^\\s*\\*.*
3:/*开头的行,正则是 ^\\s*/\\*.*
4:*/结尾的行,正则 \\*/\\s*$
5:我把空行也认为是注释,正则 ^\\s+
第2种情况,有可能块注释中除首末外其它行并不以*开头,也是注释,因此这里比较麻烦,要在代码中判断。

代码如下:
public class FindStrInFiles implements Listener {
	private Text msrText;
	private Button msrBtn;
	private Text projectText;
	private Button projectBtn;
	private ProgressBar progressBar;
	private Button searchBtn;
	private Text resultText;
	private Label statusLabel;
	private Pattern commentPattern;
	private Matcher commentMatcher;
	private BufferedReader br;
	private String line;
	private boolean preComment = false;
	private Display display;
	private Shell shell;
	private LinkedList<String> msrList;
	private boolean isUsed;
	private WorkThread workThread;
	private boolean isStopped;
	private boolean isSuspended;

	public static void main(String... args) {
		FindStrInFiles find = new FindStrInFiles();
		find.init();
	}
	
	private void init() {
		// 以// * /*开头或者以*/结尾的都是注释,空行也认为是注释,
		// 还有一种情况是在块注释中间的行,在Pattern中无法判断,需要在代码中单独判断
		this.commentPattern = Pattern
				.compile("(^\\s*//.*)|(^\\s*\\*.*)|(^\\s*/\\*.*)|(\\*/\\s*$)|(^\\s+)");

		display = new Display();
		shell = new Shell(display);
		GridLayout layout = new GridLayout(3, false);
		layout.horizontalSpacing = 10;
		layout.marginLeft = layout.marginRight = layout.marginBottom = 5;
		shell.setLayout(layout);
		Label label = new Label(shell, SWT.NONE);
		label.setText("多语言文件");
		GridData gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false,
				false, 1, 1);
		label.setLayoutData(gridData);
		this.msrText = new Text(shell, SWT.BORDER | SWT.SINGLE);
		gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gridData.heightHint = 18;
		this.msrText.setLayoutData(gridData);
		this.msrBtn = new Button(shell, SWT.BORDER | SWT.NONE);
		this.msrBtn.setText("选择");
		gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1);
		gridData.widthHint = 50;
		this.msrBtn.setLayoutData(gridData);
		this.msrBtn.addListener(SWT.Selection, this);
		label = new Label(shell, SWT.NONE | SWT.UNDERLINE_SINGLE);
		label.setText("工程父目录");
		label.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
		label.setToolTipText("该目录下的所有项目中src下的源代码都会被搜索,不是工程的文件夹被忽略");
		gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1);
		label.setLayoutData(gridData);
		this.projectText = new Text(shell, SWT.BORDER | SWT.SINGLE);
		gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gridData.heightHint = 18;
		this.projectText.setLayoutData(gridData);
		this.projectBtn = new Button(shell, SWT.BORDER);
		this.projectBtn.setText("选择");
		gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1);
		gridData.widthHint = 50;
		this.projectBtn.setLayoutData(gridData);
		this.projectBtn.addListener(SWT.Selection, this);
		this.progressBar = new ProgressBar(shell, SWT.SIMPLE);
		gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
		this.progressBar.setLayoutData(gridData);
		this.searchBtn = new Button(shell, SWT.BORDER);
		this.searchBtn.setText("搜索");
		this.searchBtn.addListener(SWT.Selection, this);
		gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1);
		gridData.widthHint = 50;
		this.searchBtn.setLayoutData(gridData);
		label = new Label(shell, SWT.NONE);
		label.setText("结果");
		gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, true, 1, 1);
		label.setLayoutData(gridData);
		this.resultText = new Text(shell, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL | SWT.READ_ONLY);
		gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
		FontData fontData = new FontData();
		fontData.setHeight(11);
		this.resultText.setFont(new Font(display, fontData));
		this.resultText.setLayoutData(gridData);
		this.statusLabel = new Label(shell, SWT.NONE);
		gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1);
		this.statusLabel.setLayoutData(gridData);

		shell.setBounds(100, 20, 800, 600);
		shell.setDefaultButton(this.msrBtn);
		shell.setText("搜索未使用的多语言ID");
		shell.addListener(SWT.Dispose, this);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		shell.dispose();
	}

	@Override
	public void handleEvent(Event event) {
		int type = event.type;
		Widget widget = event.widget;
		if (SWT.Selection == type) {
			if (widget == this.msrBtn) {
				FileDialog dialog = new FileDialog(shell, SWT.SIMPLE | SWT.OPEN
						| SWT.SINGLE);
				dialog.setFilterPath("E:\\workspace\\eclipsej2ee3.7\\XXX\\conf");
				dialog.setFilterExtensions(new String[] { "*.xml" });
				String filePath = dialog.open();
				if (filePath == null) {
					return;
				}
				if (!dialog.getFileName().startsWith("message.")) {
					MessageBox box = new MessageBox(shell, SWT.ICON_INFORMATION);
					box.setText("Tip");
					box.setMessage("选择的不是语言文件");
					box.open();
					return;
				}
				this.msrText.setText(filePath);
			} else if (widget == this.projectBtn) {
				DirectoryDialog dialog = new DirectoryDialog(shell, SWT.OPEN
						| SWT.SINGLE);
				dialog.setFilterPath("E:\\workspace\\eclipsej2ee3.7");
				dialog.setMessage("选择工程父目录,该目录下的所有项目中src下的源代码都会被搜索,不是工程的文件夹被忽略");
				String container = dialog.open();
				if (container == null) {
					return;
				}
				this.projectText.setText(container);
			} else if (widget == this.searchBtn) {
				String btnText = this.searchBtn.getText();
				if ("搜索".equals(btnText)) {
					String msr = msrText.getText().trim();
					String father = projectText.getText().trim();
					if (msr.length() == 0 || father.length() == 0) {
						return;
					}
					this.resultText.setText("");
					this.statusLabel.setText("");
					this.isStopped = false;
					workThread = new WorkThread(msr, father);
					workThread.start();
					this.searchBtn.setText("暂停");
				} else if ("暂停".equals(btnText)) {
					this.isSuspended = true;
					this.searchBtn.setText("继续");
				} else if ("继续".equals(btnText)) {
					synchronized(this.msrList){
						this.isSuspended = false;
						this.msrList.notifyAll();
					}
					this.searchBtn.setText("暂停");
				}

			}
		}
		if (SWT.Dispose == type) {
			this.isStopped = true;
			display.dispose();
			System.exit(0);
		}
	}

	private void checkFile(final File project, final File src,
			final String id) {
		
		if (this.isStopped) {
			return;
		}
		if(this.isSuspended){
			synchronized(this.msrList){
				try {
					this.msrList.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		if (src.isDirectory()) {
			File[] files = src.listFiles();
			for (final File f : files) {
				if (this.isUsed) {
					return;
				}
				// 跳过类似.svn这样的目录
				if (f.isHidden()) {
					continue;
				}
				this.checkFile(project, f, id);
			}
		} else {
			// 跳过非java文件
			if (!src.getName().endsWith(".java")) {
				return;
			}
			if (display.isDisposed()) {
				return;
			}
			display.asyncExec(new Runnable() {
				@Override
				public void run() {
					if (statusLabel.isDisposed()) {
						return;
					}
					statusLabel.setText("查找ID: "+id+" 分析文件: " + src.getPath());
				}
			});
			try {
				br = new BufferedReader(new FileReader(src));
				int index = -1;
				while ((line = br.readLine()) != null) {
					index++;
					// 注释跳过
					if (this.isComment(line)) {

					} else {
						if (line.indexOf("\"" + id + "\"") != -1) {
							this.isUsed = true;
							System.out.println(id + " occurs at project: "
									+ project.getName() + ", file: "
									+ src.getPath() + ", row number: " + index);
							return;
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
				return;
			} finally {
				if (br != null) {
					try {
						br.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	private boolean isComment(String line) {
		this.commentMatcher = this.commentPattern.matcher(line);
		if (this.commentMatcher.matches()) {
			// 注释块的第一行
			if (line.trim().startsWith("/*")) {
				this.preComment = true;
			}
			// 注释块的最后一行
			if (line.trim().endsWith("*/")) {
				this.preComment = false;
			}
			return true;
		}
		// 如果在注释块中间
		if (this.preComment) {
			return true;
		}
		return false;
	}

	private void setBtnStatus(final boolean flag) {
		display.asyncExec(new Runnable() {
			@Override
			public void run() {
				if (msrBtn.isDisposed() || projectBtn.isDisposed()) {
					return;
				}
				msrBtn.setEnabled(flag);
				projectBtn.setEnabled(flag);
			}
		});
	}

	// ==========================
	class WorkThread extends Thread {
		private String xmlPath;
		private String container;

		public WorkThread(String xmlPath, String container) {
			this.xmlPath = xmlPath;
			this.container = container;
		}

		@Override
		public void run() {
			setBtnStatus(false);
			msrList = new LinkedList<String>();
			Document doc = null;
			try {
				doc = new SAXBuilder().build(this.xmlPath);
			} catch (JDOMException e1) {
				e1.printStackTrace();
				return;
			} catch (IOException e1) {
				e1.printStackTrace();
				return;
			}
			Element root = doc.getRootElement();
			List<Element> children = root.getChildren("msr");
			if (children == null || children.size() == 0) {
				return;
			}
			Iterator<Element> it = children.iterator();
			while (it.hasNext()) {
				msrList.add(it.next().getChildText("id"));
			}
			doc = null;
			final File[] projects = new File(this.container).listFiles();
			int msrIndex = 0;
			int projectIndex = 0;
			for (final String id : msrList) {
				if (isStopped) {
					return;
				}
				msrIndex++;
				isUsed = false;
				for (File f : projects) {
					if (isStopped) {
						return;
					}
					projectIndex++;
					final int ratio = (int) ((projects.length * (msrIndex - 1) + msrIndex) / (projects.length
							* msrList.size() / 100));
					if (display.isDisposed()) {
						return;
					}
					display.asyncExec(new Runnable() {
						@Override
						public void run() {
							if (progressBar.isDisposed()) {
								return;
							}
							progressBar.setSelection(ratio);
						}
					});
					// 非目录则跳过
					if (f.isFile()) {
						continue;
					}
					// 不是工程则直接跳过
					if (!new File(f, ".project").exists()) {
						continue;
					}
					// 隐藏目录跳过
					if (f.isHidden()) {
						continue;
					}
					File src = new File(f, "src");
					if (!src.exists()) {
						continue;
					}
					checkFile(f, src, id);
					if (isUsed) {
						break;
					} else {

					}
				}
				if (!isUsed && !isStopped) {
					if (display.isDisposed()) {
						return;
					}
					display.asyncExec(new Runnable() {
						@Override
						public void run() {
							if (resultText.isDisposed()) {
								return;
							}
							resultText.append(id
									+ System.getProperty("line.separator"));
						}
					});
				}
			}
			setBtnStatus(true);
			display.asyncExec(new Runnable() {
				@Override
				public void run() {
					if (statusLabel.isDisposed()) {
						return;
					}
					searchBtn.setText("搜索");
					statusLabel.setText("搜索完毕,共有"
							+ (resultText.getLineCount() - 1) + " 条记录");
				}
			});
		}
	}
}


这里遇到的几个问题:FileDialog和DirectoryDialog不能指定size和location, 如果想指定size和location,只能用Shell去模拟Dialog了。

还有两个常见的技术:在暂停搜索的时候,用了wait和notifyAll,由于搜索是个比较耗时的工作,因此不能直接在GUI线程中去完成,这里用WorkThread去完成搜索,由于swt和swing都是GUI 单线程机制,如果在GUI/EDT中去完成搜索的话,会造成UI假死。解决方法就是display.asyncExec和display.syncExec,SwintUtilities.invokeLater,SwingUtilities.invokeAndWait,前者表示直接让UI事件插队而返回,后者表示等待UI事件执行完才返回。
分享到:
评论

相关推荐

    java SWT简单小工具

    本项目名为"java SWT简单小工具",显然是一个使用SWT库开发的简易应用程序示例。 在描述中,"java SWT简单小工具"被重复提及,这可能表明该项目专注于展示如何使用SWT库来构建简单的GUI(图形用户界面)应用。由于...

    初学SWT&JFace

    【初学SWT&JFace】—— 探索Java图形用户界面的新篇章 在Java编程领域,GUI(图形用户界面)开发是构建交互式应用程序的关键部分。SWT(Standard Widget Toolkit)与JFace是两个非常重要的库,它们为Java开发者提供...

    用SWT写的简单的通讯录

    这对于初学者或者希望了解SWT实际应用的开发者来说非常有价值,他们可以研究代码结构,学习如何使用SWT组件来构建用户界面,以及如何处理用户交互和数据管理。 至于“工具”标签,可能意味着这个通讯录程序除了基本...

    SWT可视化插件

    对于初学者,可以先从理解SWT的基本组件和布局管理开始,然后逐渐深入到事件处理、自定义控件以及与其他Eclipse服务的集成等方面。同时,Window Builder的使用技巧也非常重要,例如熟悉其各种编辑模式、快捷键和预览...

    初学SWT (一)

    SWT,全称Standard Widget Toolkit(标准小部件工具包),是IBM开发的一款用于Java编程的图形用户界面(GUI)工具包。它为Java应用程序提供了与操作系统更紧密集成的GUI组件,使开发者可以构建出与操作系统风格一致的...

    swt的简单代码

    通过实际的代码示例,作者向读者展示了SWT的基本用法,帮助初学者快速理解并掌握SWT的核心概念。 【标签】"源码"和"工具" "源码"标签表明我们将讨论的是具体的编程代码,而"工具"则指SWT作为一种用于构建图形用户...

    IBM GUI库SWT教程

    本教程将深入探讨SWT库的使用方法和特性,帮助开发者更好地理解和应用这一强大的GUI工具。 ### SWT基础 1. **组件库**:SWT提供了丰富的组件,如按钮、文本框、列表、树视图、表格等,这些组件可以组合起来构建...

    swt学SWT者必备的帮助文档

    SWT(Standard Widget Toolkit)是Java编程中用于创建桌面应用程序用户界面的一种库,它是Eclipse项目的一部分,提供了丰富的图形...无论你是初学者还是有经验的开发者,这份资料都将是你探索和提升SWT技能的重要指南。

    swt原生库(用java开发swt用)

    总的来说,SWT是Java开发原生风格GUI应用的一个强大工具,它结合了Java的跨平台性和原生界面的性能与美观。使用SWT时,开发者需要对Java、操作系统API以及Eclipse RCP有一定的了解,才能充分发挥其潜力。对于初学者...

    Java swt完整教程

    Java SWT(Standard Widget Toolkit)是Java编程环境中用于创建桌面应用程序的一种图形用户界面(GUI)工具包。它是Eclipse基金会的一部分,提供了与操作系统本机UI组件紧密集成的能力,使得开发出的程序具有原生...

    SWT编程开发学习资料

    7. **Eclipse开发**:Eclipse作为SWT的主要使用者,其开发工具对SWT提供了很好的支持。学习如何在Eclipse环境中创建、调试和部署SWT应用是提升开发效率的关键。 8. **性能优化**:由于SWT直接操作系统资源,了解...

    swtdesigner

    对于初学者,可以通过在线教程、官方文档和社区论坛学习如何使用SwTDesigner。理解Swing组件的性质和Eclipse插件的运作方式是关键,这将有助于更好地利用SwTDesigner进行开发。 总之,SwTDesigner是Java SE开发者的...

    SWT.rar_SWT_eclipse swt

    SWT的设计目标是提供一个高效、轻量级且与操作系统紧密集成的GUI工具包,它允许开发者创建出与操作系统平台风格一致的用户界面。在Eclipse IDE中,SWT是开发桌面应用程序的基础,它与JFace一起,构成了强大的图形...

    SWT.rar_SWT tutorial_java swt_swt 登陆窗口_swt tutori_swt-designer

    本教程“SWT tutorial”针对SWT进行深入讲解,特别适合初学者学习。 SWT的核心概念是组件(Widgets),这些组件包括按钮、文本框、列表等,它们构成了GUI的基本元素。通过组合和配置这些组件,开发者可以创建各种...

    SWT API

    **SWT API 深入解析** `SWT (Standard Widget Toolkit)` 是一个开源的Java图形用户界面(GUI)库,由Eclipse基金会维护。...无论是初学者还是经验丰富的开发者,深入学习SWT API都将为开发工作带来显著的效率提升。

    Java SWT教程

    这个"Java SWT教程"文档,特别提到的"SWT Designer"是一个强大的可视化设计工具,它极大地简化了使用SWT进行GUI开发的过程,对于初学者来说非常友好。 在Java GUI编程中,AWT(Abstract Window Toolkit)和Swing是...

    SWT.rar_ java swt_SWT_java swt_java s_java swt

    总的来说,SWT为Java开发者提供了一种强大的工具,用于构建具有原生外观和高性能的GUI应用。通过这个SWT实例,初学者可以快速上手,熟练掌握GUI开发技术,进一步提升其Java编程能力。无论是简单的控制台应用还是复杂...

    swt入门范例新手适用,入门级

    SWT作为GUI工具包,提供了丰富的组件,如按钮、文本框、列表、树视图等,用于构建用户界面。与Java Swing不同,SWT更接近于操作系统原生的UI,因此在性能和外观上都有优势。接下来,我们将深入探讨SWT的一些关键知识...

Global site tag (gtag.js) - Google Analytics