随笔:25 文章:1 评论:66 引用:0
BlogJava 首页 发新随笔
发新文章 联系 聚合管理

2006年6月2日

Sorry, I have already moved to JavaEye and Fanfou, please update if you have questions.
posted @ 2009-05-09 22:13 steeven 阅读(225) | 评论 (0)编辑 收藏
 
最近让新来的实习生写订餐机器人,羽毛球活动预定机器人,两个人写了几个星期,看得我心急火燎。现在的研究生啊。。。。

自己拿来skype4java看了一下,感觉很好用。里面提供了一个application机制,类似socket,又强于socket。为什么说强呢?因为是基于skype, 穿透防火墙啦。
windows自带的远程桌面很好用,在速度上,比以前基于位图传送的netmeeting/pcanywhere之类的都要强。
linux下面的远程桌面做的比较好的是nx系列。但是这些远程桌面的致命问题就是网关、防火墙问题。
就是说你要在家访问公司电脑,基本上要在防火墙上凿洞,或者借助于vpn,softether之类的东东。

skype的application利用skype自身的通讯机制,屏蔽了这些问题,当然,你的应用也必须依赖skype了。

java做远程桌面要能截屏、控制鼠标键盘,所幸有java.awt.Robot, 原来这个东西是为了做自动化测试,刚好。
剩下就是穿数据的问题。屏幕图片,如果是bmp,比较硕大,即使是上网等文本界面,压缩下来也要几十k, 如果网络带宽不够的话,比如公司有几个下载爱好者,会比较惨。所以呢,决定传差异,缓存前面的屏幕,看看如果差别不大,就只传变化的部分。这样数据量就比较小。但是呢,压缩图片的时候就不能采用有损压缩啦,否则屏幕会变得越来越怪异。。。

比较遗憾的是没能象windows自带的rdp那样拦截绘图操作,在点阵图的方案上效率还是比较低的。希望有高手指点!

skype4java是个日本人写的,几个听了我介绍的朋友都有这疑问:日本人写的?
呵呵,如果你能写出更好的,咱就不用它。那个日本作者还不错,上班比较忙,还是答应抽空fix几个bug,感谢中~

体验一下吧:skypeRDP
posted @ 2006-12-06 20:18 steeven 阅读(2597) | 评论 (6)编辑 收藏
 

适用版本GWT 1.0.21。
由于目前google web toolkit还没有正式release, 所以问题多多。记录一下碰到的问题:

1. Shell调试模式和实际编译结果有差异。
shell中报告的异常在运行中只是一些凌乱的脚本错误,或者干脆没有响应。
shell中通过的程序在实际运行时还会有错误。
2. 避免错误的方法是捕获异常,
在onModuleLoad方法中try catch
或者GWT.setUnCaughtExceptionHandler()//全局异常捕获
3. LOG, 利用GWT.log(). shell模式下会输出到控制台。
4. 远程调用属于异步。同步远程调用可以自己包装ClientCallback,在一个结束后调用另外一个.
5. RPC调用中Set传递有bug, 暂时用List
6. Eclipse直接运行Compiler/Shell, 加入gwt-dev-windows.jar。
main: com.google.gwt.dev.GWTCompiler/GWTShell
arguments: -out ${project_loc}\WebContent real/Index.html
classpath->UserEnties->advanced->add folder->选择项目的src目录,要在第一位。
7. Tomcat5问题多多, 用tomcat4.
8. gwt-user中非法包含javax.servlet, tomcat认为其无效。直接放到tomcat/common/lib中。或者在jar中去掉。
9. Exception.getStackTrace() 在Shell模式下有效, GWT.isScript()可以判断
10. 静态中文在html中乱码,要在html header中加入<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

posted @ 2006-07-14 18:10 steeven 阅读(2938) | 评论 (6)编辑 收藏
 
开发设计两个类:
鸡,构造的时候要带入蛋.
蛋,构造的时候要带入鸡.

编译没问题,初始化数据的时候问题出来了.
new 鸡(new 蛋(???)) //蛋是谁下的?
作为一个正统的进化论学生,解决如下:构造原始鸡类,鸡开始是不下蛋的,把鸡的构造函数改成空的,这时候初始化一条原始鸡的数据没问题.然后进化出来蛋,鸡下的,类不用改,把蛋的数据初始化好.这时候鸡进化,由蛋孵出来,构造方法要带蛋进来,初始化一只新鸡,删除原始鸡数据.

OK,问题解决了吗?这样程序每次初始化数据的时候要改造鸡类,好像不大容易啊....

那上帝造物学说怎样解决问题呢?:
鸡1 = new 鸡(null);
蛋1 = new 蛋(null);
鸡1.set蛋(蛋1);
蛋1.set鸡(鸡1);
save(鸡1,蛋1);
鸡和蛋同时出来了.上帝造物法胜利

是不是我的类设计有问题,怎么会碰到鸡生蛋蛋孵鸡这种郁闷的问题呢?
posted @ 2006-07-02 20:28 steeven 阅读(1447) | 评论 (2)编辑 收藏
 

db4o目前还没有unique index/primary key机制。(5.4)

     public   static   void  main(String[] args)  {
        ObjectContainer db 
=  Db4o.openFile( " test.yap " );
        db.set(
new  User( " abc " , 234 ));
        db.set(
new  User( " abc " , 234 ));
        ObjectSet
< User >  list  =  db.query(User. class );
        System.out.println(list);
        db.close(); 
// halt without this line in 5.2
    }

上面的例子会存储两个同样的User对象。
仅有的ID是一个存储文件中的ID, 经过碎片整理之后会发生变化,显然不适用。
要实现一个auto_increament的主键恐怕要自行实现。或者用已有的UUID实现。

可能db4o太年轻的关系,目前还没有支援这些功能。建议用@Annotation来实现。并且控制存储。
@ID
@Unique
@Index
在EJB3里面已经有现成的定义可以参考。
posted @ 2006-06-19 18:15 steeven 阅读(907) | 评论 (0)编辑 收藏
 
原来说是xaml只是随着下一个版本的windows放出,后来改编到winfx里面,最近听说作为.net3.0出现.这样的直接后果就是这个b/s+c/s通吃的UI框架不但要寄生在新版windows里面,也要被用来在xp上攻城略地.

微软这回蓄势待发xaml有多强大呢?3d(感觉不够纯粹)/强大的数据绑定/动画/多媒体支持...
这里可怕的不仅仅是框架,还有配套的GUI开发工具.有趣的是Interactive Designer据说就是用wpf开发的.
xaml只是个xml描述文件,里面可以包含代码,编译成UI界面.所有的界面内容也可以由程序动态运行.
这样未来运行在browser里面的UI不是复杂的ajax,是和后台一致的托管代码.

Java怎样应对呢?Java+Flash? 开发bs都困难重重.除非Flash能放弃as,直接同java结合,或者两个公司合作开发一个新框架.这个新框架应该是什么样子呢?完全的3D视角,时间轴控制...重演c#后来居上的历史.

Java在Sun的手里一直半死不活,真希望能赶快被google并购,或者sun主动把java捐赠出来.

如果没有"意外",在wpf正式发行以后,桌面应用将逐步过渡到wpf开发.HTML由于其跨平台,可能会平分秋色.

面对wpf,如何反抗?java.net是太监,在.net阵营里面连二奶都不算,等于投降.
利用xaml? xaml被编译加载,其执行框架还是.net,机会似乎不大.在浏览器上可能会有类似lasszlo的组合.

作为Java爱好者,祈祷奇迹发生吧,还好在Java世界中奇迹是家常便饭 :)
posted @ 2006-06-18 22:57 steeven 阅读(2444) | 评论 (3)编辑 收藏
 

一般Apply按钮应该在用户有输入时有效,输入没有变化时无效。
为了达到这个效果,一般界面上每个输入控件要监听,并且和以前的值做比较,实现起来相当麻烦。

因为我们已有的界面是基于数据绑定,绑定到一个克隆的对象上。这样判断有没有变化就很简单,updateInput之后,比较两个对象是否一致即可。

什么时候去判断呢?在用户输入之后:捕捉键盘、鼠标事件。

拦截键盘鼠标事件目前找到两种方法:
1. Toolkit.getDefaultToolkit().addAWTEventListener(listener,eventMask);
这个方法注册全局的监听机制,无论哪个窗口。里面注册为weakHashmap,应该不用考虑垃圾回收问题。因为是全局的,不建议采用。
2. 拦截每个component自己的事件。
正常来说,如果在textbox里面打字,事件不会交给window处理。enableInputMethods(true)可以帮忙。
enable以后调用getInputContext(),取得InputContext处理。
注意,InputContext的dispatchEvent(AWTEvent)会接到各种消息,感兴趣的getID()有以下三个:
   MouseEvent.MOUSE_CLICKED
   MouseEvent.MOUSE_WHEEL
   KeyEvent.KEY_TYPED

posted @ 2006-06-13 16:52 steeven 阅读(1618) | 评论 (2)编辑 收藏
 
上海这方面活动比较少,难得逮到一个,跑去凑个热闹。天不作美,下班前一场大雨,让参加的人少了很多。

零星记了一些笔记,对我这个ajax门外汉来说收获还是很大。主讲是ajaxcn.org的两位高手。robbin的Rubby讲座因为时间关系要改期。

1. JS2的一些新特性:class/extend/interface/package/import/块作用域/操作符函数. 明年底会有browser开始支持。
//干脆把java直接搬到browser里面算了。
//以后是不是弄个标准接口允许加载不同语言的脚本引擎?大家就不用受js的鸟气了。
2. 推荐的ajax框架:Dojo/DWR/Prototype/GWT/YUI
//排名有先后
3. 新技术:
canvas 画图,已有多数浏览器支持。据说有人用它实现了3D游戏
SVG 基于xml的矢量图。据说和canvas都支持3d绘图。
E4X: xml的包装, firefox支持
4. 技术和需求水涨船高 //我们不会失业了
5. HiJax:
用传统方式快速开发。在传统网页基础上hack成ajax应用。
对禁用js的浏览器表现为传统网页。
前期开发和后期改造独立性很强。
//后期要改造为完美的ajax,对server端要做些小的改动来适应。
6. 推荐用FireFox调试AJAX, 插件三剑客:
firebug/web develope tool/temper data分别用来调试脚本,观察页面dom,监听通信。
//js调试的日子好过多了,但不要忘记总体效率。。。

