wasw100's Blog
2012/02/23

Google AD

2009年09月26日

Swing中Timer定时器的使用

类名:javax.swing.Timer

构造方法:Timer(int delay, ActionListener listener)
          
创建一个每 delay 毫秒将通知其侦听器的 Timer。

int delay = 1000; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          //...Perform a task...
      }
  };
  new Timer(delay, taskPerformer).start();

 

该代码创建并启动一个每秒激发一次操作事件的计时器(正如该 Timer 构造方法的第一个参数指定的那样)。该 Timer 构造方法的第二个参数指定一个接收该计时器操作事件的侦听器。

 

上面是API上说明,javax.swing.Timer在 GUI编程在组件内容更新时经常用到Timer,例如JTable、JLabel内容更新。

下面是一个简单的显示时间的GUI程序,可以加深对Timer的使用的理解:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

/**
 * 测试swing中Timer的使用
 * 一个显示时间的GUI程序
 * @author wasw100
 *
 */
public class TimerTest extends JFrame implements ActionListener {
	// 一个显示时间的JLabel
	private JLabel jlTime = new JLabel();
	private Timer timer;

	public TimerTest() {
		setTitle("Timer测试");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(180, 80);
		add(jlTime);

		//设置Timer定时器,并启动
		timer = new Timer(500, this);
		timer.start();
		setVisible(true);
	}

