`
abruzzi
  • 浏览: 452773 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

一个Swing的小应用(Todo-List)

阅读更多

前言

 

以前开发过一些简单的UI程序,大多都是借助IDE完成所有的工作,比如用DELPHI,或者C++ Builder等构筑,在这些工具中,UI是很容易开发的,但是在Java中就不一样了。Swing,在计算机科学界来说,其设计思想,整个体系的内涵,都是无以伦比的,但是要快速的用Swing开发一个能用的程序出来,还是比较困难的,其一,没有一个IDE支持(netbeans的高版本确实可以支持,但是,你对其Swing Application Framework不熟悉的话,开发出来的东西,你自己都不清楚所有细节),其二,貌似Swing的资料比较难找,找到的也大多是写不忍卒读的,即使想学也没有办法。

 

长期进行Java开发,UI部分还真没有涉及过,大多是WEB方面的,所以就找机会自己补习补习,关于Swing的资料,国外的好像比较多,而且也比较好,特别是Sun的员工的博客,确实不一般,如果英文过的去,就赶紧找找RSS订阅。

 

总体设计

先看下效果:


Todo-list


 

新建一个Task

stodo(http://code.google.com/p/stodo/)是我最近学习swing的一个总结,也算是个可以用的小软件,尽管不是很好用,呵呵。

 

stodo内部使用sqlite作为数据存储,一来为了小巧,二来数据库配起来比较麻烦,这个好,不要用户名密码,但是对数据的存取都是通过标准的SQL语句,很方便。

 

主要用到JList控件,对JList的ListCellRenderer进行定制,使得这个List的Cell比较漂亮,然后对List的DataModel进行扩展,使得List中的数据为我们需要的数据类型。通过这些的定制,发现Swing的设计思想确实很了不起,框架很清晰,以后做UI框架,最好还是学习Swing的这一套机制。

 

 

部分实现

好了,我们来看看实现的部分代码,如果要所有的源代码,可以去(http://code.google.com/p/stodo/)下载。

 

经验来看,做UI还是用IDE帮忙,我的界面中元素的布局都是用netbeans的UI设计器来设计的,然后将之CC到应用框架中即可。

 

 

	public static void main(String[] args){
		SwingUtilities.invokeLater(new Runnable(){
			public void run() {
				ListMainFrame lMain = new ListMainFrame("My todo list");
				lMain.initUI();
			}
		});
	}

 

在主入口处,创建TodoList的主界面,绑定菜单:

 

	public void initUI(){
    	try{
    		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    	}catch(Exception e){
    		System.err.println(e.getMessage());
    	}
    	
    	systemTray = SystemTray.getSystemTray();
		try {
			trayIcon = new TrayIcon(ImageIO.read(new File("imgs/icon.png")));
			systemTray.add(trayIcon);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (AWTException e) {
			e.printStackTrace();
		}

		addWindowListener(new WindowAdapter() {
			public void windowIconified(WindowEvent e) {
				dispose();
			}
		});

		trayIcon.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2)
					setExtendedState(NORMAL);
				setVisible(true);
			}
		});
		
    	//get todo-items from embedded database
    	TodoItemListBuilder builder = new TodoItemListBuilder();
    	List<TodoItem> tlist = builder.getTodoItems();
    	TodoListModel listModel = new TodoListModel();
    	
    	for(TodoItem item : tlist){
    		listModel.addElement(item);
    	}
    	
    	todolist = new TodoList(listModel);
    	todolist.setCellRenderer(new TodoListCellRenderer());
    	todolist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    	JScrollPane sp = new JScrollPane(todolist);
    	
    	todolist.addMouseListener(new ListItemListener());
    	
    	JMenuBar mbar = new JMenuBar();
    	JMenu fileMenu = new JMenu("File");
    	JMenuItem newTask = new JMenuItem("New task", new ImageIcon("imgs/schedule_new.gif"));
    	newTask.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
    	newTask.setIconTextGap(4);
    	newTask.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				if(newTaskDialog == null){
					newTaskDialog = new NewTaskDialog(ListMainFrame.this, "New Task");
				}
				newTaskDialog.setVisible(true);
			}
    		
    	});
    	
    	JMenuItem exit = new JMenuItem("Exit", new ImageIcon("imgs/close.gif"));
    	exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK));
    	exit.setIconTextGap(4);
    	exit.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				int y = JOptionPane.showConfirmDialog(
						null, 
						"Confirm exit", 
						"Confirm Exit Dialog", 
						JOptionPane.YES_NO_OPTION);
				if(y == JOptionPane.YES_OPTION){
					System.exit(0);
				}
			}
    		
    	});
    	
    	fileMenu.add(newTask);
    	fileMenu.add(exit);
    	
    	JMenu editMenu = new JMenu("Edit");
    	JMenuItem exportText = new JMenuItem("Export Text", new ImageIcon("imgs/exptotext.gif"));
    	JMenuItem exportExcel = new JMenuItem("Export Excel", new ImageIcon("imgs/exptoexcel.gif"));
    	
    	editMenu.add(exportText);
    	editMenu.add(exportExcel);
    	
    	mbar.add(fileMenu);
    	mbar.add(editMenu);
    	
    	setJMenuBar(mbar);
    	
    	getContentPane().add(sp);
    	setSize(400, 650);
    	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	setResizable(false);
    	setLocationRelativeTo(null);//center of the screen
    	setVisible(true);
	}

在JDK6中,用Swing开发桌面应用,比如调用浏览器,邮件客户端等都已经很容易,这里用到了系统托盘,这个也是JDK6中新添加的,可以使应用程序显得更加专业。

 

当添加一个新的task的时候,stodo先将记录插入数据库,然后更新主界面的JList的dataModel,Swing很好的做使用了MVC框架,更新了数据模型dataModel以后,控制器会自动更新JList。

 

另一个比较隐晦的问题是,当你自定义渲染器为List的Cell提供渲染的时候,你会发现,你在渲染器中绑定的事件会失效,因为JList会将这些事件处理,而不会继续传递,这就需要自己为鼠标绑一些事件处理(目前还没有找到更好的解决方法,如果你有好办法,请分享,谢谢)。

 

	class ListItemListener extends MouseAdapter{
		public void mouseEntered(MouseEvent e){
			JList list = (JList)e.getSource();
			int index = list.locationToIndex(e.getPoint());
			TodoItem item = (TodoItem)list.getModel().getElementAt(index);
			String tooltip = 
				"Desc : "+item.getDesc()+
				", Status : "+item.getStatus()+
				", Timeout:"+item.getTimeout();
			list.setToolTipText(
					"<html>"+tooltip+
					"</html>"
			);
		}
		
		public void mouseExited(MouseEvent e){
			JList list = (JList)e.getSource();
			list.setToolTipText("");
		}
		
		public void mouseClicked(MouseEvent e){
			if(e.getClickCount() == 2){
				JList list = (JList)e.getSource();
				int index = list.locationToIndex(e.getPoint());
				TodoItem item = (TodoItem)list.getModel().getElementAt(index);
					
				EditTaskDialog editTaskDialog = 
					new EditTaskDialog(ListMainFrame.this, "Edit exist task", item);
				
				editTaskDialog.setVisible(true);
			}
		}
	}
 

注意:这里摘录的都是一些代码片段,尽量给出解释,要看完整的代码,请参考上文。

 

后记

Swing非常强大,非常灵活,如果能基于现有的框架进行一个更高层次的封装,则可以更方便,易用。Swing的定制功能令人惊叹,这种哲学和*nix下的编辑器,shell等都是一脉相承的。

 

  • 大小: 45.4 KB
  • 大小: 12.3 KB
分享到:
评论
33 楼 rmn190 2010-07-09  
越来越想研究下Swing中用到的的设计模式了。

32 楼 BarryWei 2010-05-27  
Renderer用的很不错,很有意思。
如果需要在第一行加一个标题栏,估计就要换成JTable去做了。
如果不用JTable,能否实现第一行是一个标题栏呢!???
31 楼 abruzzi 2010-05-12  
xfei6868 写道
本程序看了一下,但是怎么没有0.5版的源文件代码呢。

而且还有一个问题不支持中文路径。


现在项目中的代码就是0.5的源码了,直接用svn check就可以了。中文路径我没有测试过,我下来再测试下。谢谢你的提醒。
30 楼 xfei6868 2010-05-12  
本程序看了一下,但是怎么没有0.5版的源文件代码呢。

而且还有一个问题不支持中文路径。
29 楼 bradwoo8621 2010-03-12  
abruzzi 写道
mallon 写道
Swing Application Framework其实只是Swing的简单封装,NetBeans GUI设计器还是相当好用的,我们现在正在开发的一个大型项目使用的是NetBeans RCP,很方便

嗯,确实,NetBeans的UI设计器是很好用的,我的很多控件都是用它来做布局设计的,如果有时间应该把SAF也好好研究研究,SAF对资源管理(多语言),EDT的管理(Swing假死)等都已经做了一个包装,用起来会很方便,自己写不但费事,而且容易出错。


NetBeans有用到他自己的Layout吗?

不过还是自己写的好, 这UI代码真是乱。。。
28 楼 abruzzi 2009-10-09  
wen.owen 写道
发现一个Bug,task不能被删除,删除后重启软件后被删的task仍然存在,请楼主确认一下。

PS: 能否在在源码中贴上依赖的jar文件,好好向楼主学习一下,希望有机会和楼主一起完善这款小软件。


非常抱歉,上次有个朋友也要我贴上jar,不过一直忙,一定会贴出来的。Task在这个版本中不能直接删除,只是在列表中删掉了,数据库中的没有去做。谢谢。
27 楼 wen.owen 2009-10-09  
发现一个Bug,task不能被删除,删除后重启软件后被删的task仍然存在,请楼主确认一下。

PS: 能否在在源码中贴上依赖的jar文件,好好向楼主学习一下,希望有机会和楼主一起完善这款小软件。
26 楼 abruzzi 2009-09-26  
zxz414644665 写道
LZ:我想说一下,界面还是可以,但主要的还是功能方面,我下了你的程序运行了一下,发现速度还是不怎么提的上去,像那个列表的更新好像比较慢,submit,cancel的时候,这个如果在开一个线程的话应该比较好,个人觉得。。。

嗯,数据操作部分确实有些问题,v0.3可能稍微好一些,我现在正在完善(导出,插件机制)。
25 楼 zxz414644665 2009-09-26  
LZ:我想说一下,界面还是可以,但主要的还是功能方面,我下了你的程序运行了一下,发现速度还是不怎么提的上去,像那个列表的更新好像比较慢,submit,cancel的时候,这个如果在开一个线程的话应该比较好,个人觉得。。。
24 楼 狂奔蜗牛 2009-09-25  
。。支持一下。。。
23 楼 kunee 2009-09-17  
界面挺好看的
22 楼 abruzzi 2009-09-15  
andyyehoo 写道
鸡肋,鸡肋

么子是鸡肋呢?
21 楼 andyyehoo 2009-09-15  
鸡肋,鸡肋
20 楼 qiren83 2009-09-15  
flex 来做不是更好吗?
19 楼 abruzzi 2009-09-14  
mallon 写道
Swing Application Framework其实只是Swing的简单封装,NetBeans GUI设计器还是相当好用的,我们现在正在开发的一个大型项目使用的是NetBeans RCP,很方便

嗯,确实,NetBeans的UI设计器是很好用的,我的很多控件都是用它来做布局设计的,如果有时间应该把SAF也好好研究研究,SAF对资源管理(多语言),EDT的管理(Swing假死)等都已经做了一个包装,用起来会很方便,自己写不但费事,而且容易出错。
18 楼 mallon 2009-09-14  
Swing Application Framework其实只是Swing的简单封装,NetBeans GUI设计器还是相当好用的,我们现在正在开发的一个大型项目使用的是NetBeans RCP,很方便
17 楼 istudy 2009-09-14  
界面设计的不错。。。。
16 楼 wantdrink 2009-09-14  
赫赫,楼主挖了个很好的坑
15 楼 abruzzi 2009-09-14  
不错,软件的功能是最重要的,但是,如果UI设计的很粗糙,用户可能直接就放弃掉了。我用Swing也算是刚上手,边学习边实践吧,呵呵。
14 楼 zhengyutong 2009-09-14  
楼主可以使用一套开源的皮肤,像楼上说的那样。然后找些漂亮的 icon 点缀一下,就会很好看了。当然,软件的功能是最重要的,尽量多为用户的操作方便考虑。

我只学了swing的一点皮毛,虽然swing还是经常被一些程序员嘲笑。

相关推荐

    ToDo-list:一个简单的待办事项列表应用程序

    【标题】"ToDo-list"是一个基于Java开发的简单待办事项列表应用程序,旨在帮助用户管理日常任务和提高生产力。这个程序遵循Aldo Ziflaj的教程指导,提供了基本的任务添加和删除功能。 【核心知识点】: 1. **Java...

    ToDo-List:活动或工作的剩余说明

    项目文件"ToDo-List-main"可能包含了项目的源代码、资源文件、配置文件等,通常会包括以下几个部分: 1. **源代码目录**:包含Java源文件,如主程序、任务类、用户界面组件等。 2. **资源文件**:可能包含GUI的样式...

    todo-list:待办事项清单项目

    在本项目中,“todo-list”是基于Java编程语言实现的,具体来说,是一个“香草Java”项目,意味着它可能没有依赖任何重型框架,而是使用了Java的核心特性。 【描述】:“香草Java待办事项清单”可能是一个简单的...

    First-TODO-App

    【标题】"First-TODO-App" 是一个初学者级别的项目,旨在帮助用户构建他们的第一个待办事项应用程序。这个项目通常用于教授基本的编程概念,尤其是对于那些刚刚接触 Java 编程的人。通过创建这样一个应用,学习者...

    JavaEye论坛热点推荐_-_2009年09月_-_总第16期.pdf

    7. **Swing小应用(Todo-List)**:展示了如何使用Swing构建一个简单的待办事项列表应用,提供了基础的GUI编程示例。 8. **日志库性能比较**:比较了log4j与JDK内置的日志系统在性能上的差异,为选择合适的日志库...

    Javaswing登录页面的实现

    // TODO Auto-generated catch block e1.printStackTrace(); } } else { JOptionPane pane = new JOptionPane("验证码错误,请重新输入"); JDialog dialog = pane.createDialog(this, "警告"); System.out....

    Java_Database_ToDo_List

    Java_Database_ToDo_List是一个基于Java编程语言的项目,用于创建一个简单的待办事项管理应用程序。它结合了数据库技术,为用户提供了一个存储、管理和跟踪日常任务的平台。这个项目主要面向初学者和中级Java开发者...

    todo_list

    在IT行业中,待办事项清单(Todo List...在学习和分析这个"todo_list"项目时,你可以深入理解Java的编程实践、GUI编程、以及如何组织一个完整的应用项目。通过阅读源码,可以提升对Java语言特性和软件工程实践的理解。

    JavaAppGui:我的带有 Swing GUI 的 Java 应用程序

    在本项目中,"JavaAppGui:我的带有 Swing GUI 的 Java 应用程序" 是一个使用 Java 编程语言开发的桌面应用,它利用了 Swing 工具包来构建图形用户界面(GUI)。Swing 是 Java Foundation Classes (JFC) 的一部分,...

    新版Android开发教程.rar

    Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...

    job4j_todo

    这个项目可能是为了教学目的,让学习者了解如何在Java环境下实现一个简单的待办事项(Todo List)应用。让我们深入探讨一下这个项目可能涉及的Java技术点。 1. **MVC设计模式**: "Todo List"应用通常采用Model-...

    todo_detail_app

    【标题】"todo_detail_app" 是一个基于Java技术开发的待办事项详情应用程序。这个项目可能是一个简单的任务管理工具,专注于展示和管理每个任务的详细信息。在Java领域,这样的应用通常涉及到面向对象编程、GUI设计...

    TodoList2:todoList

    【标题】:“TodoList2:一个基于Java的待办事项应用” 【描述】:“TodoList2是一个用Java语言开发的简单待办事项管理应用程序。它为用户提供了创建、编辑、删除和跟踪日常任务的能力,是学习Java编程以及理解面向...

    SimpleTodoList:只是简单的待办事项清单

    在编程世界中,创建一个待办事项(Todo List)应用是学习新语言或技术的常见起点。这不仅因为其功能简单直观,易于理解,而且它能让我们快速接触到基本的用户界面、数据存储和事件处理等核心概念。本次我们将深入...

    stodo:简单的所有经理

    `TodoManager`类可能会有一个List&lt;Todo&gt;用于保存所有的待办事项。 3. **GUI设计**:如果项目包含了图形用户界面,那么可能会使用JavaFX或者Swing库来创建。用户可以通过界面添加、删除和查看待办事项,这涉及到布局...

    待办事项清单

    3. **用户界面**:如果这是一个桌面应用,开发者可能使用JavaFX或Swing来构建用户界面,让用户能交互式地添加、编辑和删除待办事项。 4. **数据持久化**:为了保存用户的待办事项,开发者可能使用文件存储(如JSON...

    待办事项清单项目

    在IT行业中,待办事项清单项目(Todo List Project)是一种常见的练习或小型应用程序,它用于管理个人或团队的任务。这个项目通常用编程语言实现,比如Java,以展示基础的编程概念和软件工程实践。在这里,我们将...

    Java_final_ToDoList

    `Java_final_ToDoList`是一个基于Java语言开发的待办事项(Todo List)应用程序。它展示了如何利用Java的核心特性和设计模式来构建一个实用的桌面应用。这个项目主要涉及到以下几个核心知识点: 1. **Java基础**:...

    火车售票系统

    //创建一个连接对象con con = DriverManager.getConnection(url, user, password); //创建statement对象 stmt = con.createStatement(); }catch (SQLException e){} try { stmt.executeUpdate("insert into ...

Global site tag (gtag.js) - Google Analytics