目录
零、关于观察者模式:
设计模式:5、观察者模式(发布-订阅模式)_发布模式 uml-优快云博客
一、设计要求
- 设计一个窗口,该窗口中有三个文本区。
- 三个文本区中的其中一个可供用户编辑文本,另外两个用户不可编辑。
- 当用户在可编辑的文本中进行文本编辑操作时,另外两个不可编辑文本区中的一个将显示用户所编辑文本中出现的单词,另一个将显示用户所编辑文本中所包含的数字
二、设计实现
1、主题
本问题中,使用java.util包中的Observable类作为主题
2、观察者
观察者是Java.util包中的Observer接口
3、具体主题
InputTextSubject是Observerble类的子类,负责创建具体主题。InputTextSubject类包含一个可编辑的JTextArea文本区,代码如下:
package xyz.jangle.design.app.observer;
import java.util.Observable;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/**
* 具体主题
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月10日 下午3:34:39
*
*/
@SuppressWarnings("deprecation")
public class InputTextSubject extends Observable {
String content;
JTextArea text;
public InputTextSubject() {
text = new JTextArea(10, 15);
text.setLineWrap(true);
text.setWrapStyleWord(true);
(text.getDocument()).addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}
@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
content = text.getText();
setChanged();
notifyObservers(content);
}
});
}
public String getContent() {
return content;
}
public JTextArea getJTextArea() {
return text;
}
}
4、具体观察者
负责创建具体观察者的类是ShowWord和ShowDigit,代码如下:
package xyz.jangle.design.app.observer;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.TreeSet;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月10日 下午3:41:48
*
*/
@SuppressWarnings("deprecation")
public class ShowWord extends JPanel implements Observer {
/**
*
*/
private static final long serialVersionUID = 3141650329393665296L;
Observable subject;
JTextArea text;
TreeSet<String> wordList;
public ShowWord(Observable subject) {
super();
this.subject = subject;
subject.addObserver(this);
text = new JTextArea(10, 15);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setEditable(false);
add(new JScrollPane(text));
wordList = new TreeSet<String>();
}
@Override
public void update(Observable o, Object arg) {
text.setText(null);
text.append("出现的单词有(按字典序排序)");
wordList.clear();
String content = arg.toString();
String regex = "[\\s\\d\\p{Punct}]+";
String words[] = content.split(regex);
for(int i = 0;i<words.length;i++) {
wordList.add(words[i]);
}
Iterator<String> iterator = wordList.iterator();
while(iterator.hasNext()) {
text.append(iterator.next() + " ");
}
}
}
package xyz.jangle.design.app.observer;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月10日 下午3:57:13
*
*/
@SuppressWarnings("deprecation")
public class ShowDigit extends JPanel implements Observer {
/**
*
*/
private static final long serialVersionUID = 68790415105796644L;
Observable subject;
JTextArea text;
Vector<String> vector;
public ShowDigit(Observable subject) {
super();
this.subject = subject;
this.subject.addObserver(this);
text = new JTextArea(10, 15);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setEditable(false);
add(new JScrollPane(text));
vector = new Vector<String>();
}
@Override
public void update(Observable o, Object arg) {
text.setText(null);
text.append("出现的数字有:\n");
vector.removeAllElements();
String content = arg.toString();
String regex = "\\D+"; // 非数字字符构成的正则表达式
String digitWords[] = content.split(regex);
for(int i=0;i<digitWords.length;i++) {
if(!vector.contains(digitWords[i])) {
vector.add(digitWords[i]);
}
}
for(int i=0;i<vector.size();i++) {
text.append(vector.elementAt(i)+ " ");
// vector.get(i);
}
}
}
5、应用程序
package xyz.jangle.design.app.observer;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
/**
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月10日 下午4:08:33
*
*/
public class Application extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1766425301653051370L;
public Application() throws HeadlessException {
super();
InputTextSubject inputTextSubject = new InputTextSubject();
ShowWord observerOne = new ShowWord(inputTextSubject);
ShowDigit observerTwo = new ShowDigit(inputTextSubject);
setLayout(new FlowLayout());
add(new JScrollPane(inputTextSubject.getJTextArea()));
add(observerOne);
add(observerTwo);
setBounds(20, 20, 400, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Application();
}
}
三、执行效果

553



被折叠的 条评论
为什么被折叠?



