随笔-5  评论-1  文章-0  trackbacks-0
  2010年4月21日

因为我们的项目可以通过编写脚本(javascript)进行功能扩展,所以为了方便现场实施人员,所以突发奇想想在网页上(系统是B/S的)提供一个javascript的编辑器。

为什么不用textarea呢?

1 没有高亮

2 tab键无法使用。——按tab键会切换到下个控件

3 没有代码格式化。——因为习惯了Eclipse的环境,可以使用ctrl+shift+F来代码进行格式化。

 

当然,我还没强大到自己实现的程度,而且用脚趾头都能想到肯定有人实现了,就看找不找得着。

经过了艰难的搜索,终于在SourceForge上找到一个叫EditArea的项目,感觉挺好。http://sourceforge.net/projects/editarea/

它的sample也很清楚

在网页上用以下方法构造

 

代码
<script language="Javascript" type="text/javascript" src="../edit_area/edit_area_full.js"></script>
<script language="Javascript" type="text/javascript">
// initialisation
editAreaLoader.init({
    id: 
"example_1"    // id of the textarea to transform        
    ,start_highlight: true    // if start with highlight
    ,allow_resize: "both"
    ,allow_toggle: 
true
    ,word_wrap: 
true
    ,language: 
"zh" //国际化
    ,syntax: "js"    //代码的样式,支持js ,php,sql,
     //以下是格式化的支持
    ,begin_toolbar: "btn_beautifier,|"  //插入工具栏
    ,plugins: "beautifier"              //使用控件
});
</script>

 

 

便可以在页面中出现代码的编辑框

 

能够解决第一个和第二个问题,但是还能解决。

因此我又找啊找,找到这个网站:http://jsbeautifier.org/。这个网站做了一个js的格式化工具,甚至可以格式化经过某个混淆器混淆的js代码。

于是我根据上面项目中的插件规范,将这两个东东整合了起来。看上面图中的按钮,按下以后,就变成了

看,高亮和格式化都有了。

 

需要下载的可以从这里下载(已经包含代码格式化的插件了):/Files/anic/editarea_0_8_2.zip

样例见\exemples\example.html

格式化的插件实现在\edit_area\plugins\beautifier\beautifier.js

 

posted @ 2010-04-21 21:07 Anic 阅读(243) 评论(1) 编辑
  2010年4月10日

