日期:2014-05-20  浏览次数:20617 次

charva实现原理初探(不知道如何归类了,没有J2SE类别)
    在eclipse上,先按一般的swing程序开发,画出界面。在需要切换到终端的时候,修改import部分,修改成import charva.*****即可。
按照http://www.iteye.com/topic/77387《在win32下编译charva,运行demo的一个小实验》一文,编译,发布即可看到效果。
对比发现,charva 实现了swing/awt除图形控件外的所有输出控件界面。因此在开发过程中,只要不用到图形控件,切换成charva应该是没有任何问题。

以jbutton为例,我们来看看,是如何画出图形来的:
jpanel southpanel = new jpanel();
jbutton cancelbutton = new jbutton();
cancelbutton.settext("cancel");
southpanel.add(cancelbutton, null);
在用swing组件的时候,会从jfram开始,一层层调用子节的paint方法。
在用charva组件的时候,同样会从jfram开始,一层层调用子节的draw方法。
针对charva的jbutton组件我们可以看到:
    public void draw() {        super.draw();        。。。。。。        toolkit term = toolkit.getdefaulttoolkit();        term.setcursor(origin);        。。。。。。        term.addstring(">", 0, colorpair);    }

首先调用 super.draw();画出边框,然后计算坐标,画出字符串。
   toolkit term = toolkit.getdefaulttoolkit();   term.addstring(" ", toolkit.a_reverse, colorpair);

可以看到,真正在画界面的时候,都是调用toolkit类画出数据到界面。
打开toolkit.java
public native void addstring(string str_, int attrib_, int colorpair_);

我们可以看到,该方法是native的。
在tookit.c文件中,我们看到了java_charva_awt_toolkit_addstring方法,该方法就是toolkit.java的addstring的实现。
好了,到此,不考虑底层的绘制过程,我们就知道了charva是如何工作了。

在dos下,发现绘制的右边框不对齐,而且宽度太大,查看jcomponent类的draw方法:
        if (_border != null) {            _border.paintborder(this, 0,                    origin.x, origin.y,                    this.getwidth(), this.getheight());        }

可以看到,宽度计算的时候,是调用this.getwidth()取得的。继续找,在jbutton中,看到了getwidth的实现。
    public int getwidth() {        insets insets = super.getinsets();        return super.getlabelstring().length() + 2 + insets.left + insets.right;    }

哈哈,发现问题关键所在了,长度计算的时候,他是根据数据字符串的长度,加上insets的对象的左右距离计算出总长度。
恩,看到问题解决的曙光了。考虑到,并排的几个对象,虽然字符长度不一样,不过,我们希望画出来的宽度是一样的,那么问题解决只能去找insets对象了。insets又是根据border对象计算来的,那么,我们的重点就是解决border了。如何修改border,目前还没研究border是如何工作的。下次再来研究,不过总算找到入口了。<img src="/images/smiles/icon_biggrin.gif"/>