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–
解决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–
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–