	/**
	 * 执行Timer要执行的部分,
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date();
		jlTime.setText(format.format(date));

	}

	public static void main(String[] args) {
		new TimerTest();
	}
}

程序说明: 

类实现了ActionListener接口,所以可以直接timer = new Timer(500, this);使用this初始化计时器。

当计时器启动后(timer.start()执行后),每隔500毫秒执行一次实现的 ActionListener 接口中的actionPerformed的方法体

 

这里在补充一点显示时间格式的知识:

DateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);

MM表示月份  mm表示分钟   hh:12小时制显示几点  HH:24小时制显示几点 

–EOF–

2009年09月22日

解决ie6 ie7中js不能通过appendChild(tr)添加table行的方法

本机只有ie7,ff3.5,opera10,测试在这三个环境中测试通过。

在标准DOM中添加元素一般使用appendChild();
但用js在table中添加行时却失效了。
网上搜了一下说 ie6,ie7不支持table.appendChild(“tr”)

那在JavaScript中怎么在一个table中添加一行呢?
http://www.w3schools.com/htmldom/dom_obj_table.asp看到w3c文档中HTML DOM Object存在tableObject.insertRow(index)方法。何不在插入行时用这个方法呢,毕竟在html中table比普通的标签有其特殊性,碰到table添加一行时,注意使用insertRow而不是appendChild,这样代码才能使用更多浏览器。看下面一段代码:

<!DOCTYPE html>
<html>
	<head>
		<script type="text/javascript">
		function insRow()
		{
			var tbl = document.getElementById('myTable');
			var row = tbl.insertRow(0);
			var cell = row.insertCell(0);
			cell.innerHTML="new cell";
		}
</script>
	</head>

	<body>
		<table id="myTable" border="1">
			<tr>
				<td>
					cell
				</td>
			</tr>
		</table>
		<br />
		<input type="button" onclick="insRow()" value="Insert row">
	</body>
</html>

比使用标准的DOM还简单,而且也符合w3c标准,但有一点要说明的是:

innerHTML这个方法虽然没有在w3c文档中出现,但是由于使用的广泛性,很多浏览器都进行了支持,添加文本节点(text nodes)时可以用innerHTML,如果非要符合w3c标准,可以用createTextNode(str)方法,本例中在JavaScript最后一行改为:cell.appendChild(document.createTextNode(“new cell”))。

但是上面的例子还有一个与appendChild()不同的地方,就是appendChild值插在原有元素的后面,但是例子中是插在了第一行。怎么插在表格的最后一行,或者插在当前行的后一行或者前一行怎么做呢?
只要实例中把javascript改为:var row = tbl.insertRow(tbl.rows.length);

下面附加一段带有 在最后加一行,本行前前加一行,本行后加一行,删除当前行的html代码

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/htmt;charset=utf-8">
		<script type="text/javascript">
		var i=0;
		function insRow(){
			var tbl = document.getElementById("myTable");
			insRowIndex(tbl.rows.length);
		}
		function insRowIndex(rowIndex){
			var tbl = document.getElementById("myTable");
			var row = tbl.insertRow(rowIndex);
			var cell0 = row.insertCell(0);
			var cell1 = row.insertCell(1);
			cell0.innerHTML = "cell " + i++;
			cell1.innerHTML = "	<input type='button' value='delete' onclick='delRow(this)'>"
								+"<input type='button' value='insBefore' onclick='insBefore(this)'>"
								+"<input type='button' value='insAfter' onclick='insAfter(this)'>";
		}
		function delRow(row){
			var tbl = document.getElementById("myTable");
			var rowIndex =  row.parentNode.parentNode.rowIndex;
			tbl.deleteRow(rowIndex);
		}
		function insBefore(row){
			var rowIndex =  row.parentNode.parentNode.rowIndex;
			insRowIndex(rowIndex)
		}
		function insAfter(row){
			var rowIndex =  row.parentNode.parentNode.rowIndex;
			insRowIndex(rowIndex+1)
		}
</script>
	</head>

	<body>
		<table id="myTable" border="1">
			<tr>
				<td>
					单元格
				</td>
				<td>
					操作
				</td>
			</tr>
		</table>
		<br />
		<input type="button" onclick="insRow()" value="Insert row">
	</body>
</html>

–EOF–

2009年09月19日

hibernate中使用hilo生成主键的原理

hilo是hibernate中最长用的一种生成方式,hibernate给出了hilo 和 seqhilo两种生成器,他们的分别向下面一样配置

<id name="id" type="int" column="id">
        <generator class="hilo">
                <param name="table">wasw100_hilo_tbl</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
        </generator>
</id>

 

seqhilo配置

<id name="id" type="int" column="id">
        <generator class="seqhilo">
                <param name="sequence">hi_value</param>
                <param name="max_lo">100</param>
        </generator>
</id>

 

seqhilo生成器需要数据库对sequence的支持,这里只讨论更通用的hilo生成器。

如果你按照下面的方式配置

<generator class="hilo">
        <param name="max_lo">100</param>
</generator>

 这样的缺省配置对应的数据库表是:hibernate_unique_key,对应的数据库字段是:next_hi。next_hi必须有一条记录否则会出现错误。

 

讨论前先说明几个简写的意义,以最上面那个配置为例:

hi: 高值–从数据库wasw100_hilo_tbl读取的next_value值

lo: 低值–hibe自动维护,从0到max_lo(看下面)

max_lo: 配置文件中<param name=”max_lo”>100</param>的值,这里是100

 

hibernate根据hilo生成器生成主键的过程:

1.读取并记录数据库的wasw100_hilo_tbl表中next_value字段的值,数据库中此字段值加1保存

2.hibernate取得lo值(0到max_lo-1循环,lo到max_lo时,执行步骤1,然后lo继续从0到max_lo循环)

取得hi值和lo值后,根据下面的公式计算主键值:

hi*(max_lo+1)+lo;

 

例如:
hi初始为2,max_lo为3
生成的值依次是:
读取hi为2,写到数据库为3
2*(3+1)+0=8
2*(3+1)+1=9
2*(3+1)+2=10
2*(3+1)+3=11
这有次读写表wasw100_hilo_tbl操作,hi变为3,数据库成为4
3*(3+1)+0=12
3*(3+1)+1=13

关闭数据库,下次打开时,读取hi值为4,数据库变为5
4*(3+1)+0=16

 

但是有一种特殊情况,就是hi是0的时候,那么第一个值不是0*(max_lo+1)+0=0
而是lo跳过0从1开始,直接是1、2、3……

 

那max_lo配置多大合适呢?

这要根据具体情况而定,如果系统一般不重启,而且需要用此表建立大量的主键,可以吧max_lo配置大一点,这样可以减少读取数据表wasw100_hilo_tbl的次数,提高效率;反之,如果服务器经常重启,可以吧max_lo配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。

java设计模式–单例模式 的简单例子

问题域:

–系统中你需要获得某个类的唯一实例,所有客户端对它的访问都将通过一个公共的访问点获得

–创建一个类并使其:(A)定义一个私有的构造器(B)定义一个私有、静态的变量指向自己(C)定义一个公有、静态的访问方法用于返回该类的一个唯一实例

分为 饿汉式 和 懒汉式

,下面是一个简单的示例代码,应该很容易理解:

1、饿汉式代码

package pattern.singleton.basic;

/**
 * java设计模式:单例模式(饿汉式)
 * @author wasw100
 */
public class Singleton {
	// 提供一个静态私有变量指向自己,属于类
	private static Singleton instance = new Singleton();// 提前消费
	// 提供私有构造器,只有在当前类中可以使用new,外界不能构造该类的对象
	private Singleton() {
	}

