Posted on 2012-10-10 16:26
TWaver 阅读(2393)
评论(0) 编辑 收藏
TWaver提供了一些布局算法帮助我们快速为网元设置位置,很多情况下已经够用了,但是对于一些复杂的布局还需要我们自己做一些处理,请看下面这个例子:
运行截图:
这个时候直接使用TNetwork#doLayout就不好使了,因为doLayout会对network中所有网元使用同一种布局算法,但是截图中Group下多个子Group各有自己的布局方式,我的解决办法是,先对最外层的Group整个布局,然后递归遍历子Group,单独对他们进行布局。
代码实现:
TWaver中实现局部布局可以通过两种方式:
- 将要布局的Element加入到一个新的TNetwork中,然后用新的TNetwork布局
- TWaver默认只对选中的Element布局,所以可以将要布局的Element加入到SelectionModel中
在这个demo中,首先用第一种方式对最外层的Group进行布局:
1 //layoutNetwork是用来布局的临时network
2 //生成Group时,已经将布局方式存入ClientProperty
3 layoutDatabox.addElementWithDescendant(group1);
4 layoutNetwork.doLayout((Integer)group1.getClientProperty("layout"),false);
然后递归遍历group,为子group布局:
1 recursionChild(group1);
2 ..
3 4 private
void recursionChild(Group group){
5 for(
int i=0;i<group.getChildren().size();i++){
6 Element element= (Element) group.getChildren().get(i);
7 if(element
instanceof Group){
8 Group childGroup=((Group)element);
9 recursionChild(childGroup);
//如果有子Group,会一直递归
10 //使用两种方式结合,将要布局的子group加入到layoutNetwork的SelectionModel
11 layoutDatabox.getSelectionModel().clearSelection();
12 layoutDatabox.getSelectionModel().appendSelection(childGroup.getChildren());
13 layoutNetwork.doLayout((Integer) ((Group) element).getClientProperty("layout"),
false);
14 layoutDatabox.getSelectionModel().clearSelection();
15 }
16 }
17 }
最后附上全部代码:
1 public class LayoutTest extends JPanel {
2 TDataBox layoutDatabox=new TDataBox();
3 TNetwork layoutNetwork=new TNetwork(layoutDatabox);
4 public LayoutTest(){
5
6 TNetwork network=new TNetwork();
7
8 ResizableNode gatewayNode=new ResizableNode();
9
10 gatewayNode.putCustomDraw(true);
11 gatewayNode.putCustomDrawShapeFactory(TWaverConst.SHAPE_ROUND_RECTANGLE_HALF);
12 gatewayNode.putCustomDrawGradient(false);
13 gatewayNode.putCustomDrawFillColor(new Color(254, 254, 206));
14 gatewayNode.setSize(70, 30);
15 gatewayNode.setName("Gateway");
16 gatewayNode.putLabelPosition(TWaverConst.POSITION_CENTER);
17
18 Group group1=createGroup(4,TWaverConst.LAYOUT_TREE);
19 Group group1_1=createGroup(12,TWaverConst.LAYOUT_CIRCULAR);
20 Group group1_2=createGroup(5,TWaverConst.LAYOUT_EAST);
22 Link group1_2Link=new Link((Node)group1.getChildren().get(0),(Node)group1_2.getChildren().get(0));
23 setLinkStyle(group1_2Link);
24 group1.addChild(group1_2);
25 group1.addChild(group1_2Link);
26
27 Link group1_1Link=new Link((Node)group1.getChildren().get(0),(Node)group1_1.getChildren().get(0));
28 setLinkStyle(group1_1Link);
29 group1.addChild(group1_1);
30 group1.addChild(group1_1Link);
31
32 //layoutNetwork是用来布局的临时network
33 //生成Group时,已经将布局方式存入ClientProperty
34 layoutDatabox.addElementWithDescendant(group1);
35 layoutNetwork.doLayout((Integer)group1.getClientProperty("layout"),false);
36 recursionChild(group1);
37
38 TDataBox box=new TDataBox();
39 box.addElementWithDescendant(group1);
40 box.addElement(gatewayNode);
41
42 group1.putGroupOpaque(true);
43 group1.putGroupFillColor(new Color(154,206,254));
44 network.setDataBox(box);
45 this.setLayout(new GridLayout(1,3));
46 this.add(network);
47
48 Layer layer=new Layer();
49 box.getLayerModel().addLayer(layer);
50 box.getLayerModel().moveToTop(layer);
51
52 Link link1=new Link(group1,gatewayNode);
53 setLinkStyle(link1);
54 link1.setLinkType(TWaverConst.LINK_TYPE_ORTHOGONAL);
55 link1.setLayerID(layer.getID());
56 box.addElement(link1);
57 }
58
59 /**
60 * 递归Group设置布局
61 * @param group
62 */
63 private void recursionChild(Group group){
64 for(int i=0;i<group.getChildren().size();i++){
65 Element element= (Element) group.getChildren().get(i);
66 if(element instanceof Group){
67 Group childGroup=((Group)element);
68 recursionChild(childGroup);//如果有子Group,会一直递归
69 //使用两种方式结合,将要布局的子group加入到layoutNetwork的SelectionModel
70 layoutDatabox.getSelectionModel().clearSelection();
71 layoutDatabox.getSelectionModel().appendSelection(childGroup.getChildren());
72 layoutNetwork.doLayout((Integer) ((Group) element).getClientProperty("layout"), false);
73 layoutDatabox.getSelectionModel().clearSelection();
74 }
75 }
76 }
77 /**
78 * 产生测试Group及Node
79 * @param childCount
80 * @param layout
81 * @return
82 */
83 private Group createGroup(int childCount,int layout){
84 Group group=new Group();
85 group.setExpand(true);
86 group.putClientProperty("layout",layout);
87
88 ResizableNode router=new ResizableNode();
89 router.putCustomDraw(true);
90 router.putCustomDrawShapeFactory(TWaverConst.SHAPE_RECTANGLE);
91 router.putCustomDrawGradient(false);
92 router.putCustomDrawFillColor(new Color(254, 254, 206));
93 router.setSize(60, 20);
94 router.setName("Router");
95 router.putLabelPosition(TWaverConst.POSITION_CENTER);
96 group.addChild(router);
97
98 for(int i=0;i<childCount;i++){
99 Node childNode=new Node();
100 Link link=new Link(router,childNode);
101 childNode.putCustomDraw(true);
102 childNode.putCustomDrawShapeFactory(TWaverConst.SHAPE_RECTANGLE);
103 childNode.putCustomDrawGradient(false);
104 childNode.putCustomDrawFillColor(new Color(254,202,2));
105 childNode.setName("C"+i);
106 childNode.putLabelPosition(TWaverConst.POSITION_CENTER);
107
108 setLinkStyle(link);
109 group.addChild(childNode);
110 group.addChild(link);
111 }
112 return group;
113 }
114
115 /**
116 * 设置link样式
117 * @param link
118 */
119 public void setLinkStyle(Link link){
120 link.putLinkColor(Color.black);
121 link.putLinkOutlineWidth(0);
122 link.putLinkWidth(1);
123 link.putLinkAntialias(true);
124 link.putLinkToArrow(true);
125 link.putLinkToArrowOutline(false);
126 }
127 public static void main(String[] args){
128 SwingUtilities.invokeLater(new Runnable() {
129 @Override
130 public void run() {
131 JFrame frame=new JFrame("布局");
132 frame.setSize(1000,700);
133 frame.setContentPane(new LayoutTest());
134 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
135 frame.setLocationRelativeTo(null);
136 frame.setVisible(true);
137 }
138 });
139 }
140 }
141
代码和思路都很简单,希望能抛砖引玉,大家有建议或好的想法也可以交流一下