2010 的笔试,没有去年的43页,也就21页,除去了不同语言(java、c/c++、C#)的题,真正要做的也就16页左右,时间是够的。

 

基本上当了炮灰,所以在这里列出来,和大家分享一下。其实有很多都不是很难得问题,但是多了起来就很难发挥好。

 

session 1(必做)

有点变态,因为无论你什么语言,都必须答——我常用java,很久没有其他的,都忘了那些语言的特性了。

 

1 一只蜗牛,在一根10feet的杆上,每天向上3feet,晚上休息,下降1feet,问第几天什么时候到杆顶?(应该是考虑最后一天的情况)

2 考了java,对于类的static synchronized ,问:能不能编译通过,能不能锁住对象?

3 考了c#,问一下代码输出的是什么?主要有个printer2,搞了个new virtual在搞搞阵。

 1 IPrint{
 2   void print(); 
 3 
 4  
 5 class Printer1:IPrint {
 6    public void print(){ Console.WriteLine("Printer1.")} }
 7  
 8 class Printer2:Printer1
 9 {
10   public new virtual void print() { Console.WriteLine("Printer2.")} }
11 
12  
13  class Printer3:Printer2
14 {
15   public override void print() { Console.WriteLine("Printer3.")} }
16 
17  
18  class Printer4:Printer3
19 {
20   public override void print() { Console.WriteLine("Printer4.")} }
21 }  
22 
23 IPrinter ip = new Printer4();
24 ip.print(); 

 

4 考了java的一个分析wait/sleep/notifyAll 的题目,问有无死锁。

5 考了一个C++版的继承与派生的问题

 1 class Base
 2 {
 3 int val;
 4 public Base():val(5);
 5 public virtual void print(){printf("%d",val);}
 6 }
 7 
 8 class Child
 9 {
10 int _j;
11 public Child():_j(8);
12 public void print(){printf("%d",_j);}
13 }
14 
15 

 

问以下情况什么时候会输出88888

代码

 Child[
5] c;
 Base
* p = (Base*)c;
  
for(int i=0;i<5;++i)
 {
 p
->print();
 
++p;
 }
 
B...
 
 C
 Base[
5] c;
 Child
* p = (Child*)c;
 
for(int i=0;i<5;++i)
 {
 p
->print();
 
++p;
 }
 
 D
 Base[
5] c;
 Child
* p = //用dynamicCast
 for(int i=0;i<5;++i)
 {
 p
->print();
 
++p;
 }

 

 

6 考了C++一个编译的问题,问哪里有bug

代码
class A<T1,T2>
{
T1
* t1;
T2
* t2;
  
public A():t1(new T1()),t2(new T2()){} //choice A

  
public A(const A& a){  //choice B
    t1 = a.t1;
    t2 
= a.t2;
  }

  
operator =(const A& a) //choice C
  {
    t1 
= a.t1;
    t2 
= a.t2;
  }

  
~A() throw() //choice D
  {
    delete t1;
    delete t2;
  }
}

 

据说是C,因为有内存泄露。原来的指针指向的空间没有释放掉。

 

7 以下的java会怎么样?

代码
public class Foo {
    
int value;

    
public void Foo() {
        value 
= 100;
    }

    
public Foo(int i) {
        value 
= i;
    }

    
public void print() {
        System.out.println(value);
    }
    
    
public static void main(String[] args)
    {
        Foo f1 
= new Foo();
        Foo f2 
= new Foo(200);
        f1.print();
        f2.print();
    }
}

 

a 输出100和200

b 编译不过,因为value没有初值

c 编译不过,因为没有默认构造函数(应该选这个,因为有个void Foo())

... 


 

section2(必做,只不过是大题,上面的是选择题)

1 问实现一个priority queue需要用多少个queue实现? (不知道说什么)

 

2 两个已排序的O(n)的序列A、B,求两个序列merge后的中位数?如果能在O(logn)内满分,在O(n)内有一些分。

 

3 有两个文件夹,里面有很多文件,写一个算法,找到在一个文件夹里而不在另一个文件夹中的文件。 

 

4 有一份文件,里面有2^32-1个数,取值范围是[0,2^32-1],系统内存只有几百k,请问如何找出[0,2^32-1]中不在文件中出现的数。

 

5 有一个密码锁,密码锁是转盘状,有40个数字(包括0)。按一次密码需要顺时针,先转到0,转密码的第一个数字,转到0,转密码第二个数字,如此类推。密码长度是3位。问最坏情况下转了多少个数字包括0。(排列组合的题目,描述也不很清楚)

 

6 写一个“非递归”的算法,找出pattern在长串中出现的位置,如输入长串是abcbc而pattern是abc时,要输出(0,1,2)、(0,3,4)、(0,1,4)

 

session2.1

根据自己的编程语言答题,java题目如下:

1 改写main,使得不抛出运行时异常

 1 import java.lang.reflect.Constructor;
 2 
 3 public class ConTest {
 4 
 5     public ConTest(String... ops) {
 6         System.out.println("Success");
 7     }
 8 
 9     public static void main(String[] args) {
10         Class<?> clazz;
11         try {
12             clazz = Class.forName("ConTest");
13             Constructor m = clazz.getConstructors()[0];
14             String a = "";
15             m.newInstance(a);
16 
17         } catch (Exception e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }
21 
22     }
23 }
24 

 事后试出答案是m.newInstance(new Object[] { new String[] { a } });

因为ConTest(String.. ops)等同于ConTest(String[] ops)

而newInstance(Object..objs)等同于newInstanec(Object[] objs) 然后就不知道怎么回事了

考试没得查真恼火,看看javadoc一分钟就能解决。

 

2 写一个类,里面用“数组”实现List接口,List接口只要求实现三个函数。(这个比较简单,主要要注意add的时候,数组需要增长的情况)

1 public interface List
2 {
3 public boolean add(Object o);
4 public int indexOf(Object o); //给出了javadoc,如果不存在返回-1
5 public boolean remove(Object o); //如果不存在,不变,返回false
6 }

 

 


 

posted @ 2010-04-10 21:09 Anic 阅读(543) 评论(0) 编辑
  2010年3月24日

想给项目做一个Nightly build,项目特点如下:

1 使用 Eclipse开发的java和GWT混合项目

2 目前有40多个工程

3 项目处于初期,很多部分尚未稳定,因此是工程是工程间依赖工程,没有引用编译好的jar包

4 工程主要分为前台clt,公共模块common,和服务器模块svr。例如有一个A.common,一定有A.clt和A.svr依赖于A.common,但clt和svr间不相互依赖。

(这是我们项目的编译过程的特殊逻辑)


以下是选定的技术路线 

 

  1. 因为编译带有特殊的逻辑,所以使用方便编程的java,而非纯ant脚本。
  2. 不想自己整理工程的编译顺序,太多,麻烦。所以使用了dom4j读取eclipse工程配置信息。
  3. 不用ant脚本,可以使用Java程序调用Ant API。
  4. 由于javac对模板的不友好 ,所以使用jdt

 

例如以下的代码

package demo.server;

import com.extjs.gxt.ui.client.data.BaseModel;

public class TestA extends BaseModel {

    @Override
    
public <X> X get(String property) {
        
return super.get(property);
    }
}

 

 

使用javac编译,就会出现

无法确定 <X>X 的类型参数;对于上限为 X,java.lang.Object 的类型变量 X,不存在唯一最大实例

 

虽然搜索了以下,说只要返回值强制转换一下就ok,即return (X)super.get(property);

但这样的代码也比较多,明明在eclipse编译通过的,在javac就不行。所以g了一下,才知道eclipse有自己的编译器(?不太确认javac和jdt的关系),叫jdt。


首先要从Eclipse中,抽取出一个JDT的包。在Eclipse/plugin目录下,找到一个org.eclipse.jdt.core_3.5.1.v_972_R35x.jar,(版本社么的没有关系)。用winrar解压出里面的一个jdtCompilerAdapter.jar包,然后从工程中引用它。

 

顺便把

org.eclipse.jdt.compiler.tool_1.0.100.v_972_R35x.jar

org.eclipse.jdt.core_3.5.2.v_981_R35x.jar

org.eclipse.jdt.debug.ui_3.4.1.v20090811_r351.jar

这几个包也从eclipse/plugin中引用到项目里。——为什么要单独解压jdtCompilerAdapter.jar,我不太清楚啊。

 

然后,由于要调用ant,所以从apache上的ant项目中下载http://ant.apache.org/bindownload.cgi,用到两个包,

ant.jar

ant-launcher.jar

 

使用以下代码,调用ant 

package thss.platform.util.mrobuild;

import java.io.File;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.Javac.ImplementationSpecificArgument;
import org.apache.tools.ant.types.Path;

public class JavaBuilder {

    
public JavaBuilder() {
    }

    
public void execute(Path classPath, File output) {
        Project currentProject 
= new Project();
        
// 填写工程的绝对目录,这样后面可以使用相对目录
        currentProject.setBaseDir(new File("这里是工程的绝对目录"));

        Javac compileJava 
= new Javac();
        compileJava.setProject(currentProject);
        
// 调用jdt编译器
        compileJava.setCompiler("org.eclipse.jdt.core.JDTCompilerAdapter");
        compileJava.setClasspath(classPath);
        compileJava.setEncoding(
"UTF-8");

        
// 填写相对目录src
        compileJava.setSrcdir(new Path(currentProject, "src"));
        
// 编译后的结果.class输出到哪里
        compileJava.setDestdir(output);
        compileJava.setTarget(
"1.6");
        compileJava.setSource(
"1.6");
        compileJava.setNowarn(
true);
        compileJava.setDebug(
true);
        compileJava.setDebugLevel(
"lines,source");

        
// javac需要这段,换成了jdt不知道要不要了
        ImplementationSpecificArgument arg = compileJava.createCompilerArg();
        arg.setLine(
" -Xlint");

        compileJava.execute();

    }
}

 

 

可能上述文章有很多概念性的问题,例如我没有搞清的javac和jdt关系,但是问题确实是解决了,欢迎高手批评指正。by Anic 

 

posted @ 2010-03-24 22:16 Anic 阅读(1378) 评论(0) 编辑
  2010年3月6日

今天看到有个Google Code的项目,叫ZeroClipboard:http://code.google.com/p/zeroclipboard/

大意是使用flash作为媒介,将内容复制到剪贴板。这比用纯javascript好,因为不同浏览器会出于安全的原因,有不同反应,例如IE会给出提示,有的浏览器不支持复制到剪贴板。

但是用flash就可以复制。例子就是VeryCd,看“复制选中的连接”按钮是一个flash。看来flash的安全沙箱没有限制将内容复制到剪贴板 

 

 

但是也是有限制的: 

1 根据ZeroClipborad的人们说,这些flash必须通过网络加载。

 Zero Clipboard Does Not Work From Local Disk


This is a security restriction by Adobe Flash Player. Unfortunately, since we are utilizing the JavaScript-to-Flash interface ("ExternalInterface") this only works while truly online (if the page URL starts with "http://" or "https://"). It won't work running from a local file on disk.

However, there is a way for you to edit your local Flash Player security settings and allow this. Go to this website:

http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04a.html

And add the path to your local "ZeroClipboard.swf" file to the trusted files list, or try the "allow all" option.


 

2 flash虽然提供复制功能,但是前提是要通过用户的一次点击。意思就是不能在javascript中通过函数的方式setText就复制到剪贴板,而是调用了这个setText函数后,用户的鼠标在flash上有了一次点击,才可以。

This library is fully compatible with Flash Player 10, which requires that the clipboard copy operation be initiated by a user click event inside the Flash movie.  

这里和使用flash上传文件的swfupload有同样的问题。 


使用ZeroClipboard,可以将网页内容复制到剪贴板。但是ZeroClipboard没有GWT封装,我们项目是用GWT的,所以就学着swfupload的GWT封装,把ZeroClipboard也封装成GWT可以调用的形式。

1 先封装了一个zeroclipboard.jar 

2 项目中使用的是GXT控件库,为了和控件紧密结合,写了一个ZClipboardBinder类,将两者结合起来

3 使用方法见下(Zeroclipboard_test.java)

 1 package zero.clipboard.test.client;
 2 
 3 import java.util.Date;
 4 
 5 import zero.clipboard.test.client.ZClipboardBinder.ClipboardListener;
 6 
 7 import com.extjs.gxt.ui.client.widget.LayoutContainer;
 8 import com.extjs.gxt.ui.client.widget.button.Button;
 9 import com.google.gwt.core.client.EntryPoint;
10 import com.google.gwt.user.client.ui.RootPanel;
11 
12 /**
13  * Entry point classes define <code>onModuleLoad()</code>.
14  */
15 public class Zeroclipboard_test implements EntryPoint {
16 
17     public void onModuleLoad() {
18         LayoutContainer c = new LayoutContainer();
19         c.setSize(400300);
20 
21         Button btn = new Button("Copy Hello World");
22         // 将控件和ZeroClipboard绑定
23         // ZClipboardBinder.bind(btn, "Hello World");
24         ZClipboardBinder.bind(btn, new ClipboardListener() {
25 
26             @Override
27             public String prepareCopy() {
28                 return (new Date()).toString();
29             }
30         });
31         c.add(btn);
32 
33         RootPanel.get().add(c);
34     }
35 }
36 

 

相关下载都在附件中了。 

  /Files/anic/attachment.zip

示意结果

 
点击按钮后——其实是点击了上面的flash,使用ctrl+v,就能看到结果。

 

 

现在发现有很多有意义的功能都不能用javascript实现,例如多文件上传和复制到剪贴板,都是通过flash做中介,“曲线”实现的 ,不知道最后HTML5有没有解决这些问题,不用我们兜兜转转。

posted @ 2010-03-06 14:31 Anic 阅读(313) 评论(0) 编辑
  2010年2月2日

使用GWT已经半年了,查了很多资料,但发现国内关注它的人很少,而且骂声也不少(当然GWT也有让我恶心的地方),所以就把平时实验的结果和感想,在这里和大家分享一下。



GWT困扰我的一个最恶心的缺点,就是凡事要编译。系统一大,模块之间依赖很强,修改一个客户端(界面)的小功能,就要重编译整个项目,费时费劲,我们项目现在重编一次已经需要800多秒了——好在有Development mode(感叹这个东东的强大)。


之前看到过GWT提供JSNI的功能,能够使gwt 的java code与纯JavaScript互通信,因此打算尝试使用JSNI作为中介,看看能不能减轻模块间的依赖——或者实现多模块之间实现分模块编译。



想法是这样的,大部分模块基本是不变的,希望不要经常编译,假设其为Dll1;有些为客户开发的模块Dll2,它依赖于Dll1,而且经常发生变化(需求总是变化的)。希望修改了Dll2后,不重新编译Dll1。

Dll1和Dll2只是一个命名,并不是真正的dll啊!




如果按照GWT的依赖实现,Dll2中的gwt.xml中,声明inherit name="demo1.Dll1"后,重编Dll2其实就包含重编Dll1


使用JSNI,见http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html


将Dll1的接口,使用$entry方法,发布成为标准的javascript;Dll2不直接依赖Dll1,使用JSNI,调用Dll1发布成为javascript的接口。


Dll1中,用GWT的java实现了3个方法

代码
package demo1.client;
import java.util.Date;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.js.JsonConverter;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.dom.client.Element;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
public class DllImpl {
    
public static void method1(String value) {
        Window.alert(value);
    }
    
public static String methodJson() {
        BaseModel result 
= new BaseModel();
        result.set(
"int"1);
        result.set(
"double"new Double(1.2));
        result.set(
"string""str");
        result.set(
"date"new Date());
        result.set(
"boolean"true);
        JSONObject obj 
= JsonConverter.encode(result.getProperties());
        String str 
= obj.toString();
        
return str;
    }
    
public static Element methodJS() {
        TabPanel p 
= new TabPanel();
        TabItem item 
= new TabItem();
        item.setClosable(
true);
        item.setText(
"dll 1");
        item.setLayout(
new FitLayout());
        p.add(item);
        RootPanel.get(
"cross").add(p);
        
return item.getElement();
    }
    
public static native void exportStaticMethod() /*-{
        $wnd.method1 =
        $entry(@demo1.client.DllImpl::method1(Ljava/lang/String;));
        $wnd.methodJson =
        $entry(@demo1.client.DllImpl::methodJson());
        $wnd.methodJS =
        $entry(@demo1.client.DllImpl::methodJS());
    }-
*/;
}

 

 

exportStaticMothod是将类中的3个方法,发布为javascript,其路径就是$wnd.method1、$wnd.methodJson和$wnd.methodJS,参数列表参考google文档中的JSNI。

在Dll1的EntryPoint中,调用这个exportStaticMethod方法。

Dll1的Entry代码
package demo1.client;
import com.google.gwt.core.client.EntryPoint;
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 
*/
public class Dll1 implements EntryPoint {
    
public void onModuleLoad() {
        DllImpl.exportStaticMethod();
    }
}

 

 在Dll2中,就使用JSNI调用javascript,路径就是之前的$wnd.method1、$wnd.methodJson和$wnd.methodJS

代码
package demo2.client;
import java.util.Date;
import java.util.Map;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.js.JsonConverter;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Timer;
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 
*/
public class Dll2 implements EntryPoint {
    
public void onModuleLoad() {
        Timer t = new Timer() {
            @Override
            
public void run() {
                
// 由于Dll1和Dll2没有声明依赖,所以使用Timer强制延时
                callMethod1("Hello world form dll2.");
                String json = callMethodJSON();
                Map<String, Object> map = JsonConverter.decode(json);
                BaseModel m = new BaseModel(map);
                System.out.println(m.get("int"instanceof Integer);
                System.out.println(m.get("double"instanceof Double);
                System.out.println(m.get("string"instanceof String);
                System.out.println(m.get("date"instanceof Date);
                System.out.println(m.get("boolean"instanceof Boolean);
                Element x = callMethodJS();
                FormPanel f2 = new FormPanel();
                f2.setHeading("dll 2");
                f2.render((com.google.gwt.user.client.Element) x);
            }
        };
        t.schedule(2000);
    }
    
protected native void callMethod1(String value)/*-{
        $wnd.method1(value);
    }-*/;
    
protected native String callMethodJSON()/*-{
        return $wnd.methodJson();
    }-*/;
    
protected native Element callMethodJS()/*-{
        var x = $wnd.methodJS();
        //alert(x);
        return x;
    }-*/;
}

 

 之所以要用timer,是因为Dll2没有直接依赖Dll1,所以HTML声明加载Dll1和Dll2时,不能确定Dll2就是在Dll1加载后才被加载。如果Dll2在Dll1前加载,则调用的$wnd.method1()就还没被Dll1所“导出”,调用就会失败。

 

HTML是这样加载2个模块的——"mce:"是CSDN的blog自动添加上去的,主要参考那两个script标记,分别使html加载dll1模块和dll2模块。

代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link type="text/css" rel="stylesheet" href="DoubleMain.css" mce_href="DoubleMain.css">
<title>Web Application Starter Project</title>
<mce:script type="text/javascript" language="javascript"
    src
="doublemain/doublemain.nocache.js"></mce:script>
<mce:script type="text/javascript" language="javascript"
    src
="doublemain2/doublemain2.nocache.js"></mce:script>
</head>
<body>
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" mce_src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
    
style="position: absolute; width: 0; height: 0; border: 0"></iframe>
</body>
</html>

 

至此,实现了一个简单的多模块间解耦合的调用,但是这里面的问题很多,不是一劳永逸,留待下篇博文来分解。 


posted @ 2010-02-02 19:28 Anic 阅读(945) 评论(0) 编辑
昵称:Anic
园龄:2年
粉丝:1
关注:1
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

搜索

 
 

常用链接

我的标签

随笔档案

最新评论