规则引擎简介
Java规则引擎是推�引擎的一�,它起�于基于规则的专家系统。
Java规则引擎将业务决ç–从应用程åº?代ç ?ä¸åˆ†ç¦»å‡ºæ?¥ï¼Œå¹¶ä½¿ç”¨é¢„定义的è¯ä¹‰æ¨¡å?—编写业务决ç–。Java规则引擎接å?—æ•°æ?®è¾“å…¥ï¼Œè§£é‡Šä¸šåŠ¡è§„åˆ™ï¼Œå¹¶æ ¹æ?®è§„则作出业务决ç–。从这个æ„?义上æ?¥è¯´ï¼Œå®ƒæ˜¯è½¯ä»¶æ–¹æ³•å¦åœ¨”关注点分离”上的一个é‡?è¦?的进展。
JSR-94è§„èŒƒå®šä¹‰äº†ç‹¬ç«‹äºŽåŽ‚å•†çš„æ ‡å‡†API,开å?‘人员å?¯ä»¥é€šè¿‡è¿™ä¸ªæ ‡å‡†çš„API使用Java规则引擎规范的ä¸?å?Œäº§å“?实现。但值得注æ„?çš„æ˜¯ï¼Œè¿™ä¸ªè§„èŒƒå¹¶æ²¡æœ‰å¼ºåˆ¶ç»Ÿä¸€è§„åˆ™å®šä¹‰çš„è¯æ³•ï¼Œå› æ¤ï¼Œå½“需è¦?将应用移æ¤?到其他的Java规则引擎实现时,å?¯èƒ½éœ€è¦?å?˜æ?¢è§„则定义。
基于规则的专家系统(RBES)
专家系统是人工智能的一个分支,它模仿人类的推ç?†æ–¹å¼?,使用试探性的方法进行推ç?†ï¼Œå¹¶ä½¿ç”¨äººç±»èƒ½ç?†è§£çš„æœ¯è¯è§£é‡Šå’Œè¯?明它的推ç?†ç»“论。专家系统有很多分类:神ç»?网络ã€?基于案例推ç?†å’ŒåŸºäºŽè§„则系统ç‰ã€‚
规则引擎则是基于规则的专家系统的一部分。为了更深入的了解Java规则引擎,下�简�地介�基于规则的专家系统(RBES)。
RBES的技术架构
RBES包括三部分:Rule Base(knowledge base)�Working Memory(fact base)和Rule Engine(推�引擎)。它们的结构如下所示:
如上图所示,规则引擎包括三部分:Pattern Matcher�Agenda和Execution Engine。Pattern Matcher决定选择执行哪个规则,何时执行规则;Agenda管�PatternMatcher挑选出�的规则的执行次�;Execution Engine负责执行规则和其他动作。
RBES的推�(规则)引擎
和人类的æ€?维相对应,规则引擎å˜åœ¨ä¸¤è€…推ç?†æ–¹å¼?:演绎法(Forward-Chaining)和归纳法(Backward-Chaining)。演绎法从一个åˆ?始的事实出å?‘,ä¸?æ–地应用规则得出结论(或执行指定的动作)。而归纳法则是从å?‡è®¾å‡ºå?‘,ä¸?æ–地寻找符å?ˆå?‡è®¾çš„事实。
Rete算法是目�效率最高的一个Forward-Chaining推�算法,Drools项目是Rete算法的一个��对象的Java实现。
规则引擎的推ç?†æ¥éª¤å¦‚下:
1. 将�始数�(fact)输入Working Memory。
2. 使用Pattern Matcher比较规则(rule)和数�(fact)。
3. 如果执行规则å˜åœ¨å†²çª?(conflict),å?³å?Œæ—¶æ¿€æ´»äº†å¤šä¸ªè§„则,将冲çª?的规则放入冲çª?集å?ˆã€‚
4. 解决冲�,将激活的规则按顺�放入Agenda。
5. 使用规则引擎执行Agendaä¸çš„规则。é‡?å¤?æ¥éª¤2至5,直到执行完毕所有Agendaä¸çš„规则。
JSR 94:Java规则引擎API
基于规则编程是一ç§?声明å¼?的编程技术,这ç§?æŠ€æœ¯è®©ä½ å?¯ä»¥ä½¿ç”¨è¯•探性的规则而ä¸?是过程性的指令æ?¥è§£å†³é—®é¢˜ã€‚规则引擎是一个软件模å?—,它决定了如何将规则作用于推ç?†æ•°æ?®ã€‚在ä¿?险业和金èž?æœ?务业都广泛地使用了基于规则的编程技术,当需è¦?在大é‡?的数æ?®ä¸Šåº”用å¤?æ?‚的规则时,规则引擎技术特别有用。
Java规则引擎APIç”±javax.rulesåŒ…å®šä¹‰ï¼Œæ˜¯è®¿é—®è§„åˆ™å¼•æ“Žçš„æ ‡å‡†ä¼?业级API。Java规则引擎APIå…?许客户程åº?使用统一的方å¼?å’Œä¸?å?ŒåŽ‚å•†çš„è§„åˆ™å¼•æ“Žäº§å“?交互,就åƒ?使用JDBC编写独立于厂商访问ä¸?å?Œçš„æ•°æ?®åº“产å“?ä¸€æ ·ã€‚Java规则引擎API包括创建和管ç?†è§„则集å?ˆçš„æœºåˆ¶ï¼Œåœ¨Working Memory䏿·»åŠ ï¼Œåˆ é™¤å’Œä¿®æ”¹å¯¹è±¡çš„æœºåˆ¶ï¼Œä»¥å?Šåˆ?始化,é‡?置和执行规则引擎的机制。
使用Java规则引擎API
Java规则引擎API把和规则引擎的交互分为两类:管ç?†æ´»åŠ¨å’Œè¿?行时活动。管ç?†æ´»åŠ¨åŒ…æ‹¬å®žä¾‹åŒ–è§„åˆ™å¼•æ“Žå’Œè£…è½½è§„åˆ™ã€‚è€Œè¿?行时活动包括æ“?作Working Memoryå’Œæ‰§è¡Œè§„åˆ™ã€‚å¦‚æžœä½ åœ¨J2SE环境ä¸ä½¿ç”¨Javaè§„åˆ™å¼•æ“Žï¼Œä½ å?¯èƒ½éœ€è¦?在代ç ?䏿‰§è¡Œä»¥ä¸Šæ‰€æœ‰çš„æ´»åŠ¨ã€‚ç›¸å??,在J2EE环境ä¸ï¼ŒJava规则引擎的管ç?†æ´»åŠ¨æ˜¯åº”ç”¨æœ?务器的一部分。JSR 94çš„å?‚考实现包括了一个JCA连接器,用于通过JNDI获得一个RuleServiceProvider。
设置规则引擎
Java规则引擎的管ç?†æ´»åŠ¨é˜¶æ®µå¼€å§‹äºŽæŸ¥æ‰¾ä¸€ä¸ªå?ˆé€‚çš„javax.rules.RuleServiceProvider对象,这个对象是应用程åº?访问规则引擎的入å?£ã€‚在J2EE环境ä¸ï¼Œä½ å?¯èƒ½å?¯ä»¥é€šè¿‡JNDI获得RuleServiceProvider。å?¦åˆ™ï¼Œä½ å?¯ä»¥ä½¿ç”¨javax.rules.RuleServiceProviderManager类:
javax.rules.RuleServiceProviderManager class:
String implName = “org.jcp.jsr94.ri.RuleServiceProvider”;
Class.forName(implName);
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(implName);
一旦拥有了RuleServiceProviderå¯¹è±¡ï¼Œä½ å?¯ä»¥èŽ·å¾—ä¸€ä¸ªjavax.rules.admin.RuleAdministrator类。从RuleAdministratorç±»ä¸ï¼Œä½ å?¯ä»¥å¾—到一个RuleExecutionSetProvider,从类å??å?¯ä»¥çŸ¥é?“,它用于创建javax.rules.RuleExecutionSets对象。RuleExecutionSet基本上是一个装入内å˜çš„,准备好执行的规则集å?ˆã€‚
包javax.rules.admin包括两个ä¸?å?Œçš„RuleExecutionSetProvider类。RuleExecutionSetProvider类本身包括了从Serializable对象创建RuleExecutionSetsçš„æ–¹æ³•ï¼Œå› æ¤åœ¨è§„则引擎ä½?于远程æœ?务器的情况下,ä»?ç„¶å?¯ä»¥ä½¿ç”¨RuleExecutionSetProviderç±»ï¼Œæž„é€ å™¨çš„å?‚æ•°å?¯ä»¥é€šè¿‡RMIæ?¥ä¼ 递。å?¦ä¸€ä¸ªç±»æ˜¯LocalRuleExecutionSetProvider,包å?«äº†å…¶ä»–方法,用于从é?žSerializable资æº?(如java.io.Readerï¼?本地文件)创建RuleExectionSets。å?‡è®¾æ‹¥æœ‰äº†ä¸€ä¸ªRuleServiceProviderå¯¹è±¡ï¼Œä½ å?¯ä»¥ä»Žæœ¬åœ°æ–‡ä»¶rules.xml文件创建一个RuleExectionSet对象。如以下的代ç ?所示:
RuleAdministrator admin = serviceProvider.getRuleAdministrator();
HashMap properties = new HashMap();
properties.put(“name”, “My Rules”);
properties.put(“description”, “A trivial rulebase”);
FileReader reader = new FileReader(“rules.xml”);
RuleExecutionSet ruleSet = null;
try {
LocalRuleExecutionSetProvider lresp =
admin.getLocalRuleExecutionSetProvider(properties);
ruleSet = lresp.createRuleExecutionSet(reader, properties);
} finally {
reader.close();
}
接下æ?¥ï¼Œä½ å?¯ä»¥ä½¿ç”¨RuleAdministrator注册获得的RuleExecutionSet,并给它分é…?一个å??称。在è¿?è¡Œæ—¶ï¼Œä½ å?¯ä»¥ç”¨å?Œä¸€ä¸ªå??称创建一个RuleSession;该RuleSession使用了这个命å??çš„RuleExecutionSet。å?‚è§?下é?¢çš„例å?:
admin.registerRuleExecutionSet(“rules”, ruleSet, properties);
执行规则引擎
在è¿?è¡Œæ—¶é˜¶æ®µï¼Œä½ å?¯ä»¥å?‚è§?一个RuleSession对象。RuleSession对象基本上是一个装载了特定规则集å?ˆçš„è§„åˆ™å¼•æ“Žå®žä¾‹ã€‚ä½ ä»ŽRuleServiceProvider得到一个RuleRuntime对象,接下æ?¥ï¼Œä»Žjavax.rules.RuleRuntime得到RuleSession对象。
RuleSession分为两类:statefulå’Œstateless。它们具有ä¸?å?Œçš„功能。StatefulRuleSessionçš„Working Memory能够在多个方法调用期间ä¿?å˜çжæ€?ã€‚ä½ å?¯ä»¥åœ¨å¤šä¸ªæ–¹æ³•调用期间在Working Memoryä¸åŠ å…¥å¤šä¸ªå¯¹è±¡ï¼Œç„¶å?Žæ‰§è¡Œå¼•擎,接下æ?¥è¿˜å?¯ä»¥åŠ å…¥æ›´å¤šçš„å¯¹è±¡å¹¶å†?次执行引擎。相å??,StatelessRuleSession类是ä¸?ä¿?å˜çжæ€?的,为了执行它的executeRulesæ–¹æ³•ï¼Œä½ å¿…é¡»ä¸ºWorking Memoryæ??供所有的åˆ?å§‹æ•°æ?®ï¼Œæ‰§è¡Œè§„则引擎,得到一个内容列表作为返回值。
下é?¢çš„例å?ä¸ï¼Œæˆ‘们创建一个StatefulRuleSessionå®žä¾‹ï¼Œæ·»åŠ ä¸¤ä¸ªå¯¹è±¡ï¼ˆä¸€ä¸ªInteger和一个String)到Working Memory,执行规则,然å?Žå¾—到Working Memory䏿‰€æœ‰çš„内容,作为java.util.List对象返回。最å?Žï¼Œæˆ‘们调用release方法清ç?†RuleSession:
RuleRuntime runtime = rsp.getRuleRuntime();
StatefulRuleSession session = (StatefulRuleSession)
runtime.createRuleSession(“rules”, properties,
RuleRuntime.STATEFUL_SESSION_TYPE);
session.addObject(new Integer(1));
session.addObject(“A string”);
session.executeRules();
List results = session.getObjects();
session.release();
集�JSR 94产�实现
支æŒ?JSR 94规范的产å“?实现既有收费的商业产å“?,也有å…?费的开æº?项目。目å‰?最为æˆ?熟,功能最强大的商业产å“?是ILOGå…¬å?¸çš„JRules,该公å?¸ä¹Ÿæ˜¯JSR 94规范的积æž?推动者之一。支æŒ?JSR 94规范的开æº?项目目å‰?很少,å?ªæœ‰Droolså’ŒJLisa项目。值得注æ„?的是,Jessä¸?是开æº?项目,它å?¯ä»¥å…?è´¹ç”¨äºŽå¦æœ¯ç ”究,但用于商业用途则è¦?收费。
JSR 94的产�实现
Java规则引擎商业产�有:
l. ILOG公�的JRules
2. BlazeSoft公�的Blaze
3. Rules4J
4. Java Expert System Shell (JESS)
开�项目的实现包括:
l. Drools项目
2. JLisa项目
3. OFBiz Rule Engine(�支�JSR 94)
4. Mandarax(目��支�JSR 94)
使用Spring集�
集æˆ?Javaè§„åˆ™å¼•æ“Žçš„ç›®æ ‡æ˜¯ï¼Œä½¿ç”¨æ ‡å‡†çš„Java规则引擎APIå°?装ä¸?å?Œçš„实现,å±?蔽ä¸?å?Œçš„产å“?å®žçŽ°ç»†èŠ‚ã€‚è¿™æ ·å?šçš„好处是,当替æ?¢ä¸?å?Œçš„规则引擎产å“?时,å?¯ä»¥ä¸?必修改应用代ç ?。
�装JSR94实现
RuleEngineFacadeç±»å°?装Java规则引擎,使用ruleServiceProviderUrlå’ŒruleServiceProviderImpl两个å?‚数,å±?蔽了ä¸?å?Œäº§å“?çš„é…?置。代ç ?如下:
public class RuleEngineFacade {
private RuleAdministrator ruleAdministrator;
private RuleServiceProvider ruleServiceProvider;
private LocalRuleExecutionSetProvider ruleSetProvider;
private RuleRuntime ruleRuntime;
// configuration parameters
private String ruleServiceProviderUrl;
private Class ruleServiceProviderImpl;
public void setRuleServiceProviderUrl(String url) {
this.ruleServiceProviderUrl = url;
}
public void setRuleServiceProviderImpl(Class impl) {
this.ruleServiceProviderImpl = impl;
}
public void init() throws Exception {
RuleServiceProviderManager.registerRuleServiceProvider(
ruleServiceProviderUrl, ruleServiceProviderImpl);
ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider(ruleServiceProviderUrl);
ruleAdministrator = ruleServiceProvider.getRuleAdministrator();
ruleSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider(null);
}
public void addRuleExecutionSet(String bindUri,InputStream resourceAsStream)
throws Exception {
Reader ruleReader = new InputStreamReader(resourceAsStream);
RuleExecutionSet ruleExecutionSet =
ruleSetProvider.createRuleExecutionSet(ruleReader, null);
ruleAdministrator.registerRuleExecutionSet(bindUri,ruleExecutionSet,null);
}
public StatelessRuleSession getStatelessRuleSession(String key)
throws Exception {
ruleRuntime = ruleServiceProvider.getRuleRuntime();
return (StatelessRuleSession) ruleRuntime.createRuleSession(key, null, RuleRuntime.STATELESS_SESSION_TYPE);
}
public StatefulRuleSession getStatefulRuleSession(String key)
throws Exception {
ruleRuntime = ruleServiceProvider.getRuleRuntime();
return (StatefulRuleSession) ruleRuntime.createRuleSession(
key, null, RuleRuntime.STATEFUL_SESSION_TYPE);
}
public RuleServiceProvider getRuleServiceProvider() {
return this.ruleServiceProvider;
}
}
�装规则
Ruleç±»å°?装了具体的业务规则,它的输入å?‚æ•°ruleName是定义规则的é…?置文件å??,并ä¾?赖于RuleEngineFacade组件。代ç ?如下:
public class Rule {
private String ruleName;
private RuleEngineFacade engineFacade;
public void init() throws Exception {
InputStream is = Rule.class.getResourceAsStream(ruleName);
engineFacade.addRuleExecutionSet(ruleName, is);
is.close();
}
public void setRuleName(String name) {
this.ruleName = name;
}
public void setEngineFacade(RuleEngineFacade engine) {
this.engineFacade = engine;
}
public StatelessRuleSession getStatelessRuleSession()
throws Exception {
return engineFacade.getStatelessRuleSession(ruleName);
}
public StatefulRuleSession getStatefuleRuleSession()
throws Exception {
return engineFacade.getStatefulRuleSession(ruleName);
}
}
组装规则组件
组装规则的�置文件如下:
http://drools.org/
org.drools.jsr94.rules.RuleServiceProviderImpl
/test/fibonacci.drl
测试用例
最å?Žï¼Œæˆ‘们编写测试用例,代ç ?如下:
public class JSRTest extends TestCase {
ApplicationContext ctx = null;
protected void setUp() throws Exception {
super.setUp();
ctx = new FileSystemXmlApplicationContext(“testrule.xml”);
}
public void testGetRuleSession() throws Exception {
Rule rule = (Rule)ctx.getBean(“fibonacci”);
assertNotNull(rule.getStatefuleRuleSession());
assertNotNull(rule.getStatelessRuleSession());
}
public void testStatelessRule() throws Exception {
Rule rule = (Rule)ctx.getBean(“fibonacci”);
Fibonacci fibonacci = new Fibonacci(50);
List list = new ArrayList();
list.add(fibonacci);
StatelessRuleSession session = rule.getStatelessRuleSession();
session.executeRules(list);
session.release();
}
public void testStatefulRule() throws Exception {
Rule rule = (Rule)ctx.getBean(“fibonacci”);
Fibonacci fibonacci = new Fibonacci(50);
StatefulRuleSession session = rule.getStatefuleRuleSession();
session.addObject(fibonacci);
session.executeRules();
session.release();
}
}
�行测试用例,出现绿�,测试通过。
规则定义è¯è¨€ä¹‹é—´çš„å?˜æ?¢
å› ä¸ºJSR 94è§„èŒƒå¹¶æ²¡æœ‰å¼ºåˆ¶ç»Ÿä¸€è§„åˆ™å®šä¹‰çš„è¯æ³•ï¼Œå› æ¤ï¼Œå½“需è¦?将应用移æ¤?到其他的Java规则引擎实现时,å?¯èƒ½éœ€è¦?å?˜æ?¢è§„则定义,如将Droolsç§?有的DRL规则è¯è¨€è½¬æ?¢æˆ?æ ‡å‡†çš„ruleML,Jess规则è¯è¨€è½¬æ?¢æˆ?ruleMLç‰ã€‚这个工作一般由XSLT转æ?¢å™¨æ?¥å®Œæˆ?。
如何�获音频�输出音频
import java.io.*;
import javax.sound.sampled.*;
import java.net.*;
/**
* Title:Â Â Â Â Â Â Â VoiceChat
* Description: 输出音频(放音程�)
* Copyright:Â Â Â Copyright (c) 2001
* Company:
* @author     Â
* @version 1.0
*/
class Playback implements Runnable {
      final int bufSize = 16384;
      SourceDataLine line;
      Thread thread;
      Socket s;
      Playback(Socket s){//æž„é€ å™¨ å?–å¾—socket以获得网络输入æµ?
        this.s=s;
      }
      public void start() {
          thread = new Thread(this);
          thread.setName(“Playback”);
          thread.start();
      }
      public void stop() {
          thread = null;
      }
      public void run() {
          AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
          BufferedInputStream playbackInputStream;
          try {
            playbackInputStream=new BufferedInputStream(new AudioInputStream(s.getInputStream(),format,2147483647));//å°?装æˆ?音频输出æµ?,如果网络æµ?是ç»?过压缩的需在æ¤åŠ å¥—è§£åŽ‹æµ?
          }
          catch (IOException ex) {
              return;
          }
          DataLine.Info info = new DataLine.Info(SourceDataLine.class,format);
          try {
              line = (SourceDataLine) AudioSystem.getLine(info);
              line.open(format, bufSize);
          } catch (LineUnavailableException ex) {
              return;
          }
          byte[] data = new byte[1024];//æ¤å¤„数组的大å°?跟实时性关系ä¸?大,å?¯æ ¹æ?®æƒ…况进行调整
          int numBytesRead = 0;
          line.start();
          while (thread != null) {
             try{
                numBytesRead = playbackInputStream.read(data);
                line.write(data, 0,numBytesRead);
             } catch (IOException e) {
                  break;
              }
          }
          if (thread != null) {
              line.drain();
          }
          line.stop();
          line.close();
          line = null;
      }
}
import java.io.*;
import javax.sound.sampled.*;
import java.net.*;
/**
* Title:Â Â Â Â Â Â Â VoiceChat
* Description: 音频��(录音程�)
* Copyright:Â Â Â Copyright (c) 2001
* Company:
* @author     Â
* @version 1.0
*/
class Capture implements Runnable {
      TargetDataLine line;
      Thread thread;
      Socket s;
      BufferedOutputStream captrueOutputStream;
      Capture(Socket s){//æž„é€ å™¨ å?–å¾—socket以获得网络输出æµ?
        this.s=s;
      }
      public void start() {
          thread = new Thread(this);
          thread.setName(“Capture”);
          thread.start();
      }
      public void stop() {
          thread = null;
      }
      public void run() {
          try {
            captrueOutputStream=new BufferedOutputStream(s.getOutputStream());//建立输出æµ? æ¤å¤„å?¯ä»¥åŠ å¥—åŽ‹ç¼©æµ?用æ?¥åŽ‹ç¼©æ•°æ?®
          }
          catch (IOException ex) {
              return;
          }
          AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
          DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);
          try {
              line = (TargetDataLine) AudioSystem.getLine(info);
              line.open(format, line.getBufferSize());
          } catch (Exception ex) {
              return;
          }
          byte[] data = new byte[1024];//æ¤å¤„çš„1024å?¯ä»¥æƒ…况进行调整,应跟下é?¢çš„1024应ä¿?æŒ?一致
          int numBytesRead=0;
          line.start();
          while (thread != null) {
              numBytesRead = line.read(data, 0,1024);//å?–æ•°æ?®ï¼ˆ1024)的大å°?ç›´æŽ¥å…³ç³»åˆ°ä¼ è¾“çš„é€Ÿåº¦ï¼Œä¸€èˆ¬è¶Šå°?越快,
              try {
                captrueOutputStream.write(data, 0, numBytesRead);//写入网络�
              }
              catch (Exception ex) {
                  break;
              }
          }
          line.stop();
          line.close();
          line = null;
          try {
              captrueOutputStream.flush();
              captrueOutputStream.close();
          } catch (IOException ex) {
              ex.printStackTrace();
          }
      }
}
technorati tags: java
如何�获视频
package com.borland.samples.welcome;
/**
 * Title:
 * Description:
 * Copyright:   Copyright (c) 2001
 * Company:
 * @author
 * @version 1.0
 */