	// 对外提供一个公共访问点
	public static Singleton getInstance() {
		return instance;
	}
}

2、懒汉式代码

package pattern.singleton.basic;

/**
 * java设计模式:单例模式(懒汉式)
 * @author wasw100
 */
public class Singleton {
	private static Singleton instance = null;
	private Singleton(){}

	//synchronized避免在访问量比较大的时候 第一个线程的new Singleton还没来得及赋值给instance,第二个线程就来了,还要进行new ……
	public synchronized static Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
}

测试代码

package pattern.singleton.basic;

public class ClientClass {

	public static void main(String [] args){
		Singleton s1 = Singleton.getInstance();
		Singleton s2 = Singleton.getInstance();
		System.out.println(s1);
		System.out.println(s2);
	}
}

输出结果(地址相同,所以指向同一个对象):
pattern.singleton.basic.Singleton@a90653
pattern.singleton.basic.Singleton@a90653

说明:

  • 构造方法是私有的,外部类不能实例化,只能在类的内部实例化
  • 饿汉式在类加载时实例化,懒汉式在第一次程序第一次执行getInstance()方法时实例化
  • 懒汉式中synchronized避免在访问量比较大的时候 第一个线程的new Singleton还没来得及赋值给instance,第二个线程就来了,还要进行new ……

–EOF–

遍历Map的三种方法

遍历Map的三种方法,直接贴代码:

import java.util.HashMap;
import java.util.Map;

/**
 * Map的遍历
 *
 * @author wasw100
 */
public class MapTest {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("one", 1);
		map.put("two", 2);

		// 通过Map.keySet取得键的集合
		System.out.println("通过Map.keySet遍历:");
		for (String key : map.keySet()) {
			System.out.println("键:" + key + "\t值:" + map.get(key));
		}

		// 通过Map.entrySet遍历
		System.out.println();
		System.out.println("通过Map.entrySet遍历:");
		for (Map.Entry<String, Integer> s : map.entrySet()) {
			System.out.println("键:" + s.getKey() + "\t值:" + s.getValue());
		}

		// 通过Map.values()遍历所有的值,但是不能遍历键
		System.out.println();
		System.out.println("通过Map.values()遍历所有的值:");
		for (Object o : map.values()) {
			Integer i = (Integer) o;
			System.out.println("值:" + i);
		}

	}
}

运行结果:

通过Map.keySet遍历:
键:two	值:2
键:one	值:1

通过Map.entrySet遍历:
键:two	值:2
键:one	值:1

通过Map.values()遍历所有的值:
值:2
值:1

–EOF–

返回顶部