一个树分为:根节点,树枝,树叶,点击根节点触发一个事件:展开所有树枝;点击树枝触发一个事件:展开所有树叶;点击树叶触发一个事件:屏幕右方显示详细信息。那么即可说明:树是一个组件即被观察者,事件对象即观察者,只要事件源即用户点击操作发生,就通知事件对象观察者做出相应的动作,首先组装出树结构,采用安全的合成模式,类示意图如下:
如果对树组件增加监听事件,即增加观察者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
朔望魔刃 阅读(260)
评论(0) 编辑 收藏 所属分类:
设计模式&&数据结构