import java.awt.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;
class ImageCanvas extends Canvas{
 private Image image;
 private Dimension prefSize;
 public ImageCanvas(Image image){
   this.image = image;
   calculatePreferredSize();
 }
 public void setImage(Image image){
   this.image = image;
   calculatePreferredSize();
   repaint();
 }
 private void calculatePreferredSize(){
   prefSize = new Dimension(image.getWidth(this),image.getHeight(this));
   System.out.println(image.getWidth(this));
   setSize(prefSize);
 }
 public Dimension getPreferredSize() {
    return prefSize;
 }
 public Dimension getMinimumSize() {
    return prefSize;
 }
 public void update(Graphics g){
    paint(g);
 }
 public void paint(Graphics g){
    g.drawImage(image,0,0,null);
 }
}
class ImageUtils{
 public static Image getScreenImage(){
   Robot robot;
   try {
     robot = new Robot();
   }catch(Exception e) {
     throw new RuntimeException(“unable to construct Robot”);
   }
   Dimension screenDims =Toolkit.getDefaultToolkit().getScreenSize();
   Image screen =robot.createScreenCapture(new Rectangle(450,350,screenDims.width,screenDims.height)).getScaledInstance(400,300,Image.SCALE_SMOOTH);
   MediaTracker tracker =new MediaTracker(new Label());
   tracker.addImage(screen,1);
   try {
     tracker.waitForID(0);
   }catch(InterruptedException e) { /** … */ }
   return screen;
 }
}
public class ScreenCapture extends Frame{
 private ImageCanvas canvas =new ImageCanvas(ImageUtils.getScreenImage());
 public ScreenCapture(){
   add(canvas);
   setSize(400,300);
   setVisible(true);
   Thread imageThread =new UpdateThread();
   imageThread.setDaemon(true);
   imageThread.start();
}
 class UpdateThread extends Thread{
  public void run(){
     while(true){
       try {
         Thread.currentThread().sleep(1000);
       }
       catch (Exception ex) {
       }
       canvas.setImage(ImageUtils.getScreenImage());
       validate();
    }
   }
 }
 public static void main(String[] args){
  new ScreenCapture();
 }
}
technorati tags: java
Java çš„å??射机制详解
Java çš„å??射机制是使其具有动æ€?特性的é?žå¸¸å…³é”®çš„一ç§?机制,也是在JavaBean ä¸å¹¿æ³›åº”用的一ç§?特性。
è¿?用JavaBean 的最常è§?çš„é—®é¢˜æ˜¯ï¼šæ ¹æ?®æŒ‡å®šçš„ç±»å??ï¼Œç±»å—æ®µå??和所对应的数æ?®ï¼Œå¾—到该类的实例,下é?¢çš„一个例å?演示了这一实现。
-|Base.java //抽象基类
 |Son1.java //基类扩展1
 |Son2.java //基类扩展2
 |Util.java
