TWaver基本编程2

来源:互联网 发布:网络ping大包丢包 编辑:程序博客网 时间:2024/06/08 08:29

Element的选中机制

所有的Element数据都可以被选中。选中状态是Element的重要状态之一,它在实现人机交互过程中非常常用。理解和使用Element选择,对于熟练掌握TWaver开发具有重要意义。

  • 使用选择状态

    所有TWaver的Element都有一个选中状态。要么选中,要么没选中,它是一个boolean值。可以使用函数isSelected/setSelected进行获取或设置。一个对象处于选中状态时,其外观会有一定的变化,对于不同的组件,这种变化也有所不同。例如,对于拓扑图组件来说,选中的数据会显示一个高亮外框,而对于树来说,选中数据会有一个高亮的背景框。如下图。

    实际上,这些默认的外观和行为都可以被定制和修改。后续章节我们将讲述这些用法。

  • 使用选择容器Selection Model

    Selection Model可以成为选择容器,是一个DataBox附属的一个容器,它维护着DataBox中所有的被选中的数据对象的引用。DataBox作为一个大容器,它负责所有容纳其中数据的管理。但是,为了让管理职责更加清晰和明确、易于使用,DataBox还拆分出一些附属的、相对独立的小容器,分管不同的任务。选择容器Selection Model就是其中一个,专门负责管理数据的选中状态。

    其实,Element已经有了boolean值标识选中状态,那为何DataBox还要设置选择容器进行选中状态的管理呢?主要是为了开发者使用更加方便。举一个简单的例子:如果DataBox容纳了1万个节点,其中有10个被用户选中,并进行了"删除"操作。如果没有选择容器,我们只能通过遍历这1万个节点来获得这10个数据进行删除,效率和方便性上都不够好。而有了选择容器,则可以直接访问选择容器,将其中的10个节点删除即可,因为TWaver已经保证所有的选中节点都会出现在选择容器中。

    通过选择容器,还可以通过API对选择状态进行控制。例如,将数据加入选择容器会造成数据被选中;清空选择容器,会取消所有数据的选中状态,等等。

    当然,选择容器仅仅负责选择状态的管理。无论对这个容器怎么增、删、改操作,它仅仅影响数据的选中状态,而不会影响数据的其他属性,更不会导致数据从DataBox中被删除等行为。

  • 使用选择监听器

    选择监听器的作用是:用于监测数据的选择状态的变化。

    首先解释一下什么是监听器。如果读者熟悉Swing编程,可以从中看到大量使用监听器进行设计的例子。例如监听按钮被按下的动作是使用ActionListener,下拉框被修改是使用ChangeListener等等。同样,TWaver中的选择监听器SelectionListener的道理和用法类似,就是监听DataBox中数据的选中变化。

    其次解释一下为什么要监听选择的变化。根据实际应用场景的不同,其具体需求可能不同,但是监听选中的变化作用还是比较大的。例如,当用户在屏幕上对拓扑图上的一些节点进行选中,我们希望把所有选中数据的名字动态显示在窗口底部的提示栏上。此时,就可以加装选择监听器,并对事件进行处理。

    下面的例子中,我们创建了一个新的选择监听器,当任何一个Element的选择状态发生变化时,我们都打印一个字符串,表示监听到了:

    DataBoxSelectionListener l =new DataBoxSelectionAdapter(){    public void selectionChanged(DataBoxSelectionEvent e) {        System.out.println("selection changed.");    };};TDataBox box=new TDataBox();box.getSelectionModel().addDataBoxSelectionListener (l);//add more code here...

    使用交互进行选择控制拓扑图提供了很多内置的交互模式,便于用户对数据进行选择操作。这样,我们可以通过API、鼠标或键盘等多种途径对数据选择进行控制。

    设备 操作 效果 鼠标点击一个Element选择Element 拓扑图拖拽矩形区域(左上到右下)选中所有完全落入矩形区域内部的Element 拓扑图拖拽矩形区域(右下到左上)选中所有完全和非完全落入矩形区域内部的Element键盘+鼠标Ctrl键+鼠标点击Element设置或取消该Element的选中状态 Ctrl键+鼠标拖拽矩形框设置或取消该矩形框内所有Element的选中状态
定制交互

TWaver拓扑图提供了大量的默认的交互模式。例如拖拽模式、编辑模式、创建连线模式等等。如果这些模式依旧无法满足要求,可以通过扩展新的交互模式来解决。新的交互模式可以自定义鼠标、键盘等各种事件的具体行为,为用户提供更加丰富的交互方法。

