您的位置:首页 > 编程语言

《重构,改善现有代码的设计》第八章 Duplicate Observed Data

2013-02-26 20:30 302 查看
Java代码







import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;

/**
* 《重构,改善现有代码的设计》第八章 Duplicate Observed Data
*
* 业务逻辑:
* 一个JFrame(类IntervalWindow)有三个TextField,分别是start,end和length

* 如果你修改Start或End,length就会自动成为两者计算所得的长度
* 如果你修改length,End就会随之改变(start不变)
*
* 主要是使用了Observer模式:
* start,end和length之间的运算,是与具体界面无关的,应该独立出来(成为一个Subject,观察者模式里面的“目标”)

*
* 关键在于解决以下两个问题:
* 1.什么时候计算?当界面上的TextField值有变动时,由WindowObserver调用Subject的set方法

* 2.计算后如何通知界面?Subject调用notifyObservers方法,这个方法会触发WindowObserver的update方法

*
*/
public class ObserveGUIWindow {

public static
void main(String[] args) {
new WindowObserver().init();
}
}

class WindowObserver implements Observer {

private TextField startField;
private TextField endField;
private TextField lengthField;
private Subject subject;

public void init() {

JFrame f = new JFrame("This is a test");

f.setSize(200, 200);
Container content = f.getContentPane();
content.setBackground(Color.white);
content.setLayout(new FlowLayout());

startField = new TextField("0",
10);
endField = new TextField("0",
10);
lengthField = new TextField("0",
10);
SymFocus listener = new SymFocus();
startField.addFocusListener(listener);
endField.addFocusListener(listener);
lengthField.addFocusListener(listener);

Label startLabel = new Label("start:");

Label endLabel = new Label("end:");

Label lengthLabel = new Label("length:");

content.add(startLabel);
content.add(startField);
content.add(endLabel);
content.add(endField);
content.add(lengthLabel);
content.add(lengthField);

f.setLocationRelativeTo(null);
f.setVisible(true);

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {

System.exit(0);
}
});

subject = new Subject();
subject.addObserver(this);

}

//更新界面,最新的值(计算后)来自Subject
public void update(Observable o, Object arg) {

Subject subject = (Subject)o;
startField.setText(subject.getStart());
endField.setText(subject.getEnd());
lengthField.setText(subject.getLength());
}

class SymFocus extends FocusAdapter {

public void focusLost(FocusEvent event) {

Object object = event.getSource();
if (object == startField)
StartFieldFocusLost(event);
else if (object == endField)

EndFieldFocusLost(event);
else if (object == lengthField)

LengthFieldFocusLost(event);
}
}

void StartFieldFocusLost(FocusEvent event) {

//从界面取得输入的值
String start = startField.getText();
subject.setStart(isInteger(start) ? start : "0");

//交由Subject计算
subject.calculateLength();
}

void EndFieldFocusLost(FocusEvent event) {
String end = endField.getText();
subject.setEnd(isInteger(end) ? end : "0");
subject.calculateLength();
}

void LengthFieldFocusLost(FocusEvent event) {
String length = lengthField.getText();
subject.setLength(isInteger(length) ? length : "0");

subject.calculateEnd();
}

boolean isInteger(String str) {
return str != null && str.matches("[0-9]+");

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: