1、说明
利用观察者模式实现JFrame界面与数据分离解耦
2、代码
package com.hallo.refactoring.DOD;
import java.util.Observable;
import io.netty.util.internal.StringUtil;
/**
* 负责界面修改数据获取、重新计算(length = end - start)
* @author xwc
*
*/
public class Interval extends Observable {
private String _start = "0";
private String _end = "0";
private String _length = "0";
String getStart() {
return _start;
}
String getEnd() {
return _end;
}
String getLength() {
return _length;
}
void setStart(String start) {
_start = _returnZeroIfNullOrEmpty(start);
_caculateAndSetLength();
setChanged();
notifyObservers();
}
void setEnd(String end) {
_end = _returnZeroIfNullOrEmpty(end);
_caculateAndSetLength();
setChanged();
notifyObservers();
}
void setLength(String length) {
_length = _returnZeroIfNullOrEmpty(length);
_caculateAndSetEnd();
setChanged();
notifyObservers();
}
private String _returnZeroIfNullOrEmpty(String in) {
if (StringUtil.isNullOrEmpty(in)) {
return "0";
}
return in;
}
private void _caculateAndSetEnd() {
_end = String.valueOf(Integer.valueOf(_start) + Integer.valueOf(_length));
}
private void _caculateAndSetLength() {
_length = String.valueOf(Integer.valueOf(_end) - Integer.valueOf(_start));
}
}
package com.hallo.refactoring.DOD;
import java.awt.EventQueue;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
/**
* 负责界面UI修改及回显操作,数据完全来自于Interval
* @author xwc
*
*/
public class IntervalWindow extends JFrame implements Observer {
/**
*
*/
private static final long serialVersionUID = -2009756583019733200L;
private JPanel contentPane;
TextField startTextField = new TextField();
TextField endTextField = new TextField();
TextField lengthTextField = new TextField();
private Interval _subject;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
IntervalWindow frame = new IntervalWindow();
frame.setTitle("复制被监视数据");
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public IntervalWindow() {
//观察Interval
_subject = new Interval();
_subject.addObserver(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
/** start **/
startTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
try {
_startTextField_FocusLost(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
startTextField.setBounds(217, 74, 74, 23);
contentPane.add(startTextField);
Label label = new Label("start");
label.setBounds(120, 74, 69, 23);
contentPane.add(label);
/** end **/
endTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
try {
_endTextField_FocusLost(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
endTextField.setBounds(217, 117, 74, 23);
contentPane.add(endTextField);
Label label_1 = new Label("end");
label_1.setBounds(120, 117, 69, 23);
contentPane.add(label_1);
/** length **/
Label label_2 = new Label("length");
label_2.setBounds(120, 165, 69, 23);
contentPane.add(label_2);
lengthTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
try {
_lengthTextField_FocusLost(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
lengthTextField.setBounds(217, 165, 74, 23);
contentPane.add(lengthTextField);
//初始化赋值,从Interval类获取
_subject.setStart(startTextField.getText());
_subject.setEnd(endTextField.getText());
_subject.setLength(lengthTextField.getText());
}
/**
* focusLost事件触发时,将当前值传给Interval,然后通过update回调方法,更新界面3个域值
* @param e
* @throws Exception
*/
protected void _lengthTextField_FocusLost(FocusEvent e) throws Exception {
_subject.setLength(lengthTextField.getText());
}
protected void _endTextField_FocusLost(FocusEvent e) throws Exception {
_subject.setEnd(endTextField.getText());
}
protected void _startTextField_FocusLost(FocusEvent e) throws Exception {
_subject.setStart(startTextField.getText());
}
@Override
public void update(Observable o, Object arg) {
startTextField.setText(_subject.getStart());
endTextField.setText(_subject.getEnd());
lengthTextField.setText(_subject.getLength());
}
}
3、效果
修改start或end值时,length值自动修改;修改length值时,end值自动更新: