Feeling

    三人行,必有我师焉

   ::  :: 新随笔 :: 联系 ::  :: 管理 ::
  185 随笔 :: 0 文章 :: 392 评论 :: 0 Trackbacks

#

Control类:

toControl ( Point  point)
          Returns a point which is the result of converting the argument, which is specified in display relative coordinates, to coordinates relative to the receiver.

Point Display 的绝对值转化为 Control 的相对值。

toDisplay
( Point  point)
          Returns a point which is the result of converting the argument, which is specified in coordinates relative to the receiver, to display relative coordinates.
Point Control 的相对值转化为 Display 的绝对值。

Example: 
 Button button = new Button( s, SWT. BORDER );
 System. out .println( button.getLocation( ) ); //Point {0, 0}  
 System. out .println( button.toDisplay( button.getLocation( ) ) ); //Point {70, 89}  
 System. out .println( button.toControl( button.toDisplay( button.getLocation( ) ) ) ); //Point {0, 0}

Device类:
getDepth()
          Returns the bit depth of the screen, which is the number of bits it takes to represent the number of unique colors that the screen is currently capable of displaying.
拿到操作系统的颜色深度。
 

getDPI
()
          Returns a point whose x coordinate is the horizontal dots per inch of the display, and whose y coordinate is the vertical dots per inch of the display.
拿到操作系统的DPI值。

Example:
 System.out.println(Display.getDefault( ).getDepth( ));//32
 System.out.println(Display.getDefault( ).getDPI( ));//Point {96, 96}

 

posted @ 2006-06-20 17:54 三人行,必有我师焉 阅读(754) | 评论 (0)编辑 收藏

最近由于项目的需要,研究了一下SWT的Accessibility。关于Accessibility,这是一个很难缠的search,给残疾人用的东东,正常人基本上不会用到,网上文章少之又少。可以查阅到的一篇来自于IBM developerWorks的文章:使用 Eclipse 创建易访问的应用程序:介绍

易访问性是一个总括的术语,它包括生成使具有各种残疾的人易用的产品所涉及的所有东西和人。美国已经立法,不符合Accessibility规范的软件不能够在政府部门销售。在美国,创建易访问的应用程序的主要商业(对比人道主义)驱动力是 Rehabilitation Act 1998 年的修正法案,称为 Section 508。Section 508 要求联邦机构使他们的信息技术对带有残疾的人易于访问。


Eclipse 拥有一个包含 API:org.eclipse.swt.accessibility 的易访问性包。Eclipse 3.0 易访问性特征是基于 MSAA 1.3 程序设计模型所提供的功能。您可以将 Eclipse 中的 Accessible 对象联系到每个控件上,并且 org.eclipse.swt.accessibility 接口中的方法集对应 MSAA 1.3 IAccessible 界面中的消息集。

 org.eclipse.swt.accessibility 的接口    

Interface Summary
AccessibleControlListener Classes that implement this interface provide methods that deal with the events that are generated when an accessibility client sends a message to a control.
AccessibleListener Classes that implement this interface provide methods that deal with the events that are generated when an accessibility client sends a message to a control.
AccessibleTextListener Classes that implement this interface provide methods that deal with the events that are generated when an accessibility client sends a message to a control.

SWT 自身包含的控件中只有寥寥几个用到了Accessibility,JFace里也不多。看了所有的Accessibility相关代码,只能总结一部分规律:
  1. 一般的复杂控件是没有必要定义Accessibility的。
  2. 如果是模拟实现一个比较简单的基本控件,比如Combo,Label,Spinner等,有必要定义Accessibility。  
  3. 所有的自定义控件都要实现AccessibleControlListener接口。
  4. 所有的包含文本框的控件都要实现AccessibleTextListener接口。
  5. 设置AccessibleListener的getHelp( )最好是给控件加上Tooltip,因为Wineyes这些屏幕阅读器阅读都是根据Tooltip,无视getHelp( )的设置。
  6. 设置AccessibleListener的getName( ),一般来说,可以设置为这个控件相关联的Label的Text或者该控件上的某部分文字,自己斟酌考虑设置。
  7. getKeyboardShortcut( ),考虑控件的快捷操作方式,如果需要的话。

以下是CCombo的Accessibility代码:

void initAccessible() {
    AccessibleAdapter accessibleAdapter = new AccessibleAdapter () {
       publicvoid getName (AccessibleEvent e) {
           String name = null;
           Label label = getAssociatedLabel ();
           if (label != null) {
              name = stripMnemonic (label.getText());
           }
           e.result = name;
       }
       publicvoid getKeyboardShortcut(AccessibleEvent e) {
           String shortcut = null;
           Label label = getAssociatedLabel ();
           if (label != null) {
              String text = label.getText ();
              if (text != null) {
                  char mnemonic = _findMnemonic (text);
                  if (mnemonic != '\0') {
                     shortcut = "Alt+"+mnemonic;
                  }
              }
           }
           e.result = shortcut;
       }
       publicvoid getHelp (AccessibleEvent e) {
           e.result = getToolTipText ();
       }
    };
    getAccessible ().addAccessibleListener (accessibleAdapter);
    text.getAccessible ().addAccessibleListener (accessibleAdapter);
    list.getAccessible ().addAccessibleListener (accessibleAdapter);
    arrow.getAccessible ().addAccessibleListener (new AccessibleAdapter() {
       publicvoid getName (AccessibleEvent e) {
           e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open");
       }
       publicvoid getKeyboardShortcut (AccessibleEvent e) {
           e.result = "Alt+Down Arrow";
       }
       publicvoid getHelp (AccessibleEvent e) {
           e.result = getToolTipText ();
       }
    });
 
    getAccessible().addAccessibleTextListener (new AccessibleTextAdapter() {
       publicvoid getCaretOffset (AccessibleTextEvent e) {
           e.offset = text.getCaretPosition ();
       }
       publicvoid getSelectionRange(AccessibleTextEvent e) {
           Point sel = text.getSelection();
           e.offset = sel.x;
           e.length = sel.y - sel.x;
       }
    });
   
    getAccessible().addAccessibleControlListener (new AccessibleControlAdapter() {
       publicvoid getChildAtPoint (AccessibleControlEvent e) {
           Point testPoint = toControl (e.x, e.y);
           if (getBounds ().contains (testPoint)) {
              e.childID = ACC.CHILDID_SELF;
           }
       }
      
       publicvoid getLocation (AccessibleControlEvent e) {
           Rectangle location = getBounds ();
           Point pt = toDisplay (location.x, location.y);
           e.x = pt.x;
           e.y = pt.y;
           e.width = location.width;
           e.height = location.height;
       }
      
       publicvoid getChildCount (AccessibleControlEvent e) {
           e.detail = 0;
       }
      
       publicvoid getRole (AccessibleControlEvent e) {
           e.detail = ACC.ROLE_COMBOBOX;
       }
      
       publicvoid getState (AccessibleControlEvent e) {
           e.detail = ACC.STATE_NORMAL;
       }
 
       publicvoid getValue (AccessibleControlEvent e) {
           e.result = getText ();
       }
    });
 
    text.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter () {
       publicvoid getRole (AccessibleControlEvent e) {
           e.detail = text.getEditable () ? ACC.ROLE_TEXT : ACC.ROLE_LABEL;
       }
    });
 
    arrow.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter() {
       publicvoid getDefaultAction (AccessibleControlEvent e) {
           e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open");
       }
    });
}

在SWT控件中,包含Accessibility功能的控件有:CCombo,CLabel,CTableFolder,StyledText。
posted @ 2006-06-19 17:38 三人行,必有我师焉 阅读(1947) | 评论 (4)编辑 收藏

上一篇文章我们知道了Eclipse弹出菜单的基本用法。其实Eclipse的弹出菜单可以用来做很多文章,简单一点的根据文件类别,我们可以进行不同的文件操作,比如Ant的build.xml我们可以用来build,Java文件我们可以用Java Editor打开,这些基于文件类型的操作我们都可以很容易的实现。但是还有一种情况,如果文件类型一样,我们想进行不同的操作,该怎么实现呢?实际上这样的应用很多,比如同样是Java文件,含有main方法的Java文件有Run和Debug的选项,其它的都没有。还有现在的框架都是基于XML文件进行配置的,如果一个项目使用了多个框架,我们怎么根据不同的XML文件进行框架的区分呢?答案就是enablement的test。

<!ELEMENT test EMPTY>
<!ATTLIST test
property CDATA #REQUIRED
args     CDATA #IMPLIED
value    CDATA #IMPLIED>

This element is used to evaluate the property state of the object in focus. The set of testable properties can be extended using the propery tester extension point. The test expression returns EvaluationResult.NOT_LOADED if teh property tester doing the actual testing isn't loaded yet.

  • property - the name of an object's property to test.
  • args - additional arguments passed to the property tester. Multiple arguments are seperated by commas. Each individual argument is converted into a Java base type using the same rules as defined for the value attribute of the test expression.
  • value - the expected value of the property. Can be omitted if the property is a boolean property. The test expression is supposed to return EvaluationResult.TRUE if the property matches the value and EvaluationResult.FALSE otherwise. The value attribute is converted into a Java base type using the following rules:
    • the string "true" is converted into Boolean.TRUE
    • the string "false" is converted into Boolean.FALSE
    • if the string contains a dot then the interpreter tries to convert the value into a Float object. If this fails the string is treated as a java.lang.String
    • if the string only consists of numbers then the interpreter converts the value in an Integer object.
    • in all other cases the string is treated as a java.lang.String
    • the conversion of the string into a Boolean, Float, or Integer can be suppressed by surrounding the string with single quotes. For example, the attribute value="'true'" is converted into the string "true"


比如我们要让含有main方法的Java文件它的右键弹出菜单包含一个额外的选项“This is main class”,需要编写如下的Plugin.xml:

< plugin >
   
< extension
         
point ="org.eclipse.ui.popupMenus" >

      
< objectContribution
        
id ="Advanced.PopupMenus"

        objectClass
="java.lang.Object" >
     
< action  id ="Advanced.PopupMenus.Action"
        label
="AdvancedPopupMenus"
        style
="pulldown"
        menubarPath
="additions"
        class
="advancedpopupmenus.popup.actions.AdvancedPopupMenusAction"  
        enablesFor
="+" >

     
</ action >
     
< enablement >
          
< test  property ="advancedpopupmenus.popup.visable" />
     
</ enablement >   
     
</ objectContribution >

   
</ extension >
   
< extension  point ="org.eclipse.core.expressions.propertyTesters" >
   
< propertyTester
   
namespace ="advancedpopupmenus.popup"

   properties
="visable"
   type
="java.lang.Object"
   class
="advancedpopupmenus.popup.actions.VisablePropertyTester"
   id
="advancedpopupmenus.popup.propertyTesters.visable" >   
   
</ propertyTester >
      
   
</ extension >

</ plugin >

我们需要检测在当前情况下是否需要显示这个菜单项,使用扩展点 org.eclipse.core.expressions.propertyTesters
<!ELEMENT propertyTester EMPTY>
<!ATTLIST propertyTester
id         CDATA #REQUIRED
type       CDATA #REQUIRED
namespace  CDATA #REQUIRED
properties CDATA #REQUIRED
class      CDATA #REQUIRED>

id - unique identifier for the property tester
type - the type to be extended by this property tester
namespace - a unique id determining the name space the properties are added to
properties - a comma separated list of properties provided by this property tester
class - the name of the class that implements the testing methods. The class must be public and extend org.eclipse.core.expressions.PropertyTester with a public 0-argument constructor. 

这里只须注意
propertyTester的namespace和properties正好对应test的property。

