一個樹分為:根節點,樹枝,樹葉,點擊根節點觸發一個事件:展開所有樹枝;點擊樹枝觸發一個事件:展開所有樹葉;點擊樹葉觸發一個事件:屏幕右方顯示詳細信息。那么即可說明:樹是一個組件即被觀察者,事件對象即觀察者,只要事件源即用戶點擊操作發生,就通知事件對象觀察者做出相應的動作,首先組裝出樹結構,采用安全的合成模式,類示意圖如下:

如果對樹組件增加監聽事件,即增加觀察者ActionListener,那么綜合觀察者模式,增加鼠標和鍵盤監聽,第二版類圖如下:
先給出代碼:
package observer;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
public abstract class Component
{
// 監聽隊列
private static ArrayDeque<ActionListener> deque = new ArrayDeque<ActionListener>();
private String componentName;
public Component(String componentName)
{
this.componentName = componentName;
}
public String getComponentName()
{
return componentName;
}
public void setComponentName(String componentName)
{
this.componentName = componentName;
}
protected abstract Component getComponent();
protected void addActionListener(ActionListener actionListener) throws NullPointerException
{
if (actionListener == null)
throw new NullPointerException("the ActionListener is null");
deque.offerLast(actionListener);
}
protected void removeActionListener(ActionListener actionLister)
{
deque.remove(actionLister);
}
protected Collection<ActionListener> getActionListeners()
{
return deque;
}
/**
* 點擊組件事件
*/
protected void clickOperation()
{
for (Iterator<ActionListener> it = deque.iterator(); it.hasNext();)
{
ActionListener listener = it.next();
if (listener instanceof MouseActionListener)
{
((MouseActionListener) listener).clickEvent(this);
}
if (listener instanceof KeyBoardActionListener)
{
((KeyBoardActionListener) listener).keyPressEvent(this);
}
}
}
/**
* 雙擊組件事件
*/
protected void doubleClickOperation()
{
for (Iterator<ActionListener> it = deque.iterator(); it.hasNext();)
{
ActionListener listener = it.next();
if (listener instanceof MouseActionListener)
{
((MouseActionListener) listener).doubleClickEvent(this);
}
if (listener instanceof KeyBoardActionListener)
{
((KeyBoardActionListener) listener).keyPressEvent(this);
}
}
}
/**
* 拖拽組件事件
*/
protected void dragOperation()
{
for (Iterator<ActionListener> it = deque.iterator(); it.hasNext();)
{
ActionListener listener = it.next();
if (listener instanceof MouseActionListener)
{
((MouseActionListener) listener).dragEvent(this);
}
if (listener instanceof KeyBoardActionListener)
{
((KeyBoardActionListener) listener).keyReleaseEvent(this);
}
}
}
/**
* 組合模式葉子和樹枝通用方法,遍歷時候,可使葉子和樹枝相同對待
*/
protected abstract void operation();
}
package observer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Branch extends Component
{
public Branch(String branchName)
{
super(branchName);
}
private ArrayList<Component> components = new ArrayList<Component>();
public void addComponent(Component component)
{
this.components.add(component);
}
public void removeComponent(Component component)
{
this.components.remove(component);
}
public Collection<Component> getComponents()
{
return components;
}
@Override
protected Component getComponent()
{
return this;
}
public void spreadLeaf()
{
System.out.println("樹枝:" + getComponentName() + "展開節點");
}
@Override
protected void operation()
{
for (Iterator<Component> it = getComponents().iterator(); it.hasNext();)
{
Component component = it.next();
System.out.println("當前節點:"+component.getComponentName());
component.operation();
}
}
}
package observer;
public class Leaf extends Component
{
public Leaf(String leafName)
{
super(leafName);
}
@Override
protected Component getComponent()
{
return this;
}
public void clickLeaf()
{
System.out.println("點擊了" + getComponentName() );
}
@Override
protected void operation()
{
System.out.println("leafName:" + getComponentName() + " 節點");
}
}
package observer;
public interface ActionListener
{
void actionPerformer(Component component);
}
package observer;
public interface MouseActionListener extends ActionListener
{
void clickEvent(Component component);
void doubleClickEvent(Component component);
void dragEvent(Component component);
}
package observer;
public class MouseActionListenerAdapter implements MouseActionListener
{
@Override
public void actionPerformer(Component component)
{
// TODO Auto-generated method stub
}
/** 增加一個默認單擊事件實現 */
@Override
public void clickEvent(Component component)
{
if (component instanceof Branch)
{
((Branch) component).spreadLeaf();
}
if (component instanceof Leaf)
{
((Leaf) component).clickLeaf();
}
}
@Override
public void doubleClickEvent(Component component)
{
// TODO Auto-generated method stub
}
@Override
public void dragEvent(Component component)
{
// TODO Auto-generated method stub
}
}
package observer;
public interface KeyBoardActionListener extends ActionListener
{
void keyPressEvent(Component component);
void keyReleaseEvent(Component component);
}
package observer;
public class KeyBoardActionListenerAdapter implements KeyBoardActionListener
{
@Override
public void actionPerformer(Component component)
{
// TODO Auto-generated method stub
}
@Override
public void keyPressEvent(Component component)
{
// TODO Auto-generated method stub
}
@Override
public void keyReleaseEvent(Component component)
{
// TODO Auto-generated method stub
}
}
package observer;
public class Client
{
public static void main(String[] args)
{
//根節點
Branch root = new Branch("根節點");
//葉子節點
Leaf leaf1 = new Leaf("葉子1");
//增加葉子1監聽事件
leaf1.addActionListener(new MouseActionListenerAdapter());
//樹枝節點
Branch branch1 = new Branch("樹枝1");
//增加樹枝1監聽事件
branch1.addActionListener(new MouseActionListenerAdapter());
//給樹枝1再增加一個葉子和一個樹枝
Leaf leaf2 = new Leaf("葉子2");
//leaf2增加監聽事件
leaf2.addActionListener(new MouseActionListenerAdapter());
Branch branch2 = new Branch("樹枝1-1");
Leaf leaf3 = new Leaf("葉子3");
//增加監聽事件
leaf3.addActionListener(new MouseActionListenerAdapter());
branch2.addComponent(leaf3);
//添加到樹枝1 下面
branch1.addComponent(leaf2);
branch1.addComponent(branch2);
//添加到根節點下面
root.addComponent(leaf1);
root.addComponent(branch1);
//先調用一次遍歷
root.operation();
//然后 觸發點擊葉子3事件
System.out.println("
開始觸發點擊事件
");
//葉子3事件連續觸發了4次,這就是事件冒泡原理,因為上面對Component組件加了4個不同監聽
//其他組件也捕獲了這次事件,如果阻止冒泡,那么獲取該事件,做一次判斷即可
leaf3.clickOperation();
}
}
輸出結果:
當前節點:葉子1
leafName:葉子1 節點
當前節點:樹枝1
當前節點:葉子2
leafName:葉子2 節點
當前節點:樹枝1-1
當前節點:葉子3
leafName:葉子3 節點
......開始觸發點擊事件......
點擊了葉子3
點擊了葉子3
點擊了葉子3
點擊了葉子3
posted on 2013-09-30 15:08
朔望魔刃 閱讀(264)
評論(0) 編輯 收藏 所屬分類:
設計模式&&數據結構