/**
 * @author metaphy
 * create 2005-4-14 9:06:56
 * 说明:
 */
(1)Base.java 抽象基类�是一个定义
public abstract class Base {
}
(2)Son1.java /Son2.java 是已�实现的JavaBean
public class Son1 extends Base{
   private int id ;
   private String name ;
  Â
   public int getId() {
       return id;
   }
   public void setId(int id) {
       this.id = id;
   }
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
  Â
   public void son1Method(String s){
       System.out.println(s) ;
   }
}
(3)
public class Son2 extends Base{
   private int id;
   private double salary;
  Â
   public int getId() {
       return id;
   }
   public void setId(int id) {
       this.id = id;
   }
   public double getSalary() {
       return salary;
   }
   public void setSalary(double salary) {
       this.salary = salary;
   }
}
(4)Util.java æ¼”ç¤ºäº†å¦‚ä½•æ ¹æ?®æŒ‡å®šçš„ç±»å??ï¼Œç±»å—æ®µå??和所对应的数æ?®ï¼Œå¾—到一个类的实例
import java.lang.reflect.Method;
public class Util {
   //æ¤æ–¹æ³•的最大好处是没有类å??Son1,Son2 å?¯ä»¥é€šè¿‡å?‚æ•°æ?¥æŒ‡å®šï¼Œç¨‹åº?里é?¢æ ¹æœ¬ä¸?用出现
   public static Base convertStr2ServiceBean(String beanName,String fieldSetter,String paraValue){
       Base base = null ;
       try {
           Class cls = Class.forName(beanName) ;
           base = (Base)cls.newInstance() ;
           Class[] paraTypes = new Class[]{String.class };
           Method method = cls.getMethod(fieldSetter, paraTypes) ;
           String[] paraValues = new String[]{paraValue} ;
           method.invoke(base, paraValues) ;
       } catch (Throwable e) {
           System.err.println(e);
       }
       return base ;
   }
  Â
  Â
   public static void main(String[] args){
       Son1 son1 =(Son1) Util.convertStr2ServiceBean(“trying.reflect.Son1″,”setName”,”wang da sha”);
       System.out.println(“son1.getName() :”+son1.getName()) ;
   }
}
//调用结果:
//son1.getName() :wang da sha
谢谢�希望能给大家一点���
ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?
附:
//下�这篇文档��于Internet,作者�详
Reflection 是 Java 程åº?å¼€å?‘è¯è¨€çš„特å¾?之一,它å…?许è¿?行ä¸çš„ Java 程åº?对自身进行检查,或者说“自审â€?,并能直接æ“?作程åº?的内部属性。例如,使用它能获得 Java ç±»ä¸å?„æˆ?员的å??称并显示出æ?¥ã€‚
Java 的这一能力在实际应用ä¸ä¹Ÿè®¸ç”¨å¾—ä¸?是很多,但是在其它的程åº?设计è¯è¨€ä¸æ ¹æœ¬å°±ä¸?å˜åœ¨è¿™ä¸€ç‰¹æ€§ã€‚例如,Pascalã€?C 或者 C++ ä¸å°±æ²¡æœ‰åŠžæ³•åœ¨ç¨‹åº?ä¸èŽ·å¾—å‡½æ•°å®šä¹‰ç›¸å…³çš„ä¿¡æ?¯ã€‚
JavaBean 是 reflection 的实际应用之一,它能让一些工具�视化的�作软件组件。这些工具通过 reflection 动�的载入并�得 Java 组件(类) 的属性。
1. 一个简å?•的例å?
考虑下é?¢è¿™ä¸ªç®€å?•的例å?,让我们看看 reflection 是如何工作的。
import java.lang.reflect.*;
public class DumpMethods {
  public static void main(String args[]) {
      try {
          Class c = Class.forName(args[0]);
          Method m[] = c.getDeclaredMethods();
          for (int i = 0; i               System.out.println(m[i].toString());
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
按如下è¯å?¥æ‰§è¡Œï¼š
java DumpMethods java.util.Stack
它的结果输出为:
public java.lang.Object java.util.Stack.push(java.lang.Object)
public synchronized java.lang.Object java.util.Stack.pop()
public synchronized java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized int java.util.Stack.search(java.lang.Object)
è¿™æ ·å°±åˆ—å‡ºäº†java.util.Stack 类的å?„方法å??以å?Šå®ƒä»¬çš„é™?制符和返回类型。
这个程åº?使用 Class.forName 载入指定的类,然å?Žè°ƒç”¨ getDeclaredMethods æ?¥èŽ·å?–这个类ä¸å®šä¹‰äº†çš„æ–¹æ³•列表。java.lang.reflect.Methods 是用æ?¥æ??è¿°æŸ?个类ä¸å?•个方法的一个类。
2.开始使用 Reflection
用于 reflection 的类,如 Method,å?¯ä»¥åœ¨ java.lang.relfect åŒ…ä¸æ‰¾åˆ°ã€‚使用这些类的时候必须è¦?é?µå¾ªä¸‰ä¸ªæ¥éª¤ï¼šç¬¬ä¸€æ¥æ˜¯èŽ·å¾—ä½ æƒ³æ“?作的类的 java.lang.Class 对象。在è¿?行ä¸çš„ Java 程åº?ä¸ï¼Œç”¨ java.lang.Class ç±»æ?¥æ??述类和接å?£ç‰ã€‚
下�就是获得一个 Class 对象的方法之一:
Class c = Class.forName(“java.lang.String”);
è¿™æ?¡è¯å?¥å¾—到一个 String 类的类对象。还有å?¦ä¸€ç§?方法,如下é?¢çš„è¯å?¥ï¼š
Class c = int.class;
或者
Class c = Integer.TYPE;
它们å?¯èŽ·å¾—åŸºæœ¬ç±»åž‹çš„ç±»ä¿¡æ?¯ã€‚å…¶ä¸å?Žä¸€ç§?方法ä¸è®¿é—®çš„æ˜¯åŸºæœ¬ç±»åž‹çš„å°?装类 (如 Integer) ä¸é¢„先定义好的 TYPE å—æ®µã€‚
ç¬¬äºŒæ¥æ˜¯è°ƒç”¨è¯¸å¦‚ getDeclaredMethods 的方法,以å?–得该类ä¸å®šä¹‰çš„æ‰€æœ‰æ–¹æ³•的列表。
一旦å?–得这个信æ?¯ï¼Œå°±å?¯ä»¥è¿›è¡Œç¬¬ä¸‰æ¥äº†â€”—使用 reflection API æ?¥æ“?作这些信æ?¯ï¼Œå¦‚下é?¢è¿™æ®µä»£ç ?:
Class c = Class.forName(“java.lang.String”);
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());
它将以文本方å¼?打å?°å‡º String ä¸å®šä¹‰çš„第一个方法的原型。
在下é?¢çš„例å?ä¸ï¼Œè¿™ä¸‰ä¸ªæ¥éª¤å°†ä¸ºä½¿ç”¨ reflection 处ç?†ç‰¹æ®Šåº”用程åº?æ??供例è¯?。
模拟 instanceof �作符
得到类信æ?¯ä¹‹å?Žï¼Œé€šå¸¸ä¸‹ä¸€ä¸ªæ¥éª¤å°±æ˜¯è§£å†³å…³äºŽ Class 对象的一些基本的问题。例如,Class.isInstance 方法å?¯ä»¥ç”¨äºŽæ¨¡æ‹Ÿ instanceof æ“?作符:
class A {
}
public class instance1 {
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“A”);
          boolean b1 = cls.isInstance(new Integer(37));
          System.out.println(b1);
          boolean b2 = cls.isInstance(new A());
          System.out.println(b2);
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
在这个例å?ä¸åˆ›å»ºäº†ä¸€ä¸ª A 类的 Class 对象,然å?Žæ£€æŸ¥ä¸€äº›å¯¹è±¡æ˜¯å?¦æ˜¯ A 的实例。Integer(37) ä¸?是,但 new A() 是。
3.找出类的方法
找出一个类ä¸å®šä¹‰äº†äº›ä»€ä¹ˆæ–¹æ³•,这是一个é?žå¸¸æœ‰ä»·å€¼ä¹Ÿé?žå¸¸åŸºç¡€çš„ reflection 用法。下é?¢çš„代ç ?就实现了这一用法:
import java.lang.reflect.*;
public class method1 {
  private int f1(Object p, int x) throws NullPointerException {
      if (p == null)
          throw new NullPointerException();
      return x;
  }
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“method1″);
          Method methlist[] = cls.getDeclaredMethods();
          for (int i = 0; i               Method m = methlist[i];
              System.out.println(“name = ” + m.getName());
              System.out.println(“decl class = ” + m.getDeclaringClass());
              Class pvec[] = m.getParameterTypes();
              for (int j = 0; j                   System.out.println(“param #” + j + ” ” + pvec[j]);
              Class evec[] = m.getExceptionTypes();
              for (int j = 0; j                   System.out.println(“exc #” + j + ” ” + evec[j]);
              System.out.println(“return type = ” + m.getReturnType());
              System.out.println(“—–”);
          }
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
这个程åº?首先å?–å¾— method1 类的æ??述,然å?Žè°ƒç”¨ getDeclaredMethods æ?¥èŽ·å?–一系列的 Method 对象,它们分别æ??述了定义在类ä¸çš„æ¯?一个方法,包括 public 方法ã€?protected 方法ã€?package 方法和 private 方法ç‰ã€‚å¦‚æžœä½ åœ¨ç¨‹åº?ä¸ä½¿ç”¨ getMethods æ?¥ä»£æ›¿ getDeclaredMethodsï¼Œä½ è¿˜èƒ½èŽ·å¾—ç»§æ‰¿æ?¥çš„å?„个方法的信æ?¯ã€‚
å?–得了 Method 对象列表之å?Žï¼Œè¦?显示这些方法的å?‚数类型ã€?异常类型和返回值类型ç‰å°±ä¸?难了。这些类型是基本类型还是类类型,都å?¯ä»¥ç”±æ??述类的对象按顺åº?给出。
输出的结果如下:
name = f1
decl class = class method1
param #0 class java.lang.Object
param #1 int
exc #0 class java.lang.NullPointerException
return type = int
—–
name = main
decl class = class method1
param #0 class [Ljava.lang.String;
return type = void
-----
4.获å?–æž„é€ å™¨ä¿¡æ?¯
获å?–ç±»æž„é€ å™¨çš„ç”¨æ³•ä¸Žä¸Šè¿°èŽ·å?–方法的用法类似,如:
import java.lang.reflect.*;
public class constructor1 {
  public constructor1() {
  }
  protected constructor1(int i, double d) {
  }
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“constructor1″);
          Constructor ctorlist[] = cls.getDeclaredConstructors();
          for (int i = 0; i               Constructor ct = ctorlist[i];
              System.out.println(“name = ” + ct.getName());
              System.out.println(“decl class = ” + ct.getDeclaringClass());
              Class pvec[] = ct.getParameterTypes();
              for (int j = 0; j                   System.out.println(“param #” + j + ” ” + pvec[j]);
              Class evec[] = ct.getExceptionTypes();
              for (int j = 0; j                   System.out.println(“exc #” + j + ” ” + evec[j]);
              System.out.println(“—–”);
          }
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
这个例å?䏿²¡èƒ½èŽ·å¾—è¿”å›žç±»åž‹çš„ç›¸å…³ä¿¡æ?¯ï¼Œé‚£æ˜¯å› ä¸ºæž„é€ å™¨æ²¡æœ‰è¿”å›žç±»åž‹ã€‚
这个程��行的结果是:
name = constructor1
decl class = class constructor1
—–
name = constructor1
decl class = class constructor1
param #0 int
param #1 double
—–
5.获å?–ç±»çš„å—æ®µ(域)
找出一个类ä¸å®šä¹‰äº†å“ªäº›æ•°æ?®å—段也是å?¯èƒ½çš„,下é?¢çš„代ç ?就在干这个事情:
import java.lang.reflect.*;
public class field1 {
  private double d;
  public static final int i = 37;
  String s = “testing”;
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“field1″);
          Field fieldlist[] = cls.getDeclaredFields();
          for (int i = 0; i               Field fld = fieldlist[i];
              System.out.println(“name = ” + fld.getName());
              System.out.println(“decl class = ” + fld.getDeclaringClass());
              System.out.println(“type = ” + fld.getType());
              int mod = fld.getModifiers();
              System.out.println(“modifiers = ” + Modifier.toString(mod));
              System.out.println(“—–”);
          }
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
这个例å?å’Œå‰?é?¢é‚£ä¸ªä¾‹å?é?žå¸¸ç›¸ä¼¼ã€‚例ä¸ä½¿ç”¨äº†ä¸€ä¸ªæ–°ä¸œè¥¿ Modifier,它也是一个 reflection 类,用æ?¥æ??è¿°å—æ®µæˆ?员的修饰è¯ï¼Œå¦‚“private intâ€?。这些修饰è¯è‡ªèº«ç”±æ•´æ•°æ??述,而且使用 Modifier.toString æ?¥è¿”回以“官方â€?顺åº?排列的å—符串æ??è¿° (如“staticâ€?在“finalâ€?之å‰?)。这个程åº?的输出是:
name = d
decl class = class field1
type = double
modifiers = private
—–
name = i
decl class = class field1
type = int
modifiers = public static final
—–
name = s
decl class = class field1
type = class java.lang.String
modifiers =
—–
和获å?–方法的情况一下,获å?–å—æ®µçš„æ—¶å€™ä¹Ÿå?¯ä»¥å?ªå?–得在当å‰?ç±»ä¸ç”³æ˜Žäº†çš„å—æ®µä¿¡æ?¯ (getDeclaredFields),或者也å?¯ä»¥å?–得父类ä¸å®šä¹‰çš„å—æ®µ (getFields) 。
6.æ ¹æ?®æ–¹æ³•çš„å??ç§°æ?¥æ‰§è¡Œæ–¹æ³•
文本到这里,所举的例å?æ— ä¸€ä¾‹å¤–éƒ½ä¸Žå¦‚ä½•èŽ·å?–类的信æ?¯æœ‰å…³ã€‚我们也å?¯ä»¥ç”¨ reflection æ?¥å?šä¸€äº›å…¶å®ƒçš„事情,比如执行一个指定了å??称的方法。下é?¢çš„示例演示了这一æ“?作:
import java.lang.reflect.*;
public class method2 {
  public int add(int a, int b) {
      return a + b;
  }
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“method2″);
          Class partypes[] = new Class[2];
          partypes[0] = Integer.TYPE;
          partypes[1] = Integer.TYPE;
          Method meth = cls.getMethod(“add”, partypes);
          method2 methobj = new method2();
          Object arglist[] = new Object[2];
          arglist[0] = new Integer(37);
          arglist[1] = new Integer(47);
          Object retobj = meth.invoke(methobj, arglist);
          Integer retval = (Integer) retobj;
          System.out.println(retval.intvalue());
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
å?‡å¦‚一个程åº?在执行的æŸ?处的时候æ‰?知é?“需è¦?执行æŸ?个方法,这个方法的å??称是在程åº?çš„è¿?è¡Œè¿‡ç¨‹ä¸æŒ‡å®šçš„ (例如,JavaBean å¼€å?‘环境ä¸å°±ä¼šå?šè¿™æ ·çš„事),那么上é?¢çš„程åº?演示了如何å?šåˆ°ã€‚
上例ä¸ï¼ŒgetMethod 用于查找一个具有两个整型å?‚数且å??为 add 的方法。找到该方法并创建了相应的 Method 对象之å?Žï¼Œåœ¨æ£ç¡®çš„å¯¹è±¡å®žä¾‹ä¸æ‰§è¡Œå®ƒã€‚执行该方法的时候,需è¦?æ??供一个å?‚æ•°åˆ—è¡¨ï¼Œè¿™åœ¨ä¸Šä¾‹ä¸æ˜¯åˆ†åˆ«åŒ…装了整数 37 å’Œ 47 的两个 Integer 对象。执行方法的返回的å?Œæ ·æ˜¯ä¸€ä¸ª Integer 对象,它å°?装了返回值 84。
7.创建新的对象
å¯¹äºŽæž„é€ å™¨ï¼Œåˆ™ä¸?能åƒ?æ‰§è¡Œæ–¹æ³•é‚£æ ·è¿›è¡Œï¼Œå› ä¸ºæ‰§è¡Œä¸€ä¸ªæž„é€ å™¨å°±æ„?味ç?€åˆ›å»ºäº†ä¸€ä¸ªæ–°çš„对象 (准确的说,创建一个对象的过程包括分é…?内å˜å’Œæž„é€ å¯¹è±¡)。所以,与上例最相似的例å?如下:
import java.lang.reflect.*;
public class constructor2 {
  public constructor2() {
  }
  public constructor2(int a, int b) {
      System.out.println(“a = ” + a + ” b = ” + b);
  }
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“constructor2″);
          Class partypes[] = new Class[2];
          partypes[0] = Integer.TYPE;
          partypes[1] = Integer.TYPE;
          Constructor ct = cls.getConstructor(partypes);
          Object arglist[] = new Object[2];
          arglist[0] = new Integer(37);
          arglist[1] = new Integer(47);
          Object retobj = ct.newInstance(arglist);
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
æ ¹æ?®æŒ‡å®šçš„å?‚æ•°ç±»åž‹æ‰¾åˆ°ç›¸åº”çš„æž„é€ å‡½æ•°å¹¶æ‰§è¡Œå®ƒï¼Œä»¥åˆ›å»ºä¸€ä¸ªæ–°çš„å¯¹è±¡å®žä¾‹ã€‚ä½¿ç”¨è¿™ç§?方法å?¯ä»¥åœ¨ç¨‹åº?è¿?行时动æ€?地创建对象,而ä¸?是在编译的时候创建对象,这一点é?žå¸¸æœ‰ä»·å€¼ã€‚
8.改å?˜å—段(域)的值
reflection 的还有一个用处就是改å?˜å¯¹è±¡æ•°æ?®å—段的值。reflection å?¯ä»¥ä»Žæ£åœ¨è¿?行的程åº?䏿 ¹æ?®å??ç§°æ‰¾åˆ°å¯¹è±¡çš„å—æ®µå¹¶æ”¹å?˜å®ƒï¼Œä¸‹é?¢çš„例å?å?¯ä»¥è¯´æ˜Žè¿™ä¸€ç‚¹ï¼š
import java.lang.reflect.*;
public class field2 {
  public double d;
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“field2″);
          Field fld = cls.getField(“d”);
          field2 f2obj = new field2();
          System.out.println(“d = ” + f2obj.d);
          fld.setDouble(f2obj, 12.34);
          System.out.println(“d = ” + f2obj.d);
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
这个例å?ä¸ï¼Œå—段 d 的值被å?˜ä¸ºäº† 12.34。
9.使用数组
本文介ç»?çš„ reflection 的最å?Žä¸€ç§?用法是创建的æ“?作数组。数组在 Java è¯è¨€ä¸æ˜¯ä¸€ç§?特殊的类类型,一个数组的引用å?¯ä»¥èµ‹ç»™ Object 引用。观察下é?¢çš„例å?看看数组是怎么工作的:
import java.lang.reflect.*;
public class array1 {
  public static void main(String args[]) {
      try {
          Class cls = Class.forName(“java.lang.String”);
          Object arr = Array.newInstance(cls, 10);
          Array.set(arr, 5, “this is a test”);
          String s = (String) Array.get(arr, 5);
          System.out.println(s);
      } catch (Throwable e) {
          System.err.println(e);
      }
  }
}
例ä¸åˆ›å»ºäº† 10 个å?•ä½?长度的 String 数组,为第 5 个ä½?置的å—符串赋了值,最å?Žå°†è¿™ä¸ªå—符串从数组ä¸å?–得并打å?°äº†å‡ºæ?¥ã€‚
下é?¢è¿™æ®µä»£ç ?æ??供了一个更å¤?æ?‚的例å?:
import java.lang.reflect.*;
public class array2 {
  public static void main(String args[]) {
      int dims[] = new int[]{5, 10, 15};
      Object arr = Array.newInstance(Integer.TYPE, dims);
      Object arrobj = Array.get(arr, 3);
      Class cls = arrobj.getClass().getComponentType();
      System.out.println(cls);
      arrobj = Array.get(arrobj, 5);
      Array.setInt(arrobj, 10, 37);
      int arrcast[][][] = (int[][][]) arr;
      System.out.println(arrcast[3][5][10]);
  }
}
例ä¸åˆ›å»ºäº†ä¸€ä¸ª 5 x 10 x 15 的整型数组,并为处于 [3][5][10] çš„å…ƒç´ èµ‹äº†å€¼ä¸º 37。注æ„?,多维数组实际上就是数组的数组,例如,第一个 Array.get 之å?Žï¼Œarrobj 是一个 10 x 15 的数组。进而å?–å¾—å…¶ä¸çš„ä¸€ä¸ªå…ƒç´ ï¼Œå?³é•¿åº¦ä¸º 15 的数组,并使用 Array.setInt 为它的第 10 ä¸ªå…ƒç´ èµ‹å€¼ã€‚
注�创建数组时的类型是动�的,在编译时并�知�其类型。
technorati tags: java
LOG4J的�置说明
LOG4Jçš„é…?置之简å?•使它é??å?ŠäºŽè¶Šæ?¥è¶Šå¤šçš„应用ä¸äº†ï¼šLog4Jé…?置文件实现了输出到控制å?°ã€?文件ã€?回滚文件ã€?å?‘é€?日志邮件ã€?输出到数æ?®åº“日志表ã€?è‡ªå®šä¹‰æ ‡ç¾ç‰å…¨å¥—功能。择其一二使用就够用了,
log4j.rootLogger=DEBUG,CONSOLE,A1,im
log4j.addivity.org.apache=true
# 应用于控制�
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#应用于文件
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
# Use this layout for LogFactor 5 analysis
# 应用于文件回滚
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# ��日志给邮件
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
# 用于数�库
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES (‘[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n’)
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH’.log4j’
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
technorati tags: log4j
在诺基亚ä¸ç”¨NOKIA UI将图片å?˜æˆ?å?Šé€?明的程åº?
/**
   * ��明渲染(�针对矩形区域)
   * @param g Graphics 图形对象
   * @param X int 渲染的矩形区域的å±?幕å??æ ‡X
   * @param Y int 渲染的矩形区域的å±?幕å??æ ‡Y
   * @param Width int 渲染的矩形区域的宽度
   * @param Height int 渲染的矩形区域的高度
   * @param Color int 渲染的颜色(�有�12�bit�有效)
   * @param transparence int 渲染程度,值越大,那么渲染色比例越大,背景色越�
   */
  protected void Game_Render_SemiTransparent(Graphics g, int X, int Y,
                                             int Width,
                                             int Height, int Color,
                                             int transparence) {
    int i;
    short pixels[] = new short[Width];
    for (i = 0; i       pixels[i] = (short) ( (transparence     }
    for (i = 0; i       DirectUtils.getDirectGraphics(g).drawPixels(pixels, true, 0,
          Width, X, i + Y, Width, 1, 0,
          DirectGraphics.
          TYPE_USHORT_4444_ARGB);
    }
    pixels = null;
  }
Â
MIDlet的生命周期的深入ç?†è§£å?Šæ¸¸æˆ?æ»æœºé—®é¢˜
å¦ä¹ j2me,首先è¦?了解MIDlet的生命周期。本文主è¦?是深入了解一下MIDlet的生命周期。以上自己的个人心得,ä¸?对之处,希望大家多多指点。 é¦–å…ˆåœ¨ä½ è¿?行一个程åº?的时候,JAM会调用该midletçš„æž„é€ å‡½æ•°æ?¥ç”Ÿæˆ?midlet的对象,然å?Žè¢«jam置于Paused状æ€?。一旦jam认为这个midlet对象å?¯ä»¥æ‰§è¡Œæ—¶ï¼Œjam就会调用startApp()方法,并将æ¤midlet置于Active状æ€?。startApp()方法由于在系统æ?¥ç”µã€?或者退回到系统è?œå?•返回时会被å†?次调用,所以这里å?ªå?¯ä»¥æ”¾åˆ?始化一次的代ç ?ã€‚æˆ–è€…ä½ æŠŠåˆ?始化一次的代ç ?放到midletçš„æž„é€ å‡½æ•°ä¸ã€‚例如:
public class Midlet extends MIDlet{
Display display = null;
MyCanvas can;
public Midelt(){
display = Display.getDisplay(this);
can = new MyCanvas();
}
public void startApp(){
display.setCurrent(can);//如果把can = new MyCanvas()放到这里,��电返回时就会出问题。
}
}
或者
public class Midlet extends MIDlet{
Display display = null;
MyCanvas can;
public Midelt(){
}
public void startApp(){
if(display ==null){
display = Display.getDisplay(this);
can = new MyCanvas();
}//æ¤å¤„å?ªä¼šè¢«è¿?行1æ¬¡ï¼Œè¿™æ ·å°±ä¸?会出错
display.setCurrent(can);//è¿™å?¥æŒ‰ç?†æ”¾åˆ°è¿™é‡Œæœ€å?ˆé€‚ï¼Œä½ æƒ³æ˜¾ç¤ºé‚£ä¸ªcanvas就放哪个ï¼?
}
}
在startApp()ä¸ï¼Œä½ 调用display.setCurrent(can)的时候,首先è¿?行的是showNotify(),接ç?€è¿?行paint()函数一次,如果有线程的è¯?ï¼Œæ¤æ—¶run()方法开始è¿?行。一般在run()æ–¹æ³•é‡Œä¸€èˆ¬è¿™ä¹ˆå†™ã€‚æ¤æ—¶çš„run()是å?¯ä»¥å¤„ç?†å¼‚æ¥äº‹ä»¶çš„ï¼Œä¹Ÿå°±æ˜¯ä½ æ?¥ç”µè¯?的时候,这里run()还是è¿?行的。ä¸?过他ä¸?会paint()什么东西,å?³ä½¿å®ƒé‡Œé?¢æœ‰repaint(),这点放心。
public void run(){
while(flag){//flag是boolean型��
try{
Thread.sleep(50);//时间自己设啦。
}catch(Exception e){}
repaint();
}
}
哇~~æ?¥ç”µè¯?äº†ï¼Œæˆ–è€…ä½ é€€åˆ°ç³»ç»Ÿè?œå?•。如nokia s60的手机。
hideNotify()首先会被调用,接�pauseApp()�被调用。
这么快,打完了,返回时:先调用showNotify(),接�调用paint()函数一次,最��是调用startApp()函数。
关于run()å’Œpaint()也å?¯ä»¥ä½¿ç”¨display.callSerially(this)è¯å?¥ã€‚这个以å?Žæœ‰æ—¶é—´äº†å†?说。
明白了生命周期,å†?æ?¥çœ‹æ»æœºé—®é¢˜ã€‚æˆ‘è¯´çš„æ»æœºé—®é¢˜ï¼Œå¤šæ˜¯æ?¥ç”µè¯?è¿”å›žæ—¶æ»æœºã€‚其实å?ªè¦?找到了问题,一切就å?˜çš„很简å?•。
ä¸ºä»€ä¹ˆæ»æœºï¼Œå½’æ ¹ç»“åº•è¿˜æ˜¯ç¨‹åº?问题。好åƒ?是废è¯?。哈~~
Graphics mg;//定义的全局�数
paint(Graphics g){
mg = g;//有的程åº?è¿™æ ·å†™ï¼Œif(mg ==null){mg =g:}è¿™æ ·å¯¹äºŽn7610系列就会出错。
mg.drawString();
switch(case){
case GAME_MUNE:
drawA();
break;
case PLAY:
drawB();
break;
default:
break;
}
}
/*下�的画图函数一定�放到paint()函数里调用,��在别的地方调用,如run()里�,上�说过,程�暂�之�返回,会先paint()一次,如果在别的地方调用就会出现问题。*/
public void drawA(){
mg.drawString();
}
public void drawB(){
mg.drawString();
}
按照上é?¢çš„写法一般ä¸?ä¼šå‡ºçŽ°æ»æœºé—®é¢˜ã€‚å½“ç„¶ï¼Œä½ ä¹Ÿå?¯ä»¥ä¸?定义全局的mg,å?¯ä»¥æŠŠgå?•ç‹¬ä¼ åˆ°å?„个画图å?函数ä¸ã€‚如,
paint(Graphics g){
g.drawString();
switch(case){
case GAME_MUNE:
drawA(g);
break;
case PLAY:
drawB(g);
break;
default:
break;
}
}
public void drawA(Graphics mg){
mg.drawString();
}
public void drawB(Graphics mg){
mg.drawString();
}