至于检测的逻辑我们在advancedpopupmenus.popup.actions.VisablePropertyTester中实现,这个类必须继承自org.eclipse.core.expressions.PropertyTester

package  advancedpopupmenus.popup.actions;

import
 org.eclipse.core.expressions.PropertyTester;
import
 org.eclipse.jdt.core.IMethod;
import
 org.eclipse.jdt.core.IType;
import
 org.eclipse.jdt.core.JavaModelException;
import
 org.eclipse.jdt.internal.core.CompilationUnit;

public   class  VisablePropertyTester  extends
 PropertyTester
{
    
public   boolean
 test( Object receiver, String property, Object[] args,
            Object expectedValue )
    {
        
if  (  ! ( receiver  instanceof
 CompilationUnit ) )
            
return   false
;
        CompilationUnit unit 
=
 (CompilationUnit) receiver;
        
try

        {
            IType[] types 
=  unit.getTypes( );
            
if  ( types  ==   null
 )
                
return   false
;
            
for  (  int  i  =   0 ; i  <  types.length; i ++
 )
            {
                IMethod[] methods 
=
 types[i].getMethods( );
                
if  ( methods  ==   null
 )
                    
return   false
;
                
for  (  int  j  =   0 ; j  <  methods.length; j ++
 )
                {
                    
if
 ( methods[j].isMainMethod( ) )
                        
return   true
;
                }
            }
        }
        
catch
 ( JavaModelException e )
        {
            e.printStackTrace( );
        }
        
return   false
;
    }
}

我们只要判断接受的Java文件中是否含有main方法,如果有,则返回True,没有则返回False。

如果我们是要接受一个Web开发的配置文件,我们可以这样写:

< plugin >
   
< extension
         
point ="org.eclipse.ui.popupMenus" >

      
< objectContribution
        
id ="Advanced.PopupMenus"

        objectClass
="org.eclipse.core.resources.IFile"
        nameFilter
="*.xml" >    
        
< action  id ="Advanced.PopupMenus.Action"

           label
="This is web xml"
           style
="pulldown"
           menubarPath
="additions"
           class
="advancedpopupmenus.popup.actions.AdvancedPopupMenusAction"     
           enablesFor
="+" >

        
</ action >
        
< enablement >
             
< test  property ="advancedpopupmenus.popup.visable" />
        
</ enablement >   
     
</ objectContribution >

   
</ extension >
   
< extension  point ="org.eclipse.core.expressions.propertyTesters" >
      
< propertyTester
            
namespace ="advancedpopupmenus.popup"

            properties
="visable"
            type
="org.eclipse.core.resources.IFile"
            class
="advancedpopupmenus.popup.actions.VisablePropertyTester"
            id
="advancedpopupmenus.popup.propertyTesters.visable" >         
      
</ propertyTester >
      
   
</ extension >

</ plugin >

注意和上一个例子不同的地方,objectClass,nameFileter和type(在上一个例子中,我们也可以使用objectClass="org.eclipse.core.resources.IFile" nameFilter ="*.java" ),相应的我们的VisablePropertyTester类也要做一些改动:

package  advancedpopupmenus.popup.actions;

import
 javax.xml.parsers.DocumentBuilder;
import
 javax.xml.parsers.DocumentBuilderFactory;
import
 org.eclipse.core.expressions.PropertyTester;
import
 org.eclipse.core.resources.IFile;
import
 org.w3c.dom.Document;
import
 org.w3c.dom.DocumentType;

public   class  VisablePropertyTester  extends
 PropertyTester
{
    
public   boolean
 test( Object receiver, String property, Object[] args,
            Object expectedValue )
    {
        
if  (  ! ( receiver  instanceof
 IFile ) )
            
return   false
;
        IFile xml 
=
 (IFile) receiver;
        
try

        {
            DocumentBuilderFactory dbf 
=  DocumentBuilderFactory.newInstance( );
            DocumentBuilder db 
=
 dbf.newDocumentBuilder( );
            Document doc 
=
 db.parse( xml.getContents( ) );
            DocumentType type 
=
 doc.getDoctype( );
            
if (type.getSystemId( ).equalsIgnoreCase(  " http://java.sun.com/j2ee/dtds/web-app_2_2.dtd "  )) return   true
;
        }
        
catch
 ( Exception e )
        {
            e.printStackTrace( );
        }        
        
return   false
;
    }
}

这样根据不同的xml SystemID,我们就能够知道到底这是哪一种框架的配置文件了。

posted @ 2006-06-16 16:15 三人行,必有我师焉 阅读(3192) | 评论 (5)编辑 收藏

复杂布局的重用,比较容易实现的就是GridLayout,至于FormLayout,基本上如果相似度不是很大,很难重用。我们在实现很多Page的时候,优先考虑的都会是GridLayout。但GridLayout在界面元素改动较大的时候也拥有一些弊端,比之FormLayout要麻烦的多。

当界面元素拥有上下文的时候,随着其上下文的改变,要想界面元素按照新的上下文重新布局,总是让人头疼。因为首先能想到的方法就是隐藏掉不需要的元素,这样会减少时间和代码上的开销。但是如果采用GridLayout布局的时候,一个Widget隐藏的时候,它仍然占用着界面空间,即使将它的hightHint和widthHint设置为0,依然不能解决问题,因为GridLayout通常设置了verticalSpacing和horizontalSpacing。

现在想到的一个解决方案就是将界面元素重新洗牌。 界面元素的生成由Model里的各个元素来决定。界面的上下文都交由一个属性控制层进行控制,它上承GUI界面,下接业务模型,属于一个过渡的层次。该层可以装饰业务模型,并附加上新的上下文,形成一个新的Model。根据这个新的Model,我们在界面上创造元素。如果Model仅仅只是值发生了变化,我们重新设置界面的值即可。如果Model发生了上下文的变化,比如不需要某个属性了或者是增加一个属性,我们就对整个界面进行重新洗牌,通过一个循环Dispose掉所有的Widget,然后根据新的上下文重新初始化界面元素,并进行赋值。由于MVC的分离,重新初始化界面是很容易的。对于不太复杂的Page,布局上的问题就可以迎刃而解,而且在时间上的开销也不会体现得很明显,至少并看不出显示上的延迟。

posted @ 2006-06-16 13:54 三人行,必有我师焉 阅读(578) | 评论 (2)编辑 收藏

这几天阅读GEF 相关的几篇文章:

  • http://benisoft.com/cn/java/AShapeDiagramEditor_zh.htm
  • http://blog.popsoft.com/more.asp?name=saden5&id=6591
  • http://www.blog.edu.cn/user1/19180/archives/2005/372857.shtml

    看下来感觉不错,有些收获,尤其是createEditPart,两个参数,EditPart是上下文,另一个是Model,有可能用到项目的Property Editor上面,根据上下文和传入的Model来控制界面的显示。GEF的这段代码可以用来研究研究。

    public classPartFactory implementsEditPartFactory {
        
    public  EditPart createEditPart(EditPart context, Object model)
    {
             EditPart part
    = null
    ;
            
    if (model instanceof
    Diagram)
                part
    = new
    DiagramPart();
           
      else if(model instanceof RectangleModel)
    {
                part
    = new
    RectanglePart();
            }

            part.setModel(model);
           
    return  part;
        }

    }

    至于GEF,感觉只要有入门文章,再看看项目上的代码,上手很容易,如果要做出复杂的应用,还要在研究研究它的API。八进制的文章写得基本上很清楚了,

    BTW:Eclipse 有些view是绝佳的查看代码的工具,比如Type Hierarchy视图,Call Hierarchy视图都非常有用。真是不用不知道呀!  

  • posted @ 2006-06-15 18:15 三人行,必有我师焉 阅读(538) | 评论 (1)编辑 收藏

    仅列出标题
    共9页: 上一页 1 2 3 4 5 6 7 8 9 
    GitHub |  开源中国社区 |  maven仓库 |  文件格式转换