View Javadoc

1   /*
2    * Copyright 2004-2008 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.uruma.renderer.impl;
17  
18  import org.eclipse.swt.widgets.Composite;
19  import org.eclipse.swt.widgets.Layout;
20  import org.seasar.framework.beans.BeanDesc;
21  import org.seasar.framework.beans.PropertyDesc;
22  import org.seasar.framework.beans.factory.BeanDescFactory;
23  import org.seasar.uruma.component.CommonAttributes;
24  import org.seasar.uruma.component.LayoutInfo;
25  import org.seasar.uruma.component.UIComponent;
26  import org.seasar.uruma.component.UICompositeComponent;
27  import org.seasar.uruma.component.jface.CompositeComponent;
28  import org.seasar.uruma.renderer.layout.LayoutSupport;
29  import org.seasar.uruma.renderer.layout.LayoutSupportFactory;
30  
31  /**
32   * {@link Composite} 用レンダラの基底クラスです。<br />
33   * {@link Composite} のサブクラスに対するレンダリングを行い場合、本クラスを継承してください。<br />
34   * 本クラスを継承することで、レイアウトに関するレンダリングは自動的に行われます。
35   * 
36   * @author y-komori
37   * 
38   * @param <COMPONENT_TYPE>
39   *            レンダラに対応するコンポーネントの型
40   * @param <COMPOSITE_TYPE>
41   *            レンダラが生成するウィジットの型
42   * @see org.eclipse.swt.widgets.Composite
43   * @see org.eclipse.swt.widgets.Layout
44   */
45  public abstract class AbstractCompositeRenderer<COMPONENT_TYPE extends CompositeComponent, COMPOSITE_TYPE extends Composite>
46          extends AbstractControlRenderer<COMPONENT_TYPE, COMPOSITE_TYPE> {
47  
48      /**
49       * サブクラスでのレンダリングを行います。</br>
50       * <p>
51       * {@link AbstractCompositeRenderer} のサブクラスは、本メソッドをオーバーライドしてレンダリングを行ってください。
52       * </p>
53       * 
54       * @param compositeComponent
55       *            コンポジットの情報を持つコンポーネント
56       * @param composite
57       *            レンダリング対象のコンポジット
58       */
59      abstract protected void doRenderComposite(
60              COMPONENT_TYPE compositeComponent, COMPOSITE_TYPE composite);
61  
62      /*
63       * @see org.seasar.uruma.renderer.impl.AbstractControlRenderer#inherit(org.seasar.uruma.component.jface.ControlComponent)
64       */
65      @Override
66      protected void inherit(final COMPONENT_TYPE uiComponent) {
67          super.inherit(uiComponent);
68          inheritCommonAttributes(uiComponent);
69      }
70  
71      /*
72       * @see org.seasar.uruma.renderer.impl.AbstractControlRenderer#doRenderControl(org.seasar.uruma.component.jface.ControlComponent,
73       *      org.eclipse.swt.widgets.Control)
74       */
75      @Override
76      protected final void doRenderControl(
77              final COMPONENT_TYPE compositeComponent,
78              final COMPOSITE_TYPE control) {
79          setLayout(compositeComponent, control);
80  
81          doRenderComposite(compositeComponent, control);
82      }
83  
84      /**
85       * レイアウトを設定します。<br />
86       * <code>control</code> に対して <code>compositeComponent</code> の保持する
87       * {@link LayoutInfo} から {@link Layout} を生成して設定します。<br />
88       * 
89       * @param compositeComponent
90       *            レイアウト情報を保持する {@link CompositeComponent}
91       * @param control
92       *            レイアウトを設定する {@link Composite}
93       */
94      @SuppressWarnings("unchecked")
95      protected void setLayout(final COMPONENT_TYPE compositeComponent,
96              final COMPOSITE_TYPE control) {
97          LayoutInfo<?> layoutInfo = compositeComponent.getLayoutInfo();
98          if (layoutInfo != null) {
99              LayoutSupport layoutSupport = LayoutSupportFactory
100                     .getLayoutSupport((Class<? extends LayoutInfo<?>>) layoutInfo
101                             .getClass());
102             Layout layout = layoutSupport.createLayout(compositeComponent
103                     .getLayoutInfo());
104             control.setLayout(layout);
105         }
106     }
107 
108     /**
109      * <code>compositeComponent</code> の親コンポーネントから共通属性をコピーします。<br />
110      * 
111      * @param compositeComponent
112      *            自コンポーネント
113      */
114     protected void inheritCommonAttributes(
115             final COMPONENT_TYPE compositeComponent) {
116         UIComponent parent = compositeComponent.getParent();
117         if (parent == null) {
118             return;
119         }
120 
121         if (!(parent instanceof UICompositeComponent)) {
122             return;
123         }
124 
125         CommonAttributes parentAttributes = ((UICompositeComponent) parent)
126                 .getCommonAttributes();
127         if (parentAttributes == null) {
128             return;
129         }
130 
131         CommonAttributes commonAttributes = compositeComponent
132                 .getCommonAttributes();
133         if (commonAttributes == null) {
134             compositeComponent.setCommonAttributes(parentAttributes);
135         } else {
136             BeanDesc desc = BeanDescFactory.getBeanDesc(commonAttributes
137                     .getClass());
138             int size = desc.getPropertyDescSize();
139             for (int i = 0; i < size; i++) {
140                 PropertyDesc pd = desc.getPropertyDesc(i);
141                 if (pd.getValue(commonAttributes) == null) {
142                     Object value = pd.getValue(parentAttributes);
143                     pd.setValue(commonAttributes, value);
144                 }
145             }
146         }
147     }
148 }