回来路上和一位tx聊起来ajax在企业中的地位好像不高,他对敏捷开发很有好感,对办公室环境的要求很有趣。
本次活动的主要心得是:自助餐很好吃,以后有活动还要去吃 :)
posted @ 2006-06-07 23:44 steeven 阅读(1315) | 评论 (4)编辑 收藏
 
gwt的这些特性还是很有意思的,感觉比echo更贴近html, 比如说尺寸等数据,写"20%"和"200px"都可以。echo则尽量封装的象swing, 屏蔽掉html.

anyway, 对于大多数逻辑都在客户端的应用,gwt可以大展身手。比如小游戏~

guess number demo看这里:http://steeven.googlepages.com/MyApp.html
完全在浏览器上运行的玩意,没有写一句js,感觉还是很爽的~

代码如下:
package org.steeven.gwt.test.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * 
@author steeven@gmail.com
 
*/

public class MyApp implements EntryPoint {

    TextBox txtCount 
= new TextBox();

    
private Grid pnlMain;

    
private Button[] numbers = new Button[100];

    
private int target;

    
private int count;

    
private DialogBox box;

    
private Button btnRetry;

    
private Button btnClose;

    
/**
     * This is the entry point method.
     
*/

    
public void onModuleLoad() {
        VerticalPanel pnlStatus 
= new VerticalPanel();
        pnlStatus.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        pnlStatus.setSpacing(
20);

        txtCount.setEnabled(
false);
        txtCount.setVisibleLength(
10);
        pnlStatus.add(txtCount);
        btnRetry 
= new Button();
        btnRetry.setHTML(
"<img src=\"replay.gif\"/> <u>R</u>etry");
        btnRetry.setAccessKey(
'r');
        btnRetry.addClickListener(
new ClickListener() {
            
public void onClick(Widget sender) {
                doInit();
            }

        }
);
        pnlStatus.add(btnRetry);

        Button btnAbout 
= new Button();
        btnAbout.setHTML(
"<img src='about.gif'/> <u>A</u>bout");
        btnAbout.setAccessKey(
'a');
        btnAbout.addClickListener(
new ClickListener() {
            
public void onClick(Widget sender) {
                doAbout();
            }

        }
);
        pnlStatus.add(btnAbout);

        RootPanel.get(
"status").add(pnlStatus);

        pnlMain 
= new Grid(1010);
        RootPanel.get(
"main").add(pnlMain);

        
for (int i = 0; i < 100; i++{
            numbers[i] 
= new Button();
            numbers[i].setText(i 
+ "");
            numbers[i].addClickListener(
new ClickListener() {
                
public void onClick(Widget sender) {
                    doGuess(sender);
                }

            }
);
            pnlMain.setWidget(i 
/ 10, i % 10, numbers[i]);
        }


        box 
= new DialogBox();
        box.setPopupPosition(
400200);
        btnClose 
= new Button("<u>C</u>lose"new ClickListener() {
            
public void onClick(Widget sender) {
                box.hide();
                doInit();
            }

        }
);
        btnClose.setAccessKey(
'c');
        box.add(btnClose);
        doInit();
    }


    
protected void doGuess(Widget sender) {
        Button btn 
= (Button) sender;
        btnRetry.setEnabled(
true);
        
int n = Integer.parseInt(btn.getText());
        txtCount.setText(
"" + (++count));
        
if (n == target) {
            numbers[n].setEnabled(
false);
            btnClose.setFocus(
true);
            box.clear();
            box
                    .setHTML(
"<center><img src='win.gif'/><h1>YOU WIN!!!</h1><br/><br/><br/>");
            box.add(btnClose);
            box.show();
        }
 else {
            
if (n < target)
                
for (int i = 0; i <= n; i++)
                    numbers[i].setEnabled(
false);
            
else
                
for (int i = n; i < 100; i++)
                    numbers[i].setEnabled(
false);
        }


    }


    
protected void doAbout() {
        box.clear();
        box
                .setHTML(
"<img src='about.gif'/><h1>Guess Number</h1><h3>Google web toolkit test</h3>");
        box.add(btnClose);
        box.show();
    }


    
private void doInit() {
        btnRetry.setEnabled(
false);
        target 
= Random.nextInt(99);
        count 
= 0;
        txtCount.setText(
"0");
        
for (int i = 0; i < 100; i++{
            numbers[i].setVisible(
true);
            numbers[i].setEnabled(
true);
        }

    }


}


第一次玩gwt, 总共花了3个小时,菜呀
posted @ 2006-06-02 15:23 steeven 阅读(1836) | 评论 (13)编辑 收藏
CALENDER
<2006年6月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

常用链接

留言簿(10)

随笔分类

随笔档案

文章档案

相册

我的链接

搜索

  •  

最新评论


Powered By: 博客园
模板提供沪江博客