交互模式的定制是TWaver比较难的部分,后续章节我们将对此进行详细介绍。

  • 设置右键菜单

    右键菜单也成为弹出菜单,本章介绍如何在拓扑图以及其他图形组件中使用右键菜单。右键菜单是一个非常常用的交互方法,通过对数据进行选择、右键菜单,可以快速调出上下文有关的操作选项,为软件使用者提供直观的交互方法。TWaver中,我们使用一个叫做弹出菜单生成器(PopupMenuGenerator)的接口,来制作各种不同的右键菜单。更多关于使用右键菜单的例子,请见后续章节。这里仅给出一个简单的例子,让读者了解弹出菜单是如何制作出来的。

    菜单生成器是一个接口,被设置在拓扑图或其他图形组件上。一旦设置,当鼠标右键点击图形组件时,TWaver就会回调这个接口获得右键菜单。TWaver会将当前的一些操作场景传入,例如被点击的图形组件、鼠标事件等等。我们要做的,就是根据这些信息,动态的生成需要的右键菜单,返回即可。具体的菜单显示等细节,TWaver会帮我们完成。

    以下弹出菜单的例子弹出一个菜单,把所有的选中的对象的名字用菜单项显示出来。代码被封装在函数step4中。

    private void step4() {//Create a popup menu generatorPopupMenuGenerator popupMenuGenerator = new PopupMenuGenerator() {/*** Add the identifier of each of the selected objects to the menu.* In this example, the items added to the menu do nothing. * In a real application, you would probably associate an * implementation of the Swing Action interface with each menu item. */ public JPopupMenu generate(TView tview, MouseEvent mouseEvent){  //Create an empty pop-up menu.  JPopupMenu popMenu = new JPopupMenu();  JMenuItem item;  //If the selectedObjects collection is empty, no objects are selected.  if (tview.getDataBox().getSelectionModel().isEmpty()) {    popMenu.add("Nothing selected");  } else {    //Access the selected objects from the selection model.    Iterator it = tview.getDataBox().getSelectionModel().selection();    while (it.hasNext()) {      Element element = (Element) it.next();      popMenu.add(element.getName());    }   }//If menu is empty, return null.   if (popMenu.getComponentCount() == 0) {    return null;   } else {    return popMenu;   }  }};//Set the pop-up menu generator for network componentsnetwork.setPopupMenuGenerator(popupMenuGenerator);}}

     

    注意:菜单生成器一旦创建,可以通过方法setPopupMenuGenerator应用在多个图形组件上。例如,上述popupMenuGenerator可以被同时设置在tree上面或表格上面。这样,无论在tree、table、拓扑图上,只要选中同样的数据,点击右键弹出的菜单将是完全一模一样的,而且我们无需编写多个菜单生成器。

  • 添加鼠标和键盘动作

    拓扑图是Java Swing组件的扩展。和其他Swing组件一样,在Network上添加鼠标、键盘动作是很容易的。唯一需要注意的一点是,拓扑图并非一个简单JComponent那么简单,它由工具条、滚动窗、画布等部分组成。所以,实际上我们一般添加动作都是针对画布的,而不是Network本身。所以,要使用network.getCanvas()方法先获得画布对象。然后,就可以像其他Swing组件那样添加各种监听器了。

    为了演示,我们在例子中添加一个双击动作,弹出消息框显示被双击的数据对象。这段代码被封装在函数step5中。

    private void step5() {network.getCanvas().addMouseListener(new MouseAdapter() {    public void mouseClicked(MouseEvent e) {      if (e.getClickCount() == 2) {        //get the element the mouse clicked.        Element element = network.getElementPhysicalAt(e.getPoint());        String message;        if (element == null) {          message = "You clicked nothing.";        } else {          message = "You clicked '" + element.getName() + "'";        }        JOptionPane.showMessageDialog(network, message);      }    }});}
    运行程序如下图。双击空白区和双击对象,都会弹出消息。

    此外,为了方便开发者对鼠标事件进行更直观的监听,TWaver添加了很多经过封装的鼠标监听方法:

    • TNetwork.addElementDoubleClickedActionListener:添加Element双击事件监听器。
    • TNetwork.addBackgroundDoubleClickedActionListener:添加空白区域双击事件监听器。
    • TNetwork.addElementClickedActionListener:添加Element单击事件监听器。

    通过这些高度封装的方法,监听鼠标事件就更加方便了。

  • 处理数据选择

    这一节将介绍如下内容:

    • 控制选择;
    • 监听选择变化;
    • 移动拓扑图以便选中数据处于可见位置;

    由于选择容器是DataBox的一个组成部分,所以所有共享同一个DataBox的图形组件也共享同一套数据选择状态。也就是说,一个对象被选择,是在数据层决定的,它在所有与DataBox相连的图形组件上都会体现出来。如果对选择变化进行监听,则从DataBox的选择容器进行加装监听器。每次选择发生变化,事件会被发送到所有监听器。我们可以在监听器中写代码执行各种任务。

    为了展示这个功能,我们创建一个监听器,当用户从tree选择一个数据后,拓扑图也会显示选中数据,并且如果这个选中的数据不在可见区域内,会自动滚动画布以保证数据处于可见视野内。

    这部分代码被封装在step6函数中。

    private void step6() {//create a selection listener.  DataBoxSelectionListener listener = new DataBoxSelectionListener() {    public void selectionChanged(DataBoxSelectionEvent e) {      //get the last selected element and make it visible.      Element element = e.getBoxSelectionModel().lastElement();      if (element != null) {        network.ensureVisible(element);      }    }  };  box.getSelectionModel().addDataBoxSelectionListener (listener);}


    无选中

    一个数据从tree被选中
    添加告警

    这一节介绍如何在数据上使用告警。TWaver提供了综合、全面、强大的告警支持,以简化电信管理软件的开发复杂度。TWaver提供了许多关于告警方面的图形渲染属性,用于控制告警的呈现。当告警发生后,对应的数据就会以相应的方式进行绘制和渲染,以便用直观、易于理解的方式提醒用户。

    每一个Element对象都有一个告警状态表Alarm State。这是一个告警信息表,记录了所有发生在Element上面的告警信息。要为数据添加告警,首先要获得告警状态表,然后在其中添加告警信息即可。数据会在拓扑图、树等图形组件上做出相应的显示变化。

    另外,还可以使用DataBox提供的告警传播机制。TWaver默认提供了一个功能完善的告警传播器,可以将告警沿着父对象的路径进行传播。也可以编写符合自己业务规则的告警传播器,设置在DataBox上使用。

    这里,我们对前面创建的数据添加一些告警,代码被封装在step7函数中。

    private void step7() {   //create and set a summing propagator to the data source,   //here will make the box propagate alarms to its parent.   box.setAlarmPropagator(new SummingAlarmPropagator());   //get a port in the equipment rack.   Port nodeA = (Port) box.getElementByID("0:0");   AlarmState alarmState = nodeA.getAlarmState();   //add an acknowledged alarm with critical severity.   alarmState.addAcknowledgeAlarm(AlarmSeverity.CRITICAL);   //add and new alarm with major severity.   alarmState.addNewAlarm(AlarmSeverity.MAJOR);   //get another port.   Port nodeB = (Port) box.getElementByID("3:3");   alarmState = nodeB.getAlarmState();   //add 10 new alarms with critical minor.   alarmState.increaseNewAlarm(AlarmSeverity.MINOR, 10); }

    上图显示了告警传播的路径。从树、拓扑图上都可以显示出告警的传播方式、告警传播后的呈现方法。

    更多关于使用告警的介绍,在后续章节有详细描述。
    添加装饰图标
  • TWaver支持在各种数据对象上附着显示一些动态图标,用来表示一些动态的网络事件信息。例如,一个设备出了告警之外,还有一些其他并不像告警那么严重的时间信息,这些信息也需要用一种非常直观、醒目的方式显示出来提示用户。这种情况下,可以使用Attachment附件机制。装饰图标就是一种附件,它用一个小图标来表示某些事件的发生,并显示在对应的宿主对象边缘,用于显示一些网络上发生的动态事件和信息。

    TWaver默认提供了一些预定义的装饰图标,可以直接使用。这些都被IconAttachmentHolder类进行统一管理。扩展新的装饰图标也很简单。我们通过代码进行演示如何操作。首先,我们需要一个小图标: ,然后我们定义一个新的装饰图标并进行注册,然后让它显示在某一个Element上面。装饰图标从IconAttachment进行继承,我们重载构造函数,指定我们的图标即可。新的装饰图标需要是一个顶级类,我们推荐用public static来定义,或者放入单独的一个文件中TUIManager.registerAttachment方法进行注册,这样在运行过程中,就可以用element.addAttachment方法显示装饰图标了。

    这段代码被封装为step8:

    //define a new LayoutedIconAttachment.//It must define as public static class.public static class MyIconAttachment extends IconAttachment{  public MyIconAttachment(String name, ElementUI ui) {    super(name, ui, TWaverUtil.getImageIcon("myIcon.png"));  }}private void step8() {  String iconName="document";  TUIManager.registerAttachment(iconName, MyIconAttachment.class);  //put a "document" icon on element B.  Element element = box.getElementByID("A");  element.addAttachment(iconName);}
    运行程序,显示如下:

    我们还可以定义更多的装饰图标,并同时显示。还可以控制图标显示的方向、角度等。更多信息,请参阅后续章节。
    添加显示特效
  • TWaver提供了丰富的显示特效,尤其在拓扑图上面。例如,我们可以在连线上显示流动的特殊动画效果。我们通过对应的API函数就可以实现这种效果,非常简单。

    以下例子展示了如何设置这种效果,代码被封装在step9函数中:

    private void step9() {  //get the link element.  Element element = box.getElementByID("link");  //make the link animating flowing  element.putLinkFlowing(true);  //set the link flowing color  element.putLinkFlowingColor(Color.black);  //set the link outline color  element.putLinkOutlineColor(Color.black);  //set the link body color.  element.putLinkColor(Color.white);  //set the link lable font  element.putLabelFont(new Font("Impact", 1, 20));  //set the link lable color  element.putLabelColor(Color.MAGENTA);}

    运行代码,效果如下图:

原